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

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

Issue 9265004: Support inlining at call-sites with mismatched number of arguments. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: finished implementation, extended tests, ported to x64&arm Created 8 years, 11 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 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2012 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
11 // with the distribution. 11 // with the distribution.
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 int bailout_id = LookupBailoutId(data, ast_id); 292 int bailout_id = LookupBailoutId(data, ast_id);
293 unsigned translation_index = data->TranslationIndex(bailout_id)->value(); 293 unsigned translation_index = data->TranslationIndex(bailout_id)->value();
294 ByteArray* translations = data->TranslationByteArray(); 294 ByteArray* translations = data->TranslationByteArray();
295 295
296 TranslationIterator iterator(translations, translation_index); 296 TranslationIterator iterator(translations, translation_index);
297 Translation::Opcode opcode = 297 Translation::Opcode opcode =
298 static_cast<Translation::Opcode>(iterator.Next()); 298 static_cast<Translation::Opcode>(iterator.Next());
299 ASSERT(Translation::BEGIN == opcode); 299 ASSERT(Translation::BEGIN == opcode);
300 USE(opcode); 300 USE(opcode);
301 int count = iterator.Next(); 301 int count = iterator.Next();
302 iterator.Next(); // Drop JS frames count.
302 ASSERT(count == 1); 303 ASSERT(count == 1);
303 USE(count); 304 USE(count);
304 305
305 opcode = static_cast<Translation::Opcode>(iterator.Next()); 306 opcode = static_cast<Translation::Opcode>(iterator.Next());
306 USE(opcode); 307 USE(opcode);
307 ASSERT(Translation::FRAME == opcode); 308 ASSERT(Translation::JS_FRAME == opcode);
308 unsigned node_id = iterator.Next(); 309 unsigned node_id = iterator.Next();
309 USE(node_id); 310 USE(node_id);
310 ASSERT(node_id == ast_id); 311 ASSERT(node_id == ast_id);
311 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator.Next())); 312 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator.Next()));
312 USE(function); 313 USE(function);
313 ASSERT(function == function_); 314 ASSERT(function == function_);
314 unsigned height = iterator.Next(); 315 unsigned height = iterator.Next();
315 unsigned height_in_bytes = height * kPointerSize; 316 unsigned height_in_bytes = height * kPointerSize;
316 USE(height_in_bytes); 317 USE(height_in_bytes);
317 318
(...skipping 18 matching lines...) Expand all
336 } 337 }
337 338
338 // There's only one output frame in the OSR case. 339 // There's only one output frame in the OSR case.
339 output_count_ = 1; 340 output_count_ = 1;
340 output_ = new FrameDescription*[1]; 341 output_ = new FrameDescription*[1];
341 output_[0] = new(output_frame_size) FrameDescription( 342 output_[0] = new(output_frame_size) FrameDescription(
342 output_frame_size, function_); 343 output_frame_size, function_);
343 #ifdef DEBUG 344 #ifdef DEBUG
344 output_[0]->SetKind(Code::OPTIMIZED_FUNCTION); 345 output_[0]->SetKind(Code::OPTIMIZED_FUNCTION);
345 #endif 346 #endif
347 output_[0]->SetType(StackFrame::JAVA_SCRIPT);
346 348
347 // Clear the incoming parameters in the optimized frame to avoid 349 // Clear the incoming parameters in the optimized frame to avoid
348 // confusing the garbage collector. 350 // confusing the garbage collector.
349 unsigned output_offset = output_frame_size - kPointerSize; 351 unsigned output_offset = output_frame_size - kPointerSize;
350 int parameter_count = function_->shared()->formal_parameter_count() + 1; 352 int parameter_count = function_->shared()->formal_parameter_count() + 1;
351 for (int i = 0; i < parameter_count; ++i) { 353 for (int i = 0; i < parameter_count; ++i) {
352 output_[0]->SetFrameSlot(output_offset, 0); 354 output_[0]->SetFrameSlot(output_offset, 0);
353 output_offset -= kPointerSize; 355 output_offset -= kPointerSize;
354 } 356 }
355 357
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 if (FLAG_trace_osr) { 432 if (FLAG_trace_osr) {
431 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ", 433 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
432 ok ? "finished" : "aborted", 434 ok ? "finished" : "aborted",
433 reinterpret_cast<intptr_t>(function)); 435 reinterpret_cast<intptr_t>(function));
434 function->PrintName(); 436 function->PrintName();
435 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc()); 437 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc());
436 } 438 }
437 } 439 }
438 440
439 441
440 void Deoptimizer::DoComputeFrame(TranslationIterator* iterator, 442 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
Kevin Millikin (Chromium) 2012/01/24 00:08:54 My suggestions about the comments in the ARM versi
Vyacheslav Egorov (Chromium) 2012/01/24 08:49:20 Done.
441 int frame_index) { 443 int frame_index) {
442 // Read the ast node id, function, and frame height for this output frame. 444 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
443 Translation::Opcode opcode = 445 unsigned height = iterator->Next();
444 static_cast<Translation::Opcode>(iterator->Next()); 446 unsigned height_in_bytes = height * kPointerSize;
445 USE(opcode); 447 if (FLAG_trace_deopt) {
446 ASSERT(Translation::FRAME == opcode); 448 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes);
449 }
450
451 unsigned fixed_frame_size = 5 * kPointerSize;
Kevin Millikin (Chromium) 2012/01/24 00:08:54 You could compute this as StandardFrameConstants:
Vyacheslav Egorov (Chromium) 2012/01/24 08:49:20 Done.
452 unsigned input_frame_size = input_->GetFrameSize();
453 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
454
455 // Allocate and store the output frame description.
456 FrameDescription* output_frame =
457 new(output_frame_size) FrameDescription(output_frame_size, function);
458 #ifdef DEBUG
459 output_frame->SetKind(Code::BUILTIN);
460 #endif
461 output_frame->SetType(StackFrame::ARGUMENTS_ADAPTOR);
462
463 // Arguments adaptor can not be topmost or bottommost.
464 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
465 ASSERT(output_[frame_index] == NULL);
466 output_[frame_index] = output_frame;
467
468 // The top address for the bottommost output frame can be computed from
469 // the input frame pointer and the output frame's height. For all
470 // subsequent output frames, it can be computed from the previous one's
471 // top address and the current frame's size.
472 uint32_t top_address;
473 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
474 output_frame->SetTop(top_address);
475
476 // Compute the incoming parameter translation.
477 int parameter_count = height;
478 unsigned output_offset = output_frame_size;
479 unsigned input_offset = input_frame_size;
480 for (int i = 0; i < parameter_count; ++i) {
481 output_offset -= kPointerSize;
482 DoTranslateCommand(iterator, frame_index, output_offset);
483 }
484 input_offset -= (parameter_count * kPointerSize);
485
486 // Compute caller's PC
487 output_offset -= kPointerSize;
488 input_offset -= kPointerSize;
489 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
490 output_frame->SetFrameSlot(output_offset, callers_pc);
491 if (FLAG_trace_deopt) {
492 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n",
493 top_address + output_offset, output_offset, callers_pc);
494 }
495
496 // Compute caller's FP
497 output_offset -= kPointerSize;
498 input_offset -= kPointerSize;
499 intptr_t value = output_[frame_index - 1]->GetFp();
500 output_frame->SetFrameSlot(output_offset, value);
501 intptr_t fp_value = top_address + output_offset;
502 output_frame->SetFp(fp_value);
503 if (FLAG_trace_deopt) {
504 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n",
505 fp_value, output_offset, value);
506 }
507
508 // For the bottommost output frame the context can be gotten from the input
509 // frame. For all subsequent output frames it can be gotten from the function
510 // so long as we don't inline functions that need local contexts.
511 output_offset -= kPointerSize;
512 input_offset -= kPointerSize;
513 intptr_t context = reinterpret_cast<intptr_t>(
514 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
515 output_frame->SetFrameSlot(output_offset, context);
516 if (FLAG_trace_deopt) {
517 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context (adaptor sentinel)\n",
518 top_address + output_offset, output_offset, context);
519 }
520
521 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
522 output_offset -= kPointerSize;
523 input_offset -= kPointerSize;
524 value = reinterpret_cast<intptr_t>(function);
525 output_frame->SetFrameSlot(output_offset, value);
526 if (FLAG_trace_deopt) {
527 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n",
528 top_address + output_offset, output_offset, value);
529 }
530
531 // Number of incomming arguments.
532 output_offset -= kPointerSize;
533 input_offset -= kPointerSize;
534 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
535 output_frame->SetFrameSlot(output_offset, value);
536 if (FLAG_trace_deopt) {
537 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n",
538 top_address + output_offset, output_offset, value, height - 1);
539 }
540
541 ASSERT(0 == output_offset);
542
543 Builtins* builtins = isolate_->builtins();
544 Code* adaptor_trampoline =
545 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
546 uint32_t pc = reinterpret_cast<uint32_t>(
547 adaptor_trampoline->instruction_start() +
548 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
549 output_frame->SetPc(pc);
550 }
551
552
553 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
554 int frame_index) {
447 int node_id = iterator->Next(); 555 int node_id = iterator->Next();
448 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 556 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
449 unsigned height = iterator->Next(); 557 unsigned height = iterator->Next();
450 unsigned height_in_bytes = height * kPointerSize; 558 unsigned height_in_bytes = height * kPointerSize;
451 if (FLAG_trace_deopt) { 559 if (FLAG_trace_deopt) {
452 PrintF(" translating "); 560 PrintF(" translating ");
453 function->PrintName(); 561 function->PrintName();
454 PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes); 562 PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes);
455 } 563 }
456 564
457 // The 'fixed' part of the frame consists of the incoming parameters and 565 // The 'fixed' part of the frame consists of the incoming parameters and
458 // the part described by JavaScriptFrameConstants. 566 // the part described by JavaScriptFrameConstants.
459 unsigned fixed_frame_size = ComputeFixedSize(function); 567 unsigned fixed_frame_size = ComputeFixedSize(function);
460 unsigned input_frame_size = input_->GetFrameSize(); 568 unsigned input_frame_size = input_->GetFrameSize();
461 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 569 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
462 570
463 // Allocate and store the output frame description. 571 // Allocate and store the output frame description.
464 FrameDescription* output_frame = 572 FrameDescription* output_frame =
465 new(output_frame_size) FrameDescription(output_frame_size, function); 573 new(output_frame_size) FrameDescription(output_frame_size, function);
466 #ifdef DEBUG 574 #ifdef DEBUG
467 output_frame->SetKind(Code::FUNCTION); 575 output_frame->SetKind(Code::FUNCTION);
468 #endif 576 #endif
577 output_frame->SetType(StackFrame::JAVA_SCRIPT);
469 578
470 bool is_bottommost = (0 == frame_index); 579 bool is_bottommost = (0 == frame_index);
471 bool is_topmost = (output_count_ - 1 == frame_index); 580 bool is_topmost = (output_count_ - 1 == frame_index);
472 ASSERT(frame_index >= 0 && frame_index < output_count_); 581 ASSERT(frame_index >= 0 && frame_index < output_count_);
473 ASSERT(output_[frame_index] == NULL); 582 ASSERT(output_[frame_index] == NULL);
474 output_[frame_index] = output_frame; 583 output_[frame_index] = output_frame;
475 584
476 // The top address for the bottommost output frame can be computed from 585 // The top address for the bottommost output frame can be computed from
477 // the input frame pointer and the output frame's height. For all 586 // the input frame pointer and the output frame's height. For all
478 // subsequent output frames, it can be computed from the previous one's 587 // subsequent output frames, it can be computed from the previous one's
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 } 930 }
822 __ bind(&done); 931 __ bind(&done);
823 } 932 }
824 933
825 #undef __ 934 #undef __
826 935
827 936
828 } } // namespace v8::internal 937 } } // namespace v8::internal
829 938
830 #endif // V8_TARGET_ARCH_IA32 939 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698