Bug 1460895: Deduplicate MegamorphicLoadSlotResult using EmitLoadStubField r=jandem
authorMatthew Gaudet <mgaudet@mozilla.com>
Tue, 30 Jan 2018 14:35:30 -0500
changeset 472404 9eb850fd168812a2a8f427814335fdd93ab64ae5
parent 472403 5d368658145949915eaaa095275cc20a6fa76748
child 472405 0f5b9cd3d7107aa8d744036247d56dc9576e1dcf
push id9374
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:43:20 +0000
treeherdermozilla-beta@160e085dfb0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1460895
milestone62.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 1460895: Deduplicate MegamorphicLoadSlotResult using EmitLoadStubField r=jandem Also rename helper method to match pre-existing spidermonkey style.
js/src/jit/BaselineCacheIRCompiler.cpp
js/src/jit/CacheIRCompiler.cpp
js/src/jit/CacheIRCompiler.h
js/src/jit/IonCacheIRCompiler.cpp
--- a/js/src/jit/BaselineCacheIRCompiler.cpp
+++ b/js/src/jit/BaselineCacheIRCompiler.cpp
@@ -539,68 +539,16 @@ BaselineCacheIRCompiler::emitLoadDynamic
 
     masm.load32(stubAddress(reader.stubOffset()), scratch);
     masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), scratch2);
     masm.loadValue(BaseIndex(scratch2, scratch, TimesOne), output.valueReg());
     return true;
 }
 
 bool
-BaselineCacheIRCompiler::emitMegamorphicLoadSlotResult()
-{
-    AutoOutputRegister output(*this);
-
-    Register obj = allocator.useRegister(masm, reader.objOperandId());
-    Address nameAddr = stubAddress(reader.stubOffset());
-    bool handleMissing = reader.readBool();
-
-    AutoScratchRegisterMaybeOutput scratch1(allocator, masm, output);
-    AutoScratchRegister scratch2(allocator, masm);
-    AutoScratchRegister scratch3(allocator, masm);
-
-    FailurePath* failure;
-    if (!addFailurePath(&failure))
-        return false;
-
-    // The object must be Native.
-    masm.branchIfNonNativeObj(obj, scratch3, failure->label());
-
-    masm.Push(UndefinedValue());
-    masm.moveStackPtrTo(scratch3.get());
-
-    LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs());
-    volatileRegs.takeUnchecked(scratch1);
-    volatileRegs.takeUnchecked(scratch2);
-    volatileRegs.takeUnchecked(scratch3);
-    masm.PushRegsInMask(volatileRegs);
-
-    masm.setupUnalignedABICall(scratch1);
-    masm.loadJSContext(scratch1);
-    masm.passABIArg(scratch1);
-    masm.passABIArg(obj);
-    masm.loadPtr(nameAddr, scratch2);
-    masm.passABIArg(scratch2);
-    masm.passABIArg(scratch3);
-    if (handleMissing)
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, (GetNativeDataProperty<true>)));
-    else
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, (GetNativeDataProperty<false>)));
-    masm.mov(ReturnReg, scratch2);
-    masm.PopRegsInMask(volatileRegs);
-
-    masm.loadTypedOrValue(Address(masm.getStackPointer(), 0), output);
-    masm.adjustStack(sizeof(Value));
-
-    masm.branchIfFalseBool(scratch2, failure->label());
-    if (JitOptions.spectreJitToCxxCalls)
-        masm.speculationBarrier();
-    return true;
-}
-
-bool
 BaselineCacheIRCompiler::emitMegamorphicStoreSlot()
 {
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     Address nameAddr = stubAddress(reader.stubOffset());
     ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
     bool needsTypeBarrier = reader.readBool();
 
     AutoScratchRegister scratch1(allocator, masm);
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -2932,17 +2932,17 @@ CacheIRCompiler::emitCallObjectHasSparse
     masm.loadTypedOrValue(Address(masm.getStackPointer(), 0), output);
     masm.adjustStack(sizeof(Value));
     return true;
 }
 
 /*
  * Move a constant value into register dest.
  */
-void CacheIRCompiler::EmitLoadStubFieldConstant(StubFieldOffset val, Register dest) {
+void CacheIRCompiler::emitLoadStubFieldConstant(StubFieldOffset val, Register dest) {
     MOZ_ASSERT(mode_ == Mode::Ion);
     switch (val.getStubFieldType()) {
       case StubField::Type::Shape:
         masm.movePtr(ImmGCPtr(shapeStubField(val.getOffset())),dest);
         break;
       case StubField::Type::String:
         masm.movePtr(ImmGCPtr(stringStubField(val.getOffset())), dest);
         break;
@@ -2954,19 +2954,19 @@ void CacheIRCompiler::EmitLoadStubFieldC
 /*
  * After this is done executing, dest contains the value; either through a constant load
  * or through the load from the stub data.
  *
  * The current policy is that Baseline will use loads from the stub data (to allow IC
  * sharing), where as Ion doesn't share ICs, and so we can safely use constants in the
  * IC.
  */
-void CacheIRCompiler::EmitLoadStubField(StubFieldOffset val, Register dest) {
+void CacheIRCompiler::emitLoadStubField(StubFieldOffset val, Register dest) {
     if (stubFieldPolicy_ == StubFieldPolicy::Constant) {
-        EmitLoadStubFieldConstant(val, dest);
+        emitLoadStubFieldConstant(val, dest);
     } else {
         Address load(ICStubReg, stubDataOffset_ + val.getOffset());
         masm.loadPtr(load, dest);
     }
 }
 
 bool
 CacheIRCompiler::emitLoadInstanceOfObjectResult()
@@ -3009,8 +3009,61 @@ CacheIRCompiler::emitLoadInstanceOfObjec
     masm.jump(&done);
 
     masm.bind(&returnTrue);
     EmitStoreBoolean(masm, true, output);
     //fallthrough
     masm.bind(&done);
     return true;
 }
+
+bool
+CacheIRCompiler::emitMegamorphicLoadSlotResult()
+{
+    AutoOutputRegister output(*this);
+
+    Register obj = allocator.useRegister(masm, reader.objOperandId());
+    StubFieldOffset name(reader.stubOffset(), StubField::Type::String);
+    bool handleMissing = reader.readBool();
+
+    AutoScratchRegisterMaybeOutput scratch1(allocator, masm, output);
+    AutoScratchRegister scratch2(allocator, masm);
+    AutoScratchRegister scratch3(allocator, masm);
+
+    FailurePath* failure;
+    if (!addFailurePath(&failure))
+        return false;
+
+    // The object must be Native.
+    masm.branchIfNonNativeObj(obj, scratch3, failure->label());
+
+    masm.Push(UndefinedValue());
+    masm.moveStackPtrTo(scratch3.get());
+
+    LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs());
+    volatileRegs.takeUnchecked(scratch1);
+    volatileRegs.takeUnchecked(scratch2);
+    volatileRegs.takeUnchecked(scratch3);
+    masm.PushRegsInMask(volatileRegs);
+
+    masm.setupUnalignedABICall(scratch1);
+    masm.loadJSContext(scratch1);
+    masm.passABIArg(scratch1);
+    masm.passABIArg(obj);
+    emitLoadStubField(name, scratch2);
+    masm.passABIArg(scratch2);
+    masm.passABIArg(scratch3);
+    if (handleMissing)
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, (GetNativeDataProperty<true>)));
+    else
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, (GetNativeDataProperty<false>)));
+    masm.mov(ReturnReg, scratch2);
+    masm.PopRegsInMask(volatileRegs);
+
+    masm.loadTypedOrValue(Address(masm.getStackPointer(), 0), output);
+    masm.adjustStack(sizeof(Value));
+
+    masm.branchIfFalseBool(scratch2, failure->label());
+    if (JitOptions.spectreJitToCxxCalls)
+        masm.speculationBarrier();
+
+    return true;
+}
\ No newline at end of file
--- a/js/src/jit/CacheIRCompiler.h
+++ b/js/src/jit/CacheIRCompiler.h
@@ -72,16 +72,17 @@ namespace jit {
     _(LoadStringTruthyResult)             \
     _(LoadObjectTruthyResult)             \
     _(CompareStringResult)                \
     _(CompareObjectResult)                \
     _(CompareSymbolResult)                \
     _(ArrayJoinResult)                    \
     _(CallPrintString)                    \
     _(Breakpoint)                         \
+    _(MegamorphicLoadSlotResult)          \
     _(MegamorphicLoadSlotByValueResult)   \
     _(MegamorphicHasPropResult)           \
     _(CallObjectHasSparseElementResult)   \
     _(WrapResult)
 
 // Represents a Value on the Baseline frame's expression stack. Slot 0 is the
 // value on top of the stack (the most recently pushed value), slot 1 is the
 // value pushed before that, etc.
@@ -654,18 +655,18 @@ class MOZ_RAII CacheIRCompiler
     }
 
     bool emitComparePointerResultShared(bool symbol);
 
 #define DEFINE_SHARED_OP(op) MOZ_MUST_USE bool emit##op();
     CACHE_IR_SHARED_OPS(DEFINE_SHARED_OP)
 #undef DEFINE_SHARED_OP
 
-    void EmitLoadStubField(StubFieldOffset val, Register dest);
-    void EmitLoadStubFieldConstant(StubFieldOffset val, Register dest);
+    void emitLoadStubField(StubFieldOffset val, Register dest);
+    void emitLoadStubFieldConstant(StubFieldOffset val, Register dest);
 
     uintptr_t readStubWord(uint32_t offset, StubField::Type type) {
         MOZ_ASSERT(stubFieldPolicy_ == StubFieldPolicy::Constant);
         MOZ_ASSERT((offset % sizeof(uintptr_t)) == 0);
         // We use nextStubField_ to access the data as it's stored in an as-of-yet
         // unpacked vector, and so using the offset can be incorrect where the index
         // would change as a result of packing.
         return writer_.readStubFieldForIon(nextStubField_++, type).asWord();
--- a/js/src/jit/IonCacheIRCompiler.cpp
+++ b/js/src/jit/IonCacheIRCompiler.cpp
@@ -926,68 +926,16 @@ IonCacheIRCompiler::emitLoadDynamicSlotR
 
     AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
     masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), scratch);
     masm.loadTypedOrValue(Address(scratch, offset), output);
     return true;
 }
 
 bool
-IonCacheIRCompiler::emitMegamorphicLoadSlotResult()
-{
-    AutoOutputRegister output(*this);
-
-    Register obj = allocator.useRegister(masm, reader.objOperandId());
-    PropertyName* name = stringStubField(reader.stubOffset())->asAtom().asPropertyName();
-    bool handleMissing = reader.readBool();
-
-    AutoScratchRegisterMaybeOutput scratch1(allocator, masm, output);
-    AutoScratchRegister scratch2(allocator, masm);
-    AutoScratchRegister scratch3(allocator, masm);
-
-    FailurePath* failure;
-    if (!addFailurePath(&failure))
-        return false;
-
-    // The object must be Native.
-    masm.branchIfNonNativeObj(obj, scratch3, failure->label());
-
-    masm.Push(UndefinedValue());
-    masm.moveStackPtrTo(scratch3.get());
-
-    LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs());
-    volatileRegs.takeUnchecked(scratch1);
-    volatileRegs.takeUnchecked(scratch2);
-    volatileRegs.takeUnchecked(scratch3);
-    masm.PushRegsInMask(volatileRegs);
-
-    masm.setupUnalignedABICall(scratch1);
-    masm.loadJSContext(scratch1);
-    masm.passABIArg(scratch1);
-    masm.passABIArg(obj);
-    masm.movePtr(ImmGCPtr(name), scratch2);
-    masm.passABIArg(scratch2);
-    masm.passABIArg(scratch3);
-    if (handleMissing)
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, (GetNativeDataProperty<true>)));
-    else
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, (GetNativeDataProperty<false>)));
-    masm.mov(ReturnReg, scratch2);
-    masm.PopRegsInMask(volatileRegs);
-
-    masm.loadTypedOrValue(Address(masm.getStackPointer(), 0), output);
-    masm.adjustStack(sizeof(Value));
-
-    masm.branchIfFalseBool(scratch2, failure->label());
-    if (JitOptions.spectreJitToCxxCalls)
-        masm.speculationBarrier();
-    return true;
-}
-
-bool
 IonCacheIRCompiler::emitMegamorphicStoreSlot()
 {
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     PropertyName* name = stringStubField(reader.stubOffset())->asAtom().asPropertyName();
     ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
     bool needsTypeBarrier = reader.readBool();
 
     AutoScratchRegister scratch1(allocator, masm);