Title: [91734] trunk/Source/_javascript_Core
Revision
91734
Author
[email protected]
Date
2011-07-25 18:04:49 -0700 (Mon, 25 Jul 2011)

Log Message

DFG non-speculative JIT emits obviously inefficient code for arithmetic
where one operand is a constant.
https://bugs.webkit.org/show_bug.cgi?id=65146

Patch by Filip Pizlo <[email protected]> on 2011-07-25
Reviewed by Gavin Barraclough.

Changed the code to emit double arithmetic inline.

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

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (91733 => 91734)


--- trunk/Source/_javascript_Core/ChangeLog	2011-07-26 01:03:39 UTC (rev 91733)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-07-26 01:04:49 UTC (rev 91734)
@@ -1,5 +1,18 @@
 2011-07-25  Filip Pizlo  <[email protected]>
 
+        DFG non-speculative JIT emits obviously inefficient code for arithmetic
+        where one operand is a constant.
+        https://bugs.webkit.org/show_bug.cgi?id=65146
+
+        Reviewed by Gavin Barraclough.
+        
+        Changed the code to emit double arithmetic inline.
+
+        * dfg/DFGNonSpeculativeJIT.cpp:
+        (JSC::DFG::NonSpeculativeJIT::knownConstantArithOp):
+
+2011-07-25  Filip Pizlo  <[email protected]>
+
         DFG JIT bytecode parser misuses pointers into objects allocated as part of a
         WTF::Vector.
         https://bugs.webkit.org/show_bug.cgi?id=65128

Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (91733 => 91734)


--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp	2011-07-26 01:03:39 UTC (rev 91733)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp	2011-07-26 01:04:49 UTC (rev 91734)
@@ -126,8 +126,12 @@
 {
     JSValueOperand regArg(this, regChild);
     GPRReg regArgGPR = regArg.gpr();
-    GPRTemporary result(this, regArg);
+    GPRTemporary result(this);
     GPRReg resultGPR = result.gpr();
+    FPRTemporary tmp1(this);
+    FPRTemporary tmp2(this);
+    FPRReg tmp1FPR = tmp1.fpr();
+    FPRReg tmp2FPR = tmp2.fpr();
     
     regArg.use();
     use(immChild);
@@ -143,15 +147,13 @@
     
     switch (op) {
     case ValueAdd:
-    case ArithAdd: {
+    case ArithAdd:
         overflow = m_jit.branchAdd32(MacroAssembler::Overflow, regArgGPR, Imm32(imm), resultGPR);
         break;
-    }
         
-    case ArithSub: {
+    case ArithSub:
         overflow = m_jit.branchSub32(MacroAssembler::Overflow, regArgGPR, Imm32(imm), resultGPR);
         break;
-    }
         
     default:
         ASSERT_NOT_REACHED();
@@ -163,31 +165,13 @@
     
     overflow.link(&m_jit);
     
-    if (regArgGPR == resultGPR) {
-        switch (op) {
-        case ValueAdd:
-        case ArithAdd: {
-            m_jit.sub32(Imm32(imm), regArgGPR);
-            break;
-        }
-            
-        case ArithSub: {
-            m_jit.add32(Imm32(imm), regArgGPR);
-            break;
-        }
-            
-        default:
-            ASSERT_NOT_REACHED();
-        }
-        m_jit.orPtr(GPRInfo::tagTypeNumberRegister, regArgGPR);
-    }
-    
-    if (!isKnownInteger(regChild))
-        notInt.link(&m_jit);
-    
-    silentSpillAllRegisters(resultGPR);
     switch (op) {
     case ValueAdd:
+        // overflow and not-int are the same
+        if (!isKnownInteger(regChild))
+            notInt.link(&m_jit);
+        
+        silentSpillAllRegisters(resultGPR);
         if (commute) {
             m_jit.move(regArgGPR, GPRInfo::argumentGPR2);
             m_jit.move(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm)))), GPRInfo::argumentGPR1);
@@ -197,31 +181,41 @@
         }
         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
         appendCallWithExceptionCheck(operationValueAdd);
+        m_jit.move(GPRInfo::returnValueGPR, resultGPR);
+        silentFillAllRegisters(resultGPR);
         break;
-        
+
     case ArithAdd:
-        if (commute) {
-            m_jit.move(regArgGPR, GPRInfo::argumentGPR1);
-            m_jit.move(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm)))), GPRInfo::argumentGPR0);
-        } else {
-            m_jit.move(regArgGPR, GPRInfo::argumentGPR0);
-            m_jit.move(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm)))), GPRInfo::argumentGPR1);
+    case ArithSub:
+        // first deal with overflow case
+        m_jit.convertInt32ToDouble(regArgGPR, tmp2FPR);
+        
+        // now deal with not-int case, if applicable
+        if (!isKnownInteger(regChild)) {
+            JITCompiler::Jump haveValue = m_jit.jump();
+            
+            notInt.link(&m_jit);
+            
+            m_jit.move(regArgGPR, resultGPR);
+            m_jit.addPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
+            m_jit.movePtrToDouble(resultGPR, tmp2FPR);
+            
+            haveValue.link(&m_jit);
         }
-        m_jit.appendCall(operationArithAdd);
-        break;
         
-    case ArithSub:
-        ASSERT(!commute);
-        m_jit.move(regArgGPR, GPRInfo::argumentGPR0);
-        m_jit.move(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm)))), GPRInfo::argumentGPR1);
-        m_jit.appendCall(operationArithSub);
+        m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfDoubleConstant(immChild)))), resultGPR);
+        m_jit.movePtrToDouble(resultGPR, tmp1FPR);
+        if (op == ArithAdd)
+            m_jit.addDouble(tmp1FPR, tmp2FPR);
+        else
+            m_jit.subDouble(tmp1FPR, tmp2FPR);
+        m_jit.moveDoubleToPtr(tmp2FPR, resultGPR);
+        m_jit.subPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
         break;
         
     default:
         ASSERT_NOT_REACHED();
     }
-    m_jit.move(GPRInfo::returnValueGPR, resultGPR);
-    silentFillAllRegisters(resultGPR);
     
     done.link(&m_jit);
         
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to