[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.21-584-g1e41756

loki at webkit.org loki at webkit.org
Fri Feb 26 22:15:33 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit c3a1c5d86a4a7968c0824eb21da6218c62100f00
Author: loki at webkit.org <loki at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Feb 9 08:50:22 2010 +0000

    Add a soft modulo operation to ARM JIT using a trampoline function.
    The performance progression is about ~1.8% on ARMv7
    https://bugs.webkit.org/show_bug.cgi?id=34424
    
    Patch by Tamas Szirbucz <szirbucz at inf.u-szeged.hu> on 2010-02-09
    Reviewed by Gavin Barraclough.
    
    Developed in cooperation with Gabor Loki.
    
    * jit/JIT.h:
    * jit/JITArithmetic.cpp:
    (JSC::JIT::emit_op_mod):
    (JSC::JIT::emitSlow_op_mod):
    * jit/JITOpcodes.cpp:
    (JSC::JIT::softModulo):
    * jit/JITStubs.h:
    (JSC::JITThunks::ctiSoftModulo):
    * wtf/Platform.h:
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54534 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index bea5ab4..7673a97 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,23 @@
+2010-02-09  Tamas Szirbucz  <szirbucz at inf.u-szeged.hu>
+
+        Reviewed by Gavin Barraclough.
+
+        Add a soft modulo operation to ARM JIT using a trampoline function.
+        The performance progression is about ~1.8% on ARMv7
+        https://bugs.webkit.org/show_bug.cgi?id=34424
+
+        Developed in cooperation with Gabor Loki.
+
+        * jit/JIT.h:
+        * jit/JITArithmetic.cpp:
+        (JSC::JIT::emit_op_mod):
+        (JSC::JIT::emitSlow_op_mod):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::softModulo):
+        * jit/JITStubs.h:
+        (JSC::JITThunks::ctiSoftModulo):
+        * wtf/Platform.h:
+
 2010-02-08  Gavin Barraclough  <barraclough at apple.com>
 
         Reviewed by NOBODY (SL/win build fixes).
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h
index 7cfd0e0..bfbb1ee 100644
--- a/JavaScriptCore/jit/JIT.h
+++ b/JavaScriptCore/jit/JIT.h
@@ -800,6 +800,9 @@ namespace JSC {
         void emit_op_to_jsnumber(Instruction*);
         void emit_op_to_primitive(Instruction*);
         void emit_op_unexpected_load(Instruction*);
+#if ENABLE(JIT_OPTIMIZE_MOD)
+        void softModulo();
+#endif
 
         void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&);
diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp
index feee8d2..2f2ffe3 100644
--- a/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/JavaScriptCore/jit/JITArithmetic.cpp
@@ -31,6 +31,7 @@
 #include "CodeBlock.h"
 #include "JITInlineMethods.h"
 #include "JITStubCall.h"
+#include "JITStubs.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "Interpreter.h"
@@ -1186,14 +1187,40 @@ void JIT::emit_op_mod(Instruction* currentInstruction)
     unsigned op1 = currentInstruction[2].u.operand;
     unsigned op2 = currentInstruction[3].u.operand;
 
+#if ENABLE(JIT_OPTIMIZE_MOD)    
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+    
+    addSlowCase(branch32(Equal, regT2, Imm32(0)));
+    
+    emitNakedCall(m_globalData->jitStubs.ctiSoftModulo());
+
+    emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
+#else
     JITStubCall stubCall(this, cti_op_mod);
     stubCall.addArgument(op1);
     stubCall.addArgument(op2);
     stubCall.call(dst);
+#endif
 }
 
-void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&)
+void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_mod);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(result);
+#else
+    ASSERT_NOT_REACHED();
+#endif
 }
 
 #endif // CPU(X86) || CPU(X86_64)
@@ -2138,15 +2165,40 @@ void JIT::emit_op_mod(Instruction* currentInstruction)
     unsigned op1 = currentInstruction[2].u.operand;
     unsigned op2 = currentInstruction[3].u.operand;
 
+#if ENABLE(JIT_OPTIMIZE_MOD)    
+    emitGetVirtualRegisters(op1, regT0, op2, regT2);
+    emitJumpSlowCaseIfNotImmediateInteger(regT0);
+    emitJumpSlowCaseIfNotImmediateInteger(regT2);
+    
+    addSlowCase(branch32(Equal, regT2, Imm32(1)));
+
+    emitNakedCall(m_globalData->jitStubs.ctiSoftModulo());
+
+    emitPutVirtualRegister(result, regT0);
+#else
     JITStubCall stubCall(this, cti_op_mod);
     stubCall.addArgument(op1, regT2);
     stubCall.addArgument(op2, regT2);
     stubCall.call(result);
+#endif
 }
 
-void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&)
+void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_mod);
+    stubCall.addArgument(op1, regT2);
+    stubCall.addArgument(op2, regT2);
+    stubCall.call(result);
+#else
     ASSERT_NOT_REACHED();
+#endif
 }
 
 #endif // CPU(X86) || CPU(X86_64)
diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp
index c450aa4..c3f20f1 100644
--- a/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/JavaScriptCore/jit/JITOpcodes.cpp
@@ -42,6 +42,10 @@ namespace JSC {
 
 void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, TrampolineStructure *trampolines)
 {
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    Label softModBegin = align();
+    softModulo();
+#endif
 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
     // (1) This function provides fast property access for string length
     Label stringLengthBegin = align();
@@ -377,6 +381,9 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
 #else
     UNUSED_PARAM(ctiVirtualCallLink);
 #endif
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    trampolines->ctiSoftModulo = trampolineAt(finalCode, softModBegin);
+#endif
 }
 
 void JIT::emit_op_mov(Instruction* currentInstruction)
@@ -1497,6 +1504,10 @@ void JIT::emit_op_profile_did_call(Instruction* currentInstruction)
 
 void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, TrampolineStructure *trampolines)
 {
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    Label softModBegin = align();
+    softModulo();
+#endif
 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
     // (2) The second function provides fast property access for string length
     Label stringLengthBegin = align();
@@ -1830,6 +1841,9 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
     trampolines->ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
     trampolines->ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin);
     trampolines->ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk);
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    trampolines->ctiSoftModulo = trampolineAt(finalCode, softModBegin);
+#endif
 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
     trampolines->ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin);
 #else
@@ -2978,6 +2992,81 @@ void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCa
 
 #endif // USE(JSVALUE32_64)
 
+// For both JSValue32_64 and JSValue32
+#if ENABLE(JIT_OPTIMIZE_MOD)
+#if CPU(ARM_TRADITIONAL)
+void JIT::softModulo()
+{
+    push(regS0);
+    push(regS1);
+    push(regT1);
+    push(regT3);
+#if USE(JSVALUE32_64)
+    m_assembler.mov_r(regT3, regT2);
+    m_assembler.mov_r(regT2, regT0);
+#else
+    m_assembler.mov_r(regT3, m_assembler.asr(regT2, 1));
+    m_assembler.mov_r(regT2, m_assembler.asr(regT0, 1));
+#endif
+    m_assembler.mov_r(regT1, ARMAssembler::getOp2(0));
+    
+    m_assembler.teq_r(regT3, ARMAssembler::getOp2(0));
+    m_assembler.rsb_r(regT3, regT3, ARMAssembler::getOp2(0), ARMAssembler::MI);
+    m_assembler.eor_r(regT1, regT1, ARMAssembler::getOp2(1), ARMAssembler::MI);
+    
+    m_assembler.teq_r(regT2, ARMAssembler::getOp2(0));
+    m_assembler.rsb_r(regT2, regT2, ARMAssembler::getOp2(0), ARMAssembler::MI);
+    m_assembler.eor_r(regT1, regT1, ARMAssembler::getOp2(2), ARMAssembler::MI);
+    
+    Jump exitBranch = branch32(LessThan, regT2, regT3);
+
+    m_assembler.sub_r(regS1, regT3, ARMAssembler::getOp2(1));
+    m_assembler.tst_r(regS1, regT3);
+    m_assembler.and_r(regT2, regT2, regS1, ARMAssembler::EQ);
+    m_assembler.and_r(regT0, regS1, regT3);
+    Jump exitBranch2 = branchTest32(Zero, regT0);
+    
+    m_assembler.clz_r(regS1, regT2);
+    m_assembler.clz_r(regS0, regT3);
+    m_assembler.sub_r(regS0, regS0, regS1);
+
+    m_assembler.rsbs_r(regS0, regS0, ARMAssembler::getOp2(31));
+
+    m_assembler.mov_r(regS0, m_assembler.lsl(regS0, 1), ARMAssembler::NE);
+
+    m_assembler.add_r(ARMRegisters::pc, ARMRegisters::pc, m_assembler.lsl(regS0, 2), ARMAssembler::NE);
+    m_assembler.mov_r(regT0, regT0);
+    
+    for (int i = 31; i > 0; --i) {
+        m_assembler.cmp_r(regT2, m_assembler.lsl(regT3, i));
+        m_assembler.sub_r(regT2, regT2, m_assembler.lsl(regT3, i), ARMAssembler::CS);
+    }
+
+    m_assembler.cmp_r(regT2, regT3);
+    m_assembler.sub_r(regT2, regT2, regT3, ARMAssembler::CS);
+    
+    exitBranch.link(this);
+    exitBranch2.link(this);
+    
+    m_assembler.teq_r(regT1, ARMAssembler::getOp2(0));
+    m_assembler.rsb_r(regT2, regT2, ARMAssembler::getOp2(0), ARMAssembler::GT);
+    
+#if USE(JSVALUE32_64)
+    m_assembler.mov_r(regT0, regT2);
+#else
+    m_assembler.mov_r(regT0, m_assembler.lsl(regT2, 1));
+    m_assembler.eor_r(regT0, regT0, ARMAssembler::getOp2(1));
+#endif
+    pop(regT3);
+    pop(regT1);
+    pop(regS1);
+    pop(regS0);
+    ret();
+}
+#else
+#error "JIT_OPTIMIZE_MOD not yet supported on this platform."
+#endif // CPU(ARM_TRADITIONAL)
+#endif
 } // namespace JSC
 
 #endif // ENABLE(JIT)
diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h
index f276fad..17fd0d9 100644
--- a/JavaScriptCore/jit/JITStubs.h
+++ b/JavaScriptCore/jit/JITStubs.h
@@ -80,6 +80,7 @@ namespace JSC {
         MacroAssemblerCodePtr ctiVirtualCallLink;
         MacroAssemblerCodePtr ctiVirtualCall;
         MacroAssemblerCodePtr ctiNativeCallThunk;
+        MacroAssemblerCodePtr ctiSoftModulo;
     };
 
 #if CPU(X86_64)
@@ -250,6 +251,7 @@ namespace JSC {
         MacroAssemblerCodePtr ctiVirtualCallLink() { return m_trampolineStructure.ctiVirtualCallLink; }
         MacroAssemblerCodePtr ctiVirtualCall() { return m_trampolineStructure.ctiVirtualCall; }
         MacroAssemblerCodePtr ctiNativeCallThunk() { return m_trampolineStructure.ctiNativeCallThunk; }
+        MacroAssemblerCodePtr ctiSoftModulo() { return m_trampolineStructure.ctiSoftModulo; }
 
     private:
         RefPtr<ExecutablePool> m_executablePool;
diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h
index 1dae678..0ad2375 100644
--- a/JavaScriptCore/wtf/Platform.h
+++ b/JavaScriptCore/wtf/Platform.h
@@ -885,6 +885,13 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
 
 #endif /* !defined(ENABLE_JIT) */
 
+/* CPU architecture specific optimizations */
+#if CPU(ARM_TRADITIONAL)
+#if ENABLE(JIT) && !defined(ENABLE_JIT_OPTIMIZE_MOD) && WTF_ARM_ARCH_AT_LEAST(5)
+#define ENABLE_JIT_OPTIMIZE_MOD 1
+#endif
+#endif
+
 #if ENABLE(JIT)
 #ifndef ENABLE_JIT_OPTIMIZE_CALL
 #define ENABLE_JIT_OPTIMIZE_CALL 1
@@ -898,6 +905,9 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
 #ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS
 #define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1
 #endif
+#ifndef ENABLE_JIT_OPTIMIZE_MOD
+#define ENABLE_JIT_OPTIMIZE_MOD 0
+#endif
 #endif
 
 #if CPU(X86) && COMPILER(MSVC)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list