Bug 1171777 - Make sure the index is nonnegative in GetElement IC with hole. r=jandem, a=lizzard
authorTooru Fujisawa <arai_a@mac.com>
Mon, 08 Jun 2015 22:31:43 +0900
changeset 275009 5abb398bb65e467f784906130911fd35f1faacde
parent 275008 d7f11dc4f9dacd75d566ec6bd0f97dcd68f8a442
child 275010 0881f2f13465069a2d53868fd60d4710c2196fd1
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem, lizzard
bugs1171777
milestone40.0a2
Bug 1171777 - Make sure the index is nonnegative in GetElement IC with hole. r=jandem, a=lizzard
js/src/jit-test/tests/basic/dense-elements-hole-negative.js
js/src/jit/IonCaches.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/dense-elements-hole-negative.js
@@ -0,0 +1,31 @@
+// The index is negative before code generation.
+
+let v = {};
+let negativeIndex = -1;
+
+function f(obj) {
+  assertEq(obj[negativeIndex] === v, true);
+}
+for (let i = 0; i < 2000; i++) {
+  let obj = {};
+  obj[1] = {};
+  obj[negativeIndex] = v;
+  f(obj);
+}
+
+// The sign of the index changes after the code generation.
+
+function g(obj, i) {
+  for (let j = 0; j < 4; j++) {
+    assertEq(obj[i-j] === v, true);
+  }
+}
+for (let i = 0; i < 2000; i++) {
+  let obj = {};
+  obj[1] = {};
+  let X = 2000 - i;
+  for (let j = 0; j < 10; j++) {
+    obj[X-j] = v;
+  }
+  g(obj, X);
+}
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -3514,17 +3514,17 @@ GetElementIC::attachDenseElement(JSConte
     setHasDenseStub();
     return linkAndAttachStub(cx, masm, attacher, ion, "dense array");
 }
 
 
 /* static */ bool
 GetElementIC::canAttachDenseElementHole(JSObject* obj, const Value& idval, TypedOrValueRegister output)
 {
-    if (!idval.isInt32())
+    if (!idval.isInt32() || idval.toInt32() < 0)
         return false;
 
     if (!output.hasValue())
         return false;
 
     if (!obj->isNative())
         return false;
 
@@ -3613,16 +3613,19 @@ GenerateDenseElementHole(JSContext* cx, 
         MOZ_ASSERT(indexReg != InvalidReg);
         ValueOperand val = index.reg().valueReg();
 
         masm.branchTestInt32(Assembler::NotEqual, val, &failures);
 
         // Unbox the index.
         masm.unboxInt32(val, indexReg);
 
+        // Make sure index is nonnegative.
+        masm.branch32(Assembler::LessThan, indexReg, Imm32(0), &failures);
+
         // Save the object register.
         masm.push(object);
         elementsReg = object;
     } else {
         MOZ_ASSERT(!index.reg().typedReg().isFloat());
         indexReg = index.reg().typedReg().gpr();
         elementsReg = scratchReg;
     }