Commit c0b54e73 authored by Jan de Mooij's avatar Jan de Mooij
Browse files

Bug 1701897 - Make check for redundant property changes more precise. r=jonco

The object flags are only relevant for the last property's shape. Comparing them
to the flags stored in the property's shape could result in doing unnecessary work
in certain (actually redundant) cases.

Differential Revision: https://phabricator.services.mozilla.com/D110222
parent 316a92df
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -974,10 +974,11 @@ Shape* NativeObject::putDataProperty(JSContext* cx, HandleNativeObject obj,
  ObjectFlags objectFlags = GetObjectFlagsForNewShape<IsAccessor::No>(
      obj->lastProperty(), id, attrs, cx);

  // Now that we've possibly preserved slot, check whether all members match.
  // If so, this is a redundant "put" and we can return without more work.
  if (shape->matchesParamsAfterId(obj->lastProperty()->base(), objectFlags,
                                  slot, attrs, nullptr, nullptr)) {
  // Now that we've possibly preserved slot, check whether the property info and
  // object flags match. If so, this is a redundant "put" and we can return
  // without more work.
  if (shape->matchesPropertyParamsAfterId(slot, attrs, nullptr, nullptr) &&
      obj->lastProperty()->objectFlags() == objectFlags) {
    return shape;
  }

@@ -1083,10 +1084,11 @@ Shape* NativeObject::putAccessorProperty(JSContext* cx, HandleNativeObject obj,
  ObjectFlags objectFlags = GetObjectFlagsForNewShape<IsAccessor::Yes>(
      obj->lastProperty(), id, attrs, cx);

  // Check whether all members match. If so, this is a redundant "put" and we
  // can return without more work.
  if (shape->matchesParamsAfterId(obj->lastProperty()->base(), objectFlags,
                                  SHAPE_INVALID_SLOT, attrs, getter, setter)) {
  // Check whether the property info and object flags match. If so, this is a
  // redundant "put" and we can return without more work.
  if (shape->matchesPropertyParamsAfterId(SHAPE_INVALID_SLOT, attrs, getter,
                                          setter) &&
      obj->lastProperty()->objectFlags() == objectFlags) {
    return shape;
  }

+6 −1
Original line number Diff line number Diff line
@@ -1150,7 +1150,12 @@ class Shape : public gc::CellWithTenuredGCPointer<gc::TenuredCell, BaseShape> {
                            uint32_t aslot, unsigned aattrs, JSObject* getter,
                            JSObject* setter) const {
    return base == this->base() && objectFlags() == aobjectFlags &&
           maybeSlot() == aslot && attrs == aattrs &&
           matchesPropertyParamsAfterId(aslot, aattrs, getter, setter);
  }

  bool matchesPropertyParamsAfterId(uint32_t aslot, unsigned aattrs,
                                    JSObject* getter, JSObject* setter) const {
    return maybeSlot() == aslot && attrs == aattrs &&
           maybeGetterObject() == getter && maybeSetterObject() == setter;
  }