7 #include "src/deoptimizer.h" 8 #include "src/objects-inl.h" 9 #include "src/register-configuration.h" 10 #include "src/safepoint-table.h" 15 const int Deoptimizer::table_entry_size_ = 5;
19 void Deoptimizer::TableEntryGenerator::Generate() {
20 Label deopt_table_entry;
21 __ bind(&deopt_table_entry);
26 const int kNumberOfRegisters = Register::kNumRegisters;
28 const int kDoubleRegsSize = kDoubleSize * XMMRegister::kNumRegisters;
29 __ subp(rsp, Immediate(kDoubleRegsSize));
31 const RegisterConfiguration* config = RegisterConfiguration::Default();
32 for (
int i = 0;
i < config->num_allocatable_double_registers(); ++
i) {
33 int code = config->GetAllocatableDoubleCode(
i);
34 XMMRegister xmm_reg = XMMRegister::from_code(code);
35 int offset = code * kDoubleSize;
36 __ Movsd(Operand(rsp, offset), xmm_reg);
39 const int kFloatRegsSize = kFloatSize * XMMRegister::kNumRegisters;
40 __ subp(rsp, Immediate(kFloatRegsSize));
42 for (
int i = 0;
i < config->num_allocatable_float_registers(); ++
i) {
43 int code = config->GetAllocatableFloatCode(
i);
44 XMMRegister xmm_reg = XMMRegister::from_code(code);
45 int offset = code * kFloatSize;
46 __ Movss(Operand(rsp, offset), xmm_reg);
51 for (
int i = 0;
i < kNumberOfRegisters;
i++) {
52 Register r = Register::from_code(
i);
56 const int kSavedRegistersAreaSize =
57 kNumberOfRegisters * kRegisterSize + kDoubleRegsSize + kFloatRegsSize;
60 ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, isolate()),
69 __ movp(rax, Operand(rsp, kSavedRegistersAreaSize));
72 __ leap(rdx, Operand(&deopt_table_entry));
76 __ subl(rax, Immediate(5));
79 __ movl(rbx, Immediate(0xcccccccd));
81 __ shrq(rax, Immediate(0x22));
84 __ movl(arg_reg_3, rax);
88 __ movp(arg_reg_4, Operand(rsp, kSavedRegistersAreaSize + 1 * kRegisterSize));
89 __ leap(arg5, Operand(rsp, kSavedRegistersAreaSize + 1 * kRegisterSize +
96 __ PrepareCallCFunction(6);
97 __ movp(rax, Immediate(0));
99 __ movp(rdi, Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset));
100 __ JumpIfSmi(rdi, &context_check);
101 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
102 __ bind(&context_check);
103 __ movp(arg_reg_1, rax);
104 __ Set(arg_reg_2, static_cast<int>(deopt_kind()));
110 __ movq(Operand(rsp, 4 * kRegisterSize), arg5);
111 __ LoadAddress(arg5, ExternalReference::isolate_address(isolate()));
112 __ movq(Operand(rsp, 5 * kRegisterSize), arg5);
115 __ LoadAddress(r9, ExternalReference::isolate_address(isolate()));
118 { AllowExternalCallThatCantCauseGC scope(masm());
119 __ CallCFunction(ExternalReference::new_deoptimizer_function(), 6);
123 __ movp(rbx, Operand(rax, Deoptimizer::input_offset()));
126 for (
int i = kNumberOfRegisters -1;
i >= 0;
i--) {
127 int offset = (
i * kPointerSize) + FrameDescription::registers_offset();
128 __ PopQuad(Operand(rbx, offset));
132 int float_regs_offset = FrameDescription::float_registers_offset();
133 for (
int i = 0;
i < XMMRegister::kNumRegisters;
i++) {
134 int src_offset =
i * kFloatSize;
135 int dst_offset =
i * kFloatSize + float_regs_offset;
136 __ movl(rcx, Operand(rsp, src_offset));
137 __ movl(Operand(rbx, dst_offset), rcx);
139 __ addp(rsp, Immediate(kFloatRegsSize));
142 int double_regs_offset = FrameDescription::double_registers_offset();
143 for (
int i = 0;
i < XMMRegister::kNumRegisters;
i++) {
144 int dst_offset =
i * kDoubleSize + double_regs_offset;
145 __ popq(Operand(rbx, dst_offset));
149 __ addp(rsp, Immediate(1 * kRegisterSize + kPCOnStackSize));
153 __ movp(rcx, Operand(rbx, FrameDescription::frame_size_offset()));
159 __ leap(rdx, Operand(rbx, FrameDescription::frame_content_offset()));
160 Label pop_loop_header;
161 __ jmp(&pop_loop_header);
164 __ Pop(Operand(rdx, 0));
165 __ addp(rdx, Immediate(
sizeof(intptr_t)));
166 __ bind(&pop_loop_header);
168 __ j(not_equal, &pop_loop);
172 __ PrepareCallCFunction(2);
173 __ movp(arg_reg_1, rax);
174 __ LoadAddress(arg_reg_2, ExternalReference::isolate_address(isolate()));
176 AllowExternalCallThatCantCauseGC scope(masm());
177 __ CallCFunction(ExternalReference::compute_output_frames_function(), 2);
181 __ movp(rsp, Operand(rax, Deoptimizer::caller_frame_top_offset()));
184 Label outer_push_loop, inner_push_loop,
185 outer_loop_header, inner_loop_header;
188 __ movl(rdx, Operand(rax, Deoptimizer::output_count_offset()));
189 __ movp(rax, Operand(rax, Deoptimizer::output_offset()));
190 __ leap(rdx, Operand(rax, rdx, times_pointer_size, 0));
191 __ jmp(&outer_loop_header);
192 __ bind(&outer_push_loop);
194 __ movp(rbx, Operand(rax, 0));
195 __ movp(rcx, Operand(rbx, FrameDescription::frame_size_offset()));
196 __ jmp(&inner_loop_header);
197 __ bind(&inner_push_loop);
198 __ subp(rcx, Immediate(
sizeof(intptr_t)));
199 __ Push(Operand(rbx, rcx, times_1, FrameDescription::frame_content_offset()));
200 __ bind(&inner_loop_header);
202 __ j(not_zero, &inner_push_loop);
203 __ addp(rax, Immediate(kPointerSize));
204 __ bind(&outer_loop_header);
206 __ j(below, &outer_push_loop);
208 for (
int i = 0;
i < config->num_allocatable_double_registers(); ++
i) {
209 int code = config->GetAllocatableDoubleCode(
i);
210 XMMRegister xmm_reg = XMMRegister::from_code(code);
211 int src_offset = code * kDoubleSize + double_regs_offset;
212 __ Movsd(xmm_reg, Operand(rbx, src_offset));
216 __ PushQuad(Operand(rbx, FrameDescription::pc_offset()));
217 __ PushQuad(Operand(rbx, FrameDescription::continuation_offset()));
220 for (
int i = 0;
i < kNumberOfRegisters;
i++) {
221 int offset = (
i * kPointerSize) + FrameDescription::registers_offset();
222 __ PushQuad(Operand(rbx, offset));
226 for (
int i = kNumberOfRegisters - 1;
i >= 0 ;
i--) {
227 Register r = Register::from_code(
i);
232 r = Register::from_code(
i - 1);
242 void Deoptimizer::TableEntryGenerator::GeneratePrologue() {
245 for (
int i = 0;
i < count();
i++) {
246 int start = masm()->pc_offset();
249 DCHECK(masm()->pc_offset() - start == table_entry_size_);
254 bool Deoptimizer::PadTopOfStackRegister() {
return false; }
256 void FrameDescription::SetCallerPc(
unsigned offset, intptr_t value) {
257 if (kPCOnStackSize == 2 * kPointerSize) {
259 SetFrameSlot(offset + kPointerSize, 0);
261 SetFrameSlot(offset, value);
265 void FrameDescription::SetCallerFp(
unsigned offset, intptr_t value) {
266 if (kFPOnStackSize == 2 * kPointerSize) {
268 SetFrameSlot(offset + kPointerSize, 0);
270 SetFrameSlot(offset, value);
274 void FrameDescription::SetCallerConstantPool(
unsigned offset, intptr_t value) {
286 #endif // V8_TARGET_ARCH_X64