| Index: src/x64/deoptimizer-x64.cc
|
| ===================================================================
|
| --- src/x64/deoptimizer-x64.cc (revision 15486)
|
| +++ src/x64/deoptimizer-x64.cc (working copy)
|
| @@ -84,8 +84,13 @@
|
| // There is room enough to write a long call instruction because we pad
|
| // LLazyBailout instructions with nops if necessary.
|
| CodePatcher patcher(call_address, Assembler::kCallInstructionLength);
|
| +#ifndef V8_TARGET_ARCH_X32
|
| patcher.masm()->Call(GetDeoptimizationEntry(isolate, i, LAZY),
|
| RelocInfo::NONE64);
|
| +#else
|
| + patcher.masm()->Call(GetDeoptimizationEntry(isolate, i, LAZY),
|
| + RelocInfo::NONE32);
|
| +#endif
|
| ASSERT(prev_call_address == NULL ||
|
| call_address >= prev_call_address + patch_size());
|
| ASSERT(call_address + patch_size() <= code->instruction_end());
|
| @@ -116,7 +121,11 @@
|
|
|
|
|
| static const byte kJnsInstruction = 0x79;
|
| +#ifndef V8_TARGET_ARCH_X32
|
| static const byte kJnsOffset = 0x1d;
|
| +#else
|
| +static const byte kJnsOffset = 0x14;
|
| +#endif
|
| static const byte kCallInstruction = 0xe8;
|
| static const byte kNopByteOne = 0x66;
|
| static const byte kNopByteTwo = 0x90;
|
| @@ -304,6 +313,15 @@
|
| for (int i = StandardFrameConstants::kCallerPCOffset;
|
| ok && i >= StandardFrameConstants::kMarkerOffset;
|
| i -= kPointerSize) {
|
| +#ifdef V8_TARGET_ARCH_X32
|
| + if (i == StandardFrameConstants::kCallerPCOffset ||
|
| + i == StandardFrameConstants::kCallerFPOffset) {
|
| + // Set the high-32 bit of PC and FP to 0.
|
| + output_[0]->SetFrameSlot(output_offset, 0);
|
| + input_offset -= kPointerSize;
|
| + output_offset -= kPointerSize;
|
| + }
|
| +#endif
|
| intptr_t input_value = input_->GetFrameSlot(input_offset);
|
| if (FLAG_trace_osr) {
|
| const char* name = "UNKNOWN";
|
| @@ -331,6 +349,11 @@
|
| output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset));
|
| input_offset -= kPointerSize;
|
| output_offset -= kPointerSize;
|
| +#ifdef V8_TARGET_ARCH_X32
|
| + if (i == StandardFrameConstants::kCallerPCOffset) {
|
| + i -= kHWRegSize - kPointerSize;
|
| + }
|
| +#endif
|
| }
|
|
|
| // Translate the rest of the frame.
|
| @@ -383,7 +406,11 @@
|
|
|
| // Fill the frame content from the actual data on the frame.
|
| for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
|
| +#ifndef V8_TARGET_ARCH_X32
|
| input_->SetFrameSlot(i, Memory::uint64_at(tos + i));
|
| +#else
|
| + input_->SetFrameSlot(i, Memory::uint32_at(tos + i));
|
| +#endif
|
| }
|
| }
|
|
|
| @@ -416,6 +443,8 @@
|
|
|
|
|
| #define __ masm()->
|
| +#define __k __
|
| +#define __q __
|
|
|
| void Deoptimizer::EntryGenerator::Generate() {
|
| GeneratePrologue();
|
| @@ -437,11 +466,16 @@
|
| // to restore all later.
|
| for (int i = 0; i < kNumberOfRegisters; i++) {
|
| Register r = Register::from_code(i);
|
| - __ push(r);
|
| + __k push(r);
|
| }
|
|
|
| +#ifndef V8_TARGET_ARCH_X32
|
| const int kSavedRegistersAreaSize = kNumberOfRegisters * kPointerSize +
|
| kDoubleRegsSize;
|
| +#else
|
| + const int kSavedRegistersAreaSize = kNumberOfRegisters * kHWRegSize +
|
| + kDoubleRegsSize;
|
| +#endif
|
|
|
| // We use this to keep the value of the fifth argument temporarily.
|
| // Unfortunately we can't store it directly in r8 (used for passing
|
| @@ -455,11 +489,15 @@
|
| // and compute the fp-to-sp delta in register arg5.
|
| if (type() == EAGER || type() == SOFT) {
|
| __ Set(arg_reg_4, 0);
|
| - __ lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize));
|
| + __q lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize));
|
| } else {
|
| +#ifndef V8_TARGET_ARCH_X32
|
| __ movq(arg_reg_4,
|
| Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize));
|
| - __ lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 2 * kPointerSize));
|
| +#else
|
| + __ movl(arg_reg_4, Operand(rsp, kSavedRegistersAreaSize + 1 * kHWRegSize));
|
| +#endif
|
| + __q lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 2 * kPointerSize));
|
| }
|
|
|
| __ subq(arg5, rbp);
|
| @@ -493,21 +531,26 @@
|
| // Fill in the input registers.
|
| for (int i = kNumberOfRegisters -1; i >= 0; i--) {
|
| int offset = (i * kPointerSize) + FrameDescription::registers_offset();
|
| +#ifndef V8_TARGET_ARCH_X32
|
| __ pop(Operand(rbx, offset));
|
| +#else
|
| + __ pop(kScratchRegister);
|
| + __ movl(Operand(rbx, offset), kScratchRegister);
|
| +#endif
|
| }
|
|
|
| // Fill in the double input registers.
|
| int double_regs_offset = FrameDescription::double_registers_offset();
|
| for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) {
|
| int dst_offset = i * kDoubleSize + double_regs_offset;
|
| - __ pop(Operand(rbx, dst_offset));
|
| + __k pop(Operand(rbx, dst_offset));
|
| }
|
|
|
| // Remove the bailout id from the stack.
|
| if (type() == EAGER || type() == SOFT) {
|
| - __ addq(rsp, Immediate(kPointerSize));
|
| + __q addq(rsp, Immediate(kPointerSize));
|
| } else {
|
| - __ addq(rsp, Immediate(2 * kPointerSize));
|
| + __q addq(rsp, Immediate(2 * kPointerSize));
|
| }
|
|
|
| // Compute a pointer to the unwinding limit in register rcx; that is
|
| @@ -530,7 +573,7 @@
|
| __ j(not_equal, &pop_loop);
|
|
|
| // Compute the output frame in the deoptimizer.
|
| - __ push(rax);
|
| + __k push(rax);
|
| __ PrepareCallCFunction(2);
|
| __ movq(arg_reg_1, rax);
|
| __ LoadAddress(arg_reg_2, ExternalReference::isolate_address(isolate()));
|
| @@ -539,7 +582,7 @@
|
| __ CallCFunction(
|
| ExternalReference::compute_output_frames_function(isolate()), 2);
|
| }
|
| - __ pop(rax);
|
| + __k pop(rax);
|
|
|
| // Replace the current frame with the output frames.
|
| Label outer_push_loop, inner_push_loop,
|
| @@ -574,15 +617,29 @@
|
|
|
| // Push state, pc, and continuation from the last output frame.
|
| if (type() != OSR) {
|
| +#ifdef V8_TARGET_ARCH_X32
|
| + __ Push(Immediate(0));
|
| +#endif
|
| __ push(Operand(rbx, FrameDescription::state_offset()));
|
| }
|
| +#ifdef V8_TARGET_ARCH_X32
|
| + __ Push(Immediate(0));
|
| +#endif
|
| __ push(Operand(rbx, FrameDescription::pc_offset()));
|
| +#ifdef V8_TARGET_ARCH_X32
|
| + __ Push(Immediate(0));
|
| +#endif
|
| __ push(Operand(rbx, FrameDescription::continuation_offset()));
|
|
|
| // Push the registers from the last output frame.
|
| for (int i = 0; i < kNumberOfRegisters; i++) {
|
| int offset = (i * kPointerSize) + FrameDescription::registers_offset();
|
| +#ifndef V8_TARGET_ARCH_X32
|
| __ push(Operand(rbx, offset));
|
| +#else
|
| + __ movl(kScratchRegister, Operand(rbx, offset));
|
| + __ push(kScratchRegister);
|
| +#endif
|
| }
|
|
|
| // Restore the registers from the stack.
|
| @@ -594,7 +651,7 @@
|
| ASSERT(i > 0);
|
| r = Register::from_code(i - 1);
|
| }
|
| - __ pop(r);
|
| + __k pop(r);
|
| }
|
|
|
| // Set up the roots register.
|
| @@ -612,13 +669,15 @@
|
| for (int i = 0; i < count(); i++) {
|
| int start = masm()->pc_offset();
|
| USE(start);
|
| - __ push_imm32(i);
|
| + __k push_imm32(i);
|
| __ jmp(&done);
|
| ASSERT(masm()->pc_offset() - start == table_entry_size_);
|
| }
|
| __ bind(&done);
|
| }
|
|
|
| +#undef __k
|
| +#undef __k
|
| #undef __
|
|
|
|
|
|
|