Backed out changeset d94b6a6469b4 (bug 1092947) for jsreftest crashes.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 14 Nov 2014 19:05:14 -0500
changeset 240186 b5fdc0c44b6c653babecfb14f2467de66eaee08a
parent 240185 261e7681ed027a3b5da5e10b6b110e027c343ce2
child 240187 6b81753950778d82e9b71142f44aef23c6f234f3
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1092947
milestone36.0a1
backs outd94b6a6469b49f666334af051b62ef0a95aceb3d
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
Backed out changeset d94b6a6469b4 (bug 1092947) for jsreftest crashes.
js/src/jit/CodeGenerator.cpp
js/src/jit/arm/CodeGenerator-arm.cpp
js/src/jit/mips/CodeGenerator-mips.cpp
js/src/jit/shared/CodeGenerator-x86-shared.cpp
js/src/jit/x64/MacroAssembler-x64.h
js/src/jit/x86/MacroAssembler-x86.h
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -2092,22 +2092,20 @@ CodeGenerator::visitOsrEntry(LOsrEntry *
     if (gen->info().executionMode() == SequentialExecution) {
         if (!emitTracelogStopEvent(TraceLogger::Baseline))
             return false;
         if (!emitTracelogStartEvent(TraceLogger::IonMonkey))
             return false;
     }
 #endif
 
-    // Allocate the full frame for this function
-    // Note we have a new entry here. So we reset MacroAssembler::framePushed()
-    // to 0, before reserving the stack.
-    MOZ_ASSERT(masm.framePushed() == frameSize());
-    masm.setFramePushed(0);
-    masm.reserveStack(frameSize());
+    // Allocate the full frame for this function.
+    uint32_t size = frameSize();
+    if (size != 0)
+        masm.subPtr(Imm32(size), StackPointer);
     return true;
 }
 
 bool
 CodeGenerator::visitOsrScopeChain(LOsrScopeChain *lir)
 {
     const LAllocation *frame   = lir->getOperand(0);
     const LDefinition *object  = lir->getDef(0);
@@ -3590,16 +3588,33 @@ CodeGenerator::generateArgumentsChecks(b
     // This function can be used the normal way to check the argument types,
     // before entering the function and bailout when arguments don't match.
     // For debug purpose, this is can also be used to force/check that the
     // arguments are correct. Upon fail it will hit a breakpoint.
 
     MIRGraph &mir = gen->graph();
     MResumePoint *rp = mir.entryResumePoint();
 
+    // Reserve the amount of stack the actual frame will use. We have to undo
+    // this before falling through to the method proper though, because the
+    // monomorphic call case will bypass this entire path.
+
+    // On windows, we cannot skip very far down the stack without touching the
+    // memory pages in-between.  This is a corner-case code for situations where the
+    // Ion frame data for a piece of code is very large.  To handle this special case,
+    // for frames over 1k in size we allocate memory on the stack incrementally, touching
+    // it as we go.
+    uint32_t frameSizeLeft = frameSize();
+    while (frameSizeLeft > 4096) {
+        masm.reserveStack(4096);
+        masm.store32(Imm32(0), Address(StackPointer, 0));
+        frameSizeLeft -= 4096;
+    }
+    masm.reserveStack(frameSizeLeft);
+
     // No registers are allocated yet, so it's safe to grab anything.
     Register temp = GeneralRegisterSet(EntryTempMask).getAny();
 
     CompileInfo &info = gen->info();
 
     Label miss;
     for (uint32_t i = info.startArgSlot(); i < info.endArgSlot(); i++) {
         // All initial parameters are guaranteed to be MParameters.
@@ -3624,16 +3639,18 @@ CodeGenerator::generateArgumentsChecks(b
             Label success;
             masm.jump(&success);
             masm.bind(&miss);
             masm.assumeUnreachable("Argument check fail.");
             masm.bind(&success);
         }
     }
 
+    masm.freeStack(frameSize());
+
     return true;
 }
 
 // Out-of-line path to report over-recursed error and fail.
 class CheckOverRecursedFailure : public OutOfLineCodeBase<CodeGenerator>
 {
     LInstruction *lir_;
 
@@ -7419,60 +7436,65 @@ CodeGenerator::generate()
         return false;
 
     if (!snapshots_.init())
         return false;
 
     if (!safepoints_.init(gen->alloc(), graph.totalSlotCount()))
         return false;
 
-    if (!generatePrologue())
-        return false;
+#ifdef JS_TRACE_LOGGING
+    if (!gen->compilingAsmJS() && gen->info().executionMode() == SequentialExecution) {
+        if (!emitTracelogScriptStart())
+            return false;
+        if (!emitTracelogStartEvent(TraceLogger::IonMonkey))
+            return false;
+    }
+#endif
 
     // Before generating any code, we generate type checks for all parameters.
     // This comes before deoptTable_, because we can't use deopt tables without
     // creating the actual frame.
     if (!generateArgumentsChecks())
         return false;
 
     if (frameClass_ != FrameSizeClass::None()) {
         deoptTable_ = gen->jitRuntime()->getBailoutTable(frameClass_);
         if (!deoptTable_)
             return false;
     }
 
-    // Skip over the alternative entry to IonScript code.
-    Label skipPrologue;
-    masm.jump(&skipPrologue);
-
-    // An alternative entry to the IonScript code, which doesn't test the
-    // arguments.
+#ifdef JS_TRACE_LOGGING
+    Label skip;
+    masm.jump(&skip);
+#endif
+
+    // Remember the entry offset to skip the argument check.
     masm.flushBuffer();
     setSkipArgCheckEntryOffset(masm.size());
-    masm.setFramePushed(0);
-    if (!generatePrologue())
-        return false;
-
-    masm.bind(&skipPrologue);
 
 #ifdef JS_TRACE_LOGGING
     if (!gen->compilingAsmJS() && gen->info().executionMode() == SequentialExecution) {
         if (!emitTracelogScriptStart())
             return false;
         if (!emitTracelogStartEvent(TraceLogger::IonMonkey))
             return false;
     }
+    masm.bind(&skip);
 #endif
 
 #ifdef DEBUG
     // Assert that the argument types are correct.
     if (!generateArgumentsChecks(/* bailout = */ false))
         return false;
 #endif
 
+    if (!generatePrologue())
+        return false;
+
     // Reset native => bytecode map table with top-level script and startPc.
     if (!addNativeToBytecodeEntry(startSite))
         return false;
 
     if (!generateBody())
         return false;
 
     // Reset native => bytecode map table with top-level script and startPc.
--- a/js/src/jit/arm/CodeGenerator-arm.cpp
+++ b/js/src/jit/arm/CodeGenerator-arm.cpp
@@ -35,17 +35,16 @@ using JS::GenericNaN;
 CodeGeneratorARM::CodeGeneratorARM(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm)
   : CodeGeneratorShared(gen, graph, masm)
 {
 }
 
 bool
 CodeGeneratorARM::generatePrologue()
 {
-    MOZ_ASSERT(masm.framePushed() == 0);
     MOZ_ASSERT(!gen->compilingAsmJS());
 
     // Note that this automatically sets MacroAssembler::framePushed().
     masm.reserveStack(frameSize());
     masm.checkStackAlignment();
     return true;
 }
 
--- a/js/src/jit/mips/CodeGenerator-mips.cpp
+++ b/js/src/jit/mips/CodeGenerator-mips.cpp
@@ -35,19 +35,17 @@ using JS::GenericNaN;
 CodeGeneratorMIPS::CodeGeneratorMIPS(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm)
   : CodeGeneratorShared(gen, graph, masm)
 {
 }
 
 bool
 CodeGeneratorMIPS::generatePrologue()
 {
-    MOZ_ASSERT(masm.framePushed() == 0);
     MOZ_ASSERT(!gen->compilingAsmJS());
-
     // Note that this automatically sets MacroAssembler::framePushed().
     masm.reserveStack(frameSize());
     masm.checkStackAlignment();
     return true;
 }
 
 bool
 CodeGeneratorMIPS::generateEpilogue()
--- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp
@@ -36,21 +36,21 @@ namespace jit {
 CodeGeneratorX86Shared::CodeGeneratorX86Shared(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm)
   : CodeGeneratorShared(gen, graph, masm)
 {
 }
 
 bool
 CodeGeneratorX86Shared::generatePrologue()
 {
-    MOZ_ASSERT(masm.framePushed() == 0);
     MOZ_ASSERT(!gen->compilingAsmJS());
 
     // Note that this automatically sets MacroAssembler::framePushed().
     masm.reserveStack(frameSize());
+
     return true;
 }
 
 bool
 CodeGeneratorX86Shared::generateEpilogue()
 {
     MOZ_ASSERT(!gen->compilingAsmJS());
 
--- a/js/src/jit/x64/MacroAssembler-x64.h
+++ b/js/src/jit/x64/MacroAssembler-x64.h
@@ -547,30 +547,18 @@ class MacroAssemblerX64 : public MacroAs
         cmpPtr(lhs, rhs);
         emitSet(cond, dest);
     }
 
     /////////////////////////////////////////////////////////////////
     // Common interface.
     /////////////////////////////////////////////////////////////////
     void reserveStack(uint32_t amount) {
-        if (amount) {
-            // On windows, we cannot skip very far down the stack without touching the
-            // memory pages in-between.  This is a corner-case code for situations where the
-            // Ion frame data for a piece of code is very large.  To handle this special case,
-            // for frames over 1k in size we allocate memory on the stack incrementally, touching
-            // it as we go.
-            uint32_t amountLeft = amount;
-            while (amountLeft > 4096) {
-                subq(Imm32(amount), StackPointer);
-                store32(Imm32(0), Address(StackPointer, 0));
-                amountLeft -= 4096;
-            }
-            subq(Imm32(amountLeft), StackPointer);
-        }
+        if (amount)
+            subq(Imm32(amount), StackPointer);
         framePushed_ += amount;
     }
     void freeStack(uint32_t amount) {
         MOZ_ASSERT(amount <= framePushed_);
         if (amount)
             addq(Imm32(amount), StackPointer);
         framePushed_ -= amount;
     }
--- a/js/src/jit/x86/MacroAssembler-x86.h
+++ b/js/src/jit/x86/MacroAssembler-x86.h
@@ -560,30 +560,18 @@ class MacroAssemblerX86 : public MacroAs
         cmpPtr(lhs, rhs);
         emitSet(cond, dest);
     }
 
     /////////////////////////////////////////////////////////////////
     // Common interface.
     /////////////////////////////////////////////////////////////////
     void reserveStack(uint32_t amount) {
-        if (amount) {
-            // On windows, we cannot skip very far down the stack without touching the
-            // memory pages in-between.  This is a corner-case code for situations where the
-            // Ion frame data for a piece of code is very large.  To handle this special case,
-            // for frames over 1k in size we allocate memory on the stack incrementally, touching
-            // it as we go.
-            uint32_t amountLeft = amount;
-            while (amountLeft > 4096) {
-                subl(Imm32(4096), StackPointer);
-                store32(Imm32(0), Address(StackPointer, 0));
-                amountLeft -= 4096;
-            }
-            subl(Imm32(amountLeft), StackPointer);
-        }
+        if (amount)
+            subl(Imm32(amount), StackPointer);
         framePushed_ += amount;
     }
     void freeStack(uint32_t amount) {
         MOZ_ASSERT(amount <= framePushed_);
         if (amount)
             addl(Imm32(amount), StackPointer);
         framePushed_ -= amount;
     }