5 #include "src/assembler-inl.h" 6 #include "src/deoptimizer.h" 7 #include "src/register-configuration.h" 8 #include "src/safepoint-table.h" 14 const int Deoptimizer::table_entry_size_ = 16;
20 void Deoptimizer::TableEntryGenerator::Generate() {
24 const int kNumberOfRegisters = Register::kNumRegisters;
26 RegList restored_regs = kJSCallerSaved | kCalleeSaved;
28 const int kDoubleRegsSize = kDoubleSize * DoubleRegister::kNumRegisters;
29 const int kFloatRegsSize = kFloatSize * FloatRegister::kNumRegisters;
32 __ lay(sp, MemOperand(sp, -kDoubleRegsSize));
33 const RegisterConfiguration* config = RegisterConfiguration::Default();
34 for (
int i = 0;
i < config->num_allocatable_double_registers(); ++
i) {
35 int code = config->GetAllocatableDoubleCode(
i);
36 const DoubleRegister dreg = DoubleRegister::from_code(code);
37 int offset = code * kDoubleSize;
38 __ StoreDouble(dreg, MemOperand(sp, offset));
41 __ lay(sp, MemOperand(sp, -kFloatRegsSize));
42 for (
int i = 0;
i < config->num_allocatable_float_registers(); ++
i) {
43 int code = config->GetAllocatableFloatCode(
i);
44 const FloatRegister dreg = FloatRegister::from_code(code);
45 int offset = code * kFloatSize;
46 __ StoreFloat32(dreg, MemOperand(sp, offset));
50 __ lay(sp, MemOperand(sp, -kNumberOfRegisters * kPointerSize));
51 __ StoreMultipleP(r0, sp, MemOperand(sp));
53 __ mov(ip, Operand(ExternalReference::Create(
54 IsolateAddressId::kCEntryFPAddress, isolate())));
55 __ StoreP(fp, MemOperand(ip));
57 const int kSavedRegistersAreaSize =
58 (kNumberOfRegisters * kPointerSize) + kDoubleRegsSize + kFloatRegsSize;
61 __ LoadP(r4, MemOperand(sp, kSavedRegistersAreaSize));
70 __ la(r6, MemOperand(sp, kSavedRegistersAreaSize + (1 * kPointerSize)));
75 __ PrepareCallCFunction(6, r7);
76 __ LoadImmP(r2, Operand::Zero());
78 __ LoadP(r3, MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset));
79 __ JumpIfSmi(r3, &context_check);
80 __ LoadP(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
81 __ bind(&context_check);
82 __ LoadImmP(r3, Operand(static_cast<int>(deopt_kind())));
87 __ mov(r7, Operand(ExternalReference::isolate_address(isolate())));
88 __ StoreP(r7, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize));
92 AllowExternalCallThatCantCauseGC scope(masm());
93 __ CallCFunction(ExternalReference::new_deoptimizer_function(), 6);
98 __ LoadP(r3, MemOperand(r2, Deoptimizer::input_offset()));
106 DCHECK_EQ(Register::kNumRegisters, kNumberOfRegisters);
107 for (
int i = 0;
i < kNumberOfRegisters;
i++) {
108 int offset = (
i * kPointerSize) + FrameDescription::registers_offset();
109 __ LoadP(r4, MemOperand(sp,
i * kPointerSize));
110 __ StoreP(r4, MemOperand(r3, offset));
113 int double_regs_offset = FrameDescription::double_registers_offset();
116 for (
int i = 0;
i < config->num_allocatable_double_registers(); ++
i) {
117 int code = config->GetAllocatableDoubleCode(
i);
118 int dst_offset = code * kDoubleSize + double_regs_offset;
120 code * kDoubleSize + kNumberOfRegisters * kPointerSize + kFloatRegsSize;
122 __ LoadDouble(d0, MemOperand(sp, src_offset));
123 __ StoreDouble(d0, MemOperand(r3, dst_offset));
126 int float_regs_offset = FrameDescription::float_registers_offset();
129 for (
int i = 0;
i < config->num_allocatable_float_registers(); ++
i) {
130 int code = config->GetAllocatableFloatCode(
i);
131 int dst_offset = code * kFloatSize + float_regs_offset;
132 int src_offset = code * kFloatSize + kNumberOfRegisters * kPointerSize;
134 __ LoadFloat32(d0, MemOperand(sp, src_offset));
135 __ StoreFloat32(d0, MemOperand(r3, dst_offset));
138 __ la(sp, MemOperand(sp, kSavedRegistersAreaSize + (1 * kPointerSize)));
142 __ LoadP(r4, MemOperand(r3, FrameDescription::frame_size_offset()));
148 __ la(r5, MemOperand(r3, FrameDescription::frame_content_offset()));
150 Label pop_loop_header;
151 __ b(&pop_loop_header, Label::kNear);
154 __ StoreP(r6, MemOperand(r5, 0));
155 __ la(r5, MemOperand(r5, kPointerSize));
156 __ bind(&pop_loop_header);
163 __ PrepareCallCFunction(1, r3);
166 AllowExternalCallThatCantCauseGC scope(masm());
167 __ CallCFunction(ExternalReference::compute_output_frames_function(), 1);
171 __ LoadP(sp, MemOperand(r2, Deoptimizer::caller_frame_top_offset()));
174 Label outer_push_loop, inner_push_loop, outer_loop_header, inner_loop_header;
177 __ LoadlW(r3, MemOperand(r2, Deoptimizer::output_count_offset()));
178 __ LoadP(r6, MemOperand(r2, Deoptimizer::output_offset()));
179 __ ShiftLeftP(r3, r3, Operand(kPointerSizeLog2));
181 __ b(&outer_loop_header, Label::kNear);
183 __ bind(&outer_push_loop);
185 __ LoadP(r4, MemOperand(r6, 0));
186 __ LoadP(r5, MemOperand(r4, FrameDescription::frame_size_offset()));
187 __ b(&inner_loop_header, Label::kNear);
189 __ bind(&inner_push_loop);
190 __ AddP(r5, Operand(-
sizeof(intptr_t)));
192 __ LoadP(r8, MemOperand(r8, FrameDescription::frame_content_offset()));
195 __ bind(&inner_loop_header);
196 __ CmpP(r5, Operand::Zero());
197 __ bne(&inner_push_loop);
199 __ AddP(r6, r6, Operand(kPointerSize));
200 __ bind(&outer_loop_header);
202 __ blt(&outer_push_loop);
204 __ LoadP(r3, MemOperand(r2, Deoptimizer::input_offset()));
205 for (
int i = 0;
i < config->num_allocatable_double_registers(); ++
i) {
206 int code = config->GetAllocatableDoubleCode(
i);
207 const DoubleRegister dreg = DoubleRegister::from_code(code);
208 int src_offset = code * kDoubleSize + double_regs_offset;
209 __ ld(dreg, MemOperand(r3, src_offset));
213 __ LoadP(r8, MemOperand(r4, FrameDescription::pc_offset()));
215 __ LoadP(r8, MemOperand(r4, FrameDescription::continuation_offset()));
220 for (
int i = kNumberOfRegisters - 1;
i > 0;
i--) {
221 int offset = (
i * kPointerSize) + FrameDescription::registers_offset();
222 if ((restored_regs & (1 <<
i)) != 0) {
223 __ LoadP(ToRegister(
i), MemOperand(r1, offset));
230 __ stop(
"Unreachable.");
233 void Deoptimizer::TableEntryGenerator::GeneratePrologue() {
237 for (
int i = 0;
i < count();
i++) {
238 int start = masm()->pc_offset();
240 __ lay(sp, MemOperand(sp, -kPointerSize));
241 __ LoadImmP(ip, Operand(
i));
243 int end = masm()->pc_offset();
245 DCHECK(masm()->pc_offset() - start == table_entry_size_);
248 __ StoreP(ip, MemOperand(sp));
251 bool Deoptimizer::PadTopOfStackRegister() {
return false; }
253 void FrameDescription::SetCallerPc(
unsigned offset, intptr_t value) {
254 SetFrameSlot(offset, value);
257 void FrameDescription::SetCallerFp(
unsigned offset, intptr_t value) {
258 SetFrameSlot(offset, value);
261 void FrameDescription::SetCallerConstantPool(
unsigned offset, intptr_t value) {