OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/compiler.h" | 5 #include "src/compiler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "src/ast/ast-numbering.h" | 9 #include "src/ast/ast-numbering.h" |
10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 | 692 |
693 // If this is OSR request, OSR must be enabled by Turbofan. | 693 // If this is OSR request, OSR must be enabled by Turbofan. |
694 bool passes_osr_test = FLAG_turbo_osr || !info->is_osr(); | 694 bool passes_osr_test = FLAG_turbo_osr || !info->is_osr(); |
695 | 695 |
696 return (is_turbofanable_asm || | 696 return (is_turbofanable_asm || |
697 is_unsupported_by_crankshaft_but_turbofanable || | 697 is_unsupported_by_crankshaft_but_turbofanable || |
698 passes_turbo_filter) && | 698 passes_turbo_filter) && |
699 passes_osr_test; | 699 passes_osr_test; |
700 } | 700 } |
701 | 701 |
702 bool GetOptimizedCodeNow(CompilationInfo* info) { | 702 bool GetOptimizedCodeNow(OptimizedCompileJob* job) { |
| 703 CompilationInfo* info = job->info(); |
703 Isolate* isolate = info->isolate(); | 704 Isolate* isolate = info->isolate(); |
704 CanonicalHandleScope canonical(isolate); | |
705 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); | |
706 TRACE_EVENT0("v8", "V8.OptimizeCode"); | |
707 | |
708 bool use_turbofan = UseTurboFan(info); | |
709 base::SmartPointer<OptimizedCompileJob> job( | |
710 use_turbofan ? compiler::Pipeline::NewCompilationJob(info) | |
711 : new HCompilationJob(info)); | |
712 | 705 |
713 // Parsing is not required when optimizing from existing bytecode. | 706 // Parsing is not required when optimizing from existing bytecode. |
714 if (!use_turbofan || !info->shared_info()->HasBytecodeArray()) { | 707 if (!info->is_optimizing_from_bytecode()) { |
715 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; | 708 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
716 } else { | |
717 info->MarkAsOptimizeFromBytecode(); | |
718 } | 709 } |
719 | 710 |
720 TimerEventScope<TimerEventRecompileSynchronous> timer(isolate); | 711 TimerEventScope<TimerEventRecompileSynchronous> timer(isolate); |
721 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); | 712 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); |
722 | 713 |
723 if (job->CreateGraph() != OptimizedCompileJob::SUCCEEDED || | 714 if (job->CreateGraph() != OptimizedCompileJob::SUCCEEDED || |
724 job->OptimizeGraph() != OptimizedCompileJob::SUCCEEDED || | 715 job->OptimizeGraph() != OptimizedCompileJob::SUCCEEDED || |
725 job->GenerateCode() != OptimizedCompileJob::SUCCEEDED) { | 716 job->GenerateCode() != OptimizedCompileJob::SUCCEEDED) { |
726 if (FLAG_trace_opt) { | 717 if (FLAG_trace_opt) { |
727 PrintF("[aborted optimizing "); | 718 PrintF("[aborted optimizing "); |
728 info->closure()->ShortPrint(); | 719 info->closure()->ShortPrint(); |
729 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); | 720 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
730 } | 721 } |
731 return false; | 722 return false; |
732 } | 723 } |
733 | 724 |
734 // Success! | 725 // Success! |
735 job->RecordOptimizationStats(); | 726 job->RecordOptimizationStats(); |
736 DCHECK(!isolate->has_pending_exception()); | 727 DCHECK(!isolate->has_pending_exception()); |
737 InsertCodeIntoOptimizedCodeMap(info); | 728 InsertCodeIntoOptimizedCodeMap(info); |
738 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info); | 729 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info); |
739 return true; | 730 return true; |
740 } | 731 } |
741 | 732 |
742 bool GetOptimizedCodeLater(CompilationInfo* info) { | 733 bool GetOptimizedCodeLater(OptimizedCompileJob* job) { |
| 734 CompilationInfo* info = job->info(); |
743 Isolate* isolate = info->isolate(); | 735 Isolate* isolate = info->isolate(); |
744 CanonicalHandleScope canonical(isolate); | |
745 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); | |
746 TRACE_EVENT0("v8", "V8.OptimizeCode"); | |
747 | 736 |
748 if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) { | 737 if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) { |
749 if (FLAG_trace_concurrent_recompilation) { | 738 if (FLAG_trace_concurrent_recompilation) { |
750 PrintF(" ** Compilation queue full, will retry optimizing "); | 739 PrintF(" ** Compilation queue full, will retry optimizing "); |
751 info->closure()->ShortPrint(); | 740 info->closure()->ShortPrint(); |
752 PrintF(" later.\n"); | 741 PrintF(" later.\n"); |
753 } | 742 } |
754 return false; | 743 return false; |
755 } | 744 } |
756 | 745 |
757 bool use_turbofan = UseTurboFan(info); | |
758 base::SmartPointer<OptimizedCompileJob> job( | |
759 use_turbofan ? compiler::Pipeline::NewCompilationJob(info) | |
760 : new HCompilationJob(info)); | |
761 | |
762 // All handles below this point will be allocated in a deferred handle scope | 746 // All handles below this point will be allocated in a deferred handle scope |
763 // that is detached and handed off to the background thread when we return. | 747 // that is detached and handed off to the background thread when we return. |
764 CompilationHandleScope handle_scope(info); | 748 CompilationHandleScope handle_scope(info); |
765 | 749 |
766 // Parsing is not required when optimizing from existing bytecode. | 750 // Parsing is not required when optimizing from existing bytecode. |
767 if (!use_turbofan || !info->shared_info()->HasBytecodeArray()) { | 751 if (!info->is_optimizing_from_bytecode()) { |
768 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; | 752 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
769 } else { | |
770 info->MarkAsOptimizeFromBytecode(); | |
771 } | 753 } |
772 | 754 |
773 // Reopen handles in the new CompilationHandleScope. | 755 // Reopen handles in the new CompilationHandleScope. |
774 info->ReopenHandlesInNewHandleScope(); | 756 info->ReopenHandlesInNewHandleScope(); |
775 info->parse_info()->ReopenHandlesInNewHandleScope(); | 757 info->parse_info()->ReopenHandlesInNewHandleScope(); |
776 | 758 |
777 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); | 759 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
778 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); | 760 TRACE_EVENT0("v8", "V8.RecompileSynchronous"); |
779 | 761 |
780 if (job->CreateGraph() != OptimizedCompileJob::SUCCEEDED) return false; | 762 if (job->CreateGraph() != OptimizedCompileJob::SUCCEEDED) return false; |
781 isolate->optimizing_compile_dispatcher()->QueueForOptimization(job.get()); | 763 isolate->optimizing_compile_dispatcher()->QueueForOptimization(job); |
782 job.Detach(); // The background recompile job owns this now. | |
783 | 764 |
784 if (FLAG_trace_concurrent_recompilation) { | 765 if (FLAG_trace_concurrent_recompilation) { |
785 PrintF(" ** Queued "); | 766 PrintF(" ** Queued "); |
786 info->closure()->ShortPrint(); | 767 info->closure()->ShortPrint(); |
787 PrintF(" for concurrent optimization.\n"); | 768 PrintF(" for concurrent optimization.\n"); |
788 } | 769 } |
789 return true; | 770 return true; |
790 } | 771 } |
791 | 772 |
792 MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, | 773 MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
843 } | 824 } |
844 | 825 |
845 // Limit the number of times we try to optimize functions. | 826 // Limit the number of times we try to optimize functions. |
846 const int kMaxOptCount = | 827 const int kMaxOptCount = |
847 FLAG_deopt_every_n_times == 0 ? FLAG_max_opt_count : 1000; | 828 FLAG_deopt_every_n_times == 0 ? FLAG_max_opt_count : 1000; |
848 if (info->shared_info()->opt_count() > kMaxOptCount) { | 829 if (info->shared_info()->opt_count() > kMaxOptCount) { |
849 info->AbortOptimization(kOptimizedTooManyTimes); | 830 info->AbortOptimization(kOptimizedTooManyTimes); |
850 return MaybeHandle<Code>(); | 831 return MaybeHandle<Code>(); |
851 } | 832 } |
852 | 833 |
| 834 CanonicalHandleScope canonical(isolate); |
| 835 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); |
| 836 TRACE_EVENT0("v8", "V8.OptimizeCode"); |
| 837 |
| 838 bool use_turbofan = UseTurboFan(info.get()); |
| 839 base::SmartPointer<OptimizedCompileJob> job( |
| 840 use_turbofan ? compiler::Pipeline::NewCompilationJob(info.get()) |
| 841 : new HCompilationJob(info.get())); |
| 842 |
| 843 // TruboFan can optimize directly from existing bytecode. |
| 844 if (use_turbofan && info->shared_info()->HasBytecodeArray()) { |
| 845 info->MarkAsOptimizeFromBytecode(); |
| 846 } |
| 847 |
853 if (mode == Compiler::CONCURRENT) { | 848 if (mode == Compiler::CONCURRENT) { |
854 if (GetOptimizedCodeLater(info.get())) { | 849 if (GetOptimizedCodeLater(job.get())) { |
855 info.Detach(); // The background recompile job owns this now. | 850 info.Detach(); // The background recompile job owns this now. |
| 851 job.Detach(); // The background recompile job owns this now. |
856 return isolate->builtins()->InOptimizationQueue(); | 852 return isolate->builtins()->InOptimizationQueue(); |
857 } | 853 } |
858 } else { | 854 } else { |
859 info->set_osr_frame(osr_frame); | 855 info->set_osr_frame(osr_frame); |
860 if (GetOptimizedCodeNow(info.get())) return info->code(); | 856 if (GetOptimizedCodeNow(job.get())) return info->code(); |
861 } | 857 } |
862 | 858 |
863 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); | 859 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); |
864 return MaybeHandle<Code>(); | 860 return MaybeHandle<Code>(); |
865 } | 861 } |
866 | 862 |
867 class InterpreterActivationsFinder : public ThreadVisitor { | 863 class InterpreterActivationsFinder : public ThreadVisitor { |
868 public: | 864 public: |
869 SharedFunctionInfo* shared_; | 865 SharedFunctionInfo* shared_; |
870 bool has_activations_; | 866 bool has_activations_; |
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1808 MaybeHandle<Code> code; | 1804 MaybeHandle<Code> code; |
1809 if (cached.code != nullptr) code = handle(cached.code); | 1805 if (cached.code != nullptr) code = handle(cached.code); |
1810 Handle<Context> native_context(function->context()->native_context()); | 1806 Handle<Context> native_context(function->context()->native_context()); |
1811 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | 1807 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, |
1812 literals, BailoutId::None()); | 1808 literals, BailoutId::None()); |
1813 } | 1809 } |
1814 } | 1810 } |
1815 | 1811 |
1816 } // namespace internal | 1812 } // namespace internal |
1817 } // namespace v8 | 1813 } // namespace v8 |
OLD | NEW |