Bug 1320408 - Part 16: Change NativeObject::removeProperty to static method. r=jandem
authorTooru Fujisawa <arai_a@mac.com>
Wed, 01 Feb 2017 05:24:45 +0900
changeset 331938 c16497ad79a932392108ed7dc8df9c4b521d670f
parent 331937 42b3573b6996fca8278b396ff0ebfce1d49402b1
child 331939 2909aaf6bc2a5486f39263bdb1cb6ddd56c738cd
push id31291
push usercbook@mozilla.com
push dateWed, 01 Feb 2017 12:14:40 +0000
treeherdermozilla-central@9e7b1041929f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1320408
milestone54.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 1320408 - Part 16: Change NativeObject::removeProperty to static method. r=jandem
js/src/vm/NativeObject.cpp
js/src/vm/NativeObject.h
js/src/vm/Shape.cpp
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -694,20 +694,20 @@ NativeObject::maybeDensifySparseElements
              * When removing a property from a dictionary, the specified
              * property will be removed from the dictionary list and the
              * last property will then be changed due to reshaping the object.
              * Compute the next shape in the traverse, watching for such
              * removals from the list.
              */
             if (shape != obj->lastProperty()) {
                 shape = shape->previous();
-                if (!obj->removeProperty(cx, id))
+                if (!NativeObject::removeProperty(cx, obj, id))
                     return DenseElementResult::Failure;
             } else {
-                if (!obj->removeProperty(cx, id))
+                if (!NativeObject::removeProperty(cx, obj, id))
                     return DenseElementResult::Failure;
                 shape = obj->lastProperty();
             }
 
             obj->setDenseElement(index, value);
         } else {
             shape = shape->previous();
         }
@@ -1067,17 +1067,17 @@ CallAddPropertyHook(ExclusiveContext* cx
                     HandleValue value)
 {
     if (JSAddPropertyOp addProperty = obj->getClass()->getAddProperty()) {
         if (!cx->shouldBeJSContext())
             return false;
 
         RootedId id(cx, shape->propid());
         if (!CallJSAddPropertyOp(cx->asJSContext(), addProperty, obj, id, value)) {
-            obj->removeProperty(cx, shape->propid());
+            NativeObject::removeProperty(cx, obj, shape->propid());
             return false;
         }
     }
     return true;
 }
 
 static inline bool
 CallAddPropertyHookDense(ExclusiveContext* cx, HandleNativeObject obj, uint32_t index,
@@ -2559,14 +2559,14 @@ js::NativeDeleteProperty(JSContext* cx, 
         // Typed array elements are non-configurable.
         MOZ_ASSERT(!obj->is<TypedArrayObject>());
 
         if (!obj->maybeCopyElementsForWrite(cx))
             return false;
 
         obj->setDenseElementHole(cx, JSID_TO_INT(id));
     } else {
-        if (!obj->removeProperty(cx, id))
+        if (!NativeObject::removeProperty(cx, obj, id))
             return false;
     }
 
     return SuppressDeletedProperty(cx, obj, id);
 }
--- a/js/src/vm/NativeObject.h
+++ b/js/src/vm/NativeObject.h
@@ -752,17 +752,17 @@ class NativeObject : public ShapedObject
                 unsigned flags);
 
     /* Change the given property into a sibling with the same id in this scope. */
     static Shape*
     changeProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleShape shape,
                    unsigned attrs, JSGetterOp getter, JSSetterOp setter);
 
     /* Remove the property named by id from this object. */
-    bool removeProperty(ExclusiveContext* cx, jsid id);
+    static bool removeProperty(ExclusiveContext* cx, HandleNativeObject obj, jsid id);
 
     /* Clear the scope, making it empty. */
     static void clear(ExclusiveContext* cx, HandleNativeObject obj);
 
   protected:
     /*
      * Internal helper that adds a shape not yet mapped by this object.
      *
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -963,138 +963,137 @@ NativeObject::changeProperty(ExclusiveCo
     RootedId propid(cx, shape->propid());
     Shape* newShape = putProperty(cx, obj, propid, getter, setter,
                                   shape->maybeSlot(), attrs, shape->flags);
 
     obj->checkShapeConsistency();
     return newShape;
 }
 
-bool
-NativeObject::removeProperty(ExclusiveContext* cx, jsid id_)
+/* static */ bool
+NativeObject::removeProperty(ExclusiveContext* cx, HandleNativeObject obj, jsid id_)
 {
     RootedId id(cx, id_);
-    RootedNativeObject self(cx, this);
 
     AutoKeepShapeTables keep(cx);
     ShapeTable::Entry* entry;
     RootedShape shape(cx);
-    if (!Shape::search(cx, lastProperty(), id, keep, shape.address(), &entry))
+    if (!Shape::search(cx, obj->lastProperty(), id, keep, shape.address(), &entry))
         return false;
 
     if (!shape)
         return true;
 
     /*
      * If shape is not the last property added, or the last property cannot
      * be removed, switch to dictionary mode.
      */
-    if (!self->inDictionaryMode() && (shape != self->lastProperty() || !self->canRemoveLastProperty())) {
-        if (!self->toDictionaryMode(cx))
+    if (!obj->inDictionaryMode() && (shape != obj->lastProperty() || !obj->canRemoveLastProperty())) {
+        if (!obj->toDictionaryMode(cx))
             return false;
-        ShapeTable* table = self->lastProperty()->maybeTable(keep);
+        ShapeTable* table = obj->lastProperty()->maybeTable(keep);
         MOZ_ASSERT(table);
         entry = &table->search<MaybeAdding::NotAdding>(shape->propid(), keep);
         shape = entry->shape();
     }
 
     /*
      * If in dictionary mode, get a new shape for the last property after the
      * removal. We need a fresh shape for all dictionary deletions, even of
      * the last property. Otherwise, a shape could replay and caches might
      * return deleted DictionaryShapes! See bug 595365. Do this before changing
      * the object or table, so the remaining removal is infallible.
      */
     RootedShape spare(cx);
-    if (self->inDictionaryMode()) {
+    if (obj->inDictionaryMode()) {
         /* For simplicity, always allocate an accessor shape for now. */
         spare = Allocate<AccessorShape>(cx);
         if (!spare)
             return false;
         new (spare) Shape(shape->base()->unowned(), 0);
-        if (shape == self->lastProperty()) {
+        if (shape == obj->lastProperty()) {
             /*
              * Get an up to date unowned base shape for the new last property
              * when removing the dictionary's last property. Information in
              * base shapes for non-last properties may be out of sync with the
              * object's state.
              */
-            RootedShape previous(cx, self->lastProperty()->parent);
-            StackBaseShape base(self->lastProperty()->base());
+            RootedShape previous(cx, obj->lastProperty()->parent);
+            StackBaseShape base(obj->lastProperty()->base());
             BaseShape* nbase = BaseShape::getUnowned(cx, base);
             if (!nbase)
                 return false;
             previous->base_ = nbase;
         }
     }
 
     /* If shape has a slot, free its slot number. */
     if (shape->hasSlot()) {
-        self->freeSlot(cx, shape->slot());
+        obj->freeSlot(cx, shape->slot());
         if (cx->isJSContext())
             ++cx->asJSContext()->runtime()->propertyRemovals;
     }
 
     /*
      * A dictionary-mode object owns mutable, unique shapes on a non-circular
      * doubly linked list, hashed by lastProperty()->table. So we can edit the
      * list and hash in place.
      */
-    if (self->inDictionaryMode()) {
-        ShapeTable* table = self->lastProperty()->maybeTable(keep);
+    if (obj->inDictionaryMode()) {
+        ShapeTable* table = obj->lastProperty()->maybeTable(keep);
         MOZ_ASSERT(table);
 
         if (entry->hadCollision()) {
             entry->setRemoved();
             table->decEntryCount();
             table->incRemovedCount();
         } else {
             entry->setFree();
             table->decEntryCount();
 
 #ifdef DEBUG
             /*
              * Check the consistency of the table but limit the number of
              * checks not to alter significantly the complexity of the
              * delete in debug builds, see bug 534493.
              */
-            Shape* aprop = self->lastProperty();
+            Shape* aprop = obj->lastProperty();
             for (int n = 50; --n >= 0 && aprop->parent; aprop = aprop->parent)
-                MOZ_ASSERT_IF(aprop != shape, self->contains(cx, aprop));
+                MOZ_ASSERT_IF(aprop != shape, obj->contains(cx, aprop));
 #endif
         }
 
         {
             /* Remove shape from its non-circular doubly linked list. */
-            Shape* oldLastProp = self->lastProperty();
-            shape->removeFromDictionary(self);
+            Shape* oldLastProp = obj->lastProperty();
+            shape->removeFromDictionary(obj);
 
             /* Hand off table from the old to new last property. */
-            oldLastProp->handoffTableTo(self->lastProperty());
+            oldLastProp->handoffTableTo(obj->lastProperty());
         }
 
         /* Generate a new shape for the object, infallibly. */
-        JS_ALWAYS_TRUE(self->generateOwnShape(cx, spare));
+        JS_ALWAYS_TRUE(obj->generateOwnShape(cx, spare));
 
         /* Consider shrinking table if its load factor is <= .25. */
         uint32_t size = table->capacity();
         if (size > ShapeTable::MIN_SIZE && table->entryCount() <= size >> 2)
             (void) table->change(cx, -1);
     } else {
         /*
          * Non-dictionary-mode shape tables are shared immutables, so all we
          * need do is retract the last property and we'll either get or else
          * lazily make via a later hashify the exact table for the new property
          * lineage.
          */
-        MOZ_ASSERT(shape == self->lastProperty());
-        self->removeLastProperty(cx);
+        MOZ_ASSERT(shape == obj->lastProperty());
+        obj->removeLastProperty(cx);
     }
 
-    self->checkShapeConsistency();
+    obj->checkShapeConsistency();
     return true;
 }
 
 /* static */ void
 NativeObject::clear(ExclusiveContext* cx, HandleNativeObject obj)
 {
     Shape* shape = obj->lastProperty();
     MOZ_ASSERT(obj->inDictionaryMode() == shape->inDictionary());
@@ -1128,17 +1127,17 @@ NativeObject::rollbackProperties(Exclusi
         if (obj->lastProperty()->isEmptyShape()) {
             MOZ_ASSERT(slotSpan == 0);
             break;
         } else {
             uint32_t slot = obj->lastProperty()->slot();
             if (slot < slotSpan)
                 break;
         }
-        if (!obj->removeProperty(cx, obj->lastProperty()->propid()))
+        if (!NativeObject::removeProperty(cx, obj, obj->lastProperty()->propid()))
             return false;
     }
 
     return true;
 }
 
 Shape*
 NativeObject::replaceWithNewEquivalentShape(ExclusiveContext* cx, Shape* oldShape, Shape* newShape,