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

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

Issue 21340002: Generate a custom OSR entrypoint for OSR compiles on all platforms, and transition to optimized cod… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remerge with recent changes. Created 7 years, 3 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
OLDNEW
1 1
2 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Copyright 2011 the V8 project authors. All rights reserved.
3 // Redistribution and use in source and binary forms, with or without 3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are 4 // modification, are permitted provided that the following conditions are
5 // met: 5 // met:
6 // 6 //
7 // * Redistributions of source code must retain the above copyright 7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer. 8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above 9 // * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following 10 // copyright notice, this list of conditions and the following
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 isolate->builtins()->builtin(Builtins::kInterruptCheck); 153 isolate->builtins()->builtin(Builtins::kInterruptCheck);
154 ASSERT(reinterpret_cast<uint32_t>( 154 ASSERT(reinterpret_cast<uint32_t>(
155 Assembler::target_address_at(pc_after - 4 * kInstrSize)) == 155 Assembler::target_address_at(pc_after - 4 * kInstrSize)) ==
156 reinterpret_cast<uint32_t>(interrupt_builtin->entry())); 156 reinterpret_cast<uint32_t>(interrupt_builtin->entry()));
157 return NOT_PATCHED; 157 return NOT_PATCHED;
158 } 158 }
159 } 159 }
160 #endif // DEBUG 160 #endif // DEBUG
161 161
162 162
163 static int LookupBailoutId(DeoptimizationInputData* data, BailoutId ast_id) {
164 ByteArray* translations = data->TranslationByteArray();
165 int length = data->DeoptCount();
166 for (int i = 0; i < length; i++) {
167 if (data->AstId(i) == ast_id) {
168 TranslationIterator it(translations, data->TranslationIndex(i)->value());
169 int value = it.Next();
170 ASSERT(Translation::BEGIN == static_cast<Translation::Opcode>(value));
171 // Read the number of frames.
172 value = it.Next();
173 if (value == 1) return i;
174 }
175 }
176 UNREACHABLE();
177 return -1;
178 }
179
180
181 void Deoptimizer::DoComputeOsrOutputFrame() {
182 DeoptimizationInputData* data = DeoptimizationInputData::cast(
183 compiled_code_->deoptimization_data());
184 unsigned ast_id = data->OsrAstId()->value();
185
186 int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
187 unsigned translation_index = data->TranslationIndex(bailout_id)->value();
188 ByteArray* translations = data->TranslationByteArray();
189
190 TranslationIterator iterator(translations, translation_index);
191 Translation::Opcode opcode =
192 static_cast<Translation::Opcode>(iterator.Next());
193 ASSERT(Translation::BEGIN == opcode);
194 USE(opcode);
195 int count = iterator.Next();
196 iterator.Skip(1); // Drop JS frame count.
197 ASSERT(count == 1);
198 USE(count);
199
200 opcode = static_cast<Translation::Opcode>(iterator.Next());
201 USE(opcode);
202 ASSERT(Translation::JS_FRAME == opcode);
203 unsigned node_id = iterator.Next();
204 USE(node_id);
205 ASSERT(node_id == ast_id);
206 int closure_id = iterator.Next();
207 USE(closure_id);
208 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
209 unsigned height = iterator.Next();
210 unsigned height_in_bytes = height * kPointerSize;
211 USE(height_in_bytes);
212
213 unsigned fixed_size = ComputeFixedSize(function_);
214 unsigned input_frame_size = input_->GetFrameSize();
215 ASSERT(fixed_size + height_in_bytes == input_frame_size);
216
217 unsigned stack_slot_size = compiled_code_->stack_slots() * kPointerSize;
218 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
219 unsigned outgoing_size = outgoing_height * kPointerSize;
220 unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size;
221 ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call.
222
223 if (FLAG_trace_osr) {
224 PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ",
225 reinterpret_cast<intptr_t>(function_));
226 PrintFunctionName();
227 PrintF(" => node=%u, frame=%d->%d]\n",
228 ast_id,
229 input_frame_size,
230 output_frame_size);
231 }
232
233 // There's only one output frame in the OSR case.
234 output_count_ = 1;
235 output_ = new FrameDescription*[1];
236 output_[0] = new(output_frame_size) FrameDescription(
237 output_frame_size, function_);
238 output_[0]->SetFrameType(StackFrame::JAVA_SCRIPT);
239
240 // Clear the incoming parameters in the optimized frame to avoid
241 // confusing the garbage collector.
242 unsigned output_offset = output_frame_size - kPointerSize;
243 int parameter_count = function_->shared()->formal_parameter_count() + 1;
244 for (int i = 0; i < parameter_count; ++i) {
245 output_[0]->SetFrameSlot(output_offset, 0);
246 output_offset -= kPointerSize;
247 }
248
249 // Translate the incoming parameters. This may overwrite some of the
250 // incoming argument slots we've just cleared.
251 int input_offset = input_frame_size - kPointerSize;
252 bool ok = true;
253 int limit = input_offset - (parameter_count * kPointerSize);
254 while (ok && input_offset > limit) {
255 ok = DoOsrTranslateCommand(&iterator, &input_offset);
256 }
257
258 // There are no translation commands for the caller's pc and fp, the
259 // context, and the function. Set them up explicitly.
260 for (int i = StandardFrameConstants::kCallerPCOffset;
261 ok && i >= StandardFrameConstants::kMarkerOffset;
262 i -= kPointerSize) {
263 uint32_t input_value = input_->GetFrameSlot(input_offset);
264 if (FLAG_trace_osr) {
265 const char* name = "UNKNOWN";
266 switch (i) {
267 case StandardFrameConstants::kCallerPCOffset:
268 name = "caller's pc";
269 break;
270 case StandardFrameConstants::kCallerFPOffset:
271 name = "fp";
272 break;
273 case StandardFrameConstants::kContextOffset:
274 name = "context";
275 break;
276 case StandardFrameConstants::kMarkerOffset:
277 name = "function";
278 break;
279 }
280 PrintF(" [sp + %d] <- 0x%08x ; [sp + %d] (fixed part - %s)\n",
281 output_offset,
282 input_value,
283 input_offset,
284 name);
285 }
286
287 output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset));
288 input_offset -= kPointerSize;
289 output_offset -= kPointerSize;
290 }
291
292 // Translate the rest of the frame.
293 while (ok && input_offset >= 0) {
294 ok = DoOsrTranslateCommand(&iterator, &input_offset);
295 }
296
297 // If translation of any command failed, continue using the input frame.
298 if (!ok) {
299 delete output_[0];
300 output_[0] = input_;
301 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_));
302 } else {
303 // Set up the frame pointer and the context pointer.
304 output_[0]->SetRegister(fp.code(), input_->GetRegister(fp.code()));
305 output_[0]->SetRegister(cp.code(), input_->GetRegister(cp.code()));
306
307 unsigned pc_offset = data->OsrPcOffset()->value();
308 uint32_t pc = reinterpret_cast<uint32_t>(
309 compiled_code_->entry() + pc_offset);
310 output_[0]->SetPc(pc);
311 }
312 Code* continuation = isolate_->builtins()->builtin(Builtins::kNotifyOSR);
313 output_[0]->SetContinuation(
314 reinterpret_cast<uint32_t>(continuation->entry()));
315
316 if (FLAG_trace_osr) {
317 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
318 ok ? "finished" : "aborted",
319 reinterpret_cast<intptr_t>(function_));
320 PrintFunctionName();
321 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc());
322 }
323 }
324
325
326 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { 163 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
327 // Set the register values. The values are not important as there are no 164 // Set the register values. The values are not important as there are no
328 // callee saved registers in JavaScript frames, so all registers are 165 // callee saved registers in JavaScript frames, so all registers are
329 // spilled. Registers fp and sp are set to the correct values though. 166 // spilled. Registers fp and sp are set to the correct values though.
330 167
331 for (int i = 0; i < Register::kNumRegisters; i++) { 168 for (int i = 0; i < Register::kNumRegisters; i++) {
332 input_->SetRegister(i, i * 4); 169 input_->SetRegister(i, i * 4);
333 } 170 }
334 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp())); 171 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
335 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp())); 172 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 __ Branch(&outer_push_loop, lt, t0, Operand(a1)); 367 __ Branch(&outer_push_loop, lt, t0, Operand(a1));
531 368
532 __ lw(a1, MemOperand(a0, Deoptimizer::input_offset())); 369 __ lw(a1, MemOperand(a0, Deoptimizer::input_offset()));
533 for (int i = 0; i < FPURegister::kMaxNumAllocatableRegisters; ++i) { 370 for (int i = 0; i < FPURegister::kMaxNumAllocatableRegisters; ++i) {
534 const FPURegister fpu_reg = FPURegister::FromAllocationIndex(i); 371 const FPURegister fpu_reg = FPURegister::FromAllocationIndex(i);
535 int src_offset = i * kDoubleSize + double_regs_offset; 372 int src_offset = i * kDoubleSize + double_regs_offset;
536 __ ldc1(fpu_reg, MemOperand(a1, src_offset)); 373 __ ldc1(fpu_reg, MemOperand(a1, src_offset));
537 } 374 }
538 375
539 // Push state, pc, and continuation from the last output frame. 376 // Push state, pc, and continuation from the last output frame.
540 if (type() != OSR) { 377 __ lw(t2, MemOperand(a2, FrameDescription::state_offset()));
541 __ lw(t2, MemOperand(a2, FrameDescription::state_offset())); 378 __ push(t2);
542 __ push(t2);
543 }
544 379
545 __ lw(t2, MemOperand(a2, FrameDescription::pc_offset())); 380 __ lw(t2, MemOperand(a2, FrameDescription::pc_offset()));
546 __ push(t2); 381 __ push(t2);
547 __ lw(t2, MemOperand(a2, FrameDescription::continuation_offset())); 382 __ lw(t2, MemOperand(a2, FrameDescription::continuation_offset()));
548 __ push(t2); 383 __ push(t2);
549 384
550 385
551 // Technically restoring 'at' should work unless zero_reg is also restored 386 // Technically restoring 'at' should work unless zero_reg is also restored
552 // but it's safer to check for this. 387 // but it's safer to check for this.
553 ASSERT(!(at.bit() & restored_regs)); 388 ASSERT(!(at.bit() & restored_regs));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 448
614 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { 449 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
615 SetFrameSlot(offset, value); 450 SetFrameSlot(offset, value);
616 } 451 }
617 452
618 453
619 #undef __ 454 #undef __
620 455
621 456
622 } } // namespace v8::internal 457 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698