| Index: src/x64/macro-assembler-x64.cc
|
| ===================================================================
|
| --- src/x64/macro-assembler-x64.cc (revision 3935)
|
| +++ src/x64/macro-assembler-x64.cc (working copy)
|
| @@ -39,7 +39,6 @@
|
|
|
| MacroAssembler::MacroAssembler(void* buffer, int size)
|
| : Assembler(buffer, size),
|
| - unresolved_(0),
|
| generating_stub_(false),
|
| allow_stub_calls_(true),
|
| code_object_(Heap::undefined_value()) {
|
| @@ -387,6 +386,16 @@
|
| }
|
|
|
|
|
| +void MacroAssembler::CallExternalReference(const ExternalReference& ext,
|
| + int num_arguments) {
|
| + movq(rax, Immediate(num_arguments));
|
| + movq(rbx, ext);
|
| +
|
| + CEntryStub stub(1);
|
| + CallStub(&stub);
|
| +}
|
| +
|
| +
|
| void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
|
| int num_arguments,
|
| int result_size) {
|
| @@ -415,38 +424,30 @@
|
| }
|
|
|
|
|
| -void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
|
| - bool resolved;
|
| - Handle<Code> code = ResolveBuiltin(id, &resolved);
|
| +void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
|
| + // Calls are not allowed in some stubs.
|
| + ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
|
|
|
| - const char* name = Builtins::GetName(id);
|
| - int argc = Builtins::GetArgumentsCount(id);
|
| -
|
| - movq(target, code, RelocInfo::EMBEDDED_OBJECT);
|
| - if (!resolved) {
|
| - uint32_t flags =
|
| - Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
|
| - Bootstrapper::FixupFlagsUseCodeObject::encode(true);
|
| - Unresolved entry = { pc_offset() - sizeof(intptr_t), flags, name };
|
| - unresolved_.Add(entry);
|
| - }
|
| - addq(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
|
| + // 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);
|
| + GetBuiltinEntry(rdx, id);
|
| + InvokeCode(rdx, expected, expected, flag);
|
| }
|
|
|
| -Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
|
| - bool* resolved) {
|
| - // Move the builtin function into the temporary function slot by
|
| - // reading it from the builtins object. NOTE: We should be able to
|
| - // reduce this to two instructions by putting the function table in
|
| - // the global object instead of the "builtins" object and by using a
|
| - // real register for the function.
|
| - movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
|
| - movq(rdx, FieldOperand(rdx, GlobalObject::kBuiltinsOffset));
|
| +
|
| +void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
|
| + // Load the JavaScript builtin function from the builtins object.
|
| + movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
|
| + movq(rdi, FieldOperand(rdi, GlobalObject::kBuiltinsOffset));
|
| int builtins_offset =
|
| JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
|
| - movq(rdi, FieldOperand(rdx, builtins_offset));
|
| -
|
| - return Builtins::GetCode(id, resolved);
|
| + movq(rdi, FieldOperand(rdi, builtins_offset));
|
| + // Load the code entry point from the function into the target register.
|
| + movq(target, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
|
| + movq(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset));
|
| + addq(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
|
| }
|
|
|
|
|
| @@ -1597,6 +1598,17 @@
|
| }
|
|
|
|
|
| +void MacroAssembler::AbortIfNotNumber(Register object, const char* msg) {
|
| + Label ok;
|
| + Condition is_smi = CheckSmi(object);
|
| + j(is_smi, &ok);
|
| + Cmp(FieldOperand(object, HeapObject::kMapOffset),
|
| + Factory::heap_number_map());
|
| + Assert(equal, msg);
|
| + bind(&ok);
|
| +}
|
| +
|
| +
|
| Condition MacroAssembler::IsObjectStringType(Register heap_object,
|
| Register map,
|
| Register instance_type) {
|
| @@ -1774,41 +1786,16 @@
|
| }
|
| }
|
|
|
| +void MacroAssembler::DebugBreak() {
|
| + ASSERT(allow_stub_calls());
|
| + xor_(rax, rax); // no arguments
|
| + movq(rbx, ExternalReference(Runtime::kDebugBreak));
|
| + CEntryStub ces(1);
|
| + Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
|
| +}
|
| #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::FixupFlagsUseCodeObject::encode(false);
|
| - Unresolved entry =
|
| - { pc_offset() - kCallTargetAddressOffset, flags, name };
|
| - unresolved_.Add(entry);
|
| - }
|
| -}
|
| -
|
| -
|
| void MacroAssembler::InvokePrologue(const ParameterCount& expected,
|
| const ParameterCount& actual,
|
| Handle<Code> code_constant,
|
| @@ -1926,6 +1913,21 @@
|
| }
|
|
|
|
|
| +void MacroAssembler::InvokeFunction(JSFunction* function,
|
| + const ParameterCount& actual,
|
| + InvokeFlag flag) {
|
| + ASSERT(function->is_compiled());
|
| + // Get the function and setup the context.
|
| + Move(rdi, Handle<JSFunction>(function));
|
| + movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
|
| +
|
| + // Invoke the cached code.
|
| + Handle<Code> code(function->code());
|
| + ParameterCount expected(function->shared()->formal_parameter_count());
|
| + InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
|
| +}
|
| +
|
| +
|
| void MacroAssembler::EnterFrame(StackFrame::Type type) {
|
| push(rbp);
|
| movq(rbp, rsp);
|
| @@ -1965,13 +1967,9 @@
|
|
|
| // Reserve room for entry stack pointer and push the debug marker.
|
| ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize);
|
| - push(Immediate(0)); // saved entry sp, patched before call
|
| - if (mode == ExitFrame::MODE_DEBUG) {
|
| - push(Immediate(0));
|
| - } else {
|
| - movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
|
| - push(kScratchRegister);
|
| - }
|
| + push(Immediate(0)); // Saved entry sp, patched before call.
|
| + movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
|
| + push(kScratchRegister); // Accessed from EditFrame::code_slot.
|
|
|
| // Save the frame pointer and the context in top.
|
| ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
|
|
|