summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/jit/JIT.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/jit/JIT.cpp')
-rw-r--r--JavaScriptCore/jit/JIT.cpp38
1 files changed, 29 insertions, 9 deletions
diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp
index eeffd5c..5d96847 100644
--- a/JavaScriptCore/jit/JIT.cpp
+++ b/JavaScriptCore/jit/JIT.cpp
@@ -221,6 +221,8 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_call_varargs)
DEFINE_OP(op_catch)
DEFINE_OP(op_construct)
+ DEFINE_OP(op_get_callee)
+ DEFINE_OP(op_create_this)
DEFINE_OP(op_convert_this)
DEFINE_OP(op_init_arguments)
DEFINE_OP(op_create_arguments)
@@ -454,17 +456,19 @@ void JIT::privateCompileSlowCases()
#endif
}
-JITCode JIT::privateCompile()
+JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
{
+ // Could use a pop_m, but would need to offset the following instruction if so.
+ preserveReturnAddressAfterCall(regT2);
+ emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC);
+
+ Label beginLabel(this);
+
sampleCodeBlock(m_codeBlock);
#if ENABLE(OPCODE_SAMPLING)
sampleInstruction(m_codeBlock->instructions().begin());
#endif
- // Could use a pop_m, but would need to offset the following instruction if so.
- preserveReturnAddressAfterCall(regT2);
- emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC);
-
Jump registerFileCheck;
if (m_codeBlock->codeType() == FunctionCode) {
// In the case of a fast linked call, we do not set this up in the caller.
@@ -481,6 +485,8 @@ JITCode JIT::privateCompile()
privateCompileLinkPass();
privateCompileSlowCases();
+ Label arityCheck;
+ Call callArityCheck;
if (m_codeBlock->codeType() == FunctionCode) {
registerFileCheck.link(this);
m_bytecodeOffset = 0;
@@ -489,6 +495,15 @@ JITCode JIT::privateCompile()
m_bytecodeOffset = (unsigned)-1; // Reset this, in order to guard its use with ASSERTs.
#endif
jump(functionBody);
+
+ arityCheck = label();
+ preserveReturnAddressAfterCall(regT2);
+ emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC);
+ branch32(Equal, regT1, Imm32(m_codeBlock->m_numParameters)).linkTo(beginLabel, this);
+ restoreArgumentReference();
+ callArityCheck = call();
+ move(regT0, callFrameRegister);
+ jump(beginLabel);
}
ASSERT(m_jmpTable.isEmpty());
@@ -567,6 +582,11 @@ JITCode JIT::privateCompile()
info.callReturnLocation = m_codeBlock->structureStubInfo(m_methodCallCompilationInfo[i].propertyAccessIndex).callReturnLocation;
}
+ if (m_codeBlock->codeType() == FunctionCode && functionEntryArityCheck) {
+ patchBuffer.link(callArityCheck, FunctionPtr(m_codeBlock->m_isConstructor ? cti_op_construct_arityCheck : cti_op_call_arityCheck));
+ *functionEntryArityCheck = patchBuffer.locationOf(arityCheck);
+ }
+
return patchBuffer.finalizeCode();
}
@@ -600,7 +620,7 @@ void JIT::unlinkCallOrConstruct(CallLinkInfo* callLinkInfo)
#endif
}
-void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JITCode& code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
+void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
{
RepatchBuffer repatchBuffer(callerCodeBlock);
@@ -613,14 +633,14 @@ void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* ca
calleeCodeBlock->addCaller(callLinkInfo);
repatchBuffer.repatch(callLinkInfo->hotPathBegin, callee);
- repatchBuffer.relink(callLinkInfo->hotPathOther, code.addressForCall());
+ repatchBuffer.relink(callLinkInfo->hotPathOther, code);
}
// 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, JITCode& code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
+void JIT::linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
{
RepatchBuffer repatchBuffer(callerCodeBlock);
@@ -633,7 +653,7 @@ void JIT::linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBloc
calleeCodeBlock->addCaller(callLinkInfo);
repatchBuffer.repatch(callLinkInfo->hotPathBegin, callee);
- repatchBuffer.relink(callLinkInfo->hotPathOther, code.addressForCall());
+ repatchBuffer.relink(callLinkInfo->hotPathOther, code);
}
// patch the call so we do not continue to try to link.