diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-18 14:03:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-18 14:03:11 +0200 |
commit | 8d473cf9743f1d30a16a27114e93bd5af5648d23 (patch) | |
tree | cdca40d0353886b3ca52f33a2d7b8f1c0011aafc /Source/JavaScriptCore/dfg | |
parent | 1b914638db989aaa98631a1c1e02c7b2d44805d8 (diff) | |
download | qtwebkit-8d473cf9743f1d30a16a27114e93bd5af5648d23.tar.gz |
Imported WebKit commit 1350e72f7345ced9da2bd9980deeeb5a8d62fab4 (http://svn.webkit.org/repository/webkit/trunk@117578)
Weekly snapshot
Diffstat (limited to 'Source/JavaScriptCore/dfg')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGCCallHelpers.h | 77 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGDriver.cpp | 6 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGJITCompiler.cpp | 3 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGOperations.cpp | 40 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h | 44 |
6 files changed, 145 insertions, 27 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h index 256608f0d..aa08da128 100644 --- a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h +++ b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h @@ -505,6 +505,29 @@ public: ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3) { + move(arg3, GPRInfo::argumentGPR3); + move(arg1, GPRInfo::argumentGPR1); + move(arg2, GPRInfo::argumentGPR2); + move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); + } + + ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3) + { + move(arg2, GPRInfo::argumentGPR2); + move(arg1, GPRInfo::argumentGPR1); + move(arg3, GPRInfo::argumentGPR3); + move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); + } + + ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3) + { + setupTwoStubArgs<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3); + move(arg1, GPRInfo::argumentGPR1); + move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); + } + + ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3) + { move(arg1, GPRInfo::argumentGPR1); move(arg2, GPRInfo::argumentGPR2); move(arg3, GPRInfo::argumentGPR3); @@ -545,6 +568,60 @@ public: poke(arg4); setupArgumentsWithExecState(arg1, arg2, arg3); } + + ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4) + { + poke(arg4); + setupArgumentsWithExecState(arg1, arg2, arg3); + } + + ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4) + { + poke(arg4); + setupArgumentsWithExecState(arg1, arg2, arg3); + } + + ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4) + { + poke(arg4); + setupArgumentsWithExecState(arg1, arg2, arg3); + } + + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5) + { + poke(arg5, 1); + poke(arg4); + setupArgumentsWithExecState(arg1, arg2, arg3); + } + + ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5) + { + poke(arg5, 1); + poke(arg4); + setupArgumentsWithExecState(arg1, arg2, arg3); + } + + ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5) + { + poke(arg5, 1); + poke(arg4); + setupArgumentsWithExecState(arg1, arg2, arg3); + } + + ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5) + { + poke(arg5, 1); + poke(arg4); + setupArgumentsWithExecState(arg1, arg2, arg3); + } + + ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5) + { + poke(arg5, 1); + poke(arg4); + setupArgumentsWithExecState(arg1, arg2, arg3); + } + #endif // NUMBER_OF_ARGUMENT_REGISTERS == 4 void setupResults(GPRReg destA, GPRReg destB) diff --git a/Source/JavaScriptCore/dfg/DFGDriver.cpp b/Source/JavaScriptCore/dfg/DFGDriver.cpp index 205e94e6b..f583a8d63 100644 --- a/Source/JavaScriptCore/dfg/DFGDriver.cpp +++ b/Source/JavaScriptCore/dfg/DFGDriver.cpp @@ -58,6 +58,12 @@ inline bool compile(CompileMode compileMode, JSGlobalData& globalData, CodeBlock if (compileMode == CompileFunction) dfg.predictArgumentTypes(); + + // By this point the DFG bytecode parser will have potentially mutated various tables + // in the CodeBlock. This is a good time to perform an early shrink, which is more + // powerful than a late one. It's safe to do so because we haven't generated any code + // that references any of the tables directly, yet. + codeBlock->shrinkToFit(CodeBlock::EarlyShrink); performRedundantPhiElimination(dfg); performPredictionPropagation(dfg); diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp index 56e0d4e18..8d5b7238c 100644 --- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp +++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp @@ -190,8 +190,7 @@ void JITCompiler::link(LinkBuffer& linkBuffer) exit.m_check.correctLateJump(linkBuffer); } - codeBlock()->shrinkWeakReferencesToFit(); - codeBlock()->shrinkWeakReferenceTransitionsToFit(); + codeBlock()->shrinkToFit(CodeBlock::LateShrink); } bool JITCompiler::compile(JITCode& entry) diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp index dfaf5dfe8..376902d97 100644 --- a/Source/JavaScriptCore/dfg/DFGOperations.cpp +++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp @@ -100,6 +100,16 @@ "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \ ); +// EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]). +// As a result, return address will be at a 4-byte further location in the following cases. +#if COMPILER_SUPPORTS(EABI) && CPU(ARM) +#define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #4]" +#define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #8]" +#else +#define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #0]" +#define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #4]" +#endif + #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \ asm ( \ ".text" "\n" \ @@ -109,7 +119,7 @@ ".thumb" "\n" \ ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \ SYMBOL_STRING(function) ":" "\n" \ - "str lr, [sp, #0]" "\n" \ + INSTRUCTION_STORE_RETURN_ADDRESS_EJI "\n" \ "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \ ); @@ -122,7 +132,7 @@ ".thumb" "\n" \ ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \ SYMBOL_STRING(function) ":" "\n" \ - "str lr, [sp, #4]" "\n" \ + INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "\n" \ "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \ ); @@ -444,9 +454,16 @@ void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSA JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); - // We should only get here if index is outside the existing vector. - ASSERT(!array->canSetIndex(index)); - JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), true); + if (index >= 0) { + // We should only get here if index is outside the existing vector. + ASSERT(!array->canSetIndex(index)); + JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), true); + return; + } + + PutPropertySlot slot(true); + array->methodTable()->put( + array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot); } void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue) @@ -454,9 +471,16 @@ void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); - // We should only get here if index is outside the existing vector. - ASSERT(!array->canSetIndex(index)); - JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), false); + if (index >= 0) { + // We should only get here if index is outside the existing vector. + ASSERT(!array->canSetIndex(index)); + JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), false); + return; + } + + PutPropertySlot slot(false); + array->methodTable()->put( + array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot); } EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array) diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp index 18db85c22..0bcee7510 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp @@ -1974,7 +1974,7 @@ void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& } GPRTemporary scratch(this); GPRReg scratchReg = scratch.gpr(); - m_jit.move(Imm32(static_cast<int>(d)), scratchReg); + m_jit.move(Imm32(toInt32(d)), scratchReg); value.adopt(scratch); valueGPR = scratchReg; } else if (at(valueUse).shouldSpeculateInteger()) { diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h index dbfaec4f8..6f8dc1156 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h @@ -1260,6 +1260,15 @@ private: return appendCallSetResult(operation, result); } #else + +// EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]). +// To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary. +#if COMPILER_SUPPORTS(EABI) && CPU(ARM) +#define EABI_32BIT_DUMMY_ARG TrustedImm32(0), +#else +#define EABI_32BIT_DUMMY_ARG +#endif + JITCompiler::Call callOperation(Z_DFGOperation_D operation, GPRReg result, FPRReg arg1) { prepareForExternalCall(); @@ -1310,12 +1319,12 @@ private: } JITCompiler::Call callOperation(J_DFGOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, void* pointer) { - m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, TrustedImmPtr(pointer)); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(pointer)); return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); } JITCompiler::Call callOperation(J_DFGOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2) { - m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, arg2); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2); return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); } JITCompiler::Call callOperation(J_DFGOperation_ECI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, Identifier* identifier) @@ -1325,22 +1334,22 @@ private: } JITCompiler::Call callOperation(J_DFGOperation_EJI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, Identifier* identifier) { - m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, TrustedImmPtr(identifier)); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(identifier)); return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); } JITCompiler::Call callOperation(J_DFGOperation_EJI operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1Tag, GPRReg arg1Payload, Identifier* identifier) { - m_jit.setupArgumentsWithExecState(arg1Payload, TrustedImm32(arg1Tag), TrustedImmPtr(identifier)); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, TrustedImm32(arg1Tag), TrustedImmPtr(identifier)); return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); } JITCompiler::Call callOperation(J_DFGOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2) { - m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, arg2); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2); return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); } JITCompiler::Call callOperation(J_DFGOperation_EJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload) { - m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag); return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); } JITCompiler::Call callOperation(C_DFGOperation_E operation, GPRReg result) @@ -1370,7 +1379,7 @@ private: } JITCompiler::Call callOperation(S_DFGOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload) { - m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag); return appendCallWithExceptionCheckSetResult(operation, result); } JITCompiler::Call callOperation(S_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2) @@ -1380,22 +1389,22 @@ private: } JITCompiler::Call callOperation(S_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload) { - m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, arg2Payload, arg2Tag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag); return appendCallWithExceptionCheckSetResult(operation, result); } JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload) { - m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, arg2Payload, arg2Tag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag); return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); } JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::TrustedImm32 imm) { - m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, imm, TrustedImm32(JSValue::Int32Tag)); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, imm, TrustedImm32(JSValue::Int32Tag)); return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); } JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, MacroAssembler::TrustedImm32 imm, GPRReg arg2Tag, GPRReg arg2Payload) { - m_jit.setupArgumentsWithExecState(imm, TrustedImm32(JSValue::Int32Tag), arg2Payload, arg2Tag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag), arg2Payload, arg2Tag); return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); } JITCompiler::Call callOperation(J_DFGOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload) @@ -1415,12 +1424,12 @@ private: } JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer) { - m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer)); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer)); return appendCallWithExceptionCheck(operation); } JITCompiler::Call callOperation(V_DFGOperation_EJCI operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, Identifier* identifier) { - m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag, arg2, TrustedImmPtr(identifier)); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(identifier)); return appendCallWithExceptionCheck(operation); } JITCompiler::Call callOperation(V_DFGOperation_ECJJ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload) @@ -1430,18 +1439,18 @@ private: } JITCompiler::Call callOperation(V_DFGOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload) { - m_jit.setupArgumentsWithExecState(arg1, arg2, arg3Payload, arg3Tag); + m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag); return appendCallWithExceptionCheck(operation); } JITCompiler::Call callOperation(V_DFGOperation_EAZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload) { - m_jit.setupArgumentsWithExecState(arg1, arg2, arg3Payload, arg3Tag); + m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag); return appendCallWithExceptionCheck(operation); } JITCompiler::Call callOperation(D_DFGOperation_EJ operation, FPRReg result, GPRReg arg1Tag, GPRReg arg1Payload) { - m_jit.setupArgumentsWithExecState(arg1Payload, arg1Tag); + m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag); return appendCallWithExceptionCheckSetResult(operation, result); } @@ -1455,6 +1464,9 @@ private: m_jit.setupArguments(arg1, arg2); return appendCallSetResult(operation, result); } + +#undef EABI_32BIT_DUMMY_ARG + #endif #ifndef NDEBUG |