| 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 |