Bug 1536439 - [Part 2] Simplify ensureShape and maybeShape into nothingness r=tcampbell
authorMatthew Gaudet <mgaudet@mozilla.com>
Thu, 28 Mar 2019 15:03:09 +0000
changeset 466584 a2cba7a15840df9b48c83d498242714b64088328
parent 466583 3a5f3266614a8cfdbb606274d1d748907c9cc898
child 466585 5090ecf6324be03db84bdb1e4d0308a0161702a7
push id35773
push userncsoregi@mozilla.com
push dateFri, 29 Mar 2019 04:11:36 +0000
treeherdermozilla-central@01c0722546ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1536439
milestone68.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 1536439 - [Part 2] Simplify ensureShape and maybeShape into nothingness r=tcampbell Differential Revision: https://phabricator.services.mozilla.com/D25074
js/src/jit/BaselineIC.cpp
js/src/jit/BaselineInspector.cpp
js/src/jit/CacheIR.cpp
js/src/jit/CacheIRSpewer.cpp
js/src/jit/IonIC.cpp
js/src/jit/MacroAssembler.cpp
js/src/jit/ScalarReplacement.cpp
js/src/jit/TemplateObject-inl.h
js/src/jit/TemplateObject.h
js/src/jit/VMFunctions.cpp
js/src/shell/js.cpp
js/src/vm/JSObject-inl.h
js/src/vm/JSObject.h
js/src/vm/Shape.cpp
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -2206,17 +2206,17 @@ bool DoSetElemFallback(JSContext* cx, Ba
              op == JSOP_INITELEM || op == JSOP_INITHIDDENELEM ||
              op == JSOP_INITELEM_ARRAY || op == JSOP_INITELEM_INC);
 
   RootedObject obj(cx, ToObjectFromStack(cx, objv));
   if (!obj) {
     return false;
   }
 
-  RootedShape oldShape(cx, obj->maybeShape());
+  RootedShape oldShape(cx, obj->shape());
   RootedObjectGroup oldGroup(cx, JSObject::getGroup(cx, obj));
   if (!oldGroup) {
     return false;
   }
 
   bool isTemporarilyUnoptimizable = false;
   bool canAddSlot = false;
   bool attached = false;
@@ -2923,17 +2923,17 @@ bool DoSetPropFallback(JSContext* cx, Ba
 
   RootedPropertyName name(cx, script->getName(pc));
   RootedId id(cx, NameToId(name));
 
   RootedObject obj(cx, ToObjectFromStack(cx, lhs));
   if (!obj) {
     return false;
   }
-  RootedShape oldShape(cx, obj->maybeShape());
+  RootedShape oldShape(cx, obj->shape());
   RootedObjectGroup oldGroup(cx, JSObject::getGroup(cx, obj));
   if (!oldGroup) {
     return false;
   }
 
   // There are some reasons we can fail to attach a stub that are temporary.
   // We want to avoid calling noteUnoptimizableAccess() if the reason we
   // failed to attach a stub is one of those temporary reasons, since we might
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -1549,17 +1549,17 @@ static bool GetCacheIRReceiverForProtoRe
   if (!reader.matchOpEither(CacheOp::LoadFixedSlotResult,
                             CacheOp::LoadDynamicSlotResult)) {
     return false;
   }
   if (reader.objOperandId() != holderId) {
     return false;
   }
 
-  if (holder->maybeShape() != holderShape) {
+  if (holder->shape() != holderShape) {
     return false;
   }
   if (*holderResult && *holderResult != holder) {
     return false;
   }
 
   *holderResult = holder;
   return true;
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -2647,17 +2647,17 @@ bool GetNameIRGenerator::tryAttachEnviro
   if (holder->getSlot(shape->slot()).isMagic()) {
     return false;
   }
 
   ObjOperandId lastObjId = objId;
   env = env_;
   while (env) {
     if (NeedEnvironmentShapeGuard(env)) {
-      writer.guardShape(lastObjId, env->maybeShape());
+      writer.guardShape(lastObjId, env->shape());
     }
 
     if (env == holder) {
       break;
     }
 
     lastObjId = writer.loadEnclosingEnvironment(lastObjId);
     env = env->enclosingEnvironment();
@@ -2797,17 +2797,17 @@ bool BindNameIRGenerator::tryAttachEnvir
       (holder->getSlot(shape->slot()).isMagic() || !shape->writable())) {
     return false;
   }
 
   ObjOperandId lastObjId = objId;
   env = env_;
   while (env) {
     if (NeedEnvironmentShapeGuard(env) && !env->is<GlobalObject>()) {
-      writer.guardShape(lastObjId, env->maybeShape());
+      writer.guardShape(lastObjId, env->shape());
     }
 
     if (env == holder) {
       break;
     }
 
     lastObjId = writer.loadEnclosingEnvironment(lastObjId);
     env = env->enclosingEnvironment();
--- a/js/src/jit/CacheIRSpewer.cpp
+++ b/js/src/jit/CacheIRSpewer.cpp
@@ -146,17 +146,17 @@ void CacheIRSpewer::valueProperty(const 
     JSString* str = v.isString() ? v.toString() : v.toSymbol()->description();
     if (str && str->isLinear()) {
       j.beginStringProperty("value");
       QuoteString(output_, &str->asLinear());
       j.endStringProperty();
     }
   } else if (v.isObject()) {
     JSObject& object = v.toObject();
-    j.formatProperty("value", "%p (shape: %p)", &object, object.maybeShape());
+    j.formatProperty("value", "%p (shape: %p)", &object, object.shape());
     if (NativeObject* nobj =
             object.isNative() ? &object.as<NativeObject>() : nullptr) {
       j.beginListProperty("flags");
       {
         if (nobj->isIndexed()) {
           j.value("indexed");
         }
         if (nobj->inDictionaryMode()) {
--- a/js/src/jit/IonIC.cpp
+++ b/js/src/jit/IonIC.cpp
@@ -254,17 +254,17 @@ bool IonSetPropertyIC::update(JSContext*
   bool isTemporarilyUnoptimizable = false;
   bool canAddSlot = false;
 
   if (ic->state().maybeTransition()) {
     ic->discardStubs(cx->zone());
   }
 
   if (ic->state().canAttachStub()) {
-    oldShape = obj->maybeShape();
+    oldShape = obj->shape();
     oldGroup = JSObject::getGroup(cx, obj);
     if (!oldGroup) {
       return false;
     }
 
     RootedValue objv(cx, ObjectValue(*obj));
     RootedScript script(cx, ic->script());
     jsbytecode* pc = ic->pc();
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -1094,19 +1094,18 @@ static void TraceCreateObject(JSObject* 
 void MacroAssembler::initGCThing(Register obj, Register temp,
                                  const TemplateObject& templateObj,
                                  bool initContents) {
   // Fast initialization of an empty object returned by allocateObject().
 
   storePtr(ImmGCPtr(templateObj.group()),
            Address(obj, JSObject::offsetOfGroup()));
 
-  if (gc::Cell* shape = templateObj.maybeShape()) {
-    storePtr(ImmGCPtr(shape), Address(obj, JSObject::offsetOfShape()));
-  }
+  storePtr(ImmGCPtr(templateObj.shape()),
+           Address(obj, JSObject::offsetOfShape()));
 
   if (templateObj.isNative()) {
     const NativeTemplateObject& ntemplate =
         templateObj.asNativeTemplateObject();
     MOZ_ASSERT_IF(!ntemplate.denseElementsAreCopyOnWrite(),
                   !ntemplate.hasDynamicElements());
     MOZ_ASSERT_IF(ntemplate.convertDoubleElements(), ntemplate.isArrayObject());
 
--- a/js/src/jit/ScalarReplacement.cpp
+++ b/js/src/jit/ScalarReplacement.cpp
@@ -212,17 +212,17 @@ static bool IsObjectEscaped(MInstruction
         }
 #endif
         break;
       }
 
       case MDefinition::Opcode::GuardShape: {
         MGuardShape* guard = def->toGuardShape();
         MOZ_ASSERT(!ins->isGuardShape());
-        if (obj->maybeShape() != guard->shape()) {
+        if (obj->shape() != guard->shape()) {
           JitSpewDef(JitSpew_Escape, "has a non-matching guard shape\n", guard);
           return true;
         }
         if (IsObjectEscaped(def->toInstruction(), obj)) {
           JitSpewDef(JitSpew_Escape, "is indirectly escaped by\n", def);
           return true;
         }
         break;
--- a/js/src/jit/TemplateObject-inl.h
+++ b/js/src/jit/TemplateObject-inl.h
@@ -48,18 +48,18 @@ inline bool TemplateObject::isPlainObjec
   return obj_->is<PlainObject>();
 }
 
 inline gc::Cell* TemplateObject::group() const {
   MOZ_ASSERT(!obj_->hasLazyGroup());
   return obj_->group();
 }
 
-inline gc::Cell* TemplateObject::maybeShape() const {
-  Shape* shape = obj_->maybeShape();
+inline gc::Cell* TemplateObject::shape() const {
+  Shape* shape = obj_->shape();
   MOZ_ASSERT(!shape->inDictionary());
   return shape;
 }
 
 inline uint32_t TemplateObject::getInlineTypedObjectSize() const {
   return obj_->as<InlineTypedObject>().size();
 }
 
--- a/js/src/jit/TemplateObject.h
+++ b/js/src/jit/TemplateObject.h
@@ -43,17 +43,17 @@ class TemplateObject {
   inline bool isRegExpObject() const;
   inline bool isInlineTypedObject() const;
   inline bool isCallObject() const;
   inline bool isPlainObject() const;
 
   // The group and shape should not change. This is true for template objects
   // because they're never exposed to arbitrary script.
   inline gc::Cell* group() const;
-  inline gc::Cell* maybeShape() const;
+  inline gc::Cell* shape() const;
 
   // Some TypedObjec methods that can be called off-thread.
   inline uint32_t getInlineTypedObjectSize() const;
   inline uint8_t* getInlineTypedObjectMem(
       const JS::AutoRequireNoGC& nogc) const;
 };
 
 class NativeTemplateObject : public TemplateObject {
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -1369,18 +1369,18 @@ void AssertValidObjectPtr(JSContext* cx,
   AutoUnsafeCallWithABI unsafe;
 #ifdef DEBUG
   // Check what we can, so that we'll hopefully assert/crash if we get a
   // bogus object (pointer).
   MOZ_ASSERT(obj->compartment() == cx->compartment());
   MOZ_ASSERT(obj->zoneFromAnyThread() == cx->zone());
   MOZ_ASSERT(obj->runtimeFromMainThread() == cx->runtime());
 
-  MOZ_ASSERT_IF(!obj->hasLazyGroup() && obj->maybeShape(),
-                obj->group()->clasp() == obj->maybeShape()->getObjectClass());
+  MOZ_ASSERT_IF(!obj->hasLazyGroup(),
+                obj->group()->clasp() == obj->shape()->getObjectClass());
 
   if (obj->isTenured()) {
     MOZ_ASSERT(obj->isAligned());
     gc::AllocKind kind = obj->asTenured().getAllocKind();
     MOZ_ASSERT(gc::IsObjectAllocKind(kind));
   }
 #endif
 }
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4124,17 +4124,17 @@ static bool EvalInWorker(JSContext* cx, 
 
 static bool ShapeOf(JSContext* cx, unsigned argc, JS::Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   if (!args.get(0).isObject()) {
     JS_ReportErrorASCII(cx, "shapeOf: object expected");
     return false;
   }
   JSObject* obj = &args[0].toObject();
-  args.rval().set(JS_NumberValue(double(uintptr_t(obj->maybeShape()) >> 3)));
+  args.rval().set(JS_NumberValue(double(uintptr_t(obj->shape()) >> 3)));
   return true;
 }
 
 static bool GroupOf(JSContext* cx, unsigned argc, JS::Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   if (!args.get(0).isObject()) {
     JS_ReportErrorASCII(cx, "groupOf: object expected");
     return false;
--- a/js/src/vm/JSObject-inl.h
+++ b/js/src/vm/JSObject-inl.h
@@ -28,24 +28,16 @@
 
 #include "gc/Marking-inl.h"
 #include "gc/ObjectKind-inl.h"
 #include "vm/JSAtom-inl.h"
 #include "vm/ObjectOperations-inl.h"  // js::MaybeHasInterestingSymbolProperty
 #include "vm/Realm-inl.h"
 #include "vm/TypeInference-inl.h"
 
-inline js::Shape* JSObject::maybeShape() const { return shape(); }
-
-inline js::Shape* JSObject::ensureShape(JSContext* cx) {
-  js::Shape* shape = maybeShape();
-  MOZ_ASSERT(shape);
-  return shape;
-}
-
 inline void JSObject::finalize(js::FreeOp* fop) {
   js::probes::FinalizeObject(this);
 
 #ifdef DEBUG
   MOZ_ASSERT(isTenured());
   if (!IsBackgroundFinalized(asTenured().getAllocKind())) {
     /* Assert we're on the main thread. */
     MOZ_ASSERT(CurrentThreadCanAccessZone(zone()));
@@ -218,20 +210,17 @@ inline js::GlobalObject& JSObject::nonCC
    * already kept live by the black JSObject's group pointer, so does not
    * need to be read-barriered.
    */
   return *nonCCWRealm()->unsafeUnbarrieredMaybeGlobal();
 }
 
 inline bool JSObject::hasAllFlags(js::BaseShape::Flag flags) const {
   MOZ_ASSERT(flags);
-  if (js::Shape* shape = maybeShape()) {
-    return shape->hasAllObjectFlags(flags);
-  }
-  return false;
+  return shape()->hasAllObjectFlags(flags);
 }
 
 inline bool JSObject::nonProxyIsExtensible() const {
   MOZ_ASSERT(!uninlinedIsProxy());
 
   // [[Extensible]] for ordinary non-proxy objects is an object flag.
   return !hasAllFlags(js::BaseShape::NOT_EXTENSIBLE);
 }
--- a/js/src/vm/JSObject.h
+++ b/js/src/vm/JSObject.h
@@ -73,17 +73,18 @@ bool SetImmutablePrototype(JSContext* cx
  *
  * NOTE: shape()->getObjectClass() must equal getClass().
  *
  * NOTE: The JIT may check |shape_| pointer value without ever inspecting
  *       |group_| or the class.
  *
  * NOTE: Some operations can change the contents of an object (including class)
  *       in-place so avoid assuming an object with same pointer has same class
- *       as before. - JSObject::swap()
+ *       as before.
+ *       - JSObject::swap()
  */
 class JSObject : public js::gc::Cell {
  protected:
   js::GCPtrObjectGroup group_;
   void* shape_;
 
  private:
   friend class js::Shape;
@@ -153,19 +154,16 @@ class JSObject : public js::gc::Cell {
    * Whether the object's group has not been constructed yet. If an object
    * might have a lazy group, use getGroup() below, otherwise group().
    */
   bool hasLazyGroup() const { return group_->lazy(); }
 
   JS::Compartment* compartment() const { return group_->compartment(); }
   JS::Compartment* maybeCompartment() const { return compartment(); }
 
-  inline js::Shape* maybeShape() const;
-  inline js::Shape* ensureShape(JSContext* cx);
-
   void initShape(js::Shape* shape) {
     // Note: JSObject::zone() uses the group and we require it to be
     // initialized before the shape.
     MOZ_ASSERT(zone() == shape->zone());
     shapeRef().init(shape);
   }
   void setShape(js::Shape* shape) {
     MOZ_ASSERT(zone() == shape->zone());
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -1466,17 +1466,17 @@ Shape* NativeObject::replaceWithNewEquiv
 bool JSObject::setFlags(JSContext* cx, HandleObject obj, BaseShape::Flag flags,
                         GenerateShape generateShape) {
   MOZ_ASSERT(cx->compartment() == obj->compartment());
 
   if (obj->hasAllFlags(flags)) {
     return true;
   }
 
-  Shape* existingShape = obj->ensureShape(cx);
+  Shape* existingShape = obj->shape();
   if (!existingShape) {
     return false;
   }
 
   if (obj->isNative() && obj->as<NativeObject>().inDictionaryMode()) {
     if (generateShape == GENERATE_SHAPE) {
       if (!NativeObject::generateOwnShape(cx, obj.as<NativeObject>())) {
         return false;
@@ -1494,20 +1494,17 @@ bool JSObject::setFlags(JSContext* cx, H
   }
 
   Shape* newShape =
       Shape::setObjectFlags(cx, flags, obj->taggedProto(), existingShape);
   if (!newShape) {
     return false;
   }
 
-  // The success of the |JSObject::ensureShape| call above means that |obj|
-  // can be assumed to have a shape.
   obj->as<JSObject>().setShape(newShape);
-
   return true;
 }
 
 /* static */
 bool NativeObject::clearFlag(JSContext* cx, HandleNativeObject obj,
                              BaseShape::Flag flag) {
   MOZ_ASSERT(obj->lastProperty()->getObjectFlags() & flag);