Title: [89643] trunk/Source/_javascript_Core
Revision
89643
Author
[email protected]
Date
2011-06-23 17:40:18 -0700 (Thu, 23 Jun 2011)

Log Message

2011-06-23  Filip Pizlo  <[email protected]>

        Reviewed by Gavin Barraclough.

        DFG non-speculative JIT should have obvious optimizations for GetById and GetByVal
        https://bugs.webkit.org/show_bug.cgi?id=63173

        * dfg/DFGJITCodeGenerator.cpp:
        (JSC::DFG::JITCodeGenerator::cachedGetById):
        * dfg/DFGJITCodeGenerator.h:
        * dfg/DFGNonSpeculativeJIT.cpp:
        (JSC::DFG::NonSpeculativeJIT::compile):
        * dfg/DFGSpeculativeJIT.cpp:
        (JSC::DFG::SpeculativeJIT::compile):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (89642 => 89643)


--- trunk/Source/_javascript_Core/ChangeLog	2011-06-24 00:33:42 UTC (rev 89642)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-06-24 00:40:18 UTC (rev 89643)
@@ -1,3 +1,18 @@
+2011-06-23  Filip Pizlo  <[email protected]>
+
+        Reviewed by Gavin Barraclough.
+
+        DFG non-speculative JIT should have obvious optimizations for GetById and GetByVal
+        https://bugs.webkit.org/show_bug.cgi?id=63173
+
+        * dfg/DFGJITCodeGenerator.cpp:
+        (JSC::DFG::JITCodeGenerator::cachedGetById):
+        * dfg/DFGJITCodeGenerator.h:
+        * dfg/DFGNonSpeculativeJIT.cpp:
+        (JSC::DFG::NonSpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
 2011-06-23  Oliver Hunt  <[email protected]>
 
         Fix Qt again.

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (89642 => 89643)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp	2011-06-24 00:33:42 UTC (rev 89642)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp	2011-06-24 00:40:18 UTC (rev 89643)
@@ -320,6 +320,36 @@
     use(child3);
 }
 
+void JITCodeGenerator::cachedGetById(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget)
+{
+    JITCompiler::DataLabelPtr structureToCompare;
+    JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::Equal, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
+    
+    if (slowPathTarget.isSet())
+        slowPathTarget.link(&m_jit);
+
+    silentSpillAllRegisters(resultGPR, baseGPR);
+    m_jit.move(baseGPR, GPRInfo::argumentGPR1);
+    m_jit.move(JITCompiler::ImmPtr(identifier(identifierNumber)), GPRInfo::argumentGPR2);
+    m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    JITCompiler::Call functionCall = appendCallWithExceptionCheck(operationGetByIdOptimize);
+    m_jit.move(GPRInfo::returnValueGPR, resultGPR);
+    silentFillAllRegisters(resultGPR);
+
+    JITCompiler::Jump handledByC = m_jit.jump();
+    structureCheck.link(&m_jit);
+
+    m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
+    JITCompiler::DataLabelCompact loadWithPatch = m_jit.loadPtrWithCompactAddressOffsetPatch(JITCompiler::Address(resultGPR, 0), resultGPR);
+
+    intptr_t checkToCall = m_jit.differenceBetween(structureToCompare, functionCall);
+    intptr_t callToLoad = m_jit.differenceBetween(functionCall, loadWithPatch);
+
+    handledByC.link(&m_jit);
+
+    m_jit.addPropertyAccess(functionCall, checkToCall, callToLoad);
+}
+
 #ifndef NDEBUG
 static const char* dataFormatString(DataFormat format)
 {

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (89642 => 89643)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-06-24 00:33:42 UTC (rev 89642)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-06-24 00:40:18 UTC (rev 89643)
@@ -500,6 +500,8 @@
         }
     }
 
+    void cachedGetById(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
+
     // Called once a node has completed code generation but prior to setting
     // its result, to free up its children. (This must happen prior to setting
     // the nodes result, since the node may have the same VirtualRegister as

Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (89642 => 89643)


--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp	2011-06-24 00:33:42 UTC (rev 89642)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp	2011-06-24 00:40:18 UTC (rev 89643)
@@ -493,16 +493,53 @@
     }
 
     case GetByVal: {
-        JSValueOperand arg1(this, node.child1);
-        JSValueOperand arg2(this, node.child2);
-        GPRReg arg1GPR = arg1.gpr();
-        GPRReg arg2GPR = arg2.gpr();
-        flushRegisters();
+        JSValueOperand base(this, node.child1);
+        JSValueOperand property(this, node.child2);
 
-        GPRResult result(this);
-        callOperation(operationGetByVal, result.gpr(), arg1GPR, arg2GPR);
+        GPRTemporary storage(this);
+        GPRTemporary cleanIndex(this);
 
-        jsValueResult(result.gpr(), m_compileIndex);
+        GPRReg baseGPR = base.gpr();
+        GPRReg propertyGPR = property.gpr();
+        GPRReg storageGPR = storage.gpr();
+        GPRReg cleanIndexGPR = cleanIndex.gpr();
+
+        JITCompiler::Jump baseNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
+
+        JITCompiler::Jump propertyNotInt = m_jit.branchPtr(MacroAssembler::Below, propertyGPR, GPRInfo::tagTypeNumberRegister);
+
+        // Get the array storage. We haven't yet checked this is a JSArray, so this is only safe if
+        // an access with offset JSArray::storageOffset() is valid for all JSCells!
+        m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR);
+
+        JITCompiler::Jump baseNotArray = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr));
+
+        m_jit.zeroExtend32ToPtr(propertyGPR, cleanIndexGPR);
+
+        JITCompiler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, cleanIndexGPR, MacroAssembler::Address(baseGPR, JSArray::vectorLengthOffset()));
+
+        m_jit.loadPtr(MacroAssembler::BaseIndex(storageGPR, cleanIndexGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), storageGPR);
+
+        JITCompiler::Jump loadFailed = m_jit.branchTestPtr(MacroAssembler::Zero, storageGPR);
+
+        JITCompiler::Jump done = m_jit.jump();
+
+        baseNotCell.link(&m_jit);
+        propertyNotInt.link(&m_jit);
+        baseNotArray.link(&m_jit);
+        outOfBounds.link(&m_jit);
+        loadFailed.link(&m_jit);
+
+        silentSpillAllRegisters(storageGPR, baseGPR, propertyGPR);
+        setupStubArguments(baseGPR, propertyGPR);
+        m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+        appendCallWithExceptionCheck(operationGetByVal);
+        m_jit.move(GPRInfo::returnValueGPR, storageGPR);
+        silentFillAllRegisters(storageGPR);
+
+        done.link(&m_jit);
+
+        jsValueResult(storageGPR, m_compileIndex);
         break;
     }
 
@@ -526,11 +563,14 @@
     case GetById: {
         JSValueOperand base(this, node.child1);
         GPRReg baseGPR = base.gpr();
-        flushRegisters();
+        GPRTemporary result(this, base);
+        GPRReg resultGPR = result.gpr();
 
-        GPRResult result(this);
-        callOperation(operationGetById, result.gpr(), baseGPR, identifier(node.identifierNumber()));
-        jsValueResult(result.gpr(), m_compileIndex);
+        JITCompiler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
+
+        cachedGetById(baseGPR, resultGPR, node.identifierNumber(), notCell);
+
+        jsValueResult(resultGPR, m_compileIndex);
         break;
     }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (89642 => 89643)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-06-24 00:33:42 UTC (rev 89642)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-06-24 00:40:18 UTC (rev 89643)
@@ -854,33 +854,10 @@
         SpeculateCellOperand base(this, node.child1);
         GPRTemporary result(this, base);
 
-        GPRReg baseGPR = base.gpr();
         GPRReg resultGPR = result.gpr();
 
-        JITCompiler::DataLabelPtr structureToCompare;
-        JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::Equal, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
+        cachedGetById(base.gpr(), resultGPR, node.identifierNumber());
 
-        silentSpillAllRegisters(resultGPR, baseGPR);
-        m_jit.move(baseGPR, GPRInfo::argumentGPR1);
-        m_jit.move(JITCompiler::ImmPtr(identifier(node.identifierNumber())), GPRInfo::argumentGPR2);
-        m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
-        JITCompiler::Call functionCall = appendCallWithExceptionCheck(operationGetByIdOptimize);
-        m_jit.move(GPRInfo::returnValueGPR, resultGPR);
-        silentFillAllRegisters(resultGPR);
-
-        JITCompiler::Jump handledByC = m_jit.jump();
-        structureCheck.link(&m_jit);
-
-        m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
-        JITCompiler::DataLabelCompact loadWithPatch = m_jit.loadPtrWithCompactAddressOffsetPatch(JITCompiler::Address(resultGPR, 0), resultGPR);
-
-        intptr_t checkToCall = m_jit.differenceBetween(structureToCompare, functionCall);
-        intptr_t callToLoad = m_jit.differenceBetween(functionCall, loadWithPatch);
-
-        handledByC.link(&m_jit);
-
-        m_jit.addPropertyAccess(functionCall, checkToCall, callToLoad);
-
         jsValueResult(resultGPR, m_compileIndex);
         break;
     }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to