Bug 1704744 part 8 - Use ShapeProperty more for GetExistingProperty/SetExistingProperty. r=jonco
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 15 Apr 2021 10:11:52 +0000
changeset 576184 9715e3dfb584fd8507f8a3ddbda7cad2b16fe703
parent 576183 c50f3fb04aa3baa887716b48bafbb9e5ea58eb0e
child 576185 d67ea8672eea2785b28403fe04566e0629fbf906
push id38377
push userncsoregi@mozilla.com
push dateThu, 15 Apr 2021 21:46:43 +0000
treeherdermozilla-central@48a99646f183 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1704744
milestone89.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 1704744 part 8 - Use ShapeProperty more for GetExistingProperty/SetExistingProperty. r=jonco Differential Revision: https://phabricator.services.mozilla.com/D111808
js/src/vm/Interpreter-inl.h
js/src/vm/NativeObject.cpp
js/src/vm/NativeObject.h
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -162,19 +162,19 @@ inline bool FetchName(JSContext* cx, Han
     ShapeProperty shapeProp = prop.shapeProperty();
     if (shapeProp.isDataProperty()) {
       /* Fast path for Object instance properties. */
       vp.set(holder->as<NativeObject>().getSlot(shapeProp.slot()));
     } else {
       // Unwrap 'with' environments for reasons given in
       // GetNameBoundInEnvironment.
       RootedObject normalized(cx, MaybeUnwrapWithEnvironment(receiver));
-      RootedShape shape(cx, shapeProp.shapeDeprecated());
+      RootedId id(cx, NameToId(name));
       if (!NativeGetExistingProperty(cx, normalized, holder.as<NativeObject>(),
-                                     shape, vp)) {
+                                     id, shapeProp, vp)) {
         return false;
       }
     }
   }
 
   // We do our own explicit checking for |this|
   if (name == cx->names().dotThis) {
     return true;
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -1466,17 +1466,17 @@ static bool IsDataDescriptor(unsigned at
   MOZ_ASSERT((attrs & (JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY)) == 0);
   return !IsAccessorDescriptor(attrs);
 }
 
 template <AllowGC allowGC>
 static MOZ_ALWAYS_INLINE bool GetExistingProperty(
     JSContext* cx, typename MaybeRooted<Value, allowGC>::HandleType receiver,
     typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
-    typename MaybeRooted<Shape*, allowGC>::HandleType shape,
+    typename MaybeRooted<jsid, allowGC>::HandleType id, ShapeProperty prop,
     typename MaybeRooted<Value, allowGC>::MutableHandleType vp);
 
 static bool GetExistingPropertyValue(JSContext* cx, HandleNativeObject obj,
                                      HandleId id, Handle<PropertyResult> prop,
                                      MutableHandleValue vp) {
   if (prop.isDenseElement()) {
     vp.set(obj->getDenseElement(prop.denseElementIndex()));
     return true;
@@ -1487,18 +1487,18 @@ static bool GetExistingPropertyValue(JSC
   }
 
   MOZ_ASSERT(!cx->isHelperThreadContext());
 
   MOZ_ASSERT(prop.shapeProperty().shapeDeprecated()->propid() == id);
   MOZ_ASSERT(obj->contains(cx, prop.shapeProperty().shapeDeprecated()));
 
   RootedValue receiver(cx, ObjectValue(*obj));
-  RootedShape shape(cx, prop.shapeProperty().shapeDeprecated());
-  return GetExistingProperty<CanGC>(cx, receiver, obj, shape, vp);
+  return GetExistingProperty<CanGC>(cx, receiver, obj, id, prop.shapeProperty(),
+                                    vp);
 }
 
 /*
  * If desc is redundant with an existing own property obj[id], then set
  * |*redundant = true| and return true.
  */
 static bool DefinePropertyIsRedundant(JSContext* cx, HandleNativeObject obj,
                                       HandleId id, Handle<PropertyResult> prop,
@@ -2118,18 +2118,18 @@ bool js::NativeGetOwnPropertyDescriptor(
         return false;
       }
     } else {
       // This is either a straight-up data property or (rarely) a custom data
       // property. The latter must be reported to the caller as a plain data
       // property, so mask away the JSPROP_CUSTOM_DATA_PROP flag.
       desc.attributesRef() &= ~JSPROP_CUSTOM_DATA_PROP;
 
-      RootedShape shape(cx, prop.shapeProperty().shapeDeprecated());
-      if (!NativeGetExistingProperty(cx, obj, obj, shape, desc.value())) {
+      if (!NativeGetExistingProperty(cx, obj, obj, id, prop.shapeProperty(),
+                                     desc.value())) {
         return false;
       }
     }
   }
 
   desc.object().set(obj);
   desc.assertComplete();
   return true;
@@ -2162,62 +2162,59 @@ static bool GetCustomDataProperty(JSCont
     }
   }
 
   cx->check(vp);
   return true;
 }
 
 static inline bool CallGetter(JSContext* cx, HandleNativeObject obj,
-                              HandleValue receiver, HandleShape shape,
-                              MutableHandleValue vp) {
-  MOZ_ASSERT(!shape->isDataProperty());
-
-  if (shape->hasGetterValue()) {
-    ShapeProperty prop = ShapeProperty(shape);
+                              HandleValue receiver, HandleId id,
+                              ShapeProperty prop, MutableHandleValue vp) {
+  MOZ_ASSERT(!prop.isDataProperty());
+
+  if (prop.isAccessorProperty()) {
     RootedValue getter(cx, obj->getGetterValue(prop));
     return js::CallGetter(cx, receiver, getter, vp);
   }
 
-  MOZ_ASSERT(shape->isCustomDataProperty());
-
-  RootedId id(cx, shape->propid());
+  MOZ_ASSERT(prop.isCustomDataProperty());
+
   return GetCustomDataProperty(cx, obj, id, vp);
 }
 
 template <AllowGC allowGC>
 static MOZ_ALWAYS_INLINE bool GetExistingProperty(
     JSContext* cx, typename MaybeRooted<Value, allowGC>::HandleType receiver,
     typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
-    typename MaybeRooted<Shape*, allowGC>::HandleType shape,
+    typename MaybeRooted<jsid, allowGC>::HandleType id, ShapeProperty prop,
     typename MaybeRooted<Value, allowGC>::MutableHandleType vp) {
-  ShapeProperty prop = ShapeProperty(shape);
   if (prop.isDataProperty()) {
     vp.set(obj->getSlot(prop.slot()));
     return true;
   }
 
   vp.setUndefined();
 
   if (!prop.isCustomDataProperty() && !obj->hasGetter(prop)) {
     return true;
   }
 
   if constexpr (!allowGC) {
     return false;
   } else {
-    return CallGetter(cx, obj, receiver, shape, vp);
+    return CallGetter(cx, obj, receiver, id, prop, vp);
   }
 }
 
 bool js::NativeGetExistingProperty(JSContext* cx, HandleObject receiver,
-                                   HandleNativeObject obj, HandleShape shape,
-                                   MutableHandleValue vp) {
+                                   HandleNativeObject obj, HandleId id,
+                                   ShapeProperty prop, MutableHandleValue vp) {
   RootedValue receiverValue(cx, ObjectValue(*receiver));
-  return GetExistingProperty<CanGC>(cx, receiverValue, obj, shape, vp);
+  return GetExistingProperty<CanGC>(cx, receiverValue, obj, id, prop, vp);
 }
 
 enum IsNameLookup { NotNameLookup = false, NameLookup = true };
 
 /*
  * Finish getting the property `receiver[id]` after looking at every object on
  * the prototype chain and not finding any such property.
  *
@@ -2311,17 +2308,18 @@ bool js::GetSparseElementHelper(JSContex
   if (!rawShape) {
     // Property not found, return directly.
     result.setUndefined();
     return true;
   }
 
   RootedValue receiver(cx, ObjectValue(*obj));
   RootedShape shape(cx, rawShape);
-  return GetExistingProperty<CanGC>(cx, receiver, obj, shape, result);
+  return GetExistingProperty<CanGC>(cx, receiver, obj, id, ShapeProperty(shape),
+                                    result);
 }
 
 template <AllowGC allowGC>
 static MOZ_ALWAYS_INLINE bool NativeGetPropertyInline(
     JSContext* cx, typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
     typename MaybeRooted<Value, allowGC>::HandleType receiver,
     typename MaybeRooted<jsid, allowGC>::HandleType id, IsNameLookup nameLookup,
     typename MaybeRooted<Value, allowGC>::MutableHandleType vp) {
@@ -2344,19 +2342,18 @@ static MOZ_ALWAYS_INLINE bool NativeGetP
         return true;
       }
       if (prop.isTypedArrayElement()) {
         size_t idx = prop.typedArrayElementIndex();
         auto* tarr = &pobj->template as<TypedArrayObject>();
         return tarr->template getElement<allowGC>(cx, idx, vp);
       }
 
-      typename MaybeRooted<Shape*, allowGC>::RootType shape(
-          cx, prop.shapeProperty().shapeDeprecated());
-      return GetExistingProperty<allowGC>(cx, receiver, pobj, shape, vp);
+      return GetExistingProperty<allowGC>(cx, receiver, pobj, id,
+                                          prop.shapeProperty(), vp);
     }
 
     // Steps 4.a-b.
     JSObject* proto = pobj->staticPrototype();
 
     // Step 4.c. The spec algorithm simply returns undefined if proto is
     // null, but see the comment on GetNonexistentProperty.
     if (!proto || prop.shouldIgnoreProtoChain()) {
@@ -2478,31 +2475,31 @@ static bool MaybeReportUndeclaredVarAssi
   return false;
 }
 
 /*
  * Finish assignment to a shapeful data property of a native object obj. This
  * conforms to no standard and there is a lot of legacy baggage here.
  */
 static bool NativeSetExistingDataProperty(JSContext* cx, HandleNativeObject obj,
-                                          HandleShape shape, HandleValue v,
+                                          HandleId id, ShapeProperty prop,
+                                          HandleValue v,
                                           ObjectOpResult& result) {
   MOZ_ASSERT(obj->is<NativeObject>());
-  MOZ_ASSERT(shape->isDataDescriptor());
-
-  if (shape->isDataProperty()) {
+  MOZ_ASSERT(prop.isDataDescriptor());
+
+  if (prop.isDataProperty()) {
     // The common path. Standard data property.
-    obj->setSlot(shape->slot(), v);
+    obj->setSlot(prop.slot(), v);
     return result.succeed();
   }
 
-  MOZ_ASSERT(shape->isCustomDataProperty());
+  MOZ_ASSERT(prop.isCustomDataProperty());
   MOZ_ASSERT(!obj->is<WithEnvironmentObject>());  // See bug 1128681.
 
-  RootedId id(cx, shape->propid());
   return SetCustomDataProperty(cx, obj, id, v, result);
 }
 
 /*
  * When a [[Set]] operation finds no existing property with the given id
  * or finds a writable data property on the prototype chain, we end up here.
  * Finish the [[Set]] by defining a new property on receiver.
  *
@@ -2679,21 +2676,20 @@ static bool SetExistingProperty(JSContex
     if (!shapeProp.writable()) {
       return result.fail(JSMSG_READ_ONLY);
     }
 
     // steps 5.c-f.
     if (receiver.isObject() && pobj == &receiver.toObject()) {
       // Pure optimization for the common case. There's no point performing
       // the lookup in step 5.c again, as our caller just did it for us. The
-      // result is |shape|.
+      // result is |shapeProp|.
 
       // Steps 5.e.i-ii.
-      RootedShape shape(cx, shapeProp.shapeDeprecated());
-      return NativeSetExistingDataProperty(cx, pobj, shape, v, result);
+      return NativeSetExistingDataProperty(cx, pobj, id, shapeProp, v, result);
     }
 
     // Shadow pobj[id] by defining a new data property receiver[id].
     // Delegate everything to SetPropertyByDefining.
     return SetPropertyByDefining(cx, id, v, receiver, result);
   }
 
   // Steps 6-11.
--- a/js/src/vm/NativeObject.h
+++ b/js/src/vm/NativeObject.h
@@ -1704,21 +1704,21 @@ extern bool NativeLookupOwnProperty(
     JSContext* cx, typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
     typename MaybeRooted<jsid, allowGC>::HandleType id,
     typename MaybeRooted<PropertyResult, allowGC>::MutableHandleType propp);
 
 /*
  * Get a property from `receiver`, after having already done a lookup and found
  * the property on a native object `obj`.
  *
- * `shape` must not be null and must not be an implicit dense property. It must
- * be present in obj's shape chain.
+ * `prop` must be present in obj's shape.
  */
 extern bool NativeGetExistingProperty(JSContext* cx, HandleObject receiver,
-                                      HandleNativeObject obj, HandleShape shape,
+                                      HandleNativeObject obj, HandleId id,
+                                      ShapeProperty prop,
                                       MutableHandleValue vp);
 
 /* * */
 
 extern bool GetNameBoundInEnvironment(JSContext* cx, HandleObject env,
                                       HandleId id, MutableHandleValue vp);
 
 } /* namespace js */