Bug 1399533 - Remove duplicate checks in ForOfPIC::Chain. r=djvj
authorAndré Bargull <andre.bargull@gmail.com>
Wed, 13 Sep 2017 18:31:22 +0200
changeset 382635 05438478048521aaf9f2f874660c8f9b16819140
parent 382634 bb40b2b9b866d49cfe13c01b1b38a64fcdbb783e
child 382636 e986a5b71a67eb21817560df77c3def5db3da103
push id95373
push userryanvm@gmail.com
push dateSun, 24 Sep 2017 20:57:30 +0000
treeherdermozilla-inbound@054384780485 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdjvj
bugs1399533
milestone58.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 1399533 - Remove duplicate checks in ForOfPIC::Chain. r=djvj
js/src/vm/PIC.cpp
js/src/vm/PIC.h
--- a/js/src/vm/PIC.cpp
+++ b/js/src/vm/PIC.cpp
@@ -76,34 +76,16 @@ js::ForOfPIC::Chain::initialize(JSContex
     arrayProtoIteratorSlot_ = iterShape->slot();
     canonicalIteratorFunc_ = iterator;
     arrayIteratorProtoShape_ = arrayIteratorProto->lastProperty();
     arrayIteratorProtoNextSlot_ = nextShape->slot();
     canonicalNextFunc_ = next;
     return true;
 }
 
-js::ForOfPIC::Stub*
-js::ForOfPIC::Chain::isArrayOptimized(ArrayObject* obj)
-{
-    Stub* stub = getMatchingStub(obj);
-    if (!stub)
-        return nullptr;
-
-    // Ensure that this is an otherwise optimizable array.
-    if (!isOptimizableArray(obj))
-        return nullptr;
-
-    // Not yet enough!  Ensure that the world as we know it remains sane.
-    if (!isArrayStateStillSane())
-        return nullptr;
-
-    return stub;
-}
-
 bool
 js::ForOfPIC::Chain::tryOptimizeArray(JSContext* cx, HandleArrayObject array, bool* optimized)
 {
     MOZ_ASSERT(optimized);
 
     *optimized = false;
 
     if (!initialized_) {
@@ -122,71 +104,62 @@ js::ForOfPIC::Chain::tryOptimizeArray(JS
 
     // If PIC is disabled, don't bother trying to optimize.
     if (disabled_)
         return true;
 
     // By the time we get here, we should have a sane array state to work with.
     MOZ_ASSERT(isArrayStateStillSane());
 
+    // Ensure array's prototype is the actual Array.prototype
+    if (array->staticPrototype() != arrayProto_)
+        return true;
+
     // Check if stub already exists.
-    ForOfPIC::Stub* stub = isArrayOptimized(&array->as<ArrayObject>());
-    if (stub) {
+    if (hasMatchingStub(array)) {
         *optimized = true;
         return true;
     }
 
+    // Ensure array doesn't define @@iterator directly.
+    if (array->lookup(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().iterator)))
+        return true;
+
     // If the number of stubs is about to exceed the limit, throw away entire
     // existing cache before adding new stubs.  We shouldn't really have heavy
     // churn on these.
     if (numStubs() >= MAX_STUBS)
         eraseChain();
 
-    // Ensure array's prototype is the actual Array.prototype
-    if (!isOptimizableArray(array))
-        return true;
-
-    // Ensure array doesn't define @@iterator directly.
-    if (array->lookup(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().iterator)))
-        return true;
-
     // Good to optimize now, create stub to add.
     RootedShape shape(cx, array->lastProperty());
-    stub = cx->new_<Stub>(shape);
+    Stub* stub = cx->new_<Stub>(shape);
     if (!stub)
         return false;
 
     // Add the stub.
     addStub(stub);
 
     *optimized = true;
     return true;
 }
 
-js::ForOfPIC::Stub*
-js::ForOfPIC::Chain::getMatchingStub(JSObject* obj)
+bool
+js::ForOfPIC::Chain::hasMatchingStub(ArrayObject* obj)
 {
     // Ensure PIC is initialized and not disabled.
-    if (!initialized_ || disabled_)
-        return nullptr;
+    MOZ_ASSERT(initialized_ && !disabled_);
 
     // Check if there is a matching stub.
     for (Stub* stub = stubs(); stub != nullptr; stub = stub->next()) {
-        if (stub->shape() == obj->maybeShape())
-            return stub;
+        if (stub->shape() == obj->shape())
+            return true;
     }
 
-    return nullptr;
-}
-
-bool
-js::ForOfPIC::Chain::isOptimizableArray(JSObject* obj)
-{
-    MOZ_ASSERT(obj->is<ArrayObject>());
-    return obj->staticPrototype() == arrayProto_;
+    return false;
 }
 
 bool
 js::ForOfPIC::Chain::isArrayStateStillSane()
 {
     // Ensure that canonical Array.prototype has matching shape.
     if (arrayProto_->lastProperty() != arrayProtoShape_)
         return false;
--- a/js/src/vm/PIC.h
+++ b/js/src/vm/PIC.h
@@ -214,19 +214,16 @@ struct ForOfPIC
             arrayIteratorProtoNextSlot_(-1),
             initialized_(false),
             disabled_(false)
         {}
 
         // Initialize the canonical iterator function.
         bool initialize(JSContext* cx);
 
-        // Check if a given array object is optimized by this PIC.
-        Stub* isArrayOptimized(ArrayObject* obj);
-
         // Try to optimize this chain for an object.
         bool tryOptimizeArray(JSContext* cx, HandleArrayObject array, bool* optimized);
 
         // Check if the global array-related objects have not been messed with
         // in a way that would disable this PIC.
         bool isArrayStateStillSane();
 
         // Check if ArrayIterator.next is still optimizable.
@@ -234,21 +231,18 @@ struct ForOfPIC
             return (arrayIteratorProto_->lastProperty() == arrayIteratorProtoShape_) &&
                 (arrayIteratorProto_->getSlot(arrayIteratorProtoNextSlot_) == canonicalNextFunc_);
         }
 
         void trace(JSTracer* trc);
         void sweep(FreeOp* fop);
 
       private:
-        // Get a matching optimized stub for the given object.
-        Stub* getMatchingStub(JSObject* obj);
-
-        // Check if the given object is for-of optimizable with this PIC.
-        bool isOptimizableArray(JSObject* obj);
+        // Check if a matching optimized stub for the given object exists.
+        bool hasMatchingStub(ArrayObject* obj);
 
         // Reset the PIC and all info associated with it.
         void reset(JSContext* cx);
 
         // Erase the stub chain.
         void eraseChain();
     };