OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/disasm.h" | 10 #include "src/disasm.h" |
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 if (bailout_type_ == Deoptimizer::SOFT) { | 585 if (bailout_type_ == Deoptimizer::SOFT) { |
586 isolate->counters()->soft_deopts_executed()->Increment(); | 586 isolate->counters()->soft_deopts_executed()->Increment(); |
587 // Soft deopts shouldn't count against the overall re-optimization count | 587 // Soft deopts shouldn't count against the overall re-optimization count |
588 // that can eventually lead to disabling optimization for a function. | 588 // that can eventually lead to disabling optimization for a function. |
589 int opt_count = function->shared()->opt_count(); | 589 int opt_count = function->shared()->opt_count(); |
590 if (opt_count > 0) opt_count--; | 590 if (opt_count > 0) opt_count--; |
591 function->shared()->set_opt_count(opt_count); | 591 function->shared()->set_opt_count(opt_count); |
592 } | 592 } |
593 } | 593 } |
594 compiled_code_ = FindOptimizedCode(function, optimized_code); | 594 compiled_code_ = FindOptimizedCode(function, optimized_code); |
595 | |
596 #if DEBUG | 595 #if DEBUG |
597 DCHECK(compiled_code_ != NULL); | 596 DCHECK(compiled_code_ != NULL); |
598 if (type == EAGER || type == SOFT || type == LAZY) { | 597 if (type == EAGER || type == SOFT || type == LAZY) { |
599 DCHECK(compiled_code_->kind() != Code::FUNCTION); | 598 DCHECK(compiled_code_->kind() != Code::FUNCTION); |
600 } | 599 } |
601 #endif | 600 #endif |
602 | 601 |
603 StackFrame::Type frame_type = function == NULL | 602 StackFrame::Type frame_type = function == NULL |
604 ? StackFrame::STUB | 603 ? StackFrame::STUB |
605 : StackFrame::JAVA_SCRIPT; | 604 : StackFrame::JAVA_SCRIPT; |
606 trace_scope_ = TraceEnabledFor(type, frame_type) ? | 605 trace_scope_ = TraceEnabledFor(type, frame_type) ? |
607 new CodeTracer::Scope(isolate->GetCodeTracer()) : NULL; | 606 new CodeTracer::Scope(isolate->GetCodeTracer()) : NULL; |
608 #ifdef DEBUG | 607 #ifdef DEBUG |
609 CHECK(AllowHeapAllocation::IsAllowed()); | 608 CHECK(AllowHeapAllocation::IsAllowed()); |
610 disallow_heap_allocation_ = new DisallowHeapAllocation(); | 609 disallow_heap_allocation_ = new DisallowHeapAllocation(); |
611 #endif // DEBUG | 610 #endif // DEBUG |
| 611 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { |
| 612 PROFILE(isolate_, CodeDeoptEvent(compiled_code_, bailout_id_, from_, |
| 613 fp_to_sp_delta_)); |
| 614 } |
612 unsigned size = ComputeInputFrameSize(); | 615 unsigned size = ComputeInputFrameSize(); |
613 input_ = new(size) FrameDescription(size, function); | 616 input_ = new(size) FrameDescription(size, function); |
614 input_->SetFrameType(frame_type); | 617 input_->SetFrameType(frame_type); |
615 } | 618 } |
616 | 619 |
617 | 620 |
618 Code* Deoptimizer::FindOptimizedCode(JSFunction* function, | 621 Code* Deoptimizer::FindOptimizedCode(JSFunction* function, |
619 Code* optimized_code) { | 622 Code* optimized_code) { |
620 switch (bailout_type_) { | 623 switch (bailout_type_) { |
621 case Deoptimizer::SOFT: | 624 case Deoptimizer::SOFT: |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 } | 743 } |
741 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); | 744 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); |
742 } | 745 } |
743 return length; | 746 return length; |
744 } | 747 } |
745 | 748 |
746 | 749 |
747 // We rely on this function not causing a GC. It is called from generated code | 750 // We rely on this function not causing a GC. It is called from generated code |
748 // without having a real stack frame in place. | 751 // without having a real stack frame in place. |
749 void Deoptimizer::DoComputeOutputFrames() { | 752 void Deoptimizer::DoComputeOutputFrames() { |
750 // Print some helpful diagnostic information. | |
751 if (FLAG_log_timer_events && | |
752 compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { | |
753 LOG(isolate(), CodeDeoptEvent(compiled_code_)); | |
754 } | |
755 base::ElapsedTimer timer; | 753 base::ElapsedTimer timer; |
756 | 754 |
757 // Determine basic deoptimization information. The optimized frame is | 755 // Determine basic deoptimization information. The optimized frame is |
758 // described by the input data. | 756 // described by the input data. |
759 DeoptimizationInputData* input_data = | 757 DeoptimizationInputData* input_data = |
760 DeoptimizationInputData::cast(compiled_code_->deoptimization_data()); | 758 DeoptimizationInputData::cast(compiled_code_->deoptimization_data()); |
761 | 759 |
762 if (trace_scope_ != NULL) { | 760 if (trace_scope_ != NULL) { |
763 timer.Start(); | 761 timer.Start(); |
764 PrintF(trace_scope_->file(), "[deoptimizing (DEOPT %s): begin ", | 762 PrintF(trace_scope_->file(), "[deoptimizing (DEOPT %s): begin ", |
(...skipping 2865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3630 | 3628 |
3631 | 3629 |
3632 const char* Deoptimizer::GetDeoptReason(DeoptReason deopt_reason) { | 3630 const char* Deoptimizer::GetDeoptReason(DeoptReason deopt_reason) { |
3633 DCHECK(deopt_reason < kLastDeoptReason); | 3631 DCHECK(deopt_reason < kLastDeoptReason); |
3634 #define DEOPT_MESSAGES_TEXTS(C, T) T, | 3632 #define DEOPT_MESSAGES_TEXTS(C, T) T, |
3635 static const char* deopt_messages_[] = { | 3633 static const char* deopt_messages_[] = { |
3636 DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_TEXTS)}; | 3634 DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_TEXTS)}; |
3637 #undef DEOPT_MESSAGES_TEXTS | 3635 #undef DEOPT_MESSAGES_TEXTS |
3638 return deopt_messages_[deopt_reason]; | 3636 return deopt_messages_[deopt_reason]; |
3639 } | 3637 } |
| 3638 |
| 3639 |
| 3640 Deoptimizer::DeoptInfo Deoptimizer::GetDeoptInfo(Code* code, int bailout_id) { |
| 3641 int last_position = 0; |
| 3642 Isolate* isolate = code->GetIsolate(); |
| 3643 Deoptimizer::DeoptReason last_reason = Deoptimizer::kNoReason; |
| 3644 int mask = RelocInfo::ModeMask(RelocInfo::DEOPT_REASON) | |
| 3645 RelocInfo::ModeMask(RelocInfo::POSITION) | |
| 3646 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); |
| 3647 for (RelocIterator it(code, mask); !it.done(); it.next()) { |
| 3648 RelocInfo* info = it.rinfo(); |
| 3649 if (info->rmode() == RelocInfo::POSITION) { |
| 3650 last_position = static_cast<int>(info->data()); |
| 3651 } else if (info->rmode() == RelocInfo::DEOPT_REASON) { |
| 3652 last_reason = static_cast<Deoptimizer::DeoptReason>(info->data()); |
| 3653 } else if (last_reason != Deoptimizer::kNoReason) { |
| 3654 if ((bailout_id == |
| 3655 Deoptimizer::GetDeoptimizationId(isolate, info->target_address(), |
| 3656 Deoptimizer::EAGER)) || |
| 3657 (bailout_id == |
| 3658 Deoptimizer::GetDeoptimizationId(isolate, info->target_address(), |
| 3659 Deoptimizer::SOFT)) || |
| 3660 (bailout_id == |
| 3661 Deoptimizer::GetDeoptimizationId(isolate, info->target_address(), |
| 3662 Deoptimizer::LAZY))) { |
| 3663 CHECK(RelocInfo::IsRuntimeEntry(info->rmode())); |
| 3664 return DeoptInfo(last_position, NULL, last_reason); |
| 3665 } |
| 3666 } |
| 3667 } |
| 3668 return DeoptInfo(0, NULL, Deoptimizer::kNoReason); |
| 3669 } |
3640 } } // namespace v8::internal | 3670 } } // namespace v8::internal |
OLD | NEW |