Switch from one global frame to another by walking the two sorted gslots lists.

This commit is contained in:
Andreas Gal 2008-07-28 23:30:16 -07:00
parent fc31baea45
commit b7fda1f5e0

View File

@ -887,6 +887,60 @@ FlushNativeStackFrame(JSContext* cx, unsigned callDepth, uint8* mp, double* np)
return true;
}
/* Switch from one global Frame to another. */
bool
SwitchNativeGlobalFrame(JSContext* cx,
unsigned from_ngslots, uint16* from_gslots, uint8* from_mp, double* from_np,
unsigned to_ngslots, uint16* to_gslots, uint8* to_mp, double* to_np)
{
JSObject* globalObj = JS_GetGlobalForObject(cx, cx->fp->scopeChain);
uint16* from_gslots_stop = from_gslots + from_ngslots;
uint16* to_gslots_stop = to_gslots + to_ngslots;
/* we have to delay the write back of at most from_ngslots doubles */
uint16* double_write_buffer_base = (uint16*)alloca(sizeof(uint16) * from_ngslots);
uint16* double_write_buffer = double_write_buffer_base;
while ((from_gslots < from_gslots_stop) && (to_gslots < to_gslots_stop)) {
uint16 from_slot = *from_gslots;
uint16 to_slot = *to_gslots;
if (from_slot == to_slot) {
/* both have this slot */
*to_np++ = *from_np++;
++from_gslots; ++from_mp;
++to_gslots; ++to_mp;
} else if (from_slot < to_slot) {
/* from frame doesn't have this slot, write it back to the global object */
if (*from_mp++ == JSVAL_DOUBLE)
*double_write_buffer++ = *from_np++;
else if (!NativeToValue(cx, STOBJ_GET_SLOT(globalObj, from_slot),
from_mp[-1], from_np++))
return false;
} else {
/* to frame doesn't have this slot, read it from the global object */
if (!ValueToNative(STOBJ_GET_SLOT(globalObj, to_slot),
*to_mp++, to_np++))
return false;
}
}
while (from_gslots < from_gslots_stop) {
uint16 from_slot = *from_gslots++;
/* from frame doesn't have this slot, write it back to the global object */
if (*from_mp++ == JSVAL_DOUBLE)
*double_write_buffer++ = *from_np++;
else if (!NativeToValue(cx, STOBJ_GET_SLOT(globalObj, from_slot),
from_mp[-1], from_np++))
return false;
}
while (to_gslots < to_gslots_stop) {
uint16 to_slot = *to_gslots++;
/* to frame doesn't have this slot, read it from the global object */
if (!ValueToNative(STOBJ_GET_SLOT(globalObj, to_slot),
*to_mp++, to_np++))
return false;
}
/* we successfully switched to a new global frame */
return true;
}
/* Emit load instructions onto the trace that read the initial stack state. */
void
TraceRecorder::import(LIns* base, ptrdiff_t offset, jsval* p, uint8& t,