DFG non-speculative JIT does not optimize PutByVal
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 31 Jul 2011 20:13:37 +0000 (20:13 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 31 Jul 2011 20:13:37 +0000 (20:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=65424

Reviewed by Gavin Barraclough.

Added code to emit PutByVal inline fast path.

* dfg/DFGNonSpeculativeJIT.cpp:
(JSC::DFG::NonSpeculativeJIT::compile):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@92085 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp

index ff582663a11dc574e0c9e35cbdf23a6520701723..c4c9965c724ff2fe4f55a87c51ab98d8b6a13cc9 100644 (file)
@@ -1,3 +1,15 @@
+2011-07-31  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG non-speculative JIT does not optimize PutByVal
+        https://bugs.webkit.org/show_bug.cgi?id=65424
+
+        Reviewed by Gavin Barraclough.
+        
+        Added code to emit PutByVal inline fast path.
+
+        * dfg/DFGNonSpeculativeJIT.cpp:
+        (JSC::DFG::NonSpeculativeJIT::compile):
+
 2011-07-31  Filip Pizlo  <fpizlo@apple.com>
 
         The JSC garbage collector returns memory to the operating system too
index 10310de2cb2a0f2d2f26aee77ac12c345d6af2be..1fe8e9576c673ba40653e62f04425c3f7085d91e 100644 (file)
@@ -819,19 +819,62 @@ void NonSpeculativeJIT::compile(SpeculationCheckIndexIterator& checkIterator, No
 
     case PutByVal:
     case PutByValAlias: {
-        JSValueOperand arg1(this, node.child1());
-        JSValueOperand arg2(this, node.child2());
-        JSValueOperand arg3(this, node.child3());
-        GPRReg arg1GPR = arg1.gpr();
-        GPRReg arg2GPR = arg2.gpr();
-        GPRReg arg3GPR = arg3.gpr();
+        JSValueOperand base(this, node.child1());
+        JSValueOperand property(this, node.child2());
+        JSValueOperand value(this, node.child3());
+        GPRTemporary storage(this);
+        GPRTemporary cleanIndex(this);
+        GPRReg baseGPR = base.gpr();
+        GPRReg propertyGPR = property.gpr();
+        GPRReg valueGPR = value.gpr();
+        GPRReg storageGPR = storage.gpr();
+        GPRReg cleanIndexGPR = cleanIndex.gpr();
         
-        arg1.use();
-        arg2.use();
-        arg3.use();
-        flushRegisters();
+        base.use();
+        property.use();
+        value.use();
+        
+        writeBarrier(m_jit, baseGPR, storageGPR);
+        
+        JITCompiler::Jump baseNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
+
+        JITCompiler::Jump propertyNotInt = m_jit.branchPtr(MacroAssembler::Below, propertyGPR, GPRInfo::tagTypeNumberRegister);
+
+        m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR);
 
-        callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);
+        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()));
+        
+        JITCompiler::Jump notHoleValue = m_jit.branchTestPtr(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageGPR, cleanIndexGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
+        
+        JITCompiler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, cleanIndexGPR, MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)));
+        
+        m_jit.add32(TrustedImm32(1), cleanIndexGPR);
+        m_jit.store32(cleanIndexGPR, MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)));
+        m_jit.zeroExtend32ToPtr(propertyGPR, cleanIndexGPR);
+        
+        lengthDoesNotNeedUpdate.link(&m_jit);
+        notHoleValue.link(&m_jit);
+        
+        m_jit.storePtr(valueGPR, MacroAssembler::BaseIndex(storageGPR, cleanIndexGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
+        
+        JITCompiler::Jump done = m_jit.jump();
+        
+        baseNotCell.link(&m_jit);
+        propertyNotInt.link(&m_jit);
+        baseNotArray.link(&m_jit);
+        outOfBounds.link(&m_jit);
+        
+        silentSpillAllRegisters(InvalidGPRReg);
+        setupStubArguments(baseGPR, propertyGPR, valueGPR);
+        m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+        JITCompiler::Call functionCall = appendCallWithExceptionCheck(m_jit.codeBlock()->isStrictMode() ? operationPutByValStrict : operationPutByValNonStrict);
+        silentFillAllRegisters(InvalidGPRReg);
+        
+        done.link(&m_jit);
 
         noResult(m_compileIndex, UseChildrenCalledExplicitly);
         break;