Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/a64/deoptimizer-a64.cc

Issue 151603008: A64: Synchronize with r16599. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/a64/builtins-a64.cc ('k') | src/a64/lithium-a64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 // TODO(jbramley): There should be some extra assertions here (as in the ARM 142 // TODO(jbramley): There should be some extra assertions here (as in the ARM
143 // back-end), but this function is gone in bleeding_edge so it might not 143 // back-end), but this function is gone in bleeding_edge so it might not
144 // matter anyway. 144 // matter anyway.
145 Instruction* jump_or_nop = Instruction::Cast(pc_after)->preceding(3); 145 Instruction* jump_or_nop = Instruction::Cast(pc_after)->preceding(3);
146 return jump_or_nop->IsNop(Assembler::INTERRUPT_CODE_NOP) ? PATCHED_FOR_OSR 146 return jump_or_nop->IsNop(Assembler::INTERRUPT_CODE_NOP) ? PATCHED_FOR_OSR
147 : NOT_PATCHED; 147 : NOT_PATCHED;
148 } 148 }
149 #endif 149 #endif
150 150
151 151
152 static int LookupBailoutId(DeoptimizationInputData* data, BailoutId ast_id) {
153 ByteArray* translations = data->TranslationByteArray();
154 int length = data->DeoptCount();
155 for (int i = 0; i < length; i++) {
156 if (data->AstId(i) == ast_id) {
157 TranslationIterator it(translations, data->TranslationIndex(i)->value());
158 int value = it.Next();
159 ASSERT(Translation::BEGIN == static_cast<Translation::Opcode>(value));
160 // Read the number of frames.
161 value = it.Next();
162 if (value == 1) return i;
163 }
164 }
165 UNREACHABLE();
166 return -1;
167 }
168
169
170 void Deoptimizer::DoComputeOsrOutputFrame() {
171 DeoptimizationInputData* data = DeoptimizationInputData::cast(
172 compiled_code_->deoptimization_data());
173 unsigned ast_id = data->OsrAstId()->value();
174
175 int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
176 unsigned translation_index = data->TranslationIndex(bailout_id)->value();
177 ByteArray* translations = data->TranslationByteArray();
178
179 TranslationIterator iterator(translations, translation_index);
180 Translation::Opcode opcode =
181 static_cast<Translation::Opcode>(iterator.Next());
182 ASSERT(Translation::BEGIN == opcode);
183 USE(opcode);
184 int count = iterator.Next();
185 iterator.Skip(1); // Drop JS frame count.
186 ASSERT(count == 1);
187 USE(count);
188
189 opcode = static_cast<Translation::Opcode>(iterator.Next());
190 USE(opcode);
191 ASSERT(Translation::JS_FRAME == opcode);
192 unsigned node_id = iterator.Next();
193 USE(node_id);
194 ASSERT(node_id == ast_id);
195 int closure_id = iterator.Next();
196 USE(closure_id);
197 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
198 unsigned height = iterator.Next();
199 unsigned height_in_bytes = height * kPointerSize;
200 USE(height_in_bytes);
201
202 unsigned fixed_size = ComputeFixedSize(function_);
203 unsigned input_frame_size = input_->GetFrameSize();
204 ASSERT(fixed_size + height_in_bytes == input_frame_size);
205
206 unsigned stack_slot_size = compiled_code_->stack_slots() * kPointerSize;
207 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
208 unsigned outgoing_size = outgoing_height * kPointerSize;
209 unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size;
210 ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call.
211
212 if (FLAG_trace_osr) {
213 PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ",
214 reinterpret_cast<intptr_t>(function_));
215 PrintFunctionName();
216 PrintF(" => node=%u, frame=%d->%d]\n",
217 ast_id,
218 input_frame_size,
219 output_frame_size);
220 }
221
222 // There's only one output frame in the OSR case.
223 output_count_ = 1;
224 output_ = new FrameDescription*[1];
225 output_[0] = new(output_frame_size) FrameDescription(
226 output_frame_size, function_);
227 output_[0]->SetFrameType(StackFrame::JAVA_SCRIPT);
228
229 // Clear the incoming parameters in the optimized frame to avoid
230 // confusing the garbage collector.
231 unsigned output_offset = output_frame_size - kPointerSize;
232 int parameter_count = function_->shared()->formal_parameter_count() + 1;
233 for (int i = 0; i < parameter_count; ++i) {
234 output_[0]->SetFrameSlot(output_offset, 0);
235 output_offset -= kPointerSize;
236 }
237
238 // Translate the incoming parameters. This may overwrite some of the
239 // incoming argument slots we've just cleared.
240 int input_offset = input_frame_size - kPointerSize;
241 bool ok = true;
242 int limit = input_offset - (parameter_count * kPointerSize);
243 while (ok && input_offset > limit) {
244 ok = DoOsrTranslateCommand(&iterator, &input_offset);
245 }
246
247 // There are no translation commands for the caller's pc and fp, the
248 // context, and the function. Set them up explicitly.
249 for (int i = StandardFrameConstants::kCallerPCOffset;
250 ok && i >= StandardFrameConstants::kMarkerOffset;
251 i -= kPointerSize) {
252 uint32_t input_value = input_->GetFrameSlot(input_offset);
253 if (FLAG_trace_osr) {
254 const char* name = "UNKNOWN";
255 switch (i) {
256 case StandardFrameConstants::kCallerPCOffset:
257 name = "caller's pc";
258 break;
259 case StandardFrameConstants::kCallerFPOffset:
260 name = "fp";
261 break;
262 case StandardFrameConstants::kContextOffset:
263 name = "context";
264 break;
265 case StandardFrameConstants::kMarkerOffset:
266 name = "function";
267 break;
268 }
269 PrintF(" [sp + %d] <- 0x%08x ; [sp + %d] (fixed part - %s)\n",
270 output_offset,
271 input_value,
272 input_offset,
273 name);
274 }
275
276 output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset));
277 input_offset -= kPointerSize;
278 output_offset -= kPointerSize;
279 }
280
281 // Translate the rest of the frame.
282 while (ok && input_offset >= 0) {
283 ok = DoOsrTranslateCommand(&iterator, &input_offset);
284 }
285
286 // If translation of any command failed, continue using the input frame.
287 if (!ok) {
288 delete output_[0];
289 output_[0] = input_;
290 output_[0]->SetPc(reinterpret_cast<uint64_t>(from_));
291 } else {
292 // Set up the frame pointer and the context pointer.
293 output_[0]->SetRegister(fp.code(), input_->GetRegister(fp.code()));
294 output_[0]->SetRegister(cp.code(), input_->GetRegister(cp.code()));
295
296 unsigned pc_offset = data->OsrPcOffset()->value();
297 uint64_t pc = reinterpret_cast<uint64_t>(
298 compiled_code_->entry() + pc_offset);
299 output_[0]->SetPc(pc);
300 }
301 Code* continuation = isolate_->builtins()->builtin(Builtins::kNotifyOSR);
302 output_[0]->SetContinuation(
303 reinterpret_cast<uint64_t>(continuation->entry()));
304
305 if (FLAG_trace_osr) {
306 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
307 ok ? "finished" : "aborted",
308 reinterpret_cast<intptr_t>(function_));
309 PrintFunctionName();
310 PrintF(" => pc=0x%0lx]\n", output_[0]->GetPc());
311 }
312 }
313
314
315 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { 152 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
316 // Set the register values. The values are not important as there are no 153 // Set the register values. The values are not important as there are no
317 // callee saved registers in JavaScript frames, so all registers are 154 // callee saved registers in JavaScript frames, so all registers are
318 // spilled. Registers fp and sp are set to the correct values though. 155 // spilled. Registers fp and sp are set to the correct values though.
319 for (int i = 0; i < Register::NumRegisters(); i++) { 156 for (int i = 0; i < Register::NumRegisters(); i++) {
320 input_->SetRegister(i, 0); 157 input_->SetRegister(i, 0);
321 } 158 }
322 159
323 // TODO(all): Do we also need to set a value to csp? 160 // TODO(all): Do we also need to set a value to csp?
324 input_->SetRegister(jssp.code(), reinterpret_cast<intptr_t>(frame->sp())); 161 input_->SetRegister(jssp.code(), reinterpret_cast<intptr_t>(frame->sp()));
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 ASSERT(!saved_fp_registers.IncludesAliasOf(crankshaft_fp_scratch) && 347 ASSERT(!saved_fp_registers.IncludesAliasOf(crankshaft_fp_scratch) &&
511 !saved_fp_registers.IncludesAliasOf(fp_zero) && 348 !saved_fp_registers.IncludesAliasOf(fp_zero) &&
512 !saved_fp_registers.IncludesAliasOf(fp_scratch)); 349 !saved_fp_registers.IncludesAliasOf(fp_scratch));
513 int src_offset = FrameDescription::double_registers_offset(); 350 int src_offset = FrameDescription::double_registers_offset();
514 while (!saved_fp_registers.IsEmpty()) { 351 while (!saved_fp_registers.IsEmpty()) {
515 const CPURegister reg = saved_fp_registers.PopLowestIndex(); 352 const CPURegister reg = saved_fp_registers.PopLowestIndex();
516 __ Ldr(reg, MemOperand(x1, src_offset)); 353 __ Ldr(reg, MemOperand(x1, src_offset));
517 src_offset += kDoubleSize; 354 src_offset += kDoubleSize;
518 } 355 }
519 356
520 // Push state, pc, and continuation from the last output frame. 357 // Push state from the last output frame.
521 if (type() != OSR) { 358 __ Ldr(x6, MemOperand(current_frame, FrameDescription::state_offset()));
522 __ Ldr(x6, MemOperand(current_frame, FrameDescription::state_offset())); 359 __ Push(x6);
523 __ Push(x6); 360
524 } 361 // TODO(all): ARM copies a lot (if not all) of the last output frame onto the
362 // stack, then pops it all into registers. Here, we try to load it directly
363 // into the relevant registers. Is this correct? If so, we should improve the
364 // ARM code.
525 365
526 // TODO(all): This code needs to be revisited, We probably don't need to 366 // TODO(all): This code needs to be revisited, We probably don't need to
527 // restore all the registers as fullcodegen does not keep live values in 367 // restore all the registers as fullcodegen does not keep live values in
528 // registers (note that at least fp must be restored though). 368 // registers (note that at least fp must be restored though).
529 369
530 // Restore registers from the last output frame. 370 // Restore registers from the last output frame.
531 // Note that lr is not in the list of saved_registers and will be restored 371 // Note that lr is not in the list of saved_registers and will be restored
532 // later. We can use it to hold the address of last output frame while 372 // later. We can use it to hold the address of last output frame while
533 // reloading the other registers. 373 // reloading the other registers.
534 ASSERT(!saved_registers.IncludesAliasOf(lr)); 374 ASSERT(!saved_registers.IncludesAliasOf(lr));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 434
595 435
596 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { 436 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
597 SetFrameSlot(offset, value); 437 SetFrameSlot(offset, value);
598 } 438 }
599 439
600 440
601 #undef __ 441 #undef __
602 442
603 } } // namespace v8::internal 443 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/a64/builtins-a64.cc ('k') | src/a64/lithium-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698