| Index: src/x64/macro-assembler-x64.cc
|
| ===================================================================
|
| --- src/x64/macro-assembler-x64.cc (revision 7563)
|
| +++ src/x64/macro-assembler-x64.cc (working copy)
|
| @@ -44,7 +44,7 @@
|
| : Assembler(buffer, size),
|
| generating_stub_(false),
|
| allow_stub_calls_(true),
|
| - code_object_(Heap::undefined_value()) {
|
| + code_object_(HEAP->undefined_value()) {
|
| }
|
|
|
|
|
| @@ -402,7 +402,7 @@
|
|
|
|
|
| void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) {
|
| - Runtime::Function* function = Runtime::FunctionForId(id);
|
| + const Runtime::Function* function = Runtime::FunctionForId(id);
|
| Set(rax, function->nargs);
|
| movq(rbx, ExternalReference(function));
|
| CEntryStub ces(1);
|
| @@ -417,7 +417,8 @@
|
| }
|
|
|
|
|
| -void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
|
| +void MacroAssembler::CallRuntime(const Runtime::Function* f,
|
| + int num_arguments) {
|
| // If the expected number of arguments of the runtime function is
|
| // constant, we check that the actual number of arguments match the
|
| // expectation.
|
| @@ -437,13 +438,13 @@
|
| }
|
|
|
|
|
| -MaybeObject* MacroAssembler::TryCallRuntime(Runtime::Function* f,
|
| +MaybeObject* MacroAssembler::TryCallRuntime(const Runtime::Function* f,
|
| int num_arguments) {
|
| if (f->nargs >= 0 && f->nargs != num_arguments) {
|
| IllegalOperation(num_arguments);
|
| // Since we did not call the stub, there was no allocation failure.
|
| // Return some non-failure object.
|
| - return Heap::undefined_value();
|
| + return HEAP->undefined_value();
|
| }
|
|
|
| // TODO(1236192): Most runtime routines don't need the number of
|
| @@ -598,7 +599,7 @@
|
|
|
| // Check if the function scheduled an exception.
|
| movq(rsi, scheduled_exception_address);
|
| - Cmp(Operand(rsi, 0), Factory::the_hole_value());
|
| + Cmp(Operand(rsi, 0), FACTORY->the_hole_value());
|
| j(not_equal, &promote_scheduled_exception);
|
|
|
| LeaveApiExitFrame();
|
| @@ -613,13 +614,18 @@
|
|
|
| bind(&empty_result);
|
| // It was zero; the result is undefined.
|
| - Move(rax, Factory::undefined_value());
|
| + Move(rax, FACTORY->undefined_value());
|
| jmp(&prologue);
|
|
|
| // HandleScope limit has changed. Delete allocated extensions.
|
| bind(&delete_allocated_handles);
|
| movq(Operand(base_reg, kLimitOffset), prev_limit_reg);
|
| movq(prev_limit_reg, rax);
|
| +#ifdef _WIN64
|
| + movq(rcx, ExternalReference::isolate_address());
|
| +#else
|
| + movq(rdi, ExternalReference::isolate_address());
|
| +#endif
|
| movq(rax, ExternalReference::delete_handle_scope_extensions());
|
| call(rax);
|
| movq(rax, prev_limit_reg);
|
| @@ -1620,7 +1626,7 @@
|
| push(Immediate(0)); // NULL frame pointer.
|
| }
|
| // Save the current handler.
|
| - movq(kScratchRegister, ExternalReference(Top::k_handler_address));
|
| + movq(kScratchRegister, ExternalReference(Isolate::k_handler_address));
|
| push(Operand(kScratchRegister, 0));
|
| // Link this handler.
|
| movq(Operand(kScratchRegister, 0), rsp);
|
| @@ -1630,7 +1636,7 @@
|
| void MacroAssembler::PopTryHandler() {
|
| ASSERT_EQ(0, StackHandlerConstants::kNextOffset);
|
| // Unlink this handler.
|
| - movq(kScratchRegister, ExternalReference(Top::k_handler_address));
|
| + movq(kScratchRegister, ExternalReference(Isolate::k_handler_address));
|
| pop(Operand(kScratchRegister, 0));
|
| // Remove the remaining fields.
|
| addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
|
| @@ -1649,7 +1655,7 @@
|
| movq(rax, value);
|
| }
|
|
|
| - ExternalReference handler_address(Top::k_handler_address);
|
| + ExternalReference handler_address(Isolate::k_handler_address);
|
| movq(kScratchRegister, handler_address);
|
| movq(rsp, Operand(kScratchRegister, 0));
|
| // get next in chain
|
| @@ -1677,7 +1683,7 @@
|
| movq(rax, value);
|
| }
|
| // Fetch top stack handler.
|
| - ExternalReference handler_address(Top::k_handler_address);
|
| + ExternalReference handler_address(Isolate::k_handler_address);
|
| movq(kScratchRegister, handler_address);
|
| movq(rsp, Operand(kScratchRegister, 0));
|
|
|
| @@ -1700,12 +1706,13 @@
|
|
|
| if (type == OUT_OF_MEMORY) {
|
| // Set external caught exception to false.
|
| - ExternalReference external_caught(Top::k_external_caught_exception_address);
|
| + ExternalReference external_caught(
|
| + Isolate::k_external_caught_exception_address);
|
| movq(rax, Immediate(false));
|
| store_rax(external_caught);
|
|
|
| // Set pending exception and rax to out of memory exception.
|
| - ExternalReference pending_exception(Top::k_pending_exception_address);
|
| + ExternalReference pending_exception(Isolate::k_pending_exception_address);
|
| movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE);
|
| store_rax(pending_exception);
|
| }
|
| @@ -1781,7 +1788,7 @@
|
| Condition is_smi = CheckSmi(object);
|
| j(is_smi, &ok);
|
| Cmp(FieldOperand(object, HeapObject::kMapOffset),
|
| - Factory::heap_number_map());
|
| + FACTORY->heap_number_map());
|
| Assert(equal, "Operand not a number");
|
| bind(&ok);
|
| }
|
| @@ -2040,7 +2047,7 @@
|
| push(kScratchRegister);
|
| if (emit_debug_code()) {
|
| movq(kScratchRegister,
|
| - Factory::undefined_value(),
|
| + FACTORY->undefined_value(),
|
| RelocInfo::EMBEDDED_OBJECT);
|
| cmpq(Operand(rsp, 0), kScratchRegister);
|
| Check(not_equal, "code object not properly patched");
|
| @@ -2079,10 +2086,10 @@
|
| movq(r14, rax); // Backup rax in callee-save register.
|
| }
|
|
|
| - movq(kScratchRegister, ExternalReference(Top::k_c_entry_fp_address));
|
| + movq(kScratchRegister, ExternalReference(Isolate::k_c_entry_fp_address));
|
| movq(Operand(kScratchRegister, 0), rbp);
|
|
|
| - movq(kScratchRegister, ExternalReference(Top::k_context_address));
|
| + movq(kScratchRegister, ExternalReference(Isolate::k_context_address));
|
| movq(Operand(kScratchRegister, 0), rsi);
|
| }
|
|
|
| @@ -2109,7 +2116,7 @@
|
| }
|
|
|
| // Get the required frame alignment for the OS.
|
| - static const int kFrameAlignment = OS::ActivationFrameAlignment();
|
| + const int kFrameAlignment = OS::ActivationFrameAlignment();
|
| if (kFrameAlignment > 0) {
|
| ASSERT(IsPowerOf2(kFrameAlignment));
|
| movq(kScratchRegister, Immediate(-kFrameAlignment));
|
| @@ -2174,7 +2181,7 @@
|
|
|
| void MacroAssembler::LeaveExitFrameEpilogue() {
|
| // Restore current context from top and clear it in debug mode.
|
| - ExternalReference context_address(Top::k_context_address);
|
| + ExternalReference context_address(Isolate::k_context_address);
|
| movq(kScratchRegister, context_address);
|
| movq(rsi, Operand(kScratchRegister, 0));
|
| #ifdef DEBUG
|
| @@ -2182,7 +2189,7 @@
|
| #endif
|
|
|
| // Clear the top frame.
|
| - ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
|
| + ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address);
|
| movq(kScratchRegister, c_entry_fp_address);
|
| movq(Operand(kScratchRegister, 0), Immediate(0));
|
| }
|
| @@ -2211,7 +2218,7 @@
|
| // Check the context is a global context.
|
| if (emit_debug_code()) {
|
| Cmp(FieldOperand(scratch, HeapObject::kMapOffset),
|
| - Factory::global_context_map());
|
| + FACTORY->global_context_map());
|
| Check(equal, "JSGlobalObject::global_context should be a global context.");
|
| }
|
|
|
| @@ -2636,6 +2643,11 @@
|
| }
|
| }
|
|
|
| +#ifdef _WIN64
|
| +static const int kRegisterPassedArguments = 4;
|
| +#else
|
| +static const int kRegisterPassedArguments = 6;
|
| +#endif
|
|
|
| void MacroAssembler::LoadGlobalFunction(int index, Register function) {
|
| // Load the global or builtins object from the current context.
|
| @@ -2653,7 +2665,7 @@
|
| movq(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
|
| if (emit_debug_code()) {
|
| Label ok, fail;
|
| - CheckMap(map, Factory::meta_map(), &fail, false);
|
| + CheckMap(map, FACTORY->meta_map(), &fail, false);
|
| jmp(&ok);
|
| bind(&fail);
|
| Abort("Global functions must have initial map");
|
| @@ -2671,11 +2683,10 @@
|
| // and the caller does not reserve stack slots for them.
|
| ASSERT(num_arguments >= 0);
|
| #ifdef _WIN64
|
| - static const int kMinimumStackSlots = 4;
|
| + const int kMinimumStackSlots = kRegisterPassedArguments;
|
| if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots;
|
| return num_arguments;
|
| #else
|
| - static const int kRegisterPassedArguments = 6;
|
| if (num_arguments < kRegisterPassedArguments) return 0;
|
| return num_arguments - kRegisterPassedArguments;
|
| #endif
|
| @@ -2686,6 +2697,10 @@
|
| int frame_alignment = OS::ActivationFrameAlignment();
|
| ASSERT(frame_alignment != 0);
|
| ASSERT(num_arguments >= 0);
|
| +
|
| + // Reserve space for Isolate address which is always passed as last parameter
|
| + num_arguments += 1;
|
| +
|
| // Make stack end at alignment and allocate space for arguments and old rsp.
|
| movq(kScratchRegister, rsp);
|
| ASSERT(IsPowerOf2(frame_alignment));
|
| @@ -2705,6 +2720,26 @@
|
|
|
|
|
| void MacroAssembler::CallCFunction(Register function, int num_arguments) {
|
| + // Pass current isolate address as additional parameter.
|
| + if (num_arguments < kRegisterPassedArguments) {
|
| +#ifdef _WIN64
|
| + // First four arguments are passed in registers on Windows.
|
| + Register arg_to_reg[] = {rcx, rdx, r8, r9};
|
| +#else
|
| + // First six arguments are passed in registers on other platforms.
|
| + Register arg_to_reg[] = {rdi, rsi, rdx, rcx, r8, r9};
|
| +#endif
|
| + Register reg = arg_to_reg[num_arguments];
|
| + movq(reg, ExternalReference::isolate_address());
|
| + } else {
|
| + // Push Isolate pointer after all parameters.
|
| + int argument_slots_on_stack =
|
| + ArgumentStackSlotsForCFunctionCall(num_arguments);
|
| + movq(kScratchRegister, ExternalReference::isolate_address());
|
| + movq(Operand(rsp, argument_slots_on_stack * kPointerSize),
|
| + kScratchRegister);
|
| + }
|
| +
|
| // Check stack alignment.
|
| if (emit_debug_code()) {
|
| CheckStackAlignment();
|
| @@ -2713,6 +2748,7 @@
|
| call(function);
|
| ASSERT(OS::ActivationFrameAlignment() != 0);
|
| ASSERT(num_arguments >= 0);
|
| + num_arguments += 1;
|
| int argument_slots_on_stack =
|
| ArgumentStackSlotsForCFunctionCall(num_arguments);
|
| movq(rsp, Operand(rsp, argument_slots_on_stack * kPointerSize));
|
|
|