Bug 1362590 - Always give global scripts an extra frame slot in JIT code for compiling INITGLEXICAL. r=jandem, a=gchang
authorShu-yu Guo <shu@rfrn.org>
Thu, 11 May 2017 20:54:35 -0700
changeset 396302 c100ae56e585d7ad9176b4bead105b5c02843407
parent 396301 ec617abf72cd336c59540690e99576df8fcbd4a9
child 396303 7983fa68e19053f1b9a46d7b38f84916ba67716c
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem, gchang
bugs1362590
milestone54.0
Bug 1362590 - Always give global scripts an extra frame slot in JIT code for compiling INITGLEXICAL. r=jandem, a=gchang
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
@@ -1030,18 +1030,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 */