5 #if V8_TARGET_ARCH_IA32 7 #include "src/assembler-inl.h" 8 #include "src/deoptimizer.h" 9 #include "src/frame-constants.h" 10 #include "src/register-configuration.h" 11 #include "src/safepoint-table.h" 16 const int Deoptimizer::table_entry_size_ = 10;
20 void Deoptimizer::TableEntryGenerator::Generate() {
24 const int kNumberOfRegisters = Register::kNumRegisters;
26 const int kDoubleRegsSize = kDoubleSize * XMMRegister::kNumRegisters;
27 __ sub(esp, Immediate(kDoubleRegsSize));
28 const RegisterConfiguration* config = RegisterConfiguration::Default();
29 for (
int i = 0;
i < config->num_allocatable_double_registers(); ++
i) {
30 int code = config->GetAllocatableDoubleCode(
i);
31 XMMRegister xmm_reg = XMMRegister::from_code(code);
32 int offset = code * kDoubleSize;
33 __ movsd(Operand(esp, offset), xmm_reg);
36 STATIC_ASSERT(kFloatSize == kPointerSize);
37 const int kFloatRegsSize = kFloatSize * XMMRegister::kNumRegisters;
38 __ sub(esp, Immediate(kFloatRegsSize));
39 for (
int i = 0;
i < config->num_allocatable_float_registers(); ++
i) {
40 int code = config->GetAllocatableFloatCode(
i);
41 XMMRegister xmm_reg = XMMRegister::from_code(code);
42 int offset = code * kFloatSize;
43 __ movss(Operand(esp, offset), xmm_reg);
48 ExternalReference c_entry_fp_address =
49 ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, isolate());
50 __ mov(masm()->ExternalReferenceAsOperand(c_entry_fp_address, esi), ebp);
52 const int kSavedRegistersAreaSize =
53 kNumberOfRegisters * kPointerSize + kDoubleRegsSize + kFloatRegsSize;
56 __ mov(esi, Operand(esp, kSavedRegistersAreaSize));
60 __ mov(ecx, Operand(esp, kSavedRegistersAreaSize + 1 * kPointerSize));
61 __ lea(edx, Operand(esp, kSavedRegistersAreaSize + 2 * kPointerSize));
67 __ PrepareCallCFunction(6, eax);
68 __ mov(eax, Immediate(0));
70 __ mov(edi, Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset));
71 __ JumpIfSmi(edi, &context_check);
72 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
73 __ bind(&context_check);
74 __ mov(Operand(esp, 0 * kPointerSize), eax);
75 __ mov(Operand(esp, 1 * kPointerSize),
76 Immediate(static_cast<int>(deopt_kind())));
77 __ mov(Operand(esp, 2 * kPointerSize), esi);
78 __ mov(Operand(esp, 3 * kPointerSize), ecx);
79 __ mov(Operand(esp, 4 * kPointerSize), edx);
80 __ mov(Operand(esp, 5 * kPointerSize),
81 Immediate(ExternalReference::isolate_address(isolate())));
83 AllowExternalCallThatCantCauseGC scope(masm());
84 __ CallCFunction(ExternalReference::new_deoptimizer_function(), 6);
89 __ mov(esi, Operand(eax, Deoptimizer::input_offset()));
92 for (
int i = kNumberOfRegisters - 1;
i >= 0;
i--) {
93 int offset = (
i * kPointerSize) + FrameDescription::registers_offset();
94 __ pop(Operand(esi, offset));
97 int float_regs_offset = FrameDescription::float_registers_offset();
99 for (
int i = 0;
i < XMMRegister::kNumRegisters;
i++) {
100 int dst_offset =
i * kFloatSize + float_regs_offset;
101 __ pop(Operand(esi, dst_offset));
104 int double_regs_offset = FrameDescription::double_registers_offset();
106 for (
int i = 0;
i < config->num_allocatable_double_registers(); ++
i) {
107 int code = config->GetAllocatableDoubleCode(
i);
108 int dst_offset = code * kDoubleSize + double_regs_offset;
109 int src_offset = code * kDoubleSize;
110 __ movsd(xmm0, Operand(esp, src_offset));
111 __ movsd(Operand(esi, dst_offset), xmm0);
120 __ add(esp, Immediate(kDoubleRegsSize + 2 * kPointerSize));
124 __ mov(ecx, Operand(esi, FrameDescription::frame_size_offset()));
130 __ lea(edx, Operand(esi, FrameDescription::frame_content_offset()));
131 Label pop_loop_header;
132 __ jmp(&pop_loop_header);
135 __ pop(Operand(edx, 0));
136 __ add(edx, Immediate(
sizeof(
uint32_t)));
137 __ bind(&pop_loop_header);
139 __ j(not_equal, &pop_loop);
143 __ PrepareCallCFunction(1, esi);
144 __ mov(Operand(esp, 0 * kPointerSize), eax);
146 AllowExternalCallThatCantCauseGC scope(masm());
147 __ CallCFunction(ExternalReference::compute_output_frames_function(), 1);
151 __ mov(esp, Operand(eax, Deoptimizer::caller_frame_top_offset()));
154 Label outer_push_loop, inner_push_loop,
155 outer_loop_header, inner_loop_header;
158 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset()));
159 __ mov(eax, Operand(eax, Deoptimizer::output_offset()));
160 __ lea(edx, Operand(eax, edx, times_4, 0));
161 __ jmp(&outer_loop_header);
162 __ bind(&outer_push_loop);
165 __ mov(esi, Operand(eax, 0));
166 __ mov(ecx, Operand(esi, FrameDescription::frame_size_offset()));
167 __ jmp(&inner_loop_header);
168 __ bind(&inner_push_loop);
169 __ sub(ecx, Immediate(
sizeof(
uint32_t)));
170 __ push(Operand(esi, ecx, times_1, FrameDescription::frame_content_offset()));
171 __ bind(&inner_loop_header);
173 __ j(not_zero, &inner_push_loop);
174 __ add(eax, Immediate(kPointerSize));
175 __ bind(&outer_loop_header);
177 __ j(below, &outer_push_loop);
180 for (
int i = 0;
i < config->num_allocatable_double_registers(); ++
i) {
181 int code = config->GetAllocatableDoubleCode(
i);
182 XMMRegister xmm_reg = XMMRegister::from_code(code);
183 int src_offset = code * kDoubleSize + double_regs_offset;
184 __ movsd(xmm_reg, Operand(esi, src_offset));
188 __ push(Operand(esi, FrameDescription::pc_offset()));
189 __ push(Operand(esi, FrameDescription::continuation_offset()));
192 for (
int i = 0;
i < kNumberOfRegisters;
i++) {
193 int offset = (
i * kPointerSize) + FrameDescription::registers_offset();
194 __ push(Operand(esi, offset));
200 __ InitializeRootRegister();
207 void Deoptimizer::TableEntryGenerator::GeneratePrologue() {
210 for (
int i = 0;
i < count();
i++) {
211 int start = masm()->pc_offset();
215 DCHECK(masm()->pc_offset() - start == table_entry_size_);
220 bool Deoptimizer::PadTopOfStackRegister() {
return false; }
222 void FrameDescription::SetCallerPc(
unsigned offset, intptr_t value) {
223 SetFrameSlot(offset, value);
227 void FrameDescription::SetCallerFp(
unsigned offset, intptr_t value) {
228 SetFrameSlot(offset, value);
232 void FrameDescription::SetCallerConstantPool(
unsigned offset, intptr_t value) {
244 #endif // V8_TARGET_ARCH_IA32