diff options
author | Steve Block <steveblock@google.com> | 2010-02-15 12:23:52 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-02-16 11:48:32 +0000 |
commit | 8a0914b749bbe7da7768e07a7db5c6d4bb09472b (patch) | |
tree | 73f9065f370435d6fde32ae129d458a8c77c8dff /JavaScriptCore/jit | |
parent | bf14be70295513b8076f3fa47a268a7e42b2c478 (diff) | |
download | external_webkit-8a0914b749bbe7da7768e07a7db5c6d4bb09472b.zip external_webkit-8a0914b749bbe7da7768e07a7db5c6d4bb09472b.tar.gz external_webkit-8a0914b749bbe7da7768e07a7db5c6d4bb09472b.tar.bz2 |
Merge webkit.org at r54731 : Initial merge by git
Change-Id: Ia79977b6cf3b0b00c06ef39419989b28e57e4f4a
Diffstat (limited to 'JavaScriptCore/jit')
-rw-r--r-- | JavaScriptCore/jit/JIT.h | 9 | ||||
-rw-r--r-- | JavaScriptCore/jit/JITArithmetic.cpp | 56 | ||||
-rw-r--r-- | JavaScriptCore/jit/JITOpcodes.cpp | 109 | ||||
-rw-r--r-- | JavaScriptCore/jit/JITStubs.cpp | 2 | ||||
-rw-r--r-- | JavaScriptCore/jit/JITStubs.h | 22 |
5 files changed, 174 insertions, 24 deletions
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h index 8e0c9ac..bfbb1ee 100644 --- a/JavaScriptCore/jit/JIT.h +++ b/JavaScriptCore/jit/JIT.h @@ -317,10 +317,10 @@ namespace JSC { jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress); } - static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk) + static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, TrampolineStructure *trampolines) { JIT jit(globalData); - jit.privateCompileCTIMachineTrampolines(executablePool, globalData, ctiStringLengthTrampoline, ctiVirtualCallLink, ctiVirtualCall, ctiNativeCallThunk); + jit.privateCompileCTIMachineTrampolines(executablePool, globalData, trampolines); } static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress); @@ -361,7 +361,7 @@ namespace JSC { void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame); void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress); - void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk); + void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, TrampolineStructure *trampolines); void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress); void addSlowCase(Jump); @@ -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 d9a32d9..c3f20f1 100644 --- a/JavaScriptCore/jit/JITOpcodes.cpp +++ b/JavaScriptCore/jit/JITOpcodes.cpp @@ -40,8 +40,12 @@ namespace JSC { #if USE(JSVALUE32_64) -void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk) +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(); @@ -365,18 +369,21 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable CodeRef finalCode = patchBuffer.finalizeCode(); *executablePool = finalCode.m_executablePool; - *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin); - *ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk); + trampolines->ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin); + trampolines->ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk); #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) - *ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin); + trampolines->ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin); #else UNUSED_PARAM(ctiStringLengthTrampoline); #endif #if ENABLE(JIT_OPTIMIZE_CALL) - *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin); + trampolines->ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin); #else UNUSED_PARAM(ctiVirtualCallLink); #endif +#if ENABLE(JIT_OPTIMIZE_MOD) + trampolines->ctiSoftModulo = trampolineAt(finalCode, softModBegin); +#endif } void JIT::emit_op_mov(Instruction* currentInstruction) @@ -1495,8 +1502,12 @@ void JIT::emit_op_profile_did_call(Instruction* currentInstruction) #define RECORD_JUMP_TARGET(targetOffset) \ do { m_labels[m_bytecodeIndex + (targetOffset)].used(); } while (false) -void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk) +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(); @@ -1827,11 +1838,14 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable CodeRef finalCode = patchBuffer.finalizeCode(); *executablePool = finalCode.m_executablePool; - *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin); - *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin); - *ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk); + 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) - *ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin); + trampolines->ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin); #else UNUSED_PARAM(ctiStringLengthTrampoline); #endif @@ -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.cpp b/JavaScriptCore/jit/JITStubs.cpp index bf5168b..85471de 100644 --- a/JavaScriptCore/jit/JITStubs.cpp +++ b/JavaScriptCore/jit/JITStubs.cpp @@ -757,7 +757,7 @@ extern "C" { JITThunks::JITThunks(JSGlobalData* globalData) { - JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk); + JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_trampolineStructure); #if CPU(ARM_THUMB2) // Unfortunate the arm compiler does not like the use of offsetof on JITStackFrame (since it contains non POD types), diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h index 99c2dd2..17fd0d9 100644 --- a/JavaScriptCore/jit/JITStubs.h +++ b/JavaScriptCore/jit/JITStubs.h @@ -74,6 +74,14 @@ namespace JSC { JSString* jsString() { return static_cast<JSString*>(asPointer); } ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); } }; + + struct TrampolineStructure { + MacroAssemblerCodePtr ctiStringLengthTrampoline; + MacroAssemblerCodePtr ctiVirtualCallLink; + MacroAssemblerCodePtr ctiVirtualCall; + MacroAssemblerCodePtr ctiNativeCallThunk; + MacroAssemblerCodePtr ctiSoftModulo; + }; #if CPU(X86_64) struct JITStackFrame { @@ -239,18 +247,16 @@ namespace JSC { static void tryCacheGetByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot&, StructureStubInfo* stubInfo); static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&, StructureStubInfo* stubInfo); - MacroAssemblerCodePtr ctiStringLengthTrampoline() { return m_ctiStringLengthTrampoline; } - MacroAssemblerCodePtr ctiVirtualCallLink() { return m_ctiVirtualCallLink; } - MacroAssemblerCodePtr ctiVirtualCall() { return m_ctiVirtualCall; } - MacroAssemblerCodePtr ctiNativeCallThunk() { return m_ctiNativeCallThunk; } + MacroAssemblerCodePtr ctiStringLengthTrampoline() { return m_trampolineStructure.ctiStringLengthTrampoline; } + 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; - MacroAssemblerCodePtr m_ctiStringLengthTrampoline; - MacroAssemblerCodePtr m_ctiVirtualCallLink; - MacroAssemblerCodePtr m_ctiVirtualCall; - MacroAssemblerCodePtr m_ctiNativeCallThunk; + TrampolineStructure m_trampolineStructure; }; extern "C" { |