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

Side by Side Diff: src/compiler.cc

Issue 1903273004: [compiler] Add baseline tier to compilation pipeline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments. Created 4 years, 8 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
« no previous file with comments | « src/compiler.h ('k') | src/ia32/builtins-ia32.cc » ('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 // 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"
11 #include "src/ast/scopeinfo.h" 11 #include "src/ast/scopeinfo.h"
12 #include "src/ast/scopes.h" 12 #include "src/ast/scopes.h"
13 #include "src/bootstrapper.h" 13 #include "src/bootstrapper.h"
14 #include "src/codegen.h" 14 #include "src/codegen.h"
15 #include "src/compilation-cache.h" 15 #include "src/compilation-cache.h"
16 #include "src/compiler/pipeline.h" 16 #include "src/compiler/pipeline.h"
17 #include "src/crankshaft/hydrogen.h" 17 #include "src/crankshaft/hydrogen.h"
18 #include "src/debug/debug.h" 18 #include "src/debug/debug.h"
19 #include "src/debug/liveedit.h" 19 #include "src/debug/liveedit.h"
20 #include "src/deoptimizer.h" 20 #include "src/deoptimizer.h"
21 #include "src/frames-inl.h"
21 #include "src/full-codegen/full-codegen.h" 22 #include "src/full-codegen/full-codegen.h"
22 #include "src/interpreter/interpreter.h" 23 #include "src/interpreter/interpreter.h"
23 #include "src/isolate-inl.h" 24 #include "src/isolate-inl.h"
24 #include "src/log-inl.h" 25 #include "src/log-inl.h"
25 #include "src/messages.h" 26 #include "src/messages.h"
26 #include "src/parsing/parser.h" 27 #include "src/parsing/parser.h"
27 #include "src/parsing/rewriter.h" 28 #include "src/parsing/rewriter.h"
28 #include "src/parsing/scanner-character-streams.h" 29 #include "src/parsing/scanner-character-streams.h"
29 #include "src/profiler/cpu-profiler.h" 30 #include "src/profiler/cpu-profiler.h"
30 #include "src/runtime-profiler.h" 31 #include "src/runtime-profiler.h"
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 VMState<COMPILER> state(info->isolate()); 584 VMState<COMPILER> state(info->isolate());
584 PostponeInterruptsScope postpone(info->isolate()); 585 PostponeInterruptsScope postpone(info->isolate());
585 586
586 // Parse and update CompilationInfo with the results. 587 // Parse and update CompilationInfo with the results.
587 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); 588 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>();
588 Handle<SharedFunctionInfo> shared = info->shared_info(); 589 Handle<SharedFunctionInfo> shared = info->shared_info();
589 DCHECK_EQ(shared->language_mode(), info->literal()->language_mode()); 590 DCHECK_EQ(shared->language_mode(), info->literal()->language_mode());
590 591
591 // Compile either unoptimized code or bytecode for the interpreter. 592 // Compile either unoptimized code or bytecode for the interpreter.
592 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); 593 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>();
593 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info);
594 594
595 // Update the shared function info with the scope info. 595 // Update the shared function info with the scope info.
596 InstallSharedScopeInfo(info, shared); 596 InstallSharedScopeInfo(info, shared);
597 597
598 // Install compilation result on the shared function info 598 // Install compilation result on the shared function info
599 InstallSharedCompilationResult(info, shared); 599 InstallSharedCompilationResult(info, shared);
600 600
601 // Record the function compilation event.
602 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info);
603
601 return info->code(); 604 return info->code();
602 } 605 }
603 606
604 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( 607 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap(
605 Handle<JSFunction> function, BailoutId osr_ast_id) { 608 Handle<JSFunction> function, BailoutId osr_ast_id) {
606 Handle<SharedFunctionInfo> shared(function->shared()); 609 Handle<SharedFunctionInfo> shared(function->shared());
607 DisallowHeapAllocation no_gc; 610 DisallowHeapAllocation no_gc;
608 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( 611 CodeAndLiterals cached = shared->SearchOptimizedCodeMap(
609 function->context()->native_context(), osr_ast_id); 612 function->context()->native_context(), osr_ast_id);
610 if (cached.code != nullptr) { 613 if (cached.code != nullptr) {
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 PrintF("[found optimized code for "); 801 PrintF("[found optimized code for ");
799 function->ShortPrint(); 802 function->ShortPrint();
800 if (!osr_ast_id.IsNone()) { 803 if (!osr_ast_id.IsNone()) {
801 PrintF(" at OSR AST id %d", osr_ast_id.ToInt()); 804 PrintF(" at OSR AST id %d", osr_ast_id.ToInt());
802 } 805 }
803 PrintF("]\n"); 806 PrintF("]\n");
804 } 807 }
805 return cached_code; 808 return cached_code;
806 } 809 }
807 810
808 DCHECK(AllowCompilation::IsAllowed(isolate)); 811 // Reset profiler ticks, function is no longer considered hot.
809
810 if (shared->is_compiled()) { 812 if (shared->is_compiled()) {
811 shared->code()->set_profiler_ticks(0); 813 shared->code()->set_profiler_ticks(0);
812 } 814 }
813 815
814 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing 816 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing
815 // an eval scope and hence would fail at parsing the eval source again. 817 // an eval scope and hence would fail at parsing the eval source again.
816 if (shared->disable_optimization_reason() == kEval) { 818 if (shared->disable_optimization_reason() == kEval) {
817 return MaybeHandle<Code>(); 819 return MaybeHandle<Code>();
818 } 820 }
819 821
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 } 855 }
854 } else { 856 } else {
855 info->set_osr_frame(osr_frame); 857 info->set_osr_frame(osr_frame);
856 if (GetOptimizedCodeNow(info.get())) return info->code(); 858 if (GetOptimizedCodeNow(info.get())) return info->code();
857 } 859 }
858 860
859 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); 861 if (isolate->has_pending_exception()) isolate->clear_pending_exception();
860 return MaybeHandle<Code>(); 862 return MaybeHandle<Code>();
861 } 863 }
862 864
865 class InterpreterActivationsFinder : public ThreadVisitor {
866 public:
867 SharedFunctionInfo* shared_;
868 bool has_activations_;
869
870 explicit InterpreterActivationsFinder(SharedFunctionInfo* shared)
871 : shared_(shared), has_activations_(false) {}
872
873 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
874 JavaScriptFrameIterator it(isolate, top);
875 for (; !it.done() && !has_activations_; it.Advance()) {
876 JavaScriptFrame* frame = it.frame();
877 if (!frame->is_interpreted()) continue;
878 if (frame->function()->shared() == shared_) has_activations_ = true;
879 }
880 }
881 };
882
883 bool HasInterpreterActivations(Isolate* isolate, SharedFunctionInfo* shared) {
884 InterpreterActivationsFinder activations_finder(shared);
885 activations_finder.VisitThread(isolate, isolate->thread_local_top());
886 isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
887 return activations_finder.has_activations_;
888 }
889
890 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) {
891 Isolate* isolate = function->GetIsolate();
892 VMState<COMPILER> state(isolate);
893 PostponeInterruptsScope postpone(isolate);
894 CompilationInfoWithZone info(function);
895
896 // Reset profiler ticks, function is no longer considered hot.
897 if (function->shared()->HasBytecodeArray()) {
898 function->shared()->set_profiler_ticks(0);
899 }
900
901 // We do not switch to baseline code when the debugger might have created a
902 // copy of the bytecode with break slots to be able to set break points.
903 if (function->shared()->HasDebugInfo()) {
904 return MaybeHandle<Code>();
905 }
906
907 // TODO(4280): For now we do not switch generators to baseline code because
908 // there might be suspended activations stored in generator objects on the
909 // heap. We could eventually go directly to TurboFan in this case.
910 if (function->shared()->is_generator()) {
911 return MaybeHandle<Code>();
912 }
913
914 // TODO(4280): For now we disable switching to baseline code in the presence
915 // of interpreter activations of the given function. The reasons are:
916 // 1) The debugger assumes each function is either full-code or bytecode.
917 // 2) The underlying bytecode is cleared below, breaking stack unwinding.
918 if (HasInterpreterActivations(isolate, function->shared())) {
919 if (FLAG_trace_opt) {
920 OFStream os(stdout);
921 os << "[unable to switch " << Brief(*function) << " due to activations]"
922 << std::endl;
923 }
924 return MaybeHandle<Code>();
925 }
926
927 if (FLAG_trace_opt) {
928 OFStream os(stdout);
929 os << "[switching method " << Brief(*function) << " to baseline code]"
930 << std::endl;
931 }
932
933 // Parse and update CompilationInfo with the results.
934 if (!Parser::ParseStatic(info.parse_info())) return MaybeHandle<Code>();
935 Handle<SharedFunctionInfo> shared = info.shared_info();
936 DCHECK_EQ(shared->language_mode(), info.literal()->language_mode());
937
938 // Compile baseline code using the full code generator.
939 if (!Compiler::Analyze(info.parse_info()) ||
940 !FullCodeGenerator::MakeCode(&info)) {
941 if (!isolate->has_pending_exception()) isolate->StackOverflow();
942 return MaybeHandle<Code>();
943 }
944
945 // TODO(4280): For now we play it safe and remove the bytecode array when we
946 // switch to baseline code. We might consider keeping around the bytecode so
947 // that it can be used as the "source of truth" eventually.
948 shared->ClearBytecodeArray();
949
950 // Update the shared function info with the scope info.
951 InstallSharedScopeInfo(&info, shared);
952
953 // Install compilation result on the shared function info
954 InstallSharedCompilationResult(&info, shared);
955
956 // Record the function compilation event.
957 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &info);
958
959 return info.code();
960 }
961
863 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { 962 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) {
864 Isolate* isolate = function->GetIsolate(); 963 Isolate* isolate = function->GetIsolate();
865 DCHECK(!isolate->has_pending_exception()); 964 DCHECK(!isolate->has_pending_exception());
866 DCHECK(!function->is_compiled()); 965 DCHECK(!function->is_compiled());
867 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); 966 TimerEventScope<TimerEventCompileCode> compile_timer(isolate);
868 TRACE_EVENT0("v8", "V8.CompileCode"); 967 TRACE_EVENT0("v8", "V8.CompileCode");
869 AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy()); 968 AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy());
870 969
871 if (FLAG_turbo_cache_shared_code) { 970 if (FLAG_turbo_cache_shared_code) {
872 Handle<Code> cached_code; 971 Handle<Code> cached_code;
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 // Install code on closure. 1181 // Install code on closure.
1083 function->ReplaceCode(*code); 1182 function->ReplaceCode(*code);
1084 1183
1085 // Check postconditions on success. 1184 // Check postconditions on success.
1086 DCHECK(!isolate->has_pending_exception()); 1185 DCHECK(!isolate->has_pending_exception());
1087 DCHECK(function->shared()->is_compiled()); 1186 DCHECK(function->shared()->is_compiled());
1088 DCHECK(function->is_compiled()); 1187 DCHECK(function->is_compiled());
1089 return true; 1188 return true;
1090 } 1189 }
1091 1190
1191 bool Compiler::CompileBaseline(Handle<JSFunction> function) {
1192 Isolate* isolate = function->GetIsolate();
1193 DCHECK(AllowCompilation::IsAllowed(isolate));
1194
1195 // Start a compilation.
1196 Handle<Code> code;
1197 if (!GetBaselineCode(function).ToHandle(&code)) {
1198 // Baseline generation failed, get unoptimized code.
1199 DCHECK(function->shared()->is_compiled());
1200 code = handle(function->shared()->code());
1201 isolate->clear_pending_exception();
1202 }
1203
1204 // Install code on closure.
1205 function->ReplaceCode(*code);
1206
1207 // Check postconditions on success.
1208 DCHECK(!isolate->has_pending_exception());
1209 DCHECK(function->shared()->is_compiled());
1210 DCHECK(function->is_compiled());
1211 return true;
1212 }
1213
1092 bool Compiler::CompileOptimized(Handle<JSFunction> function, 1214 bool Compiler::CompileOptimized(Handle<JSFunction> function,
1093 ConcurrencyMode mode) { 1215 ConcurrencyMode mode) {
1094 if (function->IsOptimized()) return true; 1216 if (function->IsOptimized()) return true;
1095 Isolate* isolate = function->GetIsolate(); 1217 Isolate* isolate = function->GetIsolate();
1096 DCHECK(AllowCompilation::IsAllowed(isolate)); 1218 DCHECK(AllowCompilation::IsAllowed(isolate));
1097 1219
1098 // Start a compilation. 1220 // Start a compilation.
1099 Handle<Code> code; 1221 Handle<Code> code;
1100 if (!GetOptimizedCode(function, mode).ToHandle(&code)) { 1222 if (!GetOptimizedCode(function, mode).ToHandle(&code)) {
1101 // Optimization failed, get unoptimized code. 1223 // Optimization failed, get unoptimized code.
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 MaybeHandle<Code> code; 1799 MaybeHandle<Code> code;
1678 if (cached.code != nullptr) code = handle(cached.code); 1800 if (cached.code != nullptr) code = handle(cached.code);
1679 Handle<Context> native_context(function->context()->native_context()); 1801 Handle<Context> native_context(function->context()->native_context());
1680 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, 1802 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code,
1681 literals, BailoutId::None()); 1803 literals, BailoutId::None());
1682 } 1804 }
1683 } 1805 }
1684 1806
1685 } // namespace internal 1807 } // namespace internal
1686 } // namespace v8 1808 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/ia32/builtins-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698