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 266227 c569e4e29be6
parent 266226 8de5d18494ab
child 266228 6fe433fed5fb
push id4792
push userryanvm@gmail.com
push date2015-06-10 20:30 +0000
treeherdermozilla-beta@f137fedd1455 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem, lizzard
bugs1171777
milestone39.0
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
@@ -3517,17 +3517,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;
 
@@ -3616,16 +3616,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;
     }