mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Eliminate separate global frame and merge it with InterpState (482377, r=brendan).
This commit is contained in:
parent
1b820884be
commit
1af13483ea
@ -1240,7 +1240,6 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* _anchor, Fragment* _frag
|
|||||||
lirbuf->sp = addName(lir->insLoad(LIR_ldp, lirbuf->state, (int)offsetof(InterpState, sp)), "sp");
|
lirbuf->sp = addName(lir->insLoad(LIR_ldp, lirbuf->state, (int)offsetof(InterpState, sp)), "sp");
|
||||||
lirbuf->rp = addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(InterpState, rp)), "rp");
|
lirbuf->rp = addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(InterpState, rp)), "rp");
|
||||||
cx_ins = addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(InterpState, cx)), "cx");
|
cx_ins = addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(InterpState, cx)), "cx");
|
||||||
gp_ins = addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(InterpState, global)), "gp");
|
|
||||||
eos_ins = addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(InterpState, eos)), "eos");
|
eos_ins = addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(InterpState, eos)), "eos");
|
||||||
eor_ins = addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(InterpState, eor)), "eor");
|
eor_ins = addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(InterpState, eor)), "eor");
|
||||||
globalObj_ins = addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(InterpState, globalObj)), "globalObj");
|
globalObj_ins = addName(lir->insLoad(LIR_ldp, lirbuf->state, offsetof(InterpState, globalObj)), "globalObj");
|
||||||
@ -1349,8 +1348,8 @@ TraceRecorder::nativeGlobalOffset(jsval* p) const
|
|||||||
{
|
{
|
||||||
JS_ASSERT(isGlobal(p));
|
JS_ASSERT(isGlobal(p));
|
||||||
if (size_t(p - globalObj->fslots) < JS_INITIAL_NSLOTS)
|
if (size_t(p - globalObj->fslots) < JS_INITIAL_NSLOTS)
|
||||||
return size_t(p - globalObj->fslots) * sizeof(double);
|
return sizeof(InterpState) + size_t(p - globalObj->fslots) * sizeof(double);
|
||||||
return ((p - globalObj->dslots) + JS_INITIAL_NSLOTS) * sizeof(double);
|
return sizeof(InterpState) + ((p - globalObj->dslots) + JS_INITIAL_NSLOTS) * sizeof(double);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine whether a value is a global stack slot */
|
/* Determine whether a value is a global stack slot */
|
||||||
@ -1818,7 +1817,7 @@ TraceRecorder::import(TreeInfo* treeInfo, LIns* sp, unsigned stackSlots, unsigne
|
|||||||
uint16* gslots = treeInfo->globalSlots->data();
|
uint16* gslots = treeInfo->globalSlots->data();
|
||||||
uint8* m = globalTypeMap;
|
uint8* m = globalTypeMap;
|
||||||
FORALL_GLOBAL_SLOTS(cx, ngslots, gslots,
|
FORALL_GLOBAL_SLOTS(cx, ngslots, gslots,
|
||||||
import(gp_ins, nativeGlobalOffset(vp), vp, *m, vpname, vpnum, NULL);
|
import(lirbuf->state, nativeGlobalOffset(vp), vp, *m, vpname, vpnum, NULL);
|
||||||
m++;
|
m++;
|
||||||
);
|
);
|
||||||
ptrdiff_t offset = -treeInfo->nativeStackBase;
|
ptrdiff_t offset = -treeInfo->nativeStackBase;
|
||||||
@ -1867,7 +1866,8 @@ TraceRecorder::lazilyImportGlobalSlot(unsigned slot)
|
|||||||
if ((type == JSVAL_INT) && oracle.isGlobalSlotUndemotable(cx, slot))
|
if ((type == JSVAL_INT) && oracle.isGlobalSlotUndemotable(cx, slot))
|
||||||
type = JSVAL_DOUBLE;
|
type = JSVAL_DOUBLE;
|
||||||
treeInfo->typeMap.add(type);
|
treeInfo->typeMap.add(type);
|
||||||
import(gp_ins, slot*sizeof(double), vp, type, "global", index, NULL);
|
import(lirbuf->state, sizeof(struct InterpState) + slot*sizeof(double),
|
||||||
|
vp, type, "global", index, NULL);
|
||||||
specializeTreesToMissingGlobals(cx, treeInfo);
|
specializeTreesToMissingGlobals(cx, treeInfo);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1898,13 +1898,13 @@ TraceRecorder::set(jsval* p, LIns* i, bool initializing)
|
|||||||
LIns* x = nativeFrameTracker.get(p);
|
LIns* x = nativeFrameTracker.get(p);
|
||||||
if (!x) {
|
if (!x) {
|
||||||
if (isGlobal(p))
|
if (isGlobal(p))
|
||||||
x = writeBack(i, gp_ins, nativeGlobalOffset(p));
|
x = writeBack(i, lirbuf->state, nativeGlobalOffset(p));
|
||||||
else
|
else
|
||||||
x = writeBack(i, lirbuf->sp, -treeInfo->nativeStackBase + nativeStackOffset(p));
|
x = writeBack(i, lirbuf->sp, -treeInfo->nativeStackBase + nativeStackOffset(p));
|
||||||
nativeFrameTracker.set(p, x);
|
nativeFrameTracker.set(p, x);
|
||||||
} else {
|
} else {
|
||||||
#define ASSERT_VALID_CACHE_HIT(base, offset) \
|
#define ASSERT_VALID_CACHE_HIT(base, offset) \
|
||||||
JS_ASSERT(base == lirbuf->sp || base == gp_ins); \
|
JS_ASSERT(base == lirbuf->sp || base == lirbuf->state); \
|
||||||
JS_ASSERT(offset == ((base == lirbuf->sp) \
|
JS_ASSERT(offset == ((base == lirbuf->sp) \
|
||||||
? -treeInfo->nativeStackBase + nativeStackOffset(p) \
|
? -treeInfo->nativeStackBase + nativeStackOffset(p) \
|
||||||
: nativeGlobalOffset(p))); \
|
: nativeGlobalOffset(p))); \
|
||||||
@ -2042,7 +2042,7 @@ TraceRecorder::adjustCallerTypes(Fragment* f)
|
|||||||
LIns* i = get(vp);
|
LIns* i = get(vp);
|
||||||
bool isPromote = isPromoteInt(i);
|
bool isPromote = isPromoteInt(i);
|
||||||
if (isPromote && *m == JSVAL_DOUBLE)
|
if (isPromote && *m == JSVAL_DOUBLE)
|
||||||
lir->insStorei(get(vp), gp_ins, nativeGlobalOffset(vp));
|
lir->insStorei(get(vp), lirbuf->state, nativeGlobalOffset(vp));
|
||||||
else if (!isPromote && *m == JSVAL_INT) {
|
else if (!isPromote && *m == JSVAL_INT) {
|
||||||
debug_only_v(printf("adjusting will fail, %s%d, slot %d\n", vpname, vpnum, m - map);)
|
debug_only_v(printf("adjusting will fail, %s%d, slot %d\n", vpname, vpnum, m - map);)
|
||||||
oracle.markGlobalSlotUndemotable(cx, gslots[n]);
|
oracle.markGlobalSlotUndemotable(cx, gslots[n]);
|
||||||
@ -3907,17 +3907,7 @@ js_ExecuteTree(JSContext* cx, Fragment* f, uintN& inlineCallCount,
|
|||||||
TreeInfo* ti = (TreeInfo*)f->vmprivate;
|
TreeInfo* ti = (TreeInfo*)f->vmprivate;
|
||||||
unsigned ngslots = ti->globalSlots->length();
|
unsigned ngslots = ti->globalSlots->length();
|
||||||
uint16* gslots = ti->globalSlots->data();
|
uint16* gslots = ti->globalSlots->data();
|
||||||
|
unsigned globalFrameSize = STOBJ_NSLOTS(globalObj);
|
||||||
InterpState state;
|
|
||||||
|
|
||||||
state.cx = cx;
|
|
||||||
state.globalObj = globalObj;
|
|
||||||
state.inlineCallCountp = &inlineCallCount;
|
|
||||||
state.innermostNestedGuardp = innermostNestedGuardp;
|
|
||||||
state.outermostTree = ti;
|
|
||||||
state.lastTreeExitGuard = NULL;
|
|
||||||
state.lastTreeCallGuard = NULL;
|
|
||||||
state.rpAtLastTreeCall = NULL;
|
|
||||||
|
|
||||||
/* Make sure the global object is sane. */
|
/* Make sure the global object is sane. */
|
||||||
JS_ASSERT(!ngslots || (OBJ_SHAPE(JS_GetGlobalForObject(cx, cx->fp->scopeChain)) == ti->globalShape));
|
JS_ASSERT(!ngslots || (OBJ_SHAPE(JS_GetGlobalForObject(cx, cx->fp->scopeChain)) == ti->globalShape));
|
||||||
@ -3928,35 +3918,44 @@ js_ExecuteTree(JSContext* cx, Fragment* f, uintN& inlineCallCount,
|
|||||||
if (!js_ReserveObjects(cx, MAX_CALL_STACK_ENTRIES))
|
if (!js_ReserveObjects(cx, MAX_CALL_STACK_ENTRIES))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
/* Setup the interpreter state block, which is followed by the native global frame. */
|
||||||
|
InterpState* state = (InterpState*)alloca(sizeof(InterpState) + (globalFrameSize+1)*sizeof(double));
|
||||||
|
state->cx = cx;
|
||||||
|
state->globalObj = globalObj;
|
||||||
|
state->inlineCallCountp = &inlineCallCount;
|
||||||
|
state->innermostNestedGuardp = innermostNestedGuardp;
|
||||||
|
state->outermostTree = ti;
|
||||||
|
state->lastTreeExitGuard = NULL;
|
||||||
|
state->lastTreeCallGuard = NULL;
|
||||||
|
state->rpAtLastTreeCall = NULL;
|
||||||
|
|
||||||
/* Setup the native global frame. */
|
/* Setup the native global frame. */
|
||||||
unsigned globalFrameSize = STOBJ_NSLOTS(globalObj);
|
double* global = (double*)(state+1);
|
||||||
state.global = (double*)alloca((globalFrameSize+1) * sizeof(double));
|
|
||||||
|
|
||||||
/* Setup the native stack frame. */
|
/* Setup the native stack frame. */
|
||||||
double stack_buffer[MAX_NATIVE_STACK_SLOTS];
|
double stack_buffer[MAX_NATIVE_STACK_SLOTS];
|
||||||
state.stackBase = stack_buffer;
|
state->stackBase = stack_buffer;
|
||||||
double* entry_sp = &stack_buffer[ti->nativeStackBase/sizeof(double)];
|
state->sp = stack_buffer + (ti->nativeStackBase/sizeof(double));
|
||||||
state.sp = entry_sp;
|
state->eos = stack_buffer + MAX_NATIVE_STACK_SLOTS;
|
||||||
state.eos = state.sp + MAX_NATIVE_STACK_SLOTS;
|
|
||||||
|
|
||||||
/* Setup the native call stack frame. */
|
/* Setup the native call stack frame. */
|
||||||
FrameInfo* callstack_buffer[MAX_CALL_STACK_ENTRIES];
|
FrameInfo* callstack_buffer[MAX_CALL_STACK_ENTRIES];
|
||||||
state.callstackBase = callstack_buffer;
|
state->callstackBase = callstack_buffer;
|
||||||
state.rp = callstack_buffer;
|
state->rp = callstack_buffer;
|
||||||
state.eor = callstack_buffer + MAX_CALL_STACK_ENTRIES;
|
state->eor = callstack_buffer + MAX_CALL_STACK_ENTRIES;
|
||||||
|
|
||||||
void *reserve;
|
void *reserve;
|
||||||
state.stackMark = JS_ARENA_MARK(&cx->stackPool);
|
state->stackMark = JS_ARENA_MARK(&cx->stackPool);
|
||||||
JS_ARENA_ALLOCATE(reserve, &cx->stackPool, MAX_INTERP_STACK_BYTES);
|
JS_ARENA_ALLOCATE(reserve, &cx->stackPool, MAX_INTERP_STACK_BYTES);
|
||||||
if (!reserve)
|
if (!reserve)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
memset(stack_buffer, 0xCD, sizeof(stack_buffer));
|
memset(stack_buffer, 0xCD, sizeof(stack_buffer));
|
||||||
memset(state.global, 0xCD, (globalFrameSize+1)*sizeof(double));
|
memset(global, 0xCD, (globalFrameSize+1)*sizeof(double));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
debug_only(*(uint64*)&state.global[globalFrameSize] = 0xdeadbeefdeadbeefLL;)
|
debug_only(*(uint64*)&global[globalFrameSize] = 0xdeadbeefdeadbeefLL;)
|
||||||
debug_only_v(printf("entering trace at %s:%u@%u, native stack slots: %u code: %p\n",
|
debug_only_v(printf("entering trace at %s:%u@%u, native stack slots: %u code: %p\n",
|
||||||
cx->fp->script->filename,
|
cx->fp->script->filename,
|
||||||
js_FramePCToLineNumber(cx, cx->fp),
|
js_FramePCToLineNumber(cx, cx->fp),
|
||||||
@ -3967,14 +3966,14 @@ js_ExecuteTree(JSContext* cx, Fragment* f, uintN& inlineCallCount,
|
|||||||
JS_ASSERT(ti->nGlobalTypes() == ngslots);
|
JS_ASSERT(ti->nGlobalTypes() == ngslots);
|
||||||
|
|
||||||
if (ngslots)
|
if (ngslots)
|
||||||
BuildNativeGlobalFrame(cx, ngslots, gslots, ti->globalTypeMap(), state.global);
|
BuildNativeGlobalFrame(cx, ngslots, gslots, ti->globalTypeMap(), global);
|
||||||
BuildNativeStackFrame(cx, 0/*callDepth*/, ti->typeMap.data(), stack_buffer);
|
BuildNativeStackFrame(cx, 0/*callDepth*/, ti->typeMap.data(), stack_buffer);
|
||||||
|
|
||||||
union { NIns *code; GuardRecord* (FASTCALL *func)(InterpState*, Fragment*); } u;
|
union { NIns *code; GuardRecord* (FASTCALL *func)(InterpState*, Fragment*); } u;
|
||||||
u.code = f->code();
|
u.code = f->code();
|
||||||
|
|
||||||
#ifdef EXECUTE_TREE_TIMER
|
#ifdef EXECUTE_TREE_TIMER
|
||||||
state.startTime = rdtsc();
|
state->startTime = rdtsc();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set a flag that indicates to the runtime system that we are running in native code
|
/* Set a flag that indicates to the runtime system that we are running in native code
|
||||||
@ -3983,14 +3982,14 @@ js_ExecuteTree(JSContext* cx, Fragment* f, uintN& inlineCallCount,
|
|||||||
and eventually triggers the GC. */
|
and eventually triggers the GC. */
|
||||||
JS_ASSERT(!tm->onTrace);
|
JS_ASSERT(!tm->onTrace);
|
||||||
tm->onTrace = true;
|
tm->onTrace = true;
|
||||||
cx->interpState = &state;
|
cx->interpState = state;
|
||||||
|
|
||||||
debug_only(fflush(NULL);)
|
debug_only(fflush(NULL);)
|
||||||
GuardRecord* rec;
|
GuardRecord* rec;
|
||||||
#if defined(JS_NO_FASTCALL) && defined(NANOJIT_IA32)
|
#if defined(JS_NO_FASTCALL) && defined(NANOJIT_IA32)
|
||||||
SIMULATE_FASTCALL(rec, &state, NULL, u.func);
|
SIMULATE_FASTCALL(rec, state, NULL, u.func);
|
||||||
#else
|
#else
|
||||||
rec = u.func(&state, NULL);
|
rec = u.func(state, NULL);
|
||||||
#endif
|
#endif
|
||||||
VMSideExit* lr = (VMSideExit*)rec->exit;
|
VMSideExit* lr = (VMSideExit*)rec->exit;
|
||||||
|
|
||||||
@ -3998,8 +3997,8 @@ js_ExecuteTree(JSContext* cx, Fragment* f, uintN& inlineCallCount,
|
|||||||
|
|
||||||
JS_ASSERT(lr->exitType != LOOP_EXIT || !lr->calldepth);
|
JS_ASSERT(lr->exitType != LOOP_EXIT || !lr->calldepth);
|
||||||
tm->onTrace = false;
|
tm->onTrace = false;
|
||||||
LeaveTree(state, lr);
|
LeaveTree(*state, lr);
|
||||||
return state.innermost;
|
return state->innermost;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JS_FORCES_STACK void
|
static JS_FORCES_STACK void
|
||||||
@ -4195,8 +4194,9 @@ LeaveTree(InterpState& state, VMSideExit* lr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* write back interned globals */
|
/* write back interned globals */
|
||||||
FlushNativeGlobalFrame(cx, ngslots, gslots, globalTypeMap, state.global);
|
double* global = (double*)(&state + 1);
|
||||||
JS_ASSERT(*(uint64*)&state.global[STOBJ_NSLOTS(state.globalObj)] == 0xdeadbeefdeadbeefLL);
|
FlushNativeGlobalFrame(cx, ngslots, gslots, globalTypeMap, global);
|
||||||
|
JS_ASSERT(*(uint64*)&global[STOBJ_NSLOTS(state.globalObj)] == 0xdeadbeefdeadbeefLL);
|
||||||
|
|
||||||
/* write back native stack frame */
|
/* write back native stack frame */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -348,7 +348,6 @@ struct InterpState
|
|||||||
{
|
{
|
||||||
double *sp; // native stack pointer, stack[0] is spbase[0]
|
double *sp; // native stack pointer, stack[0] is spbase[0]
|
||||||
void *rp; // call stack pointer
|
void *rp; // call stack pointer
|
||||||
double *global; // global frame pointer
|
|
||||||
JSContext *cx; // current VM context handle
|
JSContext *cx; // current VM context handle
|
||||||
double *eos; // first unusable word after the native stack
|
double *eos; // first unusable word after the native stack
|
||||||
void *eor; // first unusable word after the call stack
|
void *eor; // first unusable word after the call stack
|
||||||
@ -402,7 +401,6 @@ class TraceRecorder : public avmplus::GCObject {
|
|||||||
nanojit::LirWriter* float_filter;
|
nanojit::LirWriter* float_filter;
|
||||||
#endif
|
#endif
|
||||||
nanojit::LIns* cx_ins;
|
nanojit::LIns* cx_ins;
|
||||||
nanojit::LIns* gp_ins;
|
|
||||||
nanojit::LIns* eos_ins;
|
nanojit::LIns* eos_ins;
|
||||||
nanojit::LIns* eor_ins;
|
nanojit::LIns* eor_ins;
|
||||||
nanojit::LIns* globalObj_ins;
|
nanojit::LIns* globalObj_ins;
|
||||||
|
Loading…
Reference in New Issue
Block a user