Bug 857579 - Monitor ICGetIntrinsic_Fallback for when bailing Ion->Baseline during eager compilation. (r=djvj)
authorShu-yu Guo <shu@rfrn.org>
Thu, 04 Apr 2013 08:13:22 -0700
changeset 127706 9cbf2e118de6437a9bbc4fcd7a1ccdc78cd57268
parent 127705 d29304061c08eefd589e79983a445d16705e07aa
child 127707 1aa1dc84a1a40a4616755115bdfd1e566c46cf3c
push id24512
push userryanvm@gmail.com
push dateFri, 05 Apr 2013 20:13:49 +0000
treeherdermozilla-central@139b6ba547fa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdjvj
bugs857579
milestone23.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 857579 - Monitor ICGetIntrinsic_Fallback for when bailing Ion->Baseline during eager compilation. (r=djvj)
js/src/ion/BaselineBailouts.cpp
js/src/ion/BaselineIC.h
js/src/jit-test/tests/baseline/bug857579.js
--- a/js/src/ion/BaselineBailouts.cpp
+++ b/js/src/ion/BaselineBailouts.cpp
@@ -654,18 +654,18 @@ InitFromBailout(JSContext *cx, HandleScr
         *callPC = NULL;
 
         // If the bailout was a resumeAfter, and the opcode is monitored,
         // then the bailed out state should be in a position to enter
         // into the ICTypeMonitor chain for the op.
         bool enterMonitorChain = false;
         if (resumeAfter && (js_CodeSpec[op].format & JOF_TYPESET)) {
             // Not every monitored op has a monitored fallback stub, e.g.
-            // JSOP_GETINTRINSIC will always return the same value so does
-            // not need a monitor chain.
+            // JSOP_NEWOBJECT, which always returns the same type for a
+            // particular script/pc location.
             ICEntry &icEntry = baselineScript->icEntryFromPCOffset(pcOff);
             ICFallbackStub *fallbackStub = icEntry.firstStub()->getChainFallback();
             if (fallbackStub->isMonitoredFallback())
                 enterMonitorChain = true;
         }
 
         uint32_t numCallArgs = isCall ? GET_ARGC(pc) : 0;
 
--- a/js/src/ion/BaselineIC.h
+++ b/js/src/ion/BaselineIC.h
@@ -3587,22 +3587,22 @@ class ICBindName_Fallback : public ICFal
             return ICBindName_Fallback::New(space, getStubCode());
         }
     };
 };
 
 // GetIntrinsic
 //      JSOP_GETINTRINSIC
 //      JSOP_CALLINTRINSIC
-class ICGetIntrinsic_Fallback : public ICFallbackStub
+class ICGetIntrinsic_Fallback : public ICMonitoredFallbackStub
 {
     friend class ICStubSpace;
 
     ICGetIntrinsic_Fallback(IonCode *stubCode)
-      : ICFallbackStub(ICStub::GetIntrinsic_Fallback, stubCode)
+      : ICMonitoredFallbackStub(ICStub::GetIntrinsic_Fallback, stubCode)
     { }
 
   public:
     static inline ICGetIntrinsic_Fallback *New(ICStubSpace *space, IonCode *code) {
         if (!code)
             return NULL;
         return space->allocate<ICGetIntrinsic_Fallback>(code);
     }
@@ -3612,17 +3612,20 @@ class ICGetIntrinsic_Fallback : public I
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::GetIntrinsic_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
-            return ICGetIntrinsic_Fallback::New(space, getStubCode());
+            ICGetIntrinsic_Fallback *stub = ICGetIntrinsic_Fallback::New(space, getStubCode());
+            if (!stub || !stub->initMonitoringChain(cx, space))
+                return NULL;
+            return stub;
         }
     };
 };
 
 // Stub that loads the constant result of a GETINTRINSIC operation.
 class ICGetIntrinsic_Constant : public ICStub
 {
     friend class ICStubSpace;
@@ -5199,9 +5202,8 @@ class ICTypeOf_Typed : public ICFallback
         }
     };
 };
 
 } // namespace ion
 } // namespace js
 
 #endif
-
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/baseline/bug857579.js
@@ -0,0 +1,18 @@
+// |jit-test| ion-eager; error: TypeError
+
+function testMonitorIntrinsic() {
+  var N = 2;
+  // Make an NxN array of zeros.
+  var p = new ParallelArray([N,N], function () 0);
+  // |i| will go out of bounds!
+  for (var i = 0; i < N+1; i++) {
+    for (var j = 0; j < 2; j++) {
+      // When |i| goes out of bounds, we will bail from Ion to BC on an
+      // 'undefined' result inside parallel array's .get, tripping a type
+      // barrier on GETINTRINSIC.
+      p.get(i).get(j);
+    }
+  }
+}
+
+testMonitorIntrinsic();