[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