Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (90413 => 90414)
--- trunk/Source/_javascript_Core/ChangeLog 2011-07-05 23:16:18 UTC (rev 90413)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-07-05 23:18:23 UTC (rev 90414)
@@ -1,3 +1,25 @@
+2011-07-05 Filip Pizlo <[email protected]>
+
+ JSC JIT has code duplication for the handling of call and construct
+ https://bugs.webkit.org/show_bug.cgi?id=63957
+
+ Reviewed by Gavin Barraclough.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::linkFor):
+ * jit/JIT.h:
+ * jit/JITStubs.cpp:
+ (JSC::jitCompileFor):
+ (JSC::DEFINE_STUB_FUNCTION):
+ (JSC::arityCheckFor):
+ (JSC::lazyLinkFor):
+ * runtime/Executable.h:
+ (JSC::ExecutableBase::generatedJITCodeFor):
+ (JSC::FunctionExecutable::compileFor):
+ (JSC::FunctionExecutable::isGeneratedFor):
+ (JSC::FunctionExecutable::generatedBytecodeFor):
+ (JSC::FunctionExecutable::generatedJITCodeWithArityCheckFor):
+
2011-07-05 Gavin Barraclough <[email protected]>
Build fix following last patch.
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (90413 => 90414)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2011-07-05 23:16:18 UTC (rev 90413)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2011-07-05 23:18:23 UTC (rev 90414)
@@ -609,7 +609,7 @@
return patchBuffer.finalizeCode();
}
-void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
+void JIT::linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData, CodeSpecializationKind kind)
{
RepatchBuffer repatchBuffer(callerCodeBlock);
@@ -622,22 +622,12 @@
}
// patch the call so we do not continue to try to link.
- repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualCall());
-}
-
-void JIT::linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
-{
- RepatchBuffer repatchBuffer(callerCodeBlock);
-
- // Currently we only link calls with the exact number of arguments.
- // If this is a native call calleeCodeBlock is null so the number of parameters is unimportant
- if (!calleeCodeBlock || (callerArgCount == calleeCodeBlock->m_numParameters)) {
- ASSERT(!callLinkInfo->isLinked());
- callLinkInfo->callee.set(*globalData, callLinkInfo->hotPathBegin, callerCodeBlock->ownerExecutable(), callee);
- repatchBuffer.relink(callLinkInfo->hotPathOther, code);
+ if (kind == CodeForCall) {
+ repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualCall());
+ return;
}
- // patch the call so we do not continue to try to link.
+ ASSERT(kind == CodeForConstruct);
repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualConstruct());
}
Modified: trunk/Source/_javascript_Core/jit/JIT.h (90413 => 90414)
--- trunk/Source/_javascript_Core/jit/JIT.h 2011-07-05 23:16:18 UTC (rev 90413)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2011-07-05 23:18:23 UTC (rev 90414)
@@ -246,8 +246,7 @@
return jit.privateCompilePatchGetArrayLength(returnAddress);
}
- static void linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*);
- static void linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*);
+ static void linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*, CodeSpecializationKind);
private:
struct JSRInfo {
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (90413 => 90414)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2011-07-05 23:16:18 UTC (rev 90413)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2011-07-05 23:18:23 UTC (rev 90414)
@@ -1902,20 +1902,13 @@
return stackFrame.args[0].function()->make(stackFrame.callFrame, stackFrame.callFrame->scopeChain());
}
-DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
+inline void* jitCompileFor(JITStackFrame& stackFrame, CodeSpecializationKind kind)
{
- STUB_INIT_STACK_FRAME(stackFrame);
-
-#if !ASSERT_DISABLED
- CallData callData;
- ASSERT(stackFrame.callFrame->callee()->getCallData(callData) == CallTypeJS);
-#endif
-
JSFunction* function = asFunction(stackFrame.callFrame->callee());
ASSERT(!function->isHostFunction());
FunctionExecutable* executable = function->jsExecutable();
ScopeChainNode* callDataScopeChain = function->scope();
- JSObject* error = executable->compileForCall(stackFrame.callFrame, callDataScopeChain);
+ JSObject* error = executable->compileFor(stackFrame.callFrame, callDataScopeChain, kind);
if (error) {
stackFrame.callFrame->globalData().exception = error;
return 0;
@@ -1923,6 +1916,18 @@
return function;
}
+DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
+{
+ STUB_INIT_STACK_FRAME(stackFrame);
+
+#if !ASSERT_DISABLED
+ CallData callData;
+ ASSERT(stackFrame.callFrame->callee()->getCallData(callData) == CallTypeJS);
+#endif
+
+ return jitCompileFor(stackFrame, CodeForCall);
+}
+
DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -1931,27 +1936,16 @@
ConstructData constructData;
ASSERT(asFunction(stackFrame.callFrame->callee())->getConstructData(constructData) == ConstructTypeJS);
#endif
-
- JSFunction* function = asFunction(stackFrame.callFrame->callee());
- ASSERT(!function->isHostFunction());
- FunctionExecutable* executable = function->jsExecutable();
- ScopeChainNode* callDataScopeChain = function->scope();
- JSObject* error = executable->compileForConstruct(stackFrame.callFrame, callDataScopeChain);
- if (error) {
- stackFrame.callFrame->globalData().exception = error;
- return 0;
- }
- return function;
+
+ return jitCompileFor(stackFrame, CodeForConstruct);
}
-DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
+inline void* arityCheckFor(JITStackFrame& stackFrame, CodeSpecializationKind kind, ReturnAddressPtr& stubReturnAddress)
{
- STUB_INIT_STACK_FRAME(stackFrame);
-
CallFrame* callFrame = stackFrame.callFrame;
JSFunction* callee = asFunction(callFrame->callee());
ASSERT(!callee->isHostFunction());
- CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeForCall();
+ CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeFor(kind);
int argCount = callFrame->argumentCountIncludingThis();
ReturnAddressPtr pc = callFrame->returnPC();
@@ -1968,7 +1962,7 @@
// Rewind to the previous call frame because op_call already optimistically
// moved the call frame forward.
ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
- STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
+ stubReturnAddress = ReturnAddressPtr(handler.catchRoutine);
return handler.callFrame;
}
@@ -1983,7 +1977,7 @@
// Rewind to the previous call frame because op_call already optimistically
// moved the call frame forward.
ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
- STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
+ stubReturnAddress = ReturnAddressPtr(handler.catchRoutine);
return handler.callFrame;
}
@@ -2003,68 +1997,22 @@
return callFrame;
}
+DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
+{
+ STUB_INIT_STACK_FRAME(stackFrame);
+
+ return arityCheckFor(stackFrame, CodeForCall, STUB_RETURN_ADDRESS);
+}
+
DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck)
{
STUB_INIT_STACK_FRAME(stackFrame);
- CallFrame* callFrame = stackFrame.callFrame;
- JSFunction* callee = asFunction(callFrame->callee());
- ASSERT(!callee->isHostFunction());
- CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeForConstruct();
- int argCount = callFrame->argumentCountIncludingThis();
- ReturnAddressPtr pc = callFrame->returnPC();
-
- ASSERT(argCount != newCodeBlock->m_numParameters);
-
- CallFrame* oldCallFrame = callFrame->callerFrame();
-
- Register* r;
- if (argCount > newCodeBlock->m_numParameters) {
- size_t numParameters = newCodeBlock->m_numParameters;
- r = callFrame->registers() + numParameters;
- Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
- if (!stackFrame.registerFile->grow(newEnd)) {
- // Rewind to the previous call frame because op_call already optimistically
- // moved the call frame forward.
- ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
- STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
- return handler.callFrame;
- }
-
- Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount;
- for (size_t i = 0; i < numParameters; ++i)
- argv[i + argCount] = argv[i];
- } else {
- size_t omittedArgCount = newCodeBlock->m_numParameters - argCount;
- r = callFrame->registers() + omittedArgCount;
- Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
- if (!stackFrame.registerFile->grow(newEnd)) {
- // Rewind to the previous call frame because op_call already optimistically
- // moved the call frame forward.
- ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
- STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
- return handler.callFrame;
- }
-
- Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
- for (size_t i = 0; i < omittedArgCount; ++i)
- argv[i] = jsUndefined();
- }
-
- callFrame = CallFrame::create(r);
- callFrame->setCallerFrame(oldCallFrame);
- callFrame->setArgumentCountIncludingThis(argCount);
- callFrame->setCallee(callee);
- callFrame->setScopeChain(callee->scope());
- callFrame->setReturnPC(pc.value());
-
- ASSERT((void*)callFrame <= stackFrame.registerFile->end());
- return callFrame;
+ return arityCheckFor(stackFrame, CodeForConstruct, STUB_RETURN_ADDRESS);
}
-DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
+inline void* lazyLinkFor(JITStackFrame& stackFrame, CodeSpecializationKind kind)
{
- STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
JSFunction* callee = asFunction(callFrame->callee());
ExecutableBase* executable = callee->executable();
@@ -2072,62 +2020,42 @@
MacroAssemblerCodePtr codePtr;
CodeBlock* codeBlock = 0;
if (executable->isHostFunction())
- codePtr = executable->generatedJITCodeForCall().addressForCall();
+ codePtr = executable->generatedJITCodeFor(kind).addressForCall();
else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- JSObject* error = functionExecutable->compileForCall(callFrame, callee->scope());
+ JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind);
if (error) {
callFrame->globalData().exception = createStackOverflowError(callFrame);
return 0;
}
- codeBlock = &functionExecutable->generatedBytecodeForCall();
+ codeBlock = &functionExecutable->generatedBytecodeFor(kind);
if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
- codePtr = functionExecutable->generatedJITCodeForCall().addressForCall();
+ codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
else
- codePtr = functionExecutable->generatedJITCodeForCallWithArityCheck();
+ codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
}
CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
if (!callLinkInfo->seenOnce())
callLinkInfo->setSeen();
else
- JIT::linkCall(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData);
+ JIT::linkFor(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData, kind);
return codePtr.executableAddress();
}
-DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
+DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
{
STUB_INIT_STACK_FRAME(stackFrame);
- CallFrame* callFrame = stackFrame.callFrame;
- JSFunction* callee = asFunction(callFrame->callee());
- ExecutableBase* executable = callee->executable();
+
+ return lazyLinkFor(stackFrame, CodeForCall);
+}
- MacroAssemblerCodePtr codePtr;
- CodeBlock* codeBlock = 0;
- if (executable->isHostFunction())
- codePtr = executable->generatedJITCodeForConstruct().addressForCall();
- else {
- FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- JSObject* error = functionExecutable->compileForConstruct(callFrame, callee->scope());
- if (error) {
- throwStackOverflowError(callFrame, stackFrame.globalData, ReturnAddressPtr(callFrame->returnPC()), STUB_RETURN_ADDRESS);
- return 0;
- }
- codeBlock = &functionExecutable->generatedBytecodeForConstruct();
- if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
- codePtr = functionExecutable->generatedJITCodeForConstruct().addressForCall();
- else
- codePtr = functionExecutable->generatedJITCodeForConstructWithArityCheck();
- }
- CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
-
- if (!callLinkInfo->seenOnce())
- callLinkInfo->setSeen();
- else
- JIT::linkConstruct(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData);
-
- return codePtr.executableAddress();
+DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
+{
+ STUB_INIT_STACK_FRAME(stackFrame);
+
+ return lazyLinkFor(stackFrame, CodeForConstruct);
}
DEFINE_STUB_FUNCTION(JSObject*, op_push_activation)
Modified: trunk/Source/_javascript_Core/runtime/Executable.h (90413 => 90414)
--- trunk/Source/_javascript_Core/runtime/Executable.h 2011-07-05 23:16:18 UTC (rev 90413)
+++ trunk/Source/_javascript_Core/runtime/Executable.h 2011-07-05 23:18:23 UTC (rev 90414)
@@ -43,6 +43,8 @@
class ScopeChainNode;
struct ExceptionInfo;
+
+ enum CodeSpecializationKind { CodeForCall, CodeForConstruct };
class ExecutableBase : public JSCell {
friend class JIT;
@@ -91,6 +93,14 @@
ASSERT(m_jitCodeForConstruct);
return m_jitCodeForConstruct;
}
+
+ JITCode& generatedJITCodeFor(CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return generatedJITCodeForCall();
+ ASSERT(kind == CodeForConstruct);
+ return generatedJITCodeForConstruct();
+ }
void clearExecutableCode()
{
@@ -387,6 +397,30 @@
ASSERT(m_codeBlockForConstruct);
return *m_codeBlockForConstruct;
}
+
+ JSObject* compileFor(ExecState* exec, ScopeChainNode* scopeChainNode, CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return compileForCall(exec, scopeChainNode);
+ ASSERT(kind == CodeForConstruct);
+ return compileForConstruct(exec, scopeChainNode);
+ }
+
+ bool isGeneratedFor(CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return isGeneratedForCall();
+ ASSERT(kind == CodeForConstruct);
+ return isGeneratedForConstruct();
+ }
+
+ FunctionCodeBlock& generatedBytecodeFor(CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return generatedBytecodeForCall();
+ ASSERT(kind == CodeForConstruct);
+ return generatedBytecodeForConstruct();
+ }
const Identifier& name() { return m_name; }
size_t parameterCount() const { return m_parameters->size(); }
@@ -437,6 +471,14 @@
ASSERT(m_jitCodeForConstructWithArityCheck);
return m_jitCodeForConstructWithArityCheck;
}
+
+ MacroAssemblerCodePtr generatedJITCodeWithArityCheckFor(CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return generatedJITCodeForCallWithArityCheck();
+ ASSERT(kind == CodeForConstruct);
+ return generatedJITCodeForConstructWithArityCheck();
+ }
#endif
};