зеркало из https://github.com/mozilla/pjs.git
Adding test for bug 451605
This commit is contained in:
Родитель
02cda0e38b
Коммит
2919373917
|
@ -71,7 +71,10 @@
|
|||
|
||||
#include "jsautooplen.h" // generated headers last
|
||||
|
||||
/* Number of iterations of a loop before we start tracing. */
|
||||
/* Number of iterations of a loop where we start tracing. That is, we don't
|
||||
start tracing until the beginning of the HOTLOOP-th iteration. If you
|
||||
change this value, make sure to update all the tests in trace-test.js that
|
||||
depend on it. */
|
||||
#define HOTLOOP 2
|
||||
|
||||
/* Number of times we wait to exit on a side exit before we try to extend the tree. */
|
||||
|
@ -2050,6 +2053,12 @@ js_SynthesizeFrame(JSContext* cx, const FrameInfo& fi)
|
|||
newifp->callerRegs.pc = fi.callpc;
|
||||
newifp->callerRegs.sp = cx->fp->slots + fi.s.spdist;
|
||||
newifp->frame.argv = newifp->callerRegs.sp - JS_MAX(fun->nargs, argc);
|
||||
JS_ASSERT(newifp->frame.argv);
|
||||
#ifdef DEBUG
|
||||
// Initialize argv[-1] to a known-bogus value so we'll catch it if
|
||||
// someone forgets to initialize it later.
|
||||
newifp->frame.argv[-1] = JSVAL_HOLE;
|
||||
#endif
|
||||
JS_ASSERT(newifp->frame.argv >= StackBase(cx->fp));
|
||||
|
||||
newifp->frame.rval = JSVAL_VOID;
|
||||
|
@ -2500,6 +2509,14 @@ js_ExecuteTree(JSContext* cx, Fragment** treep, uintN& inlineCallCount,
|
|||
return NULL;
|
||||
JS_ASSERT(unsigned(slots) == e->numStackSlots);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Verify that our state restoration worked
|
||||
for (JSStackFrame* fp = cx->fp; fp; fp = fp->down) {
|
||||
JS_ASSERT(!fp->callee || JSVAL_IS_OBJECT(fp->argv[-1]));
|
||||
JS_ASSERT(!fp->callee || fp->thisp == JSVAL_TO_OBJECT(fp->argv[-1]));
|
||||
}
|
||||
#endif
|
||||
|
||||
AUDIT(sideExitIntoInterpreter);
|
||||
|
||||
if (!lr) /* did the tree actually execute? */
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
/**
|
||||
* A number of the tests in this file depend on the setting of
|
||||
* HOTLOOP. Define some constants up front, so they're easy to grep
|
||||
* for.
|
||||
*/
|
||||
// The HOTLOOP constant we depend on
|
||||
const HOTLOOP = 2;
|
||||
// The loop count at which we trace
|
||||
const RECORDLOOP = HOTLOOP;
|
||||
// The loop count at which we run the trace
|
||||
const RUNLOOP = HOTLOOP + 1;
|
||||
|
||||
var testName = null;
|
||||
if ("arguments" in this && arguments.length > 0)
|
||||
testName = arguments[0];
|
||||
|
@ -1446,6 +1458,37 @@ function testArrayPushPop() {
|
|||
testArrayPushPop.expected = "55,45";
|
||||
test(testArrayPushPop);
|
||||
|
||||
// Test stack reconstruction after a nested exit
|
||||
function testNestedExitStackInner(j, counter) {
|
||||
++counter;
|
||||
var b = 0;
|
||||
for (var i = 1; i <= RUNLOOP; i++) {
|
||||
++b;
|
||||
var a;
|
||||
// Make sure that once everything has been traced we suddenly switch to
|
||||
// a different control flow the first time we run the outermost tree,
|
||||
// triggering a side exit.
|
||||
if (j < RUNLOOP)
|
||||
a = 1;
|
||||
else
|
||||
a = 0;
|
||||
++b;
|
||||
b += a;
|
||||
}
|
||||
return counter + b;
|
||||
}
|
||||
function testNestedExitStackOuter() {
|
||||
var counter = 0;
|
||||
for (var j = 1; j <= RUNLOOP; ++j) {
|
||||
for (var k = 1; k <= RUNLOOP; ++k) {
|
||||
counter = testNestedExitStackInner(j, counter);
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
testNestedExitStackOuter.expected = 81;
|
||||
test(testNestedExitStackOuter);
|
||||
|
||||
/* Keep these at the end so that we can see the summary after the trace-debug spew. */
|
||||
print("\npassed:", passes.length && passes.join(","));
|
||||
print("\nFAILED:", fails.length && fails.join(","));
|
||||
|
|
Загрузка…
Ссылка в новой задаче