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

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

Powered by Google App Engine
This is Rietveld 408576698