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

Side by Side Diff: src/compiler.cc

Issue 151603004: A64: Synchronize with r16587. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/compiler.h ('k') | src/contexts.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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 #include "vm-state-inl.h" 51 #include "vm-state-inl.h"
52 52
53 namespace v8 { 53 namespace v8 {
54 namespace internal { 54 namespace internal {
55 55
56 56
57 CompilationInfo::CompilationInfo(Handle<Script> script, 57 CompilationInfo::CompilationInfo(Handle<Script> script,
58 Zone* zone) 58 Zone* zone)
59 : flags_(LanguageModeField::encode(CLASSIC_MODE)), 59 : flags_(LanguageModeField::encode(CLASSIC_MODE)),
60 script_(script), 60 script_(script),
61 osr_ast_id_(BailoutId::None()) { 61 osr_ast_id_(BailoutId::None()),
62 osr_pc_offset_(0) {
62 Initialize(script->GetIsolate(), BASE, zone); 63 Initialize(script->GetIsolate(), BASE, zone);
63 } 64 }
64 65
65 66
66 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, 67 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info,
67 Zone* zone) 68 Zone* zone)
68 : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)), 69 : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)),
69 shared_info_(shared_info), 70 shared_info_(shared_info),
70 script_(Handle<Script>(Script::cast(shared_info->script()))), 71 script_(Handle<Script>(Script::cast(shared_info->script()))),
71 osr_ast_id_(BailoutId::None()) { 72 osr_ast_id_(BailoutId::None()),
73 osr_pc_offset_(0) {
72 Initialize(script_->GetIsolate(), BASE, zone); 74 Initialize(script_->GetIsolate(), BASE, zone);
73 } 75 }
74 76
75 77
76 CompilationInfo::CompilationInfo(Handle<JSFunction> closure, 78 CompilationInfo::CompilationInfo(Handle<JSFunction> closure,
77 Zone* zone) 79 Zone* zone)
78 : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)), 80 : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)),
79 closure_(closure), 81 closure_(closure),
80 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), 82 shared_info_(Handle<SharedFunctionInfo>(closure->shared())),
81 script_(Handle<Script>(Script::cast(shared_info_->script()))), 83 script_(Handle<Script>(Script::cast(shared_info_->script()))),
82 context_(closure->context()), 84 context_(closure->context()),
83 osr_ast_id_(BailoutId::None()) { 85 osr_ast_id_(BailoutId::None()),
86 osr_pc_offset_(0) {
84 Initialize(script_->GetIsolate(), BASE, zone); 87 Initialize(script_->GetIsolate(), BASE, zone);
85 } 88 }
86 89
87 90
88 CompilationInfo::CompilationInfo(HydrogenCodeStub* stub, 91 CompilationInfo::CompilationInfo(HydrogenCodeStub* stub,
89 Isolate* isolate, 92 Isolate* isolate,
90 Zone* zone) 93 Zone* zone)
91 : flags_(LanguageModeField::encode(CLASSIC_MODE) | 94 : flags_(LanguageModeField::encode(CLASSIC_MODE) |
92 IsLazy::encode(true)), 95 IsLazy::encode(true)),
93 osr_ast_id_(BailoutId::None()) { 96 osr_ast_id_(BailoutId::None()),
97 osr_pc_offset_(0) {
94 Initialize(isolate, STUB, zone); 98 Initialize(isolate, STUB, zone);
95 code_stub_ = stub; 99 code_stub_ = stub;
96 } 100 }
97 101
98 102
99 void CompilationInfo::Initialize(Isolate* isolate, 103 void CompilationInfo::Initialize(Isolate* isolate,
100 Mode mode, 104 Mode mode,
101 Zone* zone) { 105 Zone* zone) {
102 isolate_ = isolate; 106 isolate_ = isolate;
103 function_ = NULL; 107 function_ = NULL;
104 scope_ = NULL; 108 scope_ = NULL;
105 global_scope_ = NULL; 109 global_scope_ = NULL;
106 extension_ = NULL; 110 extension_ = NULL;
107 pre_parse_data_ = NULL; 111 pre_parse_data_ = NULL;
108 zone_ = zone; 112 zone_ = zone;
109 deferred_handles_ = NULL; 113 deferred_handles_ = NULL;
110 code_stub_ = NULL; 114 code_stub_ = NULL;
111 prologue_offset_ = kPrologueOffsetNotSet; 115 prologue_offset_ = kPrologueOffsetNotSet;
112 opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count(); 116 opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count();
113 no_frame_ranges_ = isolate->cpu_profiler()->is_profiling() 117 no_frame_ranges_ = isolate->cpu_profiler()->is_profiling()
114 ? new List<OffsetRange>(2) : NULL; 118 ? new List<OffsetRange>(2) : NULL;
115 for (int i = 0; i < DependentCode::kGroupCount; i++) { 119 for (int i = 0; i < DependentCode::kGroupCount; i++) {
116 dependencies_[i] = NULL; 120 dependencies_[i] = NULL;
117 } 121 }
118 if (mode == STUB) { 122 if (mode == STUB) {
119 mode_ = STUB; 123 mode_ = STUB;
120 return; 124 return;
121 } 125 }
122 mode_ = V8::UseCrankshaft() ? mode : NONOPT; 126 mode_ = isolate->use_crankshaft() ? mode : NONOPT;
123 abort_due_to_dependency_ = false; 127 abort_due_to_dependency_ = false;
124 if (script_->type()->value() == Script::TYPE_NATIVE) { 128 if (script_->type()->value() == Script::TYPE_NATIVE) {
125 MarkAsNative(); 129 MarkAsNative();
126 } 130 }
127 if (!shared_info_.is_null()) { 131 if (!shared_info_.is_null()) {
128 ASSERT(language_mode() == CLASSIC_MODE); 132 ASSERT(language_mode() == CLASSIC_MODE);
129 SetLanguageMode(shared_info_->language_mode()); 133 SetLanguageMode(shared_info_->language_mode());
130 } 134 }
131 set_bailout_reason(kUnknown); 135 set_bailout_reason(kUnknown);
132 } 136 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 } 223 }
220 224
221 225
222 // Primitive functions are unlikely to be picked up by the stack-walking 226 // Primitive functions are unlikely to be picked up by the stack-walking
223 // profiler, so they trigger their own optimization when they're called 227 // profiler, so they trigger their own optimization when they're called
224 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. 228 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time.
225 bool CompilationInfo::ShouldSelfOptimize() { 229 bool CompilationInfo::ShouldSelfOptimize() {
226 return FLAG_self_optimization && 230 return FLAG_self_optimization &&
227 FLAG_crankshaft && 231 FLAG_crankshaft &&
228 !function()->flags()->Contains(kDontSelfOptimize) && 232 !function()->flags()->Contains(kDontSelfOptimize) &&
229 !function()->flags()->Contains(kDontOptimize) && 233 !function()->dont_optimize() &&
230 function()->scope()->AllowsLazyCompilation() && 234 function()->scope()->AllowsLazyCompilation() &&
231 (shared_info().is_null() || !shared_info()->optimization_disabled()); 235 (shared_info().is_null() || !shared_info()->optimization_disabled());
232 } 236 }
233 237
234 238
235 // Determine whether to use the full compiler for all code. If the flag 239 // Determine whether to use the full compiler for all code. If the flag
236 // --always-full-compiler is specified this is the case. For the virtual frame 240 // --always-full-compiler is specified this is the case. For the virtual frame
237 // based compiler the full compiler is also used if a debugger is connected, as 241 // based compiler the full compiler is also used if a debugger is connected, as
238 // the code from the full compiler supports mode precise break points. For the 242 // the code from the full compiler supports mode precise break points. For the
239 // crankshaft adaptive compiler debugging the optimized code is not possible at 243 // crankshaft adaptive compiler debugging the optimized code is not possible at
240 // all. However crankshaft support recompilation of functions, so in this case 244 // all. However crankshaft support recompilation of functions, so in this case
241 // the full compiler need not be be used if a debugger is attached, but only if 245 // the full compiler need not be be used if a debugger is attached, but only if
242 // break points has actually been set. 246 // break points has actually been set.
243 static bool IsDebuggerActive(Isolate* isolate) { 247 static bool IsDebuggerActive(Isolate* isolate) {
244 #ifdef ENABLE_DEBUGGER_SUPPORT 248 #ifdef ENABLE_DEBUGGER_SUPPORT
245 return V8::UseCrankshaft() ? 249 return isolate->use_crankshaft() ?
246 isolate->debug()->has_break_points() : 250 isolate->debug()->has_break_points() :
247 isolate->debugger()->IsDebuggerActive(); 251 isolate->debugger()->IsDebuggerActive();
248 #else 252 #else
249 return false; 253 return false;
250 #endif 254 #endif
251 } 255 }
252 256
253 257
254 static bool AlwaysFullCompiler(Isolate* isolate) { 258 static bool AlwaysFullCompiler(Isolate* isolate) {
255 return FLAG_always_full_compiler || IsDebuggerActive(isolate); 259 return FLAG_always_full_compiler || IsDebuggerActive(isolate);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 if (status != OptimizingCompiler::SUCCEEDED) { 307 if (status != OptimizingCompiler::SUCCEEDED) {
304 status = compiler.AbortOptimization(); 308 status = compiler.AbortOptimization();
305 return status != OptimizingCompiler::FAILED; 309 return status != OptimizingCompiler::FAILED;
306 } 310 }
307 status = compiler.GenerateAndInstallCode(); 311 status = compiler.GenerateAndInstallCode();
308 return status != OptimizingCompiler::FAILED; 312 return status != OptimizingCompiler::FAILED;
309 } 313 }
310 314
311 315
312 OptimizingCompiler::Status OptimizingCompiler::CreateGraph() { 316 OptimizingCompiler::Status OptimizingCompiler::CreateGraph() {
313 ASSERT(V8::UseCrankshaft()); 317 ASSERT(isolate()->use_crankshaft());
314 ASSERT(info()->IsOptimizing()); 318 ASSERT(info()->IsOptimizing());
315 ASSERT(!info()->IsCompilingForDebugging()); 319 ASSERT(!info()->IsCompilingForDebugging());
316 320
317 // We should never arrive here if there is no code object on the 321 // We should never arrive here if there is no code object on the
318 // shared function object. 322 // shared function object.
319 ASSERT(info()->shared_info()->code()->kind() == Code::FUNCTION); 323 ASSERT(info()->shared_info()->code()->kind() == Code::FUNCTION);
320 324
321 if (FLAG_trace_opt) { 325 if (FLAG_trace_opt) {
322 // TODO(jbramley): This was added to help analyse the behaviour of 326 // TODO(jbramley): This was added to help analyse the behaviour of
323 // Crankshaft for the A64 Crankshaft port. It should eventually be deleted. 327 // Crankshaft for the A64 Crankshaft port. It should eventually be deleted.
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 Handle<Code> optimized_code = chunk_->Codegen(); 500 Handle<Code> optimized_code = chunk_->Codegen();
497 if (optimized_code.is_null()) { 501 if (optimized_code.is_null()) {
498 if (info()->bailout_reason() == kNoReason) { 502 if (info()->bailout_reason() == kNoReason) {
499 info()->set_bailout_reason(kCodeGenerationFailed); 503 info()->set_bailout_reason(kCodeGenerationFailed);
500 } 504 }
501 return AbortOptimization(); 505 return AbortOptimization();
502 } 506 }
503 info()->SetCode(optimized_code); 507 info()->SetCode(optimized_code);
504 } 508 }
505 RecordOptimizationStats(); 509 RecordOptimizationStats();
510 // Add to the weak list of optimized code objects.
511 info()->context()->native_context()->AddOptimizedCode(*info()->code());
506 return SetLastStatus(SUCCEEDED); 512 return SetLastStatus(SUCCEEDED);
507 } 513 }
508 514
509 515
510 static bool GenerateCode(CompilationInfo* info) { 516 static bool GenerateCode(CompilationInfo* info) {
511 bool is_optimizing = V8::UseCrankshaft() && 517 bool is_optimizing = info->isolate()->use_crankshaft() &&
512 !info->IsCompilingForDebugging() && 518 !info->IsCompilingForDebugging() &&
513 info->IsOptimizing(); 519 info->IsOptimizing();
514 if (is_optimizing) { 520 if (is_optimizing) {
515 Logger::TimerEventScope timer( 521 Logger::TimerEventScope timer(
516 info->isolate(), Logger::TimerEventScope::v8_recompile_synchronous); 522 info->isolate(), Logger::TimerEventScope::v8_recompile_synchronous);
517 return MakeCrankshaftCode(info); 523 return MakeCrankshaftCode(info);
518 } else { 524 } else {
519 if (info->IsOptimizing()) { 525 if (info->IsOptimizing()) {
520 // Have the CompilationInfo decide if the compilation should be 526 // Have the CompilationInfo decide if the compilation should be
521 // BASE or NONOPT. 527 // BASE or NONOPT.
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 ASSERT(!function->IsOptimized()); 842 ASSERT(!function->IsOptimized());
837 } 843 }
838 844
839 // Set the expected number of properties for instances. 845 // Set the expected number of properties for instances.
840 FunctionLiteral* lit = info->function(); 846 FunctionLiteral* lit = info->function();
841 int expected = lit->expected_property_count(); 847 int expected = lit->expected_property_count();
842 SetExpectedNofPropertiesFromEstimate(shared, expected); 848 SetExpectedNofPropertiesFromEstimate(shared, expected);
843 849
844 // Check the function has compiled code. 850 // Check the function has compiled code.
845 ASSERT(shared->is_compiled()); 851 ASSERT(shared->is_compiled());
846 shared->set_dont_optimize(lit->flags()->Contains(kDontOptimize)); 852 shared->set_dont_optimize_reason(lit->dont_optimize_reason());
847 shared->set_dont_inline(lit->flags()->Contains(kDontInline)); 853 shared->set_dont_inline(lit->flags()->Contains(kDontInline));
848 shared->set_ast_node_count(lit->ast_node_count()); 854 shared->set_ast_node_count(lit->ast_node_count());
849 855
850 if (V8::UseCrankshaft() && 856 if (info->isolate()->use_crankshaft() &&
851 !function.is_null() && 857 !function.is_null() &&
852 !shared->optimization_disabled()) { 858 !shared->optimization_disabled()) {
853 // If we're asked to always optimize, we compile the optimized 859 // If we're asked to always optimize, we compile the optimized
854 // version of the function right away - unless the debugger is 860 // version of the function right away - unless the debugger is
855 // active as it makes no sense to compile optimized code then. 861 // active as it makes no sense to compile optimized code then.
856 if (FLAG_always_opt && 862 if (FLAG_always_opt &&
857 !info->isolate()->DebuggerHasBreakPoints()) { 863 !info->isolate()->DebuggerHasBreakPoints()) {
858 CompilationInfoWithZone optimized(function); 864 CompilationInfoWithZone optimized(function);
859 optimized.SetOptimizing(BailoutId::None()); 865 optimized.SetOptimizing(BailoutId::None());
860 return Compiler::CompileLazy(&optimized); 866 return Compiler::CompileLazy(&optimized);
(...skipping 16 matching lines...) Expand all
877 if (shared->code() == *code) { 883 if (shared->code() == *code) {
878 // Do not send compilation event for the same code twice. 884 // Do not send compilation event for the same code twice.
879 return; 885 return;
880 } 886 }
881 Compiler::RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); 887 Compiler::RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
882 } 888 }
883 889
884 890
885 static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { 891 static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
886 Handle<Code> code = info->code(); 892 Handle<Code> code = info->code();
887 if (FLAG_cache_optimized_code && 893 if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do.
888 info->osr_ast_id().IsNone() && 894
889 code->kind() == Code::OPTIMIZED_FUNCTION) { 895 // Cache non-OSR optimized code.
896 if (FLAG_cache_optimized_code && info->osr_ast_id().IsNone()) {
890 Handle<JSFunction> function = info->closure(); 897 Handle<JSFunction> function = info->closure();
891 Handle<SharedFunctionInfo> shared(function->shared()); 898 Handle<SharedFunctionInfo> shared(function->shared());
892 Handle<FixedArray> literals(function->literals()); 899 Handle<FixedArray> literals(function->literals());
893 Handle<Context> native_context(function->context()->native_context()); 900 Handle<Context> native_context(function->context()->native_context());
894 SharedFunctionInfo::AddToOptimizedCodeMap( 901 SharedFunctionInfo::AddToOptimizedCodeMap(
895 shared, native_context, code, literals); 902 shared, native_context, code, literals);
896 } 903 }
897 } 904 }
898 905
899 906
900 static bool InstallCodeFromOptimizedCodeMap(CompilationInfo* info) { 907 static bool InstallCodeFromOptimizedCodeMap(CompilationInfo* info) {
901 if (FLAG_cache_optimized_code && 908 if (!info->IsOptimizing()) return false; // Nothing to look up.
902 info->osr_ast_id().IsNone() && 909
903 info->IsOptimizing()) { 910 // Lookup non-OSR optimized code.
911 if (FLAG_cache_optimized_code && info->osr_ast_id().IsNone()) {
904 Handle<SharedFunctionInfo> shared = info->shared_info(); 912 Handle<SharedFunctionInfo> shared = info->shared_info();
905 Handle<JSFunction> function = info->closure(); 913 Handle<JSFunction> function = info->closure();
906 ASSERT(!function.is_null()); 914 ASSERT(!function.is_null());
907 Handle<Context> native_context(function->context()->native_context()); 915 Handle<Context> native_context(function->context()->native_context());
908 int index = shared->SearchOptimizedCodeMap(*native_context); 916 int index = shared->SearchOptimizedCodeMap(*native_context);
909 if (index > 0) { 917 if (index > 0) {
910 if (FLAG_trace_opt) { 918 if (FLAG_trace_opt) {
911 PrintF("[found optimized code for "); 919 PrintF("[found optimized code for ");
912 function->ShortPrint(); 920 function->ShortPrint();
913 PrintF("]\n"); 921 PrintF("]\n");
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
965 return InstallFullCode(info); 973 return InstallFullCode(info);
966 } 974 }
967 } 975 }
968 } 976 }
969 977
970 ASSERT(info->code().is_null()); 978 ASSERT(info->code().is_null());
971 return false; 979 return false;
972 } 980 }
973 981
974 982
975 void Compiler::RecompileConcurrent(Handle<JSFunction> closure) { 983 bool Compiler::RecompileConcurrent(Handle<JSFunction> closure,
976 ASSERT(closure->IsMarkedForConcurrentRecompilation()); 984 uint32_t osr_pc_offset) {
985 bool compiling_for_osr = (osr_pc_offset != 0);
977 986
978 Isolate* isolate = closure->GetIsolate(); 987 Isolate* isolate = closure->GetIsolate();
979 // Here we prepare compile data for the concurrent recompilation thread, but 988 // Here we prepare compile data for the concurrent recompilation thread, but
980 // this still happens synchronously and interrupts execution. 989 // this still happens synchronously and interrupts execution.
981 Logger::TimerEventScope timer( 990 Logger::TimerEventScope timer(
982 isolate, Logger::TimerEventScope::v8_recompile_synchronous); 991 isolate, Logger::TimerEventScope::v8_recompile_synchronous);
983 992
984 if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) { 993 if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) {
985 if (FLAG_trace_concurrent_recompilation) { 994 if (FLAG_trace_concurrent_recompilation) {
986 PrintF(" ** Compilation queue full, will retry optimizing "); 995 PrintF(" ** Compilation queue full, will retry optimizing ");
987 closure->PrintName(); 996 closure->PrintName();
988 PrintF(" on next run.\n"); 997 PrintF(" on next run.\n");
989 } 998 }
990 return; 999 return false;
991 } 1000 }
992 1001
993 SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(closure)); 1002 SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(closure));
1003 Handle<SharedFunctionInfo> shared = info->shared_info();
1004
1005 if (compiling_for_osr) {
1006 BailoutId osr_ast_id =
1007 shared->code()->TranslatePcOffsetToAstId(osr_pc_offset);
1008 ASSERT(!osr_ast_id.IsNone());
1009 info->SetOptimizing(osr_ast_id);
1010 info->set_osr_pc_offset(osr_pc_offset);
1011
1012 if (FLAG_trace_osr) {
1013 PrintF("[COSR - attempt to queue ");
1014 closure->PrintName();
1015 PrintF(" at AST id %d]\n", osr_ast_id.ToInt());
1016 }
1017 } else {
1018 info->SetOptimizing(BailoutId::None());
1019 }
1020
994 VMState<COMPILER> state(isolate); 1021 VMState<COMPILER> state(isolate);
995 PostponeInterruptsScope postpone(isolate); 1022 PostponeInterruptsScope postpone(isolate);
996 1023
997 Handle<SharedFunctionInfo> shared = info->shared_info();
998 int compiled_size = shared->end_position() - shared->start_position(); 1024 int compiled_size = shared->end_position() - shared->start_position();
999 isolate->counters()->total_compile_size()->Increment(compiled_size); 1025 isolate->counters()->total_compile_size()->Increment(compiled_size);
1000 info->SetOptimizing(BailoutId::None());
1001 1026
1002 { 1027 {
1003 CompilationHandleScope handle_scope(*info); 1028 CompilationHandleScope handle_scope(*info);
1004 1029
1005 if (InstallCodeFromOptimizedCodeMap(*info)) { 1030 if (!compiling_for_osr && InstallCodeFromOptimizedCodeMap(*info)) {
1006 return; 1031 return true;
1007 } 1032 }
1008 1033
1009 if (Parser::Parse(*info)) { 1034 if (Parser::Parse(*info)) {
1010 LanguageMode language_mode = info->function()->language_mode(); 1035 LanguageMode language_mode = info->function()->language_mode();
1011 info->SetLanguageMode(language_mode); 1036 info->SetLanguageMode(language_mode);
1012 shared->set_language_mode(language_mode); 1037 shared->set_language_mode(language_mode);
1013 info->SaveHandles(); 1038 info->SaveHandles();
1014 1039
1015 if (Rewriter::Rewrite(*info) && Scope::Analyze(*info)) { 1040 if (Rewriter::Rewrite(*info) && Scope::Analyze(*info)) {
1016 OptimizingCompiler* compiler = 1041 OptimizingCompiler* compiler =
1017 new(info->zone()) OptimizingCompiler(*info); 1042 new(info->zone()) OptimizingCompiler(*info);
1018 OptimizingCompiler::Status status = compiler->CreateGraph(); 1043 OptimizingCompiler::Status status = compiler->CreateGraph();
1019 if (status == OptimizingCompiler::SUCCEEDED) { 1044 if (status == OptimizingCompiler::SUCCEEDED) {
1020 info.Detach(); 1045 info.Detach();
1021 shared->code()->set_profiler_ticks(0); 1046 shared->code()->set_profiler_ticks(0);
1022 isolate->optimizing_compiler_thread()->QueueForOptimization(compiler); 1047 isolate->optimizing_compiler_thread()->QueueForOptimization(compiler);
1048 ASSERT(!isolate->has_pending_exception());
1049 return true;
1023 } else if (status == OptimizingCompiler::BAILED_OUT) { 1050 } else if (status == OptimizingCompiler::BAILED_OUT) {
1024 isolate->clear_pending_exception(); 1051 isolate->clear_pending_exception();
1025 InstallFullCode(*info); 1052 InstallFullCode(*info);
1026 } 1053 }
1027 } 1054 }
1028 } 1055 }
1029 } 1056 }
1030 1057
1031 if (shared->code()->back_edges_patched_for_osr()) {
1032 // At this point we either put the function on recompilation queue or
1033 // aborted optimization. In either case we want to continue executing
1034 // the unoptimized code without running into OSR. If the unoptimized
1035 // code has been patched for OSR, unpatch it.
1036 Deoptimizer::RevertInterruptCode(isolate, shared->code());
1037 }
1038
1039 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); 1058 if (isolate->has_pending_exception()) isolate->clear_pending_exception();
1059 return false;
1040 } 1060 }
1041 1061
1042 1062
1043 void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) { 1063 bool Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) {
1044 SmartPointer<CompilationInfo> info(optimizing_compiler->info()); 1064 SmartPointer<CompilationInfo> info(optimizing_compiler->info());
1045 // The function may have already been optimized by OSR. Simply continue. 1065 // The function may have already been optimized by OSR. Simply continue.
1046 // Except when OSR already disabled optimization for some reason. 1066 // Except when OSR already disabled optimization for some reason.
1047 if (info->shared_info()->optimization_disabled()) { 1067 if (info->shared_info()->optimization_disabled()) {
1048 info->AbortOptimization(); 1068 info->AbortOptimization();
1049 InstallFullCode(*info); 1069 InstallFullCode(*info);
1050 if (FLAG_trace_concurrent_recompilation) { 1070 if (FLAG_trace_concurrent_recompilation) {
1051 PrintF(" ** aborting optimization for "); 1071 PrintF(" ** aborting optimization for ");
1052 info->closure()->PrintName(); 1072 info->closure()->PrintName();
1053 PrintF(" as it has been disabled.\n"); 1073 PrintF(" as it has been disabled.\n");
1054 } 1074 }
1055 ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode()); 1075 ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode());
1056 return; 1076 return false;
1057 } 1077 }
1058 1078
1059 Isolate* isolate = info->isolate(); 1079 Isolate* isolate = info->isolate();
1060 VMState<COMPILER> state(isolate); 1080 VMState<COMPILER> state(isolate);
1061 Logger::TimerEventScope timer( 1081 Logger::TimerEventScope timer(
1062 isolate, Logger::TimerEventScope::v8_recompile_synchronous); 1082 isolate, Logger::TimerEventScope::v8_recompile_synchronous);
1063 // If crankshaft succeeded, install the optimized code else install 1083 // If crankshaft succeeded, install the optimized code else install
1064 // the unoptimized code. 1084 // the unoptimized code.
1065 OptimizingCompiler::Status status = optimizing_compiler->last_status(); 1085 OptimizingCompiler::Status status = optimizing_compiler->last_status();
1066 if (info->HasAbortedDueToDependencyChange()) { 1086 if (info->HasAbortedDueToDependencyChange()) {
(...skipping 26 matching lines...) Expand all
1093 PrintF(" installed.\n"); 1113 PrintF(" installed.\n");
1094 } 1114 }
1095 } else { 1115 } else {
1096 info->AbortOptimization(); 1116 info->AbortOptimization();
1097 InstallFullCode(*info); 1117 InstallFullCode(*info);
1098 } 1118 }
1099 // Optimized code is finally replacing unoptimized code. Reset the latter's 1119 // Optimized code is finally replacing unoptimized code. Reset the latter's
1100 // profiler ticks to prevent too soon re-opt after a deopt. 1120 // profiler ticks to prevent too soon re-opt after a deopt.
1101 info->shared_info()->code()->set_profiler_ticks(0); 1121 info->shared_info()->code()->set_profiler_ticks(0);
1102 ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode()); 1122 ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode());
1123 return status == OptimizingCompiler::SUCCEEDED;
1103 } 1124 }
1104 1125
1105 1126
1127 static uint32_t CurrentPcOffset(Isolate* isolate,
1128 Handle<JSFunction> function,
1129 Handle<Code> unoptimized) {
1130 JavaScriptFrameIterator it(isolate);
1131 JavaScriptFrame* frame = it.frame();
1132 ASSERT(frame->function() == *function);
1133 ASSERT(frame->LookupCode() == *unoptimized);
1134 ASSERT(unoptimized->contains(frame->pc()));
1135
1136 // Use linear search of the unoptimized code's back edge table to find
1137 // the AST id matching the PC.
1138 return static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start());
1139 }
1140
1141
1142 static bool IsSuitableForOnStackReplacement(Isolate* isolate,
1143 Handle<JSFunction> function,
1144 Handle<Code> unoptimized) {
1145 // Keep track of whether we've succeeded in optimizing.
1146 if (!unoptimized->optimizable()) return false;
1147 // If we are trying to do OSR when there are already optimized
1148 // activations of the function, it means (a) the function is directly or
1149 // indirectly recursive and (b) an optimized invocation has been
1150 // deoptimized so that we are currently in an unoptimized activation.
1151 // Check for optimized activations of this function.
1152 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
1153 JavaScriptFrame* frame = it.frame();
1154 if (frame->is_optimized() && frame->function() == *function) return false;
1155 }
1156
1157 return true;
1158 }
1159
1160
1161 BailoutId Compiler::CompileForOnStackReplacement(Handle<JSFunction> function) {
1162 Isolate* isolate = function->GetIsolate();
1163 // We have hit a back edge in an unoptimized frame for a function that was
1164 // selected for on-stack replacement. Find the unoptimized code object.
1165 Handle<Code> unoptimized(function->shared()->code(), isolate);
1166
1167 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
1168 if (FLAG_trace_osr) {
1169 PrintF("[OSR - restored original interrupt calls in ");
1170 function->PrintName();
1171 PrintF("]\n");
1172 }
1173
1174 if (!IsSuitableForOnStackReplacement(isolate, function, unoptimized)) {
1175 return BailoutId::None();
1176 }
1177
1178 uint32_t pc_offset = CurrentPcOffset(isolate, function, unoptimized);
1179
1180 BailoutId ast_id = unoptimized->TranslatePcOffsetToAstId(pc_offset);
1181 ASSERT(!ast_id.IsNone());
1182 if (FLAG_trace_osr) {
1183 PrintF("[OSR - replacing at AST id %d in ", ast_id.ToInt());
1184 function->PrintName();
1185 PrintF("]\n");
1186 }
1187
1188 // Try to compile the optimized code. A true return value from
1189 // CompileOptimized means that compilation succeeded, not necessarily
1190 // that optimization succeeded.
1191 if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) &&
1192 function->IsOptimized()) {
1193 DeoptimizationInputData* data = DeoptimizationInputData::cast(
1194 function->code()->deoptimization_data());
1195 if (data->OsrPcOffset()->value() >= 0) {
1196 if (FLAG_trace_osr) {
1197 PrintF("[OSR - entry, offset %d in optimized code]\n",
1198 data->OsrPcOffset()->value());
1199 }
1200 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
1201 return ast_id;
1202 }
1203 } else {
1204 if (FLAG_trace_osr) {
1205 PrintF("[OSR - optimization failed for ");
1206 function->PrintName();
1207 PrintF("]\n");
1208 }
1209 }
1210 return BailoutId::None();
1211 }
1212
1213
1214 BailoutId Compiler::CompileForConcurrentOSR(Handle<JSFunction> function) {
1215 Isolate* isolate = function->GetIsolate();
1216 Handle<Code> unoptimized(function->shared()->code(), isolate);
1217
1218 uint32_t pc_offset = CurrentPcOffset(isolate, function, unoptimized);
1219
1220 if (isolate->optimizing_compiler_thread()->
1221 IsQueuedForOSR(function, pc_offset)) {
1222 // Still waiting for the optimizing compiler thread to finish. Carry on.
1223 if (FLAG_trace_osr) {
1224 PrintF("[COSR - polling recompile tasks for ");
1225 function->PrintName();
1226 PrintF("]\n");
1227 }
1228 return BailoutId::None();
1229 }
1230
1231 OptimizingCompiler* compiler = isolate->optimizing_compiler_thread()->
1232 FindReadyOSRCandidate(function, pc_offset);
1233
1234 if (compiler != NULL) {
1235 if (FLAG_trace_osr) {
1236 PrintF("[COSR - optimization complete for ");
1237 function->PrintName();
1238 PrintF(", restoring interrupt calls]\n");
1239 }
1240 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
1241
1242 BailoutId ast_id = compiler->info()->osr_ast_id();
1243
1244 bool succeeded = InstallOptimizedCode(compiler);
1245
1246 isolate->optimizing_compiler_thread()->RemoveStaleOSRCandidates();
1247
1248 if (!succeeded) {
1249 if (FLAG_trace_osr) {
1250 PrintF("[COSR - optimization failed for ");
1251 function->PrintName();
1252 PrintF("]\n");
1253 }
1254 return BailoutId::None();
1255 }
1256
1257 DeoptimizationInputData* data = DeoptimizationInputData::cast(
1258 function->code()->deoptimization_data());
1259
1260 if (data->OsrPcOffset()->value() >= 0) {
1261 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
1262 if (FLAG_trace_osr) {
1263 PrintF("[COSR - entry at AST id %d, offset %d in optimized code]\n",
1264 ast_id.ToInt(), data->OsrPcOffset()->value());
1265 }
1266 return ast_id;
1267 }
1268 return BailoutId::None();
1269 }
1270
1271 if (!IsSuitableForOnStackReplacement(isolate, function, unoptimized)) {
1272 if (FLAG_trace_osr) {
1273 PrintF("[COSR - ");
1274 function->PrintName();
1275 PrintF(" is unsuitable, restoring interrupt calls]\n");
1276 }
1277 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
1278 return BailoutId::None();
1279 }
1280
1281 if (!RecompileConcurrent(function, pc_offset)) {
1282 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
1283 }
1284 return BailoutId::None();
1285 }
1286
1287
1106 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, 1288 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
1107 Handle<Script> script) { 1289 Handle<Script> script) {
1108 // Precondition: code has been parsed and scopes have been analyzed. 1290 // Precondition: code has been parsed and scopes have been analyzed.
1109 CompilationInfoWithZone info(script); 1291 CompilationInfoWithZone info(script);
1110 info.SetFunction(literal); 1292 info.SetFunction(literal);
1111 info.SetScope(literal->scope()); 1293 info.SetScope(literal->scope());
1112 info.SetLanguageMode(literal->scope()->language_mode()); 1294 info.SetLanguageMode(literal->scope()->language_mode());
1113 1295
1114 Isolate* isolate = info.isolate(); 1296 Isolate* isolate = info.isolate();
1115 Factory* factory = isolate->factory(); 1297 Factory* factory = isolate->factory();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 function_info->set_is_toplevel(is_toplevel); 1362 function_info->set_is_toplevel(is_toplevel);
1181 function_info->set_inferred_name(*lit->inferred_name()); 1363 function_info->set_inferred_name(*lit->inferred_name());
1182 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation()); 1364 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
1183 function_info->set_allows_lazy_compilation_without_context( 1365 function_info->set_allows_lazy_compilation_without_context(
1184 lit->AllowsLazyCompilationWithoutContext()); 1366 lit->AllowsLazyCompilationWithoutContext());
1185 function_info->set_language_mode(lit->language_mode()); 1367 function_info->set_language_mode(lit->language_mode());
1186 function_info->set_uses_arguments(lit->scope()->arguments() != NULL); 1368 function_info->set_uses_arguments(lit->scope()->arguments() != NULL);
1187 function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters()); 1369 function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
1188 function_info->set_ast_node_count(lit->ast_node_count()); 1370 function_info->set_ast_node_count(lit->ast_node_count());
1189 function_info->set_is_function(lit->is_function()); 1371 function_info->set_is_function(lit->is_function());
1190 function_info->set_dont_optimize(lit->flags()->Contains(kDontOptimize)); 1372 function_info->set_dont_optimize_reason(lit->dont_optimize_reason());
1191 function_info->set_dont_inline(lit->flags()->Contains(kDontInline)); 1373 function_info->set_dont_inline(lit->flags()->Contains(kDontInline));
1192 function_info->set_dont_cache(lit->flags()->Contains(kDontCache)); 1374 function_info->set_dont_cache(lit->flags()->Contains(kDontCache));
1193 function_info->set_is_generator(lit->is_generator()); 1375 function_info->set_is_generator(lit->is_generator());
1194 } 1376 }
1195 1377
1196 1378
1197 void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag, 1379 void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
1198 CompilationInfo* info, 1380 CompilationInfo* info,
1199 Handle<SharedFunctionInfo> shared) { 1381 Handle<SharedFunctionInfo> shared) {
1200 // SharedFunctionInfo is passed separately, because if CompilationInfo 1382 // SharedFunctionInfo is passed separately, because if CompilationInfo
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 AllowHandleDereference allow_deref; 1447 AllowHandleDereference allow_deref;
1266 bool tracing_on = info()->IsStub() 1448 bool tracing_on = info()->IsStub()
1267 ? FLAG_trace_hydrogen_stubs 1449 ? FLAG_trace_hydrogen_stubs
1268 : (FLAG_trace_hydrogen && 1450 : (FLAG_trace_hydrogen &&
1269 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); 1451 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter));
1270 return (tracing_on && 1452 return (tracing_on &&
1271 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); 1453 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL);
1272 } 1454 }
1273 1455
1274 } } // namespace v8::internal 1456 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/contexts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698