Bug 1362590 - Always give global scripts an extra frame slot in JIT code for compiling INITGLEXICAL. (r=jandem)
authorShu-yu Guo <shu@rfrn.org>
Thu, 11 May 2017 20:54:35 -0700
changeset 358028 358b6ad12d180dc0089b24e8aad8baf2ab270b2d
parent 358027 76408d97fe7a276a2e7c206d57304d11b5fad3e7
child 358029 e1a5bcc620581eebd5757f204732424292f8cb1b
push id31808
push usercbook@mozilla.com
push dateFri, 12 May 2017 12:37:49 +0000
treeherdermozilla-central@030c0a7c8781 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1362590
milestone55.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
Bug 1362590 - Always give global scripts an extra frame slot in JIT code for compiling INITGLEXICAL. (r=jandem)
js/src/jit/BaselineFrameInfo.cpp
js/src/jit/CompileInfo.h
js/src/jit/JitFrames.h
--- a/js/src/jit/BaselineFrameInfo.cpp
+++ b/js/src/jit/BaselineFrameInfo.cpp
@@ -14,17 +14,21 @@
 #include "jit/MacroAssembler-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
 bool
 FrameInfo::init(TempAllocator& alloc)
 {
-    size_t nstack = Max(script->nslots() - script->nfixed(), size_t(MinJITStackSize));
+    // An extra slot is needed for global scopes because INITGLEXICAL (stack
+    // depth 1) is compiled as a SETPROP (stack depth 2) on the global lexical
+    // scope.
+    size_t extra = script->isGlobalCode() ? 1 : 0;
+    size_t nstack = Max(script->nslots() - script->nfixed(), size_t(MinJITStackSize)) + extra;
     if (!stack.init(alloc, nstack))
         return false;
 
     return true;
 }
 
 void
 FrameInfo::sync(StackValue* val)
--- a/js/src/jit/CompileInfo.h
+++ b/js/src/jit/CompileInfo.h
@@ -216,17 +216,22 @@ class CompileInfo
             fun_ = fun_->nonLazyScript()->functionNonDelazifying();
             MOZ_ASSERT(fun_->isTenured());
         }
 
         nimplicit_ = StartArgSlot(script)                   /* env chain and argument obj */
                    + (fun ? 1 : 0);                         /* this */
         nargs_ = fun ? fun->nargs() : 0;
         nlocals_ = script->nfixed();
-        nstack_ = Max<unsigned>(script->nslots() - script->nfixed(), MinJITStackSize);
+
+        // An extra slot is needed for global scopes because INITGLEXICAL (stack
+        // depth 1) is compiled as a SETPROP (stack depth 2) on the global lexical
+        // scope.
+        uint32_t extra = script->isGlobalCode() ? 1 : 0;
+        nstack_ = Max<unsigned>(script->nslots() - script->nfixed(), MinJITStackSize) + extra;
         nslots_ = nimplicit_ + nargs_ + nlocals_ + nstack_;
 
         // For derived class constructors, find and cache the frame slot for
         // the .this binding. This slot is assumed to be always
         // observable. See isObservableFrameSlot.
         if (script->isDerivedClassConstructor()) {
             MOZ_ASSERT(script->functionHasThisBinding());
             CompileRuntime* runtime = GetJitContext()->runtime;
--- a/js/src/jit/JitFrames.h
+++ b/js/src/jit/JitFrames.h
@@ -1022,18 +1022,15 @@ class InvalidationBailoutStack
 };
 
 void
 GetPcScript(JSContext* cx, JSScript** scriptRes, jsbytecode** pcRes);
 
 CalleeToken
 TraceCalleeToken(JSTracer* trc, CalleeToken token);
 
-// The minimum stack size is two. Two slots are needed because INITGLEXICAL
-// (stack depth 1) is compiled as a SETPROP (stack depth 2) on the global
-// lexical scope. Baseline also requires one slot for this/argument type
-// checks.
-static const uint32_t MinJITStackSize = 2;
+// Baseline requires one slot for this/argument type checks.
+static const uint32_t MinJITStackSize = 1;
 
 } /* namespace jit */
 } /* namespace js */
 
 #endif /* jit_JitFrames_h */