author | Nicolas B. Pierron <nicolas.b.pierron@mozilla.com> |
Mon, 26 Jan 2015 12:07:58 +0100 | |
changeset 225636 | 85f601fa7b46d37c5934870e79e882ca4e4ea2c8 |
parent 225635 | e19c170e727f4e9d0786dd87c008da481c8d2a57 |
child 225637 | 42a50f81f29ddbf8740dc915fcd08dbc171cc4ab |
push id | 54628 |
push user | npierron@mozilla.com |
push date | Mon, 26 Jan 2015 11:10:11 +0000 |
treeherder | mozilla-inbound@85f601fa7b46 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bbouvier |
bugs | 1112162 |
milestone | 38.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -1348,21 +1348,21 @@ js::testingFunc_assertFloat32(JSContext CallArgs args = CallArgsFromVp(argc, vp); // NOP when not in IonMonkey args.rval().setUndefined(); return true; } static bool -TestingFunc_assertValidJitStack(JSContext *cx, unsigned argc, jsval *vp) +TestingFunc_assertJitStackInvariants(JSContext *cx, unsigned argc, jsval *vp) { CallArgs args = CallArgsFromVp(argc, vp); - jit::AssertValidJitStack(cx); + jit::AssertJitStackInvariants(cx); args.rval().setUndefined(); return true; } static bool SetJitCompilerOption(JSContext *cx, unsigned argc, jsval *vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -2494,18 +2494,18 @@ gc::ZealModeHelpText), JS_FN_HELP("getObjectMetadata", GetObjectMetadata, 1, 0, "getObjectMetadata(obj)", " Get the metadata for an object."), JS_FN_HELP("bailout", testingFunc_bailout, 0, 0, "bailout()", " Force a bailout out of ionmonkey (if running in ionmonkey)."), - JS_FN_HELP("assertValidJitStack", TestingFunc_assertValidJitStack, 0, 0, -"assertValidJitStack()", + JS_FN_HELP("assertJitStackInvariants", TestingFunc_assertJitStackInvariants, 0, 0, +"assertJitStackInvariants()", " Iterates the Jit stack and check that stack invariants hold."), JS_FN_HELP("setJitCompilerOption", SetJitCompilerOption, 2, 0, "setCompilerOption(<option>, <number>)", " Set a compiler option indexed in JSCompileOption enum to a number.\n"), JS_FN_HELP("setIonCheckGraphCoherency", SetIonCheckGraphCoherency, 1, 0, "setIonCheckGraphCoherency(bool)",
--- a/js/src/jit-test/tests/ion/stack-alignment.js +++ b/js/src/jit-test/tests/ion/stack-alignment.js @@ -1,14 +1,36 @@ setJitCompilerOption("baseline.warmup.trigger", 10); setJitCompilerOption("ion.warmup.trigger", 30); var i; // Check that an entry frame is always aligned properly. function entryFrame_1() { - assertValidJitStack(); + assertJitStackInvariants(); +} + +// Check rectifier frames are keeping the same alignment. +function rectifierFrame_verify(a, b, c, d) { + assertJitStackInvariants(); +} + +function rectifierFrame_1(i) { + rectifierFrame_verify(); +} +function rectifierFrame_2(i) { + rectifierFrame_verify(i); +} +function rectifierFrame_3(i) { + rectifierFrame_verify(i, i); +} +function rectifierFrame_4(i) { + rectifierFrame_verify(i, i, i); } for (i = 0; i < 40; i++) { entryFrame_1(); entryFrame_1(0); entryFrame_1(0, 1); + rectifierFrame_1(i); + rectifierFrame_2(i); + rectifierFrame_3(i); + rectifierFrame_4(i); }
--- a/js/src/jit/JitFrameIterator.h +++ b/js/src/jit/JitFrameIterator.h @@ -84,18 +84,19 @@ class CommonFrameLayout; class JitFrameLayout; class ExitFrameLayout; class BaselineFrame; class JitActivation; // Iterate over the JIT stack to assert that all invariants are respected. -// - Check that all entry frames are aligned on StackAlignment. -void AssertValidJitStack(JSContext *cx); +// - Check that all entry frames are aligned on JitStackAlignment. +// - Check that all rectifier frames keep the JitStackAlignment. +void AssertJitStackInvariants(JSContext *cx); class JitFrameIterator { protected: uint8_t *current_; FrameType type_; uint8_t *returnAddressToFp_; size_t frameSize_;
--- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -3021,22 +3021,40 @@ InvalidationBailoutStack::checkInvariant uint8_t *rawBase = ionScript()->method()->raw(); uint8_t *rawLimit = rawBase + ionScript()->method()->instructionsSize(); uint8_t *osiPoint = osiPointReturnAddress(); MOZ_ASSERT(rawBase <= osiPoint && osiPoint <= rawLimit); #endif } void -AssertValidJitStack(JSContext *cx) +AssertJitStackInvariants(JSContext *cx) { for (JitActivationIterator activations(cx->runtime()); !activations.done(); ++activations) { JitFrameIterator frames(activations); - for (; !frames.done(); ++frames) - continue; + for (; !frames.done(); ++frames) { + + if (frames.prevType() == JitFrame_Rectifier) { + size_t calleeFp = reinterpret_cast<size_t>(frames.fp()); + size_t callerFp = reinterpret_cast<size_t>(frames.prevFp()); + MOZ_ASSERT(callerFp >= calleeFp); + size_t frameSize = callerFp - calleeFp; + + MOZ_RELEASE_ASSERT(frameSize % JitStackAlignment == 0, + "The rectifier frame should keep the alignment"); + + size_t expectedFrameSize = 0 + + sizeof(Value) * (frames.callee()->nargs() + 1 /* |this| argument */ ) + + sizeof(JitFrameLayout); + MOZ_RELEASE_ASSERT(frameSize >= expectedFrameSize, + "The frame is large enough to hold all arguments"); + MOZ_RELEASE_ASSERT(expectedFrameSize + JitStackAlignment > frameSize, + "The frame size is optimal"); + } + } MOZ_RELEASE_ASSERT(frames.type() == JitFrame_Entry, "The first frame of a Jit activation should be an entry frame"); MOZ_RELEASE_ASSERT(reinterpret_cast<size_t>(frames.fp()) % JitStackAlignment == 0, "The entry frame should be properly aligned"); } }