Commit 2b95ada2 authored by msaboff@apple.com's avatar msaboff@apple.com

Transition call and construct JITStubs to CCallHelper functions

https://bugs.webkit.org/show_bug.cgi?id=122453

Reviewed by Geoffrey Garen.

Transitioned cti_op_call_eval to operationCallEval.  Migrated baseline JIT to use the same 
call thunks as the DFG.  Eliminated all of the "oldStyle" thunks and related functions.

* bytecode/CallLinkInfo.cpp:
(JSC::CallLinkInfo::unlink):
* jit/JIT.cpp:
(JSC::JIT::linkFor):
(JSC::JIT::linkSlowCall):
* jit/JIT.h:
* jit/JITCall.cpp:
(JSC::JIT::compileCallEval):
(JSC::JIT::compileCallEvalSlowCase):
(JSC::JIT::compileOpCallSlowCase):
(JSC::JIT::privateCompileClosureCall):
* jit/JITCall32_64.cpp:
(JSC::JIT::compileCallEval):
(JSC::JIT::compileCallEvalSlowCase):
(JSC::JIT::compileOpCallSlowCase):
(JSC::JIT::privateCompileClosureCall):
* jit/JITInlines.h:
(JSC::JIT::callOperationWithCallFrameRollbackOnException):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/JITStubs.cpp:
* jit/JITStubs.h:
* jit/ThunkGenerators.cpp:
* jit/ThunkGenerators.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@157164 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent f252ddd7
2013-10-08 Michael Saboff <msaboff@apple.com>
Transition call and construct JITStubs to CCallHelper functions
https://bugs.webkit.org/show_bug.cgi?id=122453
Reviewed by Geoffrey Garen.
Transitioned cti_op_call_eval to operationCallEval. Migrated baseline JIT to use the same
call thunks as the DFG. Eliminated all of the "oldStyle" thunks and related functions.
* bytecode/CallLinkInfo.cpp:
(JSC::CallLinkInfo::unlink):
* jit/JIT.cpp:
(JSC::JIT::linkFor):
(JSC::JIT::linkSlowCall):
* jit/JIT.h:
* jit/JITCall.cpp:
(JSC::JIT::compileCallEval):
(JSC::JIT::compileCallEvalSlowCase):
(JSC::JIT::compileOpCallSlowCase):
(JSC::JIT::privateCompileClosureCall):
* jit/JITCall32_64.cpp:
(JSC::JIT::compileCallEval):
(JSC::JIT::compileCallEvalSlowCase):
(JSC::JIT::compileOpCallSlowCase):
(JSC::JIT::privateCompileClosureCall):
* jit/JITInlines.h:
(JSC::JIT::callOperationWithCallFrameRollbackOnException):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/JITStubs.cpp:
* jit/JITStubs.h:
* jit/ThunkGenerators.cpp:
* jit/ThunkGenerators.h:
2013-10-09 Julien Brianceau <jbriance@cisco.com>
[sh4] Fix lots of unused parameter warnings.
......@@ -45,7 +45,7 @@ void CallLinkInfo::unlink(VM& vm, RepatchBuffer& repatchBuffer)
RELEASE_ASSERT_NOT_REACHED();
#endif
} else
repatchBuffer.relink(callReturnLocation, callType == Construct ? vm.getCTIStub(oldStyleLinkConstructGenerator).code() : vm.getCTIStub(oldStyleLinkCallGenerator).code());
repatchBuffer.relink(callReturnLocation, callType == Construct ? vm.getCTIStub(linkConstructThunkGenerator).code() : vm.getCTIStub(linkCallThunkGenerator).code());
hasSeenShouldRepatch = false;
callee.clear();
stub.clear();
......
......@@ -802,23 +802,23 @@ void JIT::linkFor(ExecState* exec, JSFunction* callee, CodeBlock* callerCodeBloc
ASSERT(callLinkInfo->callType == CallLinkInfo::Call
|| callLinkInfo->callType == CallLinkInfo::CallVarargs);
if (callLinkInfo->callType == CallLinkInfo::Call) {
repatchBuffer.relink(callLinkInfo->callReturnLocation, vm->getCTIStub(oldStyleLinkClosureCallGenerator).code());
repatchBuffer.relink(callLinkInfo->callReturnLocation, vm->getCTIStub(linkClosureCallThunkGenerator).code());
return;
}
repatchBuffer.relink(callLinkInfo->callReturnLocation, vm->getCTIStub(oldStyleVirtualCallGenerator).code());
repatchBuffer.relink(callLinkInfo->callReturnLocation, vm->getCTIStub(virtualCallThunkGenerator).code());
return;
}
ASSERT(kind == CodeForConstruct);
repatchBuffer.relink(callLinkInfo->callReturnLocation, vm->getCTIStub(oldStyleVirtualConstructGenerator).code());
repatchBuffer.relink(callLinkInfo->callReturnLocation, vm->getCTIStub(virtualConstructThunkGenerator).code());
}
void JIT::linkSlowCall(CodeBlock* callerCodeBlock, CallLinkInfo* callLinkInfo)
{
RepatchBuffer repatchBuffer(callerCodeBlock);
repatchBuffer.relink(callLinkInfo->callReturnLocation, callerCodeBlock->vm()->getCTIStub(oldStyleVirtualCallGenerator).code());
repatchBuffer.relink(callLinkInfo->callReturnLocation, callerCodeBlock->vm()->getCTIStub(virtualCallThunkGenerator).code());
}
void JIT::privateCompileExceptionHandlers()
......
......@@ -868,6 +868,7 @@ namespace JSC {
MacroAssembler::Call appendCallWithExceptionCheckSetJSValueResult(const FunctionPtr&, int);
MacroAssembler::Call callOperation(J_JITOperation_E, int);
MacroAssembler::Call callOperation(J_JITOperation_EP, int, void*);
MacroAssembler::Call callOperationWithCallFrameRollbackOnException(J_JITOperation_E);
MacroAssembler::Call callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb, CodeBlock*);
MacroAssembler::Call callOperationWithCallFrameRollbackOnException(Z_JITOperation_E);
......
......@@ -131,8 +131,7 @@ void JIT::compileLoadVarargs(Instruction* instruction)
void JIT::compileCallEval(Instruction* instruction)
{
JITStubCall stubCall(this, cti_op_call_eval); // Initializes ScopeChain; ReturnPC; CodeBlock.
stubCall.call();
callOperationWithCallFrameRollbackOnException(operationCallEval);
addSlowCase(branch64(Equal, regT0, TrustedImm64(JSValue::encode(JSValue()))));
emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister);
......@@ -146,7 +145,7 @@ void JIT::compileCallEvalSlowCase(Instruction* instruction, Vector<SlowCaseEntry
linkSlowCase(iter);
emitGetFromCallFrameHeader64(JSStack::Callee, regT0);
emitNakedCall(m_vm->getCTIStub(oldStyleVirtualCallGenerator).code());
emitNakedCall(m_vm->getCTIStub(virtualCallThunkGenerator).code());
sampleCodeBlock(m_codeBlock);
......@@ -232,8 +231,8 @@ void JIT::compileOpCallSlowCase(OpcodeID opcodeID, Instruction* instruction, Vec
}
linkSlowCase(iter);
m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(opcodeID == op_construct ? m_vm->getCTIStub(oldStyleLinkConstructGenerator).code() : m_vm->getCTIStub(oldStyleLinkCallGenerator).code());
m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(opcodeID == op_construct ? m_vm->getCTIStub(linkConstructThunkGenerator).code() : m_vm->getCTIStub(linkCallThunkGenerator).code());
sampleCodeBlock(m_codeBlock);
......@@ -263,7 +262,7 @@ void JIT::privateCompileClosureCall(CallLinkInfo* callLinkInfo, CodeBlock* calle
patchBuffer.link(call, FunctionPtr(codePtr.executableAddress()));
patchBuffer.link(done, callLinkInfo->hotPathOther.labelAtOffset(0));
patchBuffer.link(slow, CodeLocationLabel(m_vm->getCTIStub(oldStyleVirtualCallGenerator).code()));
patchBuffer.link(slow, CodeLocationLabel(m_vm->getCTIStub(virtualCallThunkGenerator).code()));
RefPtr<ClosureCallStubRoutine> stubRoutine = adoptRef(new ClosureCallStubRoutine(
FINALIZE_CODE(
......@@ -281,8 +280,8 @@ void JIT::privateCompileClosureCall(CallLinkInfo* callLinkInfo, CodeBlock* calle
repatchBuffer.replaceWithJump(
RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo->hotPathBegin),
CodeLocationLabel(stubRoutine->code().code()));
repatchBuffer.relink(callLinkInfo->callReturnLocation, m_vm->getCTIStub(oldStyleVirtualCallGenerator).code());
repatchBuffer.relink(callLinkInfo->callReturnLocation, m_vm->getCTIStub(virtualCallThunkGenerator).code());
callLinkInfo->stub = stubRoutine.release();
}
......
......@@ -202,8 +202,7 @@ void JIT::compileLoadVarargs(Instruction* instruction)
void JIT::compileCallEval(Instruction* instruction)
{
JITStubCall stubCall(this, cti_op_call_eval); // Initializes ScopeChain; ReturnPC; CodeBlock.
stubCall.call();
callOperationWithCallFrameRollbackOnException(operationCallEval);
addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag)));
emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister);
......@@ -217,7 +216,7 @@ void JIT::compileCallEvalSlowCase(Instruction* instruction, Vector<SlowCaseEntry
linkSlowCase(iter);
emitLoad(JSStack::Callee, regT1, regT0);
emitNakedCall(m_vm->getCTIStub(oldStyleVirtualCallGenerator).code());
emitNakedCall(m_vm->getCTIStub(virtualCallThunkGenerator).code());
sampleCodeBlock(m_codeBlock);
......@@ -305,8 +304,8 @@ void JIT::compileOpCallSlowCase(OpcodeID opcodeID, Instruction* instruction, Vec
linkSlowCase(iter);
linkSlowCase(iter);
m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(opcodeID == op_construct ? m_vm->getCTIStub(oldStyleLinkConstructGenerator).code() : m_vm->getCTIStub(oldStyleLinkCallGenerator).code());
m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(opcodeID == op_construct ? m_vm->getCTIStub(linkConstructThunkGenerator).code() : m_vm->getCTIStub(linkCallThunkGenerator).code());
sampleCodeBlock(m_codeBlock);
emitPutCallResult(instruction);
......@@ -335,7 +334,7 @@ void JIT::privateCompileClosureCall(CallLinkInfo* callLinkInfo, CodeBlock* calle
patchBuffer.link(call, FunctionPtr(codePtr.executableAddress()));
patchBuffer.link(done, callLinkInfo->hotPathOther.labelAtOffset(0));
patchBuffer.link(slow, CodeLocationLabel(m_vm->getCTIStub(oldStyleVirtualCallGenerator).code()));
patchBuffer.link(slow, CodeLocationLabel(m_vm->getCTIStub(virtualCallThunkGenerator).code()));
RefPtr<ClosureCallStubRoutine> stubRoutine = adoptRef(new ClosureCallStubRoutine(
FINALIZE_CODE(
......@@ -353,7 +352,7 @@ void JIT::privateCompileClosureCall(CallLinkInfo* callLinkInfo, CodeBlock* calle
repatchBuffer.replaceWithJump(
RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo->hotPathBegin),
CodeLocationLabel(stubRoutine->code().code()));
repatchBuffer.relink(callLinkInfo->callReturnLocation, m_vm->getCTIStub(oldStyleVirtualCallGenerator).code());
repatchBuffer.relink(callLinkInfo->callReturnLocation, m_vm->getCTIStub(virtualCallThunkGenerator).code());
callLinkInfo->stub = stubRoutine.release();
}
......
......@@ -243,6 +243,12 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EP operatio
return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
}
ALWAYS_INLINE MacroAssembler::Call JIT::callOperationWithCallFrameRollbackOnException(J_JITOperation_E operation)
{
setupArgumentsExecState();
return appendCallWithCallFrameRollbackOnException(operation);
}
ALWAYS_INLINE MacroAssembler::Call JIT::callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb operation, CodeBlock* pointer)
{
setupArgumentsWithExecState(TrustedImmPtr(pointer));
......
......@@ -32,6 +32,7 @@
#include "GetterSetter.h"
#include "HostCallReturnValue.h"
#include "JITOperationWrappers.h"
#include "JSGlobalObjectFunctions.h"
#include "Operations.h"
#include "Repatch.h"
......@@ -39,6 +40,22 @@ namespace JSC {
extern "C" {
#if COMPILER(MSVC)
void * _ReturnAddress(void);
#pragma intrinsic(_ReturnAddress)
#define OUR_RETURN_ADDRESS _ReturnAddress()
#else
#define OUR_RETURN_ADDRESS __builtin_return_address(0)
#endif
#if ENABLE(OPCODE_SAMPLING)
#define CTI_SAMPLER vm->interpreter->sampler()
#else
#define CTI_SAMPLER 0
#endif
void JIT_OPERATION operationStackCheck(ExecState* exec, CodeBlock* codeBlock)
{
// We pass in our own code block, because the callframe hasn't been populated.
......@@ -445,6 +462,28 @@ void JIT_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObj
base->putDirect(vm, offset, JSValue::decode(value));
}
EncodedJSValue JIT_OPERATION operationCallEval(ExecState* execCallee)
{
CallFrame* callerFrame = execCallee->callerFrame();
ASSERT(execCallee->callerFrame()->codeBlock()->codeType() != FunctionCode
|| !execCallee->callerFrame()->codeBlock()->needsFullScopeChain()
|| execCallee->callerFrame()->uncheckedR(execCallee->callerFrame()->codeBlock()->activationRegister().offset()).jsValue());
execCallee->setScope(callerFrame->scope());
execCallee->setReturnPC(static_cast<Instruction*>(OUR_RETURN_ADDRESS));
execCallee->setCodeBlock(0);
if (!isHostFunction(execCallee->calleeAsValue(), globalFuncEval))
return JSValue::encode(JSValue());
VM* vm = &execCallee->vm();
JSValue result = eval(execCallee);
if (vm->exception())
return EncodedJSValue();
return JSValue::encode(result);
}
static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
{
ExecState* exec = execCallee->callerFrame();
......@@ -513,6 +552,7 @@ inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
MacroAssemblerCodePtr codePtr;
CodeBlock* codeBlock = 0;
CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(execCallee->returnPC());
if (executable->isHostFunction())
codePtr = executable->generatedJITCodeFor(kind)->addressForCall();
else {
......@@ -523,12 +563,11 @@ inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
}
codeBlock = functionExecutable->codeBlockFor(kind);
if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo.callType == CallLinkInfo::CallVarargs)
codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
else
codePtr = functionExecutable->generatedJITCodeFor(kind)->addressForCall();
}
CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(execCallee->returnPC());
if (!callLinkInfo.seenOnce())
callLinkInfo.setSeen();
else
......
......@@ -199,6 +199,7 @@ void JIT_OPERATION operationPutByIdNonStrictBuildList(ExecState*, EncodedJSValue
void JIT_OPERATION operationPutByIdDirectStrictBuildList(ExecState*, EncodedJSValue encodedValue, JSCell* base, StringImpl*) WTF_INTERNAL;
void JIT_OPERATION operationPutByIdDirectNonStrictBuildList(ExecState*, EncodedJSValue encodedValue, JSCell* base, StringImpl*) WTF_INTERNAL;
void JIT_OPERATION operationReallocateStorageAndFinishPut(ExecState*, JSObject*, Structure*, PropertyOffset, EncodedJSValue) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationCallEval(ExecState*) WTF_INTERNAL;
char* JIT_OPERATION operationVirtualCall(ExecState*) WTF_INTERNAL;
char* JIT_OPERATION operationLinkCall(ExecState*) WTF_INTERNAL;
char* JIT_OPERATION operationLinkClosureCall(ExecState*) WTF_INTERNAL;
......
......@@ -1147,209 +1147,6 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_func)
return JSFunction::create(stackFrame.callFrame->vm(), stackFrame.args[0].function(), stackFrame.callFrame->scope());
}
inline void* jitCompileFor(CallFrame* callFrame, CodeSpecializationKind kind)
{
// This function is called by cti_op_call_jitCompile() and
// cti_op_construct_jitCompile() JIT glue trampolines to compile the
// callee function that we want to call. Both cti glue trampolines are
// called by JIT'ed code which has pushed a frame and initialized most of
// the frame content except for the codeBlock.
//
// Normally, the prologue of the callee is supposed to set the frame's cb
// pointer to the cb of the callee. But in this case, the callee code does
// not exist yet until it is compiled below. The compilation process will
// allocate memory which may trigger a GC. The GC, in turn, will scan the
// JSStack, and will expect the frame's cb to either be valid or 0. If
// we don't initialize it, the GC will be accessing invalid memory and may
// crash.
//
// Hence, we should nullify it here before proceeding with the compilation.
callFrame->setCodeBlock(0);
JSFunction* function = jsCast<JSFunction*>(callFrame->callee());
ASSERT(!function->isHostFunction());
FunctionExecutable* executable = function->jsExecutable();
JSScope* callDataScopeChain = function->scope();
JSObject* error = executable->prepareForExecution(callFrame, callDataScopeChain, kind);
if (!error)
return function;
callFrame->vm().throwException(callFrame, error);
return 0;
}
DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
{
STUB_INIT_STACK_FRAME(stackFrame);
#if !ASSERT_DISABLED
CallData callData;
ASSERT(stackFrame.callFrame->callee()->methodTable()->getCallData(stackFrame.callFrame->callee(), callData) == CallTypeJS);
#endif
CallFrame* callFrame = stackFrame.callFrame;
void* result = jitCompileFor(callFrame, CodeForCall);
if (!result)
return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return result;
}
DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile)
{
STUB_INIT_STACK_FRAME(stackFrame);
#if !ASSERT_DISABLED
ConstructData constructData;
ASSERT(jsCast<JSFunction*>(stackFrame.callFrame->callee())->methodTable()->getConstructData(stackFrame.callFrame->callee(), constructData) == ConstructTypeJS);
#endif
CallFrame* callFrame = stackFrame.callFrame;
void* result = jitCompileFor(callFrame, CodeForConstruct);
if (!result)
return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return result;
}
inline void* lazyLinkFor(CallFrame* callFrame, CodeSpecializationKind kind)
{
JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
ExecutableBase* executable = callee->executable();
MacroAssemblerCodePtr codePtr;
CodeBlock* codeBlock = 0;
CallLinkInfo* callLinkInfo = &callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
// This function is called by cti_vm_lazyLinkCall() and
// cti_lazyLinkConstruct JIT glue trampolines to link the callee function
// that we want to call. Both cti glue trampolines are called by JIT'ed
// code which has pushed a frame and initialized most of the frame content
// except for the codeBlock.
//
// Normally, the prologue of the callee is supposed to set the frame's cb
// field to the cb of the callee. But in this case, the callee may not
// exist yet, and if not, it will be generated in the compilation below.
// The compilation will allocate memory which may trigger a GC. The GC, in
// turn, will scan the JSStack, and will expect the frame's cb to be valid
// or 0. If we don't initialize it, the GC will be accessing invalid
// memory and may crash.
//
// Hence, we should nullify it here before proceeding with the compilation.
callFrame->setCodeBlock(0);
if (executable->isHostFunction())
codePtr = executable->generatedJITCodeFor(kind)->addressForCall();
else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
if (JSObject* error = functionExecutable->prepareForExecution(callFrame, callee->scope(), kind)) {
callFrame->vm().throwException(callFrame, error);
return 0;
}
codeBlock = functionExecutable->codeBlockFor(kind);
if (callFrame->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())
|| callLinkInfo->callType == CallLinkInfo::CallVarargs)
codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
else
codePtr = functionExecutable->generatedJITCodeFor(kind)->addressForCall();
}
ConcurrentJITLocker locker(callFrame->callerFrame()->codeBlock()->m_lock);
if (!callLinkInfo->seenOnce())
callLinkInfo->setSeen();
else
JIT::linkFor(callFrame->callerFrame(), callee, callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, &callFrame->vm(), kind);
return codePtr.executableAddress();
}
DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
{
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
void* result = lazyLinkFor(callFrame, CodeForCall);
if (!result)
return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return result;
}
DEFINE_STUB_FUNCTION(void*, vm_lazyLinkClosureCall)
{
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
CodeBlock* callerCodeBlock = callFrame->callerFrame()->codeBlock();
VM* vm = callerCodeBlock->vm();
CallLinkInfo* callLinkInfo = &callerCodeBlock->getCallLinkInfo(callFrame->returnPC());
JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
ExecutableBase* executable = callee->executable();
Structure* structure = callee->structure();
ASSERT(callLinkInfo->callType == CallLinkInfo::Call);
ASSERT(callLinkInfo->isLinked());
ASSERT(callLinkInfo->callee);
ASSERT(callee != callLinkInfo->callee.get());
bool shouldLink = false;
CodeBlock* calleeCodeBlock = 0;
MacroAssemblerCodePtr codePtr;
if (executable == callLinkInfo->callee.get()->executable()
&& structure == callLinkInfo->callee.get()->structure()) {
shouldLink = true;
ASSERT(executable->hasJITCodeForCall());
codePtr = executable->generatedJITCodeForCall()->addressForCall();
if (!callee->executable()->isHostFunction()) {
calleeCodeBlock = jsCast<FunctionExecutable*>(executable)->codeBlockForCall();
if (callFrame->argumentCountIncludingThis() < static_cast<size_t>(calleeCodeBlock->numParameters())) {
shouldLink = false;
codePtr = executable->generatedJITCodeWithArityCheckFor(CodeForCall);
}
}
} else if (callee->isHostFunction())
codePtr = executable->generatedJITCodeForCall()->addressForCall();
else {
// Need to clear the code block before compilation, because compilation can GC.
callFrame->setCodeBlock(0);
FunctionExecutable* functionExecutable = jsCast<FunctionExecutable*>(executable);
JSScope* scopeChain = callee->scope();
JSObject* error = functionExecutable->prepareForExecution(callFrame, scopeChain, CodeForCall);
if (error) {
callFrame->vm().throwException(callFrame, error);
return 0;
}
codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(CodeForCall);
}
if (shouldLink) {
ASSERT(codePtr);
ConcurrentJITLocker locker(callerCodeBlock->m_lock);
JIT::compileClosureCall(vm, callLinkInfo, callerCodeBlock, calleeCodeBlock, structure, executable, codePtr);
callLinkInfo->hasSeenClosure = true;
} else
JIT::linkSlowCall(callerCodeBlock, callLinkInfo);
return codePtr.executableAddress();
}
DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
{
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
void* result = lazyLinkFor(callFrame, CodeForConstruct);
if (!result)
return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return result;
}
DEFINE_STUB_FUNCTION(JSObject*, op_push_activation)
{
STUB_INIT_STACK_FRAME(stackFrame);
......@@ -1359,36 +1156,6 @@ DEFINE_STUB_FUNCTION(JSObject*, op_push_activation)
return activation;
}
DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_NotJSFunction)
{
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
JSValue callee = callFrame->calleeAsValue();
CallData callData;
CallType callType = getCallData(callee, callData);
ASSERT(callType != CallTypeJS);
if (callType != CallTypeHost) {
ASSERT(callType == CallTypeNone);
ErrorWithExecAndCalleeFunctor functor = ErrorWithExecAndCalleeFunctor(createNotAFunctionError, callee);
return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, &functor);
}
EncodedJSValue returnValue;
{
SamplingTool::CallRecord callRecord(CTI_SAMPLER, true);
returnValue = callData.native.function(callFrame);
}
if (stackFrame.vm->exception())
return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return returnValue;
}
DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_arguments)
{
STUB_INIT_STACK_FRAME(stackFrame);
......@@ -1456,35 +1223,6 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_array_buffer)
return constructArray(stackFrame.callFrame, stackFrame.args[2].arrayAllocationProfile(), stackFrame.callFrame->codeBlock()->constantBuffer(stackFrame.args[0].int32()), stackFrame.args[1].int32());
}
DEFINE_STUB_FUNCTION(EncodedJSValue, op_construct_NotJSConstruct)
{
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
JSValue callee = callFrame->calleeAsValue();
ConstructData constructData;
ConstructType constructType = getConstructData(callee, constructData);
ASSERT(constructType != ConstructTypeJS);
if (constructType != ConstructTypeHost) {
ASSERT(constructType == ConstructTypeNone);
ErrorWithExecAndCalleeFunctor functor = ErrorWithExecAndCalleeFunctor(createNotAConstructorError, callee);
return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, &functor);
}
EncodedJSValue returnValue;
{
SamplingTool::CallRecord callRecord(CTI_SAMPLER, true);
returnValue = constructData.native.function(callFrame);
}
if (stackFrame.vm->exception())
return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return returnValue;
}
static JSValue getByVal(
CallFrame* callFrame, JSValue baseValue, JSValue subscript, ReturnAddressPtr returnAddress)
{
......@@ -1897,30 +1635,6 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_func_exp)
return func;
}
DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
{
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
CallFrame* callerFrame = callFrame->callerFrame();
ASSERT(callFrame->callerFrame()->codeBlock()->codeType() != FunctionCode
|| !callFrame->callerFrame()->codeBlock()->needsFullScopeChain()
|| callFrame->callerFrame()->uncheckedR(callFrame->callerFrame()->codeBlock()->activationRegister().offset()).jsValue());
callFrame->setScope(callerFrame->scope());
callFrame->setReturnPC(static_cast<Instruction*>((STUB_RETURN_ADDRESS).value()));
callFrame->setCodeBlock(0);
if (!isHostFunction(callFrame->calleeAsValue(), globalFuncEval))
return JSValue::encode(JSValue());
JSValue result = eval(callFrame);
if (stackFrame.vm->exception())
return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
DEFINE_STUB_FUNCTION(void*, op_throw)
{
STUB_INIT_STACK_FRAME(stackFrame);
......
......@@ -330,9 +330,6 @@ extern "C" void ctiMasmProbeTrampoline();
void performPlatformSpecificJITAssertions(VM*);
extern "C" {
EncodedJSValue JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_call_eval(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_check_has_instance(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_del_by_id(STUB_ARGS_DECLARATION) WTF_INTERNAL;
......@@ -392,15 +389,10 @@ void JIT_STUB cti_op_throw_static_error(STUB_ARGS_DECLARATION) WTF_INTERNAL;
#if ENABLE(DFG_JIT)
void JIT_STUB cti_optimize(STUB_ARGS_DECLARATION) WTF_INTERNAL;
#endif
void* JIT_STUB cti_op_call_jitCompile(STUB_ARGS_DECLARATION) WTF_INTERNAL;