Bug 1246109 - pass state as reference instead of pass by value. r=jandem
authorBogdan Postelnicu <bogdan.postelnicu@softvision.ro>
Wed, 10 Feb 2016 12:10:26 +0200
changeset 330087 f1f70fa6338e63a600046c30dafee0eb3cff51ad
parent 330086 b06f5fef948812558288b1dc34f678f52d7512dd
child 330088 e254460824199368d0c8a7b5c5da40a90d6251f4
child 330094 2b116adb01738259a94b6488d7b0d06c1a63729a
push id10670
push userbmo:james@hoppipolla.co.uk
push dateWed, 10 Feb 2016 12:46:01 +0000
reviewersjandem
bugs1246109
milestone47.0a1
Bug 1246109 - pass state as reference instead of pass by value. r=jandem MozReview-Commit-ID: 5FuDBbQo5xc
js/src/jit/IonBuilder.cpp
js/src/jit/IonBuilder.h
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -2453,17 +2453,17 @@ IonBuilder::finishLoop(CFGState& state, 
     if (!current)
         return ControlStatus_Ended;
 
     pc = current->pc();
     return ControlStatus_Joined;
 }
 
 IonBuilder::ControlStatus
-IonBuilder::restartLoop(CFGState state)
+IonBuilder::restartLoop(const CFGState& state)
 {
     spew("New types at loop header, restarting loop body");
 
     if (JitOptions.limitScriptSize) {
         if (++numLoopRestarts_ >= MAX_LOOP_RESTARTS)
             return ControlStatus_Abort;
     }
 
@@ -2481,29 +2481,35 @@ IonBuilder::restartLoop(CFGState state)
     header->discardAllInstructions();
     header->discardAllResumePoints(/* discardEntry = */ false);
     header->setStackDepth(header->getPredecessor(0)->stackDepth());
 
     popCfgStack();
 
     loopDepth_++;
 
+    // Keep a local copy for these pointers since state will be overwritten in
+    // pushLoop since state is a reference to cfgStack_.back()
+    jsbytecode* condpc = state.loop.condpc;
+    jsbytecode* updatepc = state.loop.updatepc;
+    jsbytecode* updateEnd = state.loop.updateEnd;
+
     if (!pushLoop(state.loop.initialState, state.loop.initialStopAt, header, state.loop.osr,
                   state.loop.loopHead, state.loop.initialPc,
                   state.loop.bodyStart, state.loop.bodyEnd,
                   state.loop.exitpc, state.loop.continuepc))
     {
         return ControlStatus_Error;
     }
 
     CFGState& nstate = cfgStack_.back();
 
-    nstate.loop.condpc = state.loop.condpc;
-    nstate.loop.updatepc = state.loop.updatepc;
-    nstate.loop.updateEnd = state.loop.updateEnd;
+    nstate.loop.condpc = condpc;
+    nstate.loop.updatepc = updatepc;
+    nstate.loop.updateEnd = updateEnd;
 
     // Don't specializePhis(), as the header has been visited before and the
     // phis have already had their type set.
     setCurrent(header);
 
     if (!jsop_loophead(nstate.loop.loopHead))
         return ControlStatus_Error;
 
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -312,17 +312,17 @@ class IonBuilder
     // Incorporates a type/typeSet into an OSR value for a loop, after the loop
     // body has been processed.
     bool addOsrValueTypeBarrier(uint32_t slot, MInstruction** def,
                                 MIRType type, TemporaryTypeSet* typeSet);
     bool maybeAddOsrTypeBarriers();
 
     // Restarts processing of a loop if the type information at its header was
     // incomplete.
-    ControlStatus restartLoop(CFGState state);
+    ControlStatus restartLoop(const CFGState& state);
 
     void assertValidLoopHeadOp(jsbytecode* pc);
 
     ControlStatus forLoop(JSOp op, jssrcnote* sn);
     ControlStatus whileOrForInLoop(jssrcnote* sn);
     ControlStatus doWhileLoop(JSOp op, jssrcnote* sn);
     ControlStatus tableSwitch(JSOp op, jssrcnote* sn);
     ControlStatus condSwitch(JSOp op, jssrcnote* sn);