| Index: src/x64/macro-assembler-x64.cc
|
| ===================================================================
|
| --- src/x64/macro-assembler-x64.cc (revision 7267)
|
| +++ 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()) {
|
| }
|
|
|
|
|
| @@ -391,7 +391,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);
|
| @@ -406,7 +406,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.
|
| @@ -426,13 +427,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
|
| @@ -587,7 +588,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();
|
| @@ -602,13 +603,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);
|
| @@ -1609,7 +1615,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);
|
| @@ -1619,7 +1625,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));
|
| @@ -1638,7 +1644,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
|
| @@ -1666,7 +1672,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));
|
|
|
| @@ -1689,12 +1695,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);
|
| }
|
| @@ -1770,7 +1777,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);
|
| }
|
| @@ -2029,7 +2036,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");
|
| @@ -2068,10 +2075,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);
|
| }
|
|
|
| @@ -2098,7 +2105,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));
|
| @@ -2163,7 +2170,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
|
| @@ -2171,7 +2178,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));
|
| }
|
| @@ -2200,7 +2207,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.");
|
| }
|
|
|
| @@ -2625,6 +2632,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.
|
| @@ -2642,7 +2654,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");
|
| @@ -2660,11 +2672,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
|
| @@ -2675,6 +2686,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));
|
| @@ -2694,6 +2709,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();
|
| @@ -2702,6 +2737,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));
|
|
|