Bug 1259925 - Port ModuleNamespace getprop stub to CacheIR. r=efaust
authorJan de Mooij <jdemooij@mozilla.com>
Sat, 23 Apr 2016 20:09:35 +0200
changeset 332552 72235ad4fc17dead99e9ff021c1860c5e54ceffd
parent 332551 b068d21a21087b21042d106a9fab94cab3f3bcf0
child 332553 fdab10431cc98db6d9a31facdd03310a6676d80a
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersefaust
bugs1259925
milestone48.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 1259925 - Port ModuleNamespace getprop stub to CacheIR. r=efaust
js/src/jit/BaselineCacheIR.cpp
js/src/jit/BaselineInspector.cpp
js/src/jit/CacheIR.cpp
js/src/jit/CacheIR.h
js/src/jit/SharedIC.cpp
js/src/jit/SharedIC.h
js/src/jit/SharedICList.h
--- a/js/src/jit/BaselineCacheIR.cpp
+++ b/js/src/jit/BaselineCacheIR.cpp
@@ -769,16 +769,30 @@ BaselineCacheIRCompiler::emitGuardClass(
     }
 
     MOZ_ASSERT(clasp);
     masm.branchTestObjClass(Assembler::NotEqual, obj, scratch, clasp, failure->label());
     return true;
 }
 
 bool
+BaselineCacheIRCompiler::emitGuardSpecificObject()
+{
+    Register obj = allocator.useRegister(masm, reader.objOperandId());
+
+    FailurePath* failure;
+    if (!addFailurePath(&failure))
+        return false;
+
+    Address addr(stubAddress(reader.stubOffset()));
+    masm.branchPtr(Assembler::NotEqual, addr, obj, failure->label());
+    return true;
+}
+
+bool
 BaselineCacheIRCompiler::emitGuardNoUnboxedExpando()
 {
     Register obj = allocator.useRegister(masm, reader.objOperandId());
 
     FailurePath* failure;
     if (!addFailurePath(&failure))
         return false;
 
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -807,17 +807,16 @@ BaselineInspector::expectedPropertyAcces
 
           case ICStub::GetProp_Unboxed:
           case ICStub::GetProp_TypedObject:
           case ICStub::GetProp_CallScripted:
           case ICStub::GetProp_CallNative:
           case ICStub::GetProp_CallDOMProxyNative:
           case ICStub::GetProp_CallDOMProxyWithGenerationNative:
           case ICStub::GetProp_DOMProxyShadowed:
-          case ICStub::GetProp_ModuleNamespace:
           case ICStub::GetElem_NativeSlotName:
           case ICStub::GetElem_NativeSlotSymbol:
           case ICStub::GetElem_NativePrototypeSlotName:
           case ICStub::GetElem_NativePrototypeSlotSymbol:
           case ICStub::GetElem_NativePrototypeCallNativeName:
           case ICStub::GetElem_NativePrototypeCallNativeSymbol:
           case ICStub::GetElem_NativePrototypeCallScriptedName:
           case ICStub::GetElem_NativePrototypeCallScriptedSymbol:
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -57,16 +57,18 @@ GetPropIRGenerator::tryAttachStub(Maybe<
         ObjOperandId objId = writer->guardIsObject(valId);
 
         if (!emitted_ && !tryAttachObjectLength(*writer, obj, objId))
             return false;
         if (!emitted_ && !tryAttachNative(*writer, obj, objId))
             return false;
         if (!emitted_ && !tryAttachUnboxedExpando(*writer, obj, objId))
             return false;
+        if (!emitted_ && !tryAttachModuleNamespace(*writer, obj, objId))
+            return false;
     }
 
     return true;
 }
 
 static bool
 IsCacheableNoProperty(JSContext* cx, JSObject* obj, JSObject* holder, Shape* shape, jsid id,
                       jsbytecode* pc)
@@ -313,8 +315,40 @@ GetPropIRGenerator::tryAttachObjectLengt
         }
         writer.loadArgumentsObjectLengthResult(objId);
         emitted_ = true;
         return true;
     }
 
     return true;
 }
+
+bool
+GetPropIRGenerator::tryAttachModuleNamespace(CacheIRWriter& writer, HandleObject obj,
+                                             ObjOperandId objId)
+{
+    MOZ_ASSERT(!emitted_);
+
+    if (!obj->is<ModuleNamespaceObject>())
+        return true;
+
+    Rooted<ModuleNamespaceObject*> ns(cx_, &obj->as<ModuleNamespaceObject>());
+    RootedModuleEnvironmentObject env(cx_);
+    RootedShape shape(cx_);
+    if (!ns->bindings().lookup(NameToId(name_), env.address(), shape.address()))
+        return true;
+
+    // Don't emit a stub until the target binding has been initialized.
+    if (env->getSlot(shape->slot()).isMagic(JS_UNINITIALIZED_LEXICAL))
+        return true;
+
+    if (IsIonEnabled(cx_))
+        EnsureTrackPropertyTypes(cx_, env, shape->propid());
+
+    emitted_ = true;
+
+    // Check for the specific namespace object.
+    writer.guardSpecificObject(objId, ns);
+
+    ObjOperandId envId = writer.loadObject(env);
+    EmitLoadSlotResult(writer, envId, env, shape);
+    return true;
+}
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -78,16 +78,17 @@ class ObjOperandId : public OperandId
 };
 
 #define CACHE_IR_OPS(_)                   \
     _(GuardIsObject)                      \
     _(GuardShape)                         \
     _(GuardGroup)                         \
     _(GuardProto)                         \
     _(GuardClass)                         \
+    _(GuardSpecificObject)                \
     _(GuardNoUnboxedExpando)              \
     _(GuardAndLoadUnboxedExpando)         \
     _(LoadObject)                         \
     _(LoadProto)                          \
     _(LoadUnboxedExpando)                 \
     _(LoadFixedSlotResult)                \
     _(LoadDynamicSlotResult)              \
     _(LoadInt32ArrayLengthResult)         \
@@ -254,16 +255,20 @@ class MOZ_RAII CacheIRWriter
         writeOpWithOperandId(CacheOp::GuardProto, obj);
         addStubWord(uintptr_t(proto), StubField::GCType::JSObject);
     }
     void guardClass(ObjOperandId obj, GuardClassKind kind) {
         MOZ_ASSERT(uint32_t(kind) <= UINT8_MAX);
         writeOpWithOperandId(CacheOp::GuardClass, obj);
         buffer_.writeByte(uint32_t(kind));
     }
+    void guardSpecificObject(ObjOperandId obj, JSObject* expected) {
+        writeOpWithOperandId(CacheOp::GuardSpecificObject, obj);
+        addStubWord(uintptr_t(expected), StubField::GCType::JSObject);
+    }
     void guardNoUnboxedExpando(ObjOperandId obj) {
         writeOpWithOperandId(CacheOp::GuardNoUnboxedExpando, obj);
     }
     ObjOperandId guardAndLoadUnboxedExpando(ObjOperandId obj) {
         ObjOperandId res(nextOperandId_++);
         writeOpWithOperandId(CacheOp::GuardAndLoadUnboxedExpando, obj);
         writeOperandId(res);
         return res;
@@ -380,16 +385,17 @@ class MOZ_RAII GetPropIRGenerator
     bool emitted_;
 
     enum class PreliminaryObjectAction { None, Unlink, NotePreliminary };
     PreliminaryObjectAction preliminaryObjectAction_;
 
     bool tryAttachNative(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
     bool tryAttachUnboxedExpando(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
     bool tryAttachObjectLength(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
+    bool tryAttachModuleNamespace(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
 
     GetPropIRGenerator(const GetPropIRGenerator&) = delete;
     GetPropIRGenerator& operator=(const GetPropIRGenerator&) = delete;
 
   public:
     GetPropIRGenerator(JSContext* cx, jsbytecode* pc, HandleValue val, HandlePropertyName name,
                        MutableHandleValue res);
 
--- a/js/src/jit/SharedIC.cpp
+++ b/js/src/jit/SharedIC.cpp
@@ -455,22 +455,16 @@ ICStub::trace(JSTracer* trc)
         ICGetProp_CallNativeGlobal* callStub = toGetProp_CallNativeGlobal();
         callStub->receiverGuard().trace(trc);
         TraceEdge(trc, &callStub->holder(), "baseline-getpropcallnativeglobal-stub-holder");
         TraceEdge(trc, &callStub->holderShape(), "baseline-getpropcallnativeglobal-stub-holdershape");
         TraceEdge(trc, &callStub->globalShape(), "baseline-getpropcallnativeglobal-stub-globalshape");
         TraceEdge(trc, &callStub->getter(), "baseline-getpropcallnativeglobal-stub-getter");
         break;
       }
-      case ICStub::GetProp_ModuleNamespace: {
-        ICGetProp_ModuleNamespace* nsStub = toGetProp_ModuleNamespace();
-        TraceEdge(trc, &nsStub->getNamespace(), "baseline-getprop-modulenamespace-stub-namespace");
-        TraceEdge(trc, &nsStub->environment(), "baseline-getprop-modulenamespace-stub-environment");
-        break;
-      }
       case ICStub::SetProp_Native: {
         ICSetProp_Native* propStub = toSetProp_Native();
         TraceEdge(trc, &propStub->shape(), "baseline-setpropnative-stub-shape");
         TraceEdge(trc, &propStub->group(), "baseline-setpropnative-stub-group");
         break;
       }
       case ICStub::SetProp_NativeAdd: {
         ICSetProp_NativeAdd* propStub = toSetProp_NativeAdd();
@@ -2630,58 +2624,16 @@ TryAttachTypedObjectGetPropStub(JSContex
         return false;
     stub->addNewStub(newStub);
 
     *attached = true;
     return true;
 }
 
 static bool
-TryAttachModuleNamespaceGetPropStub(JSContext* cx, SharedStubInfo* info,
-                                    ICGetProp_Fallback* stub, HandlePropertyName name,
-                                    HandleValue val, bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    if (!ModuleNamespaceObject::isInstance(val))
-        return true;
-
-    Rooted<ModuleNamespaceObject*> ns(cx, &val.toObject().as<ModuleNamespaceObject>());
-
-    RootedModuleEnvironmentObject env(cx);
-    RootedShape shape(cx);
-    if (!ns->bindings().lookup(NameToId(name), env.address(), shape.address()))
-        return true;
-
-    // Don't emit a stub until the target binding has been initialized.
-    if (env->getSlot(shape->slot()).isMagic(JS_UNINITIALIZED_LEXICAL))
-        return true;
-
-    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
-
-    bool isFixedSlot;
-    uint32_t offset;
-    GetFixedOrDynamicSlotOffset(shape, &isFixedSlot, &offset);
-
-    // Instantiate this property for singleton holders, for use during Ion compilation.
-    if (IsIonEnabled(cx))
-        EnsureTrackPropertyTypes(cx, env, shape->propid());
-
-    ICGetProp_ModuleNamespace::Compiler compiler(cx, info->engine(), monitorStub,
-                                                 ns, env, isFixedSlot, offset);
-    ICStub* newStub = compiler.getStub(compiler.getStubSpace(info->outerScript(cx)));
-    if (!newStub)
-        return false;
-    stub->addNewStub(newStub);
-
-    *attached = true;
-    return true;
-}
-
-static bool
 TryAttachPrimitiveGetPropStub(JSContext* cx, SharedStubInfo* info,
                               ICGetProp_Fallback* stub, HandlePropertyName name,
                               HandleValue val, HandleValue res, bool* attached)
 {
     MOZ_ASSERT(!*attached);
 
     JSValueType primitiveType;
     RootedNativeObject proto(cx);
@@ -2914,21 +2866,16 @@ DoGetPropFallback(JSContext* cx, void* p
     if (attached)
         return true;
 
     if (!TryAttachTypedObjectGetPropStub(cx, &info, stub, name, val, &attached))
         return false;
     if (attached)
         return true;
 
-    if (!TryAttachModuleNamespaceGetPropStub(cx, &info, stub, name, val, &attached))
-        return false;
-    if (attached)
-        return true;
-
     if (val.isString() || val.isNumber() || val.isBoolean()) {
         if (!TryAttachPrimitiveGetPropStub(cx, &info, stub, name, val, res, &attached))
             return false;
         if (attached)
             return true;
     }
 
     MOZ_ASSERT(!attached);
@@ -3939,51 +3886,16 @@ ICGetProp_TypedObject::Compiler::generat
         EmitReturnFromIC(masm);
 
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
 
     return true;
 }
 
-bool
-ICGetProp_ModuleNamespace::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    Label failure;
-
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
-
-    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
-
-    // Guard on namespace object.
-    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-    Register object = masm.extractObject(R0, ExtractTemp0);
-    masm.loadPtr(Address(ICStubReg, ICGetProp_ModuleNamespace::offsetOfNamespace()), scratch);
-    masm.branchPtr(Assembler::NotEqual, object, scratch, &failure);
-
-    // Determine base pointer for load.
-    Register loadBase = regs.takeAnyExcluding(ICTailCallReg);
-    masm.loadPtr(Address(ICStubReg, ICGetProp_ModuleNamespace::offsetOfEnvironment()), loadBase);
-    if (!isFixedSlot_)
-        masm.loadPtr(Address(loadBase, NativeObject::offsetOfSlots()), loadBase);
-
-    // Load the property.
-    masm.load32(Address(ICStubReg, ICGetProp_ModuleNamespace::offsetOfOffset()), scratch);
-    masm.loadValue(BaseIndex(loadBase, scratch, TimesOne), R0);
-
-    // Enter type monitor IC to type-check result.
-    EmitEnterTypeMonitorIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-
-    return true;
-}
-
 void
 BaselineScript::noteAccessedGetter(uint32_t pcOffset)
 {
     ICEntry& entry = icEntryFromPCOffset(pcOffset);
     ICFallbackStub* stub = entry.fallbackStub();
 
     if (stub->isGetProp_Fallback())
         stub->toGetProp_Fallback()->noteAccessedGetter();
--- a/js/src/jit/SharedIC.h
+++ b/js/src/jit/SharedIC.h
@@ -2719,83 +2719,16 @@ class ICGetProp_TypedObject : public ICM
 
         ICStub* getStub(ICStubSpace* space) {
             return newStub<ICGetProp_TypedObject>(space, getStubCode(), firstMonitorStub_, shape_,
                                                   fieldOffset_);
         }
     };
 };
 
-class ICGetProp_ModuleNamespace : public ICMonitoredStub
-{
-    friend class ICStubSpace;
-
-    HeapPtrModuleNamespaceObject namespace_;
-    HeapPtrModuleEnvironmentObject environment_;
-    uint32_t offset_;
-
-    ICGetProp_ModuleNamespace(JitCode* stubCode, ICStub* firstMonitorStub,
-                              HandleModuleNamespaceObject ns, HandleModuleEnvironmentObject env,
-                              uint32_t offset)
-      : ICMonitoredStub(ICStub::GetProp_ModuleNamespace, stubCode, firstMonitorStub),
-        namespace_(ns), environment_(env), offset_(offset)
-    {
-        (void) offset_; // Silence clang warning.
-    }
-
-  public:
-    HeapPtrModuleNamespaceObject& getNamespace() {
-        return namespace_;
-    }
-    HeapPtrModuleEnvironmentObject& environment() {
-        return environment_;
-    }
-
-    static size_t offsetOfNamespace() {
-        return offsetof(ICGetProp_ModuleNamespace, namespace_);
-    }
-    static size_t offsetOfEnvironment() {
-        return offsetof(ICGetProp_ModuleNamespace, environment_);
-    }
-    static size_t offsetOfOffset() {
-        return offsetof(ICGetProp_ModuleNamespace, offset_);
-    }
-
-    class Compiler : public ICStubCompiler {
-      protected:
-        ICStub* firstMonitorStub_;
-        RootedModuleNamespaceObject namespace_;
-        RootedModuleEnvironmentObject environment_;
-        bool isFixedSlot_;
-        uint32_t offset_;
-
-        bool generateStubCode(MacroAssembler& masm);
-
-        virtual int32_t getKey() const {
-            return static_cast<int32_t>(engine_) |
-                  (static_cast<int32_t>(kind) << 1) |
-                  (static_cast<int32_t>(isFixedSlot_) << 17);
-        }
-
-      public:
-        Compiler(JSContext* cx, Engine engine, ICStub* firstMonitorStub,
-                 HandleModuleNamespaceObject ns, HandleModuleEnvironmentObject env, bool isFixedSlot,
-                 uint32_t offset)
-          : ICStubCompiler(cx, ICStub::GetProp_ModuleNamespace, engine),
-            firstMonitorStub_(firstMonitorStub),
-            namespace_(cx, ns), environment_(cx, env), isFixedSlot_(isFixedSlot), offset_(offset)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICGetProp_ModuleNamespace>(space, getStubCode(), firstMonitorStub_,
-                                                      namespace_, environment_, offset_);
-        }
-    };
-};
-
 class ICGetPropCallGetter : public ICMonitoredStub
 {
     friend class ICStubSpace;
 
   protected:
     // Shape/group of receiver object. Used for both own and proto getters.
     // In the GetPropCallDOMProxyNative case, the receiver guard enforces
     // the proxy handler, because Shape implies Class.
--- a/js/src/jit/SharedICList.h
+++ b/js/src/jit/SharedICList.h
@@ -42,17 +42,16 @@ namespace jit {
     _(GetProp_CallScripted)                      \
     _(GetProp_CallNative)                        \
     _(GetProp_CallNativeGlobal)                  \
     _(GetProp_CallDOMProxyNative)                \
     _(GetProp_CallDOMProxyWithGenerationNative)  \
     _(GetProp_DOMProxyShadowed)                  \
     _(GetProp_ArgumentsLength)                   \
     _(GetProp_ArgumentsCallee)                   \
-    _(GetProp_ModuleNamespace)                   \
     _(GetProp_Generic)                           \
                                                  \
     _(CacheIR_Monitored)                         \
                                                  \
 
 } // namespace jit
 } // namespace js