Bug 1313036 - Remove unnecessary LoadUnboxedExpando. r=h4writer
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 28 Oct 2016 12:07:43 +0200
changeset 319922 f3b662e19b24da1c42c99a3cd5d08982c3cacc8f
parent 319921 bdeb744966f16aa9274266bd719109552d9d138a
child 319923 d2f850fe57e1166ac9ac3bc3c59b2e79ee5a1017
push id30882
push userryanvm@gmail.com
push dateSat, 29 Oct 2016 13:12:06 +0000
treeherdermozilla-central@16cdd6273c48 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersh4writer
bugs1313036
milestone52.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 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);
     }