FlushNativeStackFrame currently only handles the innermost nested trees writeback, so at least make it use the proper adjusted stack base for that.
FlushNativeStackFrame currently only handles the innermost nested trees writeback, so at least make it use the proper adjusted stack base for that.
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -1768,18 +1768,21 @@ js_ExecuteTree(JSContext* cx, Fragment*
JS_ASSERT(!cx->gcDontBlock);
cx->gcDontBlock = JS_TRUE;
GuardRecord* lr = u.func(&state, NULL);
cx->gcDontBlock = JS_FALSE;
/* If we bail out on a nested exit, the compiled code returns the outermost nesting
guard but what we are really interested in is the innermost guard that we hit
instead of the guard we were expecting there. */
- if (lr->exit->exitType == NESTED_EXIT)
+ if (lr->exit->exitType == NESTED_EXIT) {
+ debug_only(printf("nested side exit, using guard %p instead of %p\n",
+ state.nestedExit, lr);)
lr = state.nestedExit;
+ }
/* sp_adj and ip_adj are relative to the tree we exit out of, not the tree we
entered into (which might be different in the presence of nested trees). */
ti = (TreeInfo*)lr->from->root->vmprivate;
/* While executing a tree we don't update state->rp, but we do so when we call another
tree. So the total call stack height is the sum of the statically calculated
calldepth in the side exit (relative to the tree entry), and the difference between
@@ -1811,17 +1814,18 @@ js_ExecuteTree(JSContext* cx, Fragment*
/* write back interned globals */
FlushNativeGlobalFrame(cx, e->numGlobalSlots, ti->globalSlots.data(), e->typeMap, global);
JS_ASSERT(ti->globalSlots.length() >= e->numGlobalSlots);
JS_ASSERT(globalFrameSize == STOBJ_NSLOTS(globalObj));
JS_ASSERT(*(uint64*)&global[globalFrameSize] == 0xdeadbeefdeadbeefLL);
/* write back native stack frame */
- FlushNativeStackFrame(cx, e->calldepth, e->typeMap + e->numGlobalSlots, stack);
+ FlushNativeStackFrame(cx, e->calldepth, e->typeMap + e->numGlobalSlots,
+ stack + (((double*)state.sp) - ((double*)entry_sp)));
AUDIT(sideExitIntoInterpreter);
if (!lr) /* did the tree actually execute? */
return NULL;
/* Adjust inlineCallCount by the total call depth at this point (call stack height). */
inlineCallCount += calldepth;