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

Side by Side Diff: src/deoptimizer.cc

Issue 11636046: Refactored deopt tracing and FindOptimizedCode. Fixed a bug when printing stubs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebased Created 8 years 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/deoptimizer.h ('k') | src/objects.h » ('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 2012 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
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 } 470 }
471 #endif 471 #endif
472 } 472 }
473 473
474 474
475 void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) { 475 void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) {
476 deoptimizer->DoComputeOutputFrames(); 476 deoptimizer->DoComputeOutputFrames();
477 } 477 }
478 478
479 479
480 static Code* FindOptimizedCode(Isolate* isolate, 480 bool Deoptimizer::TraceEnabledFor(BailoutType type) {
481 JSFunction* function,
482 Deoptimizer::BailoutType type,
483 Address from,
484 Code* optimized_code) {
485 switch (type) { 481 switch (type) {
486 case Deoptimizer::EAGER: 482 case EAGER:
487 ASSERT(from == NULL); 483 case LAZY:
488 return function->code(); 484 case DEBUGGER:
489 case Deoptimizer::LAZY: { 485 return FLAG_trace_deopt;
490 Code* compiled_code = 486 case OSR:
491 isolate->deoptimizer_data()->FindDeoptimizingCode(from); 487 return FLAG_trace_osr;
492 return (compiled_code == NULL)
493 ? static_cast<Code*>(isolate->heap()->FindCodeObject(from))
494 : compiled_code;
495 }
496 case Deoptimizer::OSR: {
497 // The function has already been optimized and we're transitioning
498 // from the unoptimized shared version to the optimized one in the
499 // function. The return address (from) points to unoptimized code.
500 Code* compiled_code = function->code();
501 ASSERT(compiled_code->kind() == Code::OPTIMIZED_FUNCTION);
502 ASSERT(!compiled_code->contains(from));
503 return compiled_code;
504 }
505 case Deoptimizer::DEBUGGER:
506 ASSERT(optimized_code->contains(from));
507 return optimized_code;
508 } 488 }
509 UNREACHABLE(); 489 UNREACHABLE();
510 return NULL; 490 return false;
511 } 491 }
512 492
513 493
494 const char* Deoptimizer::MessageFor(BailoutType type) {
495 switch (type) {
496 case EAGER:
497 case LAZY:
498 return "DEOPT";
499 case DEBUGGER:
500 return "DEOPT FOR DEBUGGER";
501 case OSR:
502 return "OSR";
503 }
504 UNREACHABLE();
505 return false;
506 }
507
508
514 Deoptimizer::Deoptimizer(Isolate* isolate, 509 Deoptimizer::Deoptimizer(Isolate* isolate,
515 JSFunction* function, 510 JSFunction* function,
516 BailoutType type, 511 BailoutType type,
517 unsigned bailout_id, 512 unsigned bailout_id,
518 Address from, 513 Address from,
519 int fp_to_sp_delta, 514 int fp_to_sp_delta,
520 Code* optimized_code) 515 Code* optimized_code)
521 : isolate_(isolate), 516 : isolate_(isolate),
522 function_(function), 517 function_(function),
523 bailout_id_(bailout_id), 518 bailout_id_(bailout_id),
524 bailout_type_(type), 519 bailout_type_(type),
525 from_(from), 520 from_(from),
526 fp_to_sp_delta_(fp_to_sp_delta), 521 fp_to_sp_delta_(fp_to_sp_delta),
527 has_alignment_padding_(0), 522 has_alignment_padding_(0),
528 input_(NULL), 523 input_(NULL),
529 output_count_(0), 524 output_count_(0),
530 jsframe_count_(0), 525 jsframe_count_(0),
531 output_(NULL), 526 output_(NULL),
532 deferred_arguments_objects_values_(0), 527 deferred_arguments_objects_values_(0),
533 deferred_arguments_objects_(0), 528 deferred_arguments_objects_(0),
534 deferred_heap_numbers_(0) { 529 deferred_heap_numbers_(0) {
535 if (FLAG_trace_deopt && type != OSR) { 530 // For COMPILED_STUBs called from builtins, the function pointer is a SMI
536 if (type == DEBUGGER) { 531 // indicating an internal frame.
537 PrintF("**** DEOPT FOR DEBUGGER: ");
538 } else {
539 PrintF("**** DEOPT: ");
540 }
541 function->PrintName();
542 PrintF(" at bailout #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
543 bailout_id,
544 reinterpret_cast<intptr_t>(from),
545 fp_to_sp_delta - (2 * kPointerSize));
546 } else if (FLAG_trace_osr && type == OSR) {
547 PrintF("**** OSR: ");
548 function->PrintName();
549 PrintF(" at ast id #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
550 bailout_id,
551 reinterpret_cast<intptr_t>(from),
552 fp_to_sp_delta - (2 * kPointerSize));
553 }
554 // For COMPILED_STUBs called from builtins, the function pointer
555 // is a SMI indicating an internal frame.
556 if (function->IsSmi()) { 532 if (function->IsSmi()) {
557 function = NULL; 533 function = NULL;
558 } 534 }
559 if (function != NULL && function->IsOptimized()) { 535 if (function != NULL && function->IsOptimized()) {
560 function->shared()->increment_deopt_count(); 536 function->shared()->increment_deopt_count();
561 } 537 }
562 compiled_code_ = 538 compiled_code_ = FindOptimizedCode(function, optimized_code);
563 FindOptimizedCode(isolate, function, type, from, optimized_code); 539 if (TraceEnabledFor(type)) Trace();
564 if (FLAG_trace_deopt && type == EAGER) {
565 compiled_code_->PrintDeoptLocation(bailout_id);
566 }
567 ASSERT(HEAP->allow_allocation(false)); 540 ASSERT(HEAP->allow_allocation(false));
568 unsigned size = ComputeInputFrameSize(); 541 unsigned size = ComputeInputFrameSize();
569 input_ = new(size) FrameDescription(size, function); 542 input_ = new(size) FrameDescription(size, function);
570 input_->SetFrameType(StackFrame::JAVA_SCRIPT); 543 input_->SetFrameType(StackFrame::JAVA_SCRIPT);
571 } 544 }
572 545
573 546
547 Code* Deoptimizer::FindOptimizedCode(JSFunction* function,
548 Code* optimized_code) {
549 switch (bailout_type_) {
550 case Deoptimizer::EAGER:
551 ASSERT(from_ == NULL);
552 return function->code();
553 case Deoptimizer::LAZY: {
554 Code* compiled_code =
555 isolate_->deoptimizer_data()->FindDeoptimizingCode(from_);
556 return (compiled_code == NULL)
557 ? static_cast<Code*>(isolate_->heap()->FindCodeObject(from_))
558 : compiled_code;
559 }
560 case Deoptimizer::OSR: {
561 // The function has already been optimized and we're transitioning
562 // from the unoptimized shared version to the optimized one in the
563 // function. The return address (from_) points to unoptimized code.
564 Code* compiled_code = function->code();
565 ASSERT(compiled_code->kind() == Code::OPTIMIZED_FUNCTION);
566 ASSERT(!compiled_code->contains(from_));
567 return compiled_code;
568 }
569 case Deoptimizer::DEBUGGER:
570 ASSERT(optimized_code->contains(from_));
571 return optimized_code;
572 }
573 UNREACHABLE();
574 return NULL;
575 }
576
577
578 void Deoptimizer::Trace() {
579 PrintF("**** %s: ", Deoptimizer::MessageFor(bailout_type_));
580 PrintFunctionName();
581 PrintF(" at id #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
582 bailout_id_,
583 reinterpret_cast<intptr_t>(from_),
584 fp_to_sp_delta_ - (2 * kPointerSize));
585 if (bailout_type_ == EAGER) compiled_code_->PrintDeoptLocation(bailout_id_);
586 }
587
588
589 void Deoptimizer::PrintFunctionName() {
590 if (function_->IsJSFunction()) {
591 function_->PrintName();
592 } else {
593 PrintF("%s", Code::Kind2String(compiled_code_->kind()));
594 }
595 }
596
597
574 Deoptimizer::~Deoptimizer() { 598 Deoptimizer::~Deoptimizer() {
575 ASSERT(input_ == NULL && output_ == NULL); 599 ASSERT(input_ == NULL && output_ == NULL);
576 } 600 }
577 601
578 602
579 void Deoptimizer::DeleteFrameDescriptions() { 603 void Deoptimizer::DeleteFrameDescriptions() {
580 delete input_; 604 delete input_;
581 for (int i = 0; i < output_count_; ++i) { 605 for (int i = 0; i < output_count_; ++i) {
582 if (output_[i] != input_) delete output_[i]; 606 if (output_[i] != input_) delete output_[i];
583 } 607 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 DoComputeOsrOutputFrame(); 698 DoComputeOsrOutputFrame();
675 return; 699 return;
676 } 700 }
677 701
678 // Print some helpful diagnostic information. 702 // Print some helpful diagnostic information.
679 int64_t start = OS::Ticks(); 703 int64_t start = OS::Ticks();
680 if (FLAG_trace_deopt) { 704 if (FLAG_trace_deopt) {
681 PrintF("[deoptimizing%s: begin 0x%08" V8PRIxPTR " ", 705 PrintF("[deoptimizing%s: begin 0x%08" V8PRIxPTR " ",
682 (bailout_type_ == LAZY ? " (lazy)" : ""), 706 (bailout_type_ == LAZY ? " (lazy)" : ""),
683 reinterpret_cast<intptr_t>(function_)); 707 reinterpret_cast<intptr_t>(function_));
684 function_->PrintName(); 708 PrintFunctionName();
685 PrintF(" @%d]\n", bailout_id_); 709 PrintF(" @%d]\n", bailout_id_);
686 } 710 }
687 711
688 // Determine basic deoptimization information. The optimized frame is 712 // Determine basic deoptimization information. The optimized frame is
689 // described by the input data. 713 // described by the input data.
690 DeoptimizationInputData* input_data = 714 DeoptimizationInputData* input_data =
691 DeoptimizationInputData::cast(compiled_code_->deoptimization_data()); 715 DeoptimizationInputData::cast(compiled_code_->deoptimization_data());
692 BailoutId node_id = input_data->AstId(bailout_id_); 716 BailoutId node_id = input_data->AstId(bailout_id_);
693 ByteArray* translations = input_data->TranslationByteArray(); 717 ByteArray* translations = input_data->TranslationByteArray();
694 unsigned translation_index = 718 unsigned translation_index =
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 } 778 }
755 } 779 }
756 780
757 // Print some helpful diagnostic information. 781 // Print some helpful diagnostic information.
758 if (FLAG_trace_deopt) { 782 if (FLAG_trace_deopt) {
759 double ms = static_cast<double>(OS::Ticks() - start) / 1000; 783 double ms = static_cast<double>(OS::Ticks() - start) / 1000;
760 int index = output_count_ - 1; // Index of the topmost frame. 784 int index = output_count_ - 1; // Index of the topmost frame.
761 JSFunction* function = output_[index]->GetFunction(); 785 JSFunction* function = output_[index]->GetFunction();
762 PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ", 786 PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ",
763 reinterpret_cast<intptr_t>(function)); 787 reinterpret_cast<intptr_t>(function));
764 function->PrintName(); 788 if (function != NULL) function->PrintName();
765 PrintF(" => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s," 789 PrintF(" => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
766 " took %0.3f ms]\n", 790 " took %0.3f ms]\n",
767 node_id.ToInt(), 791 node_id.ToInt(),
768 output_[index]->GetPc(), 792 output_[index]->GetPc(),
769 FullCodeGenerator::State2String( 793 FullCodeGenerator::State2String(
770 static_cast<FullCodeGenerator::State>( 794 static_cast<FullCodeGenerator::State>(
771 output_[index]->GetState()->value())), 795 output_[index]->GetState()->value())),
772 has_alignment_padding_ ? "with padding" : "no padding", 796 has_alignment_padding_ ? "with padding" : "no padding",
773 ms); 797 ms);
774 } 798 }
(...skipping 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after
2087 2111
2088 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { 2112 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
2089 v->VisitPointer(BitCast<Object**>(&function_)); 2113 v->VisitPointer(BitCast<Object**>(&function_));
2090 v->VisitPointers(parameters_, parameters_ + parameters_count_); 2114 v->VisitPointers(parameters_, parameters_ + parameters_count_);
2091 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); 2115 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
2092 } 2116 }
2093 2117
2094 #endif // ENABLE_DEBUGGER_SUPPORT 2118 #endif // ENABLE_DEBUGGER_SUPPORT
2095 2119
2096 } } // namespace v8::internal 2120 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698