Bug 1017428 part 2. Add a fast path to Ion for [Cached] DOM attributes. r=efaust
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 03 Jun 2014 11:38:37 -0400
changeset 205593 27cd25212b6232d2833dbf046c1bd2514397ff57
parent 205592 9ce4e8958829632492d31fb54aeb9813c9c3afff
child 205594 026bd94e5bd06146e64acd9d36c40da0fd35cea1
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersefaust
bugs1017428
milestone32.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 1017428 part 2. Add a fast path to Ion for [Cached] DOM attributes. r=efaust
js/src/jit/CodeGenerator.cpp
js/src/jit/MIR.h
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -8323,16 +8323,37 @@ CodeGenerator::visitCallInstanceOf(LCall
 bool
 CodeGenerator::visitGetDOMProperty(LGetDOMProperty *ins)
 {
     const Register JSContextReg = ToRegister(ins->getJSContextReg());
     const Register ObjectReg = ToRegister(ins->getObjectReg());
     const Register PrivateReg = ToRegister(ins->getPrivReg());
     const Register ValueReg = ToRegister(ins->getValueReg());
 
+    Label haveValue;
+    if (ins->mir()->valueMayBeInSlot()) {
+        size_t slot = ins->mir()->domMemberSlotIndex();
+        // It's a bit annoying to redo these slot calculations, which duplcate
+        // LSlots and a few other things like that, but I'm not sure there's a
+        // way to reuse those here.
+        if (slot < JSObject::MAX_FIXED_SLOTS) {
+            masm.loadValue(Address(ObjectReg, JSObject::getFixedSlotOffset(slot)),
+                           JSReturnOperand);
+        } else {
+            // It's a dynamic slot.
+            slot -= JSObject::MAX_FIXED_SLOTS;
+            // Use PrivateReg as a scratch register for the slots pointer.
+            masm.loadPtr(Address(ObjectReg, JSObject::offsetOfSlots()),
+                         PrivateReg);
+            masm.loadValue(Address(PrivateReg, slot*sizeof(js::Value)),
+                           JSReturnOperand);
+        }
+        masm.branchTestUndefined(Assembler::NotEqual, JSReturnOperand, &haveValue);
+    }
+
     DebugOnly<uint32_t> initialStack = masm.framePushed();
 
     masm.checkStackAlignment();
 
     // Make space for the outparam.  Pre-initialize it to UndefinedValue so we
     // can trace it at GC time.
     masm.Push(UndefinedValue());
     // We pass the pointer to our out param as an instance of
@@ -8372,16 +8393,18 @@ CodeGenerator::visitGetDOMProperty(LGetD
     } else {
         masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel());
 
         masm.loadValue(Address(StackPointer, IonDOMExitFrameLayout::offsetOfResult()),
                        JSReturnOperand);
     }
     masm.adjustStack(IonDOMExitFrameLayout::Size());
 
+    masm.bind(&haveValue);
+
     JS_ASSERT(masm.framePushed() == initialStack);
     return true;
 }
 
 bool
 CodeGenerator::visitGetDOMMember(LGetDOMMember *ins)
 {
     // It's simple to duplicate visitLoadFixedSlotV here than it is to try to
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -8663,16 +8663,19 @@ class MGetDOMProperty
     }
     JSJitInfo::AliasSet domAliasSet() const {
         return info_->aliasSet();
     }
     size_t domMemberSlotIndex() const {
         MOZ_ASSERT(info_->isAlwaysInSlot || info_->isLazilyCachedInSlot);
         return info_->slotIndex;
     }
+    bool valueMayBeInSlot() const {
+        return info_->isLazilyCachedInSlot;
+    }
     MDefinition *object() {
         return getOperand(0);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }