Bug 994876 - Fix DenseSetElemStubExists to check all shapes for DenseAdd stubs. r=djvj
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 15 Apr 2014 17:20:32 +0200
changeset 197147 ed50327aae73fee29da32ffb5bb11ea51a27579d
parent 197146 01530bb2ff64144546a53d20c8ff51df3b7ee726
child 197148 c3878c9f598dc2b794f2ae6023053225d31b629b
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdjvj
bugs994876
milestone31.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 994876 - Fix DenseSetElemStubExists to check all shapes for DenseAdd stubs. r=djvj
js/src/jit/BaselineIC.cpp
js/src/jit/BaselineIC.h
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -4801,34 +4801,47 @@ ICGetElem_Arguments::Compiler::generateS
     return true;
 }
 
 //
 // SetElem_Fallback
 //
 
 static bool
+SetElemDenseAddHasSameShapes(ICSetElem_DenseAdd *stub, JSObject *obj)
+{
+    size_t numShapes = stub->protoChainDepth() + 1;
+    for (size_t i = 0; i < numShapes; i++) {
+        static const size_t MAX_DEPTH = ICSetElem_DenseAdd::MAX_PROTO_CHAIN_DEPTH;
+        if (obj->lastProperty() != stub->toImplUnchecked<MAX_DEPTH>()->shape(i))
+            return false;
+        obj = obj->getProto();
+        if (!obj && i != numShapes - 1)
+            return false;
+    }
+
+    return true;
+}
+
+static bool
 DenseSetElemStubExists(JSContext *cx, ICStub::Kind kind, ICSetElem_Fallback *stub, HandleObject obj)
 {
     JS_ASSERT(kind == ICStub::SetElem_Dense || kind == ICStub::SetElem_DenseAdd);
 
     for (ICStubConstIterator iter = stub->beginChainConst(); !iter.atEnd(); iter++) {
         if (kind == ICStub::SetElem_Dense && iter->isSetElem_Dense()) {
             ICSetElem_Dense *dense = iter->toSetElem_Dense();
             if (obj->lastProperty() == dense->shape() && obj->getType(cx) == dense->type())
                 return true;
         }
 
         if (kind == ICStub::SetElem_DenseAdd && iter->isSetElem_DenseAdd()) {
             ICSetElem_DenseAdd *dense = iter->toSetElem_DenseAdd();
-            if (obj->lastProperty() == dense->toImplUnchecked<0>()->shape(0) &&
-                obj->getType(cx) == dense->type())
-            {
+            if (obj->getType(cx) == dense->type() && SetElemDenseAddHasSameShapes(dense, obj))
                 return true;
-            }
         }
     }
     return false;
 }
 
 static bool
 TypedArraySetElemStubExists(ICSetElem_Fallback *stub, HandleObject obj, bool expectOOB)
 {
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -3550,16 +3550,17 @@ class ICSetElem_DenseAdd : public ICUpda
     static size_t offsetOfType() {
         return offsetof(ICSetElem_DenseAdd, type_);
     }
 
     HeapPtrTypeObject &type() {
         return type_;
     }
     size_t protoChainDepth() const {
+        MOZ_ASSERT(extra_ < MAX_PROTO_CHAIN_DEPTH);
         return extra_;
     }
 
     template <size_t ProtoChainDepth>
     ICSetElem_DenseAddImpl<ProtoChainDepth> *toImplUnchecked() {
         return static_cast<ICSetElem_DenseAddImpl<ProtoChainDepth> *>(this);
     }