Index: src/x64/macro-assembler-x64.cc |
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc |
index fc94e5726e05045b5164a588ca0054f5b011a90a..2a22127cad6c8a71fdc0d65e1dc9d9f4dad0dc20 100644 |
--- a/src/x64/macro-assembler-x64.cc |
+++ b/src/x64/macro-assembler-x64.cc |
@@ -544,6 +544,37 @@ void MacroAssembler::CopyRegistersFromStackToMemory(Register base, |
#endif // ENABLE_DEBUGGER_SUPPORT |
+void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) { |
+ bool resolved; |
+ Handle<Code> code = ResolveBuiltin(id, &resolved); |
+ |
+ // Calls are not allowed in some stubs. |
+ ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); |
+ |
+ // Rely on the assertion to check that the number of provided |
+ // arguments match the expected number of arguments. Fake a |
+ // parameter count to avoid emitting code to do the check. |
+ ParameterCount expected(0); |
+ InvokeCode(Handle<Code>(code), expected, expected, |
+ RelocInfo::CODE_TARGET, flag); |
+ |
+ const char* name = Builtins::GetName(id); |
+ int argc = Builtins::GetArgumentsCount(id); |
+ // The target address for the jump is stored as an immediate at offset |
+ // kInvokeCodeAddressOffset. |
+ if (!resolved) { |
+ uint32_t flags = |
+ Bootstrapper::FixupFlagsArgumentsCount::encode(argc) | |
+ Bootstrapper::FixupFlagsIsPCRelative::encode(true) | |
+ Bootstrapper::FixupFlagsUseCodeObject::encode(false); |
+ Unresolved entry = { pc_offset() - kInvokeCodeAddressOffset, flags, name }; |
+ unresolved_.Add(entry); |
+ } |
+} |
+ |
+ |
+ |
+ |
void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
const ParameterCount& actual, |
Handle<Code> code_constant, |
@@ -637,12 +668,20 @@ void MacroAssembler::InvokeCode(Handle<Code> code, |
Register dummy = rax; |
InvokePrologue(expected, actual, code, dummy, &done, flag); |
movq(kScratchRegister, code, rmode); |
+#ifdef DEBUG |
+ // Address of the immediate code pointer. |
+ int immediate_address = pc_offset() - kPointerSize; |
+#endif |
+ // The kInvokeCodeAddressOffset computations assumes the REX.B prefix |
+ // on the jmp and call opcodes. |
+ ASSERT_EQ(1, kScratchRegister.high_bit()); |
if (flag == CALL_FUNCTION) { |
call(kScratchRegister); |
} else { |
ASSERT(flag == JUMP_FUNCTION); |
jmp(kScratchRegister); |
} |
+ ASSERT_EQ(kInvokeCodeAddressOffset, immediate_address - pc_offset()); |
bind(&done); |
} |