summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-18 14:03:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-18 14:03:11 +0200
commit8d473cf9743f1d30a16a27114e93bd5af5648d23 (patch)
treecdca40d0353886b3ca52f33a2d7b8f1c0011aafc /Source/JavaScriptCore/dfg
parent1b914638db989aaa98631a1c1e02c7b2d44805d8 (diff)
downloadqtwebkit-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.h77
-rw-r--r--Source/JavaScriptCore/dfg/DFGDriver.cpp6
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCompiler.cpp3
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.cpp40
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp2
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h44
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