Bug 1313036 - Remove unnecessary LoadUnboxedExpando. r=h4writer
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 28 Oct 2016 12:07:43 +0200
changeset 319979 f3b662e19b24da1c42c99a3cd5d08982c3cacc8f
parent 319978 bdeb744966f16aa9274266bd719109552d9d138a
child 319980 d2f850fe57e1166ac9ac3bc3c59b2e79ee5a1017
push id20749
push userryanvm@gmail.com
push dateSat, 29 Oct 2016 13:21:21 +0000
treeherderfx-team@1b170b39ed6b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersh4writer
bugs1313036
milestone52.0a1
Bug 1313036 - Remove unnecessary LoadUnboxedExpando. r=h4writer
js/src/jit/BaselineCacheIR.cpp
js/src/jit/BaselineInspector.cpp
js/src/jit/CacheIR.cpp
js/src/jit/CacheIR.h
--- a/js/src/jit/BaselineCacheIR.cpp
+++ b/js/src/jit/BaselineCacheIR.cpp
@@ -1056,31 +1056,16 @@ BaselineCacheIRCompiler::emitLoadProto()
 {
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     Register reg = allocator.defineRegister(masm, reader.objOperandId());
     masm.loadObjProto(obj, reg);
     return true;
 }
 
 bool
-BaselineCacheIRCompiler::emitLoadUnboxedExpando()
-{
-    Register obj = allocator.useRegister(masm, reader.objOperandId());
-    Register output = allocator.defineRegister(masm, reader.objOperandId());
-
-    FailurePath* failure;
-    if (!addFailurePath(&failure))
-        return false;
-
-    Address expandoAddr(obj, UnboxedPlainObject::offsetOfExpando());
-    masm.loadPtr(expandoAddr, output);
-    return true;
-}
-
-bool
 BaselineCacheIRCompiler::init(CacheKind kind)
 {
     size_t numInputs = writer_.numInputOperands();
     if (!allocator.init(ICStubCompiler::availableGeneralRegs(numInputs)))
         return false;
 
     MOZ_ASSERT(numInputs == 1);
     allocator.initInputLocation(0, R0);
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -108,26 +108,25 @@ AddReceiver(const ReceiverGuard& receive
 
 static bool
 GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* receiver)
 {
     // We match either:
     //
     //   GuardIsObject 0
     //   GuardShape 0
-    //   LoadFixedSlotResult or LoadDynamicSlotResult
+    //   LoadFixedSlotResult 0 or LoadDynamicSlotResult 0
     //
     // or
     //
     //   GuardIsObject 0
     //   GuardGroup 0
     //   1: GuardAndLoadUnboxedExpando 0
     //   GuardShape 1
-    //   LoadUnboxedExpando 0
-    //   LoadFixedSlotResult or LoadDynamicSlotResult
+    //   LoadFixedSlotResult 1 or LoadDynamicSlotResult 1
 
     *receiver = ReceiverGuard();
     CacheIRReader reader(stub->stubInfo());
 
     ObjOperandId objId = ObjOperandId(0);
     if (!reader.matchOp(CacheOp::GuardIsObject, objId))
         return false;
 
@@ -136,23 +135,16 @@ GetCacheIRReceiverForNativeReadSlot(ICCa
 
         if (!reader.matchOp(CacheOp::GuardAndLoadUnboxedExpando, objId))
             return false;
         objId = reader.objOperandId();
     }
 
     if (reader.matchOp(CacheOp::GuardShape, objId)) {
         receiver->shape = stub->stubInfo()->getStubField<Shape*>(stub, reader.stubOffset());
-
-        // Skip LoadUnboxedExpando. Note that this op is redundant with the
-        // previous GuardAndLoadUnboxedExpando op, but for now we match the
-        // Ion IC codegen.
-        if (reader.matchOp(CacheOp::LoadUnboxedExpando, ObjOperandId(0)))
-            objId = reader.objOperandId();
-
         return reader.matchOpEither(CacheOp::LoadFixedSlotResult, CacheOp::LoadDynamicSlotResult);
     }
 
     return false;
 }
 
 static bool
 GetCacheIRReceiverForUnboxedProperty(ICCacheIR_Monitored* stub, ReceiverGuard* receiver)
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -158,41 +158,43 @@ GeneratePrototypeGuards(CacheIRWriter& w
                 writer.guardGroup(protoId, pobj->group());
             }
         }
         pobj = pobj->staticPrototype();
     }
 }
 
 static void
-TestMatchingReceiver(CacheIRWriter& writer, JSObject* obj, Shape* shape, ObjOperandId objId)
+TestMatchingReceiver(CacheIRWriter& writer, JSObject* obj, Shape* shape, ObjOperandId objId,
+                     Maybe<ObjOperandId>* expandoId)
 {
     if (obj->is<UnboxedPlainObject>()) {
         writer.guardGroup(objId, obj->group());
 
         if (UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando()) {
-            ObjOperandId expandoId = writer.guardAndLoadUnboxedExpando(objId);
-            writer.guardShape(expandoId, expando->lastProperty());
+            expandoId->emplace(writer.guardAndLoadUnboxedExpando(objId));
+            writer.guardShape(expandoId->ref(), expando->lastProperty());
         } else {
             writer.guardNoUnboxedExpando(objId);
         }
     } else if (obj->is<UnboxedArrayObject>() || obj->is<TypedObject>()) {
         writer.guardGroup(objId, obj->group());
     } else {
         Shape* shape = obj->maybeShape();
         MOZ_ASSERT(shape);
         writer.guardShape(objId, shape);
     }
 }
 
 static void
 EmitReadSlotResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
                    Shape* shape, ObjOperandId objId)
 {
-    TestMatchingReceiver(writer, obj, shape, objId);
+    Maybe<ObjOperandId> expandoId;
+    TestMatchingReceiver(writer, obj, shape, objId, &expandoId);
 
     ObjOperandId holderId;
     if (obj != holder) {
         GeneratePrototypeGuards(writer, obj, holder, objId);
 
         if (holder) {
             // Guard on the holder's shape.
             holderId = writer.loadObject(holder);
@@ -207,17 +209,17 @@ EmitReadSlotResult(CacheIRWriter& writer
                 ObjOperandId protoId = writer.loadProto(lastObjId);
                 writer.guardShape(protoId, proto->as<NativeObject>().lastProperty());
                 proto = proto->staticPrototype();
                 lastObjId = protoId;
             }
         }
     } else if (obj->is<UnboxedPlainObject>()) {
         holder = obj->as<UnboxedPlainObject>().maybeExpando();
-        holderId = writer.loadUnboxedExpando(objId);
+        holderId = *expandoId;
     } else {
         holderId = objId;
     }
 
     // Slot access.
     if (holder) {
         MOZ_ASSERT(holderId.valid());
         EmitLoadSlotResult(writer, holderId, &holder->as<NativeObject>(), shape);
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -86,17 +86,16 @@ class ObjOperandId : public OperandId
     _(GuardProto)                         \
     _(GuardClass)                         \
     _(GuardSpecificObject)                \
     _(GuardNoDetachedTypedObjects)        \
     _(GuardNoUnboxedExpando)              \
     _(GuardAndLoadUnboxedExpando)         \
     _(LoadObject)                         \
     _(LoadProto)                          \
-    _(LoadUnboxedExpando)                 \
     _(LoadFixedSlotResult)                \
     _(LoadDynamicSlotResult)              \
     _(LoadUnboxedPropertyResult)          \
     _(LoadTypedObjectResult)              \
     _(LoadInt32ArrayLengthResult)         \
     _(LoadUnboxedArrayLengthResult)       \
     _(LoadArgumentsObjectLengthResult)    \
     _(LoadUndefinedResult)
@@ -294,22 +293,16 @@ class MOZ_RAII CacheIRWriter
         return res;
     }
     ObjOperandId loadProto(ObjOperandId obj) {
         ObjOperandId res(nextOperandId_++);
         writeOpWithOperandId(CacheOp::LoadProto, obj);
         writeOperandId(res);
         return res;
     }
-    ObjOperandId loadUnboxedExpando(ObjOperandId obj) {
-        ObjOperandId res(nextOperandId_++);
-        writeOpWithOperandId(CacheOp::LoadUnboxedExpando, obj);
-        writeOperandId(res);
-        return res;
-    }
 
     void loadUndefinedResult() {
         writeOp(CacheOp::LoadUndefinedResult);
     }
     void loadFixedSlotResult(ObjOperandId obj, size_t offset) {
         writeOpWithOperandId(CacheOp::LoadFixedSlotResult, obj);
         addStubWord(offset, StubField::GCType::NoGCThing);
     }