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-numbering.h" | 9 #include "src/ast-numbering.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 #undef PARSE_INFO_GETTER_WITH_DEFAULT | 74 #undef PARSE_INFO_GETTER_WITH_DEFAULT |
75 | 75 |
76 | 76 |
77 // Exactly like a CompilationInfo, except being allocated via {new} and it also | 77 // Exactly like a CompilationInfo, except being allocated via {new} and it also |
78 // creates and enters a Zone on construction and deallocates it on destruction. | 78 // creates and enters a Zone on construction and deallocates it on destruction. |
79 class CompilationInfoWithZone : public CompilationInfo { | 79 class CompilationInfoWithZone : public CompilationInfo { |
80 public: | 80 public: |
81 explicit CompilationInfoWithZone(Handle<JSFunction> function) | 81 explicit CompilationInfoWithZone(Handle<JSFunction> function) |
82 : CompilationInfo(new ParseInfo(&zone_, function)) {} | 82 : CompilationInfo(new ParseInfo(&zone_, function)) {} |
83 | 83 |
84 explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared) | |
Michael Starzinger
2015/07/20 11:29:40
See comment below.
Yang
2015/07/20 12:13:47
Acknowledged.
| |
85 : CompilationInfo(new ParseInfo(&zone_, shared)) {} | |
86 | |
84 // Virtual destructor because a CompilationInfoWithZone has to exit the | 87 // Virtual destructor because a CompilationInfoWithZone has to exit the |
85 // zone scope and get rid of dependent maps even when the destructor is | 88 // zone scope and get rid of dependent maps even when the destructor is |
86 // called when cast as a CompilationInfo. | 89 // called when cast as a CompilationInfo. |
87 virtual ~CompilationInfoWithZone() { | 90 virtual ~CompilationInfoWithZone() { |
88 DisableFutureOptimization(); | 91 DisableFutureOptimization(); |
89 dependencies()->Rollback(); | 92 dependencies()->Rollback(); |
90 delete parse_info_; | 93 delete parse_info_; |
91 parse_info_ = nullptr; | 94 parse_info_ = nullptr; |
92 } | 95 } |
93 | 96 |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
331 void Visit##type(type* node) override { \ | 334 void Visit##type(type* node) override { \ |
332 HOptimizedGraphBuilder::Visit##type(node); \ | 335 HOptimizedGraphBuilder::Visit##type(node); \ |
333 } | 336 } |
334 DECLARATION_NODE_LIST(DEF_VISIT) | 337 DECLARATION_NODE_LIST(DEF_VISIT) |
335 #undef DEF_VISIT | 338 #undef DEF_VISIT |
336 }; | 339 }; |
337 | 340 |
338 | 341 |
339 OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() { | 342 OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() { |
340 DCHECK(info()->IsOptimizing()); | 343 DCHECK(info()->IsOptimizing()); |
341 DCHECK(!info()->IsCompilingForDebugging()); | |
342 | 344 |
343 // Do not use Crankshaft/TurboFan if we need to be able to set break points. | 345 // Do not use Crankshaft/TurboFan if we need to be able to set break points. |
344 if (isolate()->debug()->has_break_points()) { | 346 if (info()->shared_info()->HasDebugInfo()) { |
345 return RetryOptimization(kDebuggerHasBreakPoints); | 347 return AbortOptimization(kFunctionBeingDebugged); |
346 } | 348 } |
347 | 349 |
348 // Limit the number of times we try to optimize functions. | 350 // Limit the number of times we try to optimize functions. |
349 const int kMaxOptCount = | 351 const int kMaxOptCount = |
350 FLAG_deopt_every_n_times == 0 ? FLAG_max_opt_count : 1000; | 352 FLAG_deopt_every_n_times == 0 ? FLAG_max_opt_count : 1000; |
351 if (info()->opt_count() > kMaxOptCount) { | 353 if (info()->opt_count() > kMaxOptCount) { |
352 return AbortOptimization(kOptimizedTooManyTimes); | 354 return AbortOptimization(kOptimizedTooManyTimes); |
353 } | 355 } |
354 | 356 |
355 // Check the whitelist for Crankshaft. | 357 // Check the whitelist for Crankshaft. |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
898 function, result, | 900 function, result, |
899 Compiler::NOT_CONCURRENT).ToHandle(&opt_code)) { | 901 Compiler::NOT_CONCURRENT).ToHandle(&opt_code)) { |
900 result = opt_code; | 902 result = opt_code; |
901 } | 903 } |
902 } | 904 } |
903 | 905 |
904 return result; | 906 return result; |
905 } | 907 } |
906 | 908 |
907 | 909 |
908 MaybeHandle<Code> Compiler::GetUnoptimizedCode( | |
909 Handle<SharedFunctionInfo> shared) { | |
910 DCHECK(!shared->GetIsolate()->has_pending_exception()); | |
911 DCHECK(!shared->is_compiled()); | |
912 | |
913 Zone zone; | |
914 ParseInfo parse_info(&zone, shared); | |
915 CompilationInfo info(&parse_info); | |
916 return GetUnoptimizedCodeCommon(&info); | |
917 } | |
918 | |
919 | |
920 bool Compiler::EnsureCompiled(Handle<JSFunction> function, | 910 bool Compiler::EnsureCompiled(Handle<JSFunction> function, |
921 ClearExceptionFlag flag) { | 911 ClearExceptionFlag flag) { |
922 if (function->is_compiled()) return true; | 912 if (function->is_compiled()) return true; |
923 MaybeHandle<Code> maybe_code = Compiler::GetLazyCode(function); | 913 MaybeHandle<Code> maybe_code = Compiler::GetLazyCode(function); |
924 Handle<Code> code; | 914 Handle<Code> code; |
925 if (!maybe_code.ToHandle(&code)) { | 915 if (!maybe_code.ToHandle(&code)) { |
926 if (flag == CLEAR_EXCEPTION) { | 916 if (flag == CLEAR_EXCEPTION) { |
927 function->GetIsolate()->clear_pending_exception(); | 917 function->GetIsolate()->clear_pending_exception(); |
928 } | 918 } |
929 return false; | 919 return false; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
972 shared->set_scope_info(*target_scope_info); | 962 shared->set_scope_info(*target_scope_info); |
973 } | 963 } |
974 | 964 |
975 // The existing unoptimized code was replaced with the new one. | 965 // The existing unoptimized code was replaced with the new one. |
976 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized, shared); | 966 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized, shared); |
977 } | 967 } |
978 return true; | 968 return true; |
979 } | 969 } |
980 | 970 |
981 | 971 |
982 // Compile full code for debugging. This code will have debug break slots | 972 MaybeHandle<Code> CompileForDebuggingImpl(CompilationInfo* info) { |
983 // and deoptimization information. Deoptimization information is required | 973 info->MarkAsDebug(); |
984 // in case that an optimized version of this function is still activated on | 974 VMState<COMPILER> state(info->isolate()); |
985 // the stack. It will also make sure that the full code is compiled with | 975 if (info->shared_info()->is_compiled()) { |
986 // the same flags as the previous version, that is flags which can change | 976 if (info->shared_info()->code()->is_compiled_optimizable()) { |
987 // the code generated. The current method of mapping from already compiled | 977 info->EnableDeoptimizationSupport(); |
988 // full code without debug break slots to full code with debug break slots | 978 } else { |
989 // depends on the generated code is otherwise exactly the same. | 979 info->MarkNonOptimizable(); |
990 // If compilation fails, just keep the existing code. | 980 } |
991 MaybeHandle<Code> Compiler::GetDebugCode(Handle<JSFunction> function) { | |
992 CompilationInfoWithZone info(function); | |
993 Isolate* isolate = info.isolate(); | |
994 VMState<COMPILER> state(isolate); | |
995 | |
996 info.MarkAsDebug(); | |
997 | |
998 DCHECK(!isolate->has_pending_exception()); | |
999 Handle<Code> old_code(function->shared()->code()); | |
1000 DCHECK(old_code->kind() == Code::FUNCTION); | |
1001 DCHECK(!old_code->has_debug_break_slots()); | |
1002 | |
1003 info.MarkCompilingForDebugging(); | |
1004 if (old_code->is_compiled_optimizable()) { | |
1005 info.EnableDeoptimizationSupport(); | |
1006 } else { | |
1007 info.MarkNonOptimizable(); | |
1008 } | 981 } |
1009 MaybeHandle<Code> maybe_new_code = GetUnoptimizedCodeCommon(&info); | 982 MaybeHandle<Code> maybe_new_code = GetUnoptimizedCodeCommon(info); |
1010 Handle<Code> new_code; | 983 Handle<Code> new_code; |
1011 if (!maybe_new_code.ToHandle(&new_code)) { | 984 if (!maybe_new_code.ToHandle(&new_code)) { |
1012 isolate->clear_pending_exception(); | 985 info->isolate()->clear_pending_exception(); |
1013 } else { | |
1014 DCHECK_EQ(old_code->is_compiled_optimizable(), | |
1015 new_code->is_compiled_optimizable()); | |
1016 } | 986 } |
1017 return maybe_new_code; | 987 return maybe_new_code; |
1018 } | 988 } |
1019 | 989 |
1020 | 990 |
991 MaybeHandle<Code> Compiler::CompileForDebugging(Handle<JSFunction> function) { | |
992 CompilationInfoWithZone info(function); | |
993 VMState<COMPILER> state(info.isolate()); | |
994 return CompileForDebuggingImpl(&info); | |
995 } | |
996 | |
997 | |
998 MaybeHandle<Code> Compiler::CompileForDebugging( | |
999 Handle<SharedFunctionInfo> shared) { | |
1000 DCHECK(shared->allows_lazy_compilation_without_context()); | |
1001 CompilationInfoWithZone info(shared); | |
Michael Starzinger
2015/07/20 11:29:39
There is a constant back-and-forth refactoring aro
Yang
2015/07/20 12:13:47
Done.
| |
1002 return CompileForDebuggingImpl(&info); | |
1003 } | |
1004 | |
1005 | |
1021 void Compiler::CompileForLiveEdit(Handle<Script> script) { | 1006 void Compiler::CompileForLiveEdit(Handle<Script> script) { |
1022 // TODO(635): support extensions. | 1007 // TODO(635): support extensions. |
1023 Zone zone; | 1008 Zone zone; |
1024 ParseInfo parse_info(&zone, script); | 1009 ParseInfo parse_info(&zone, script); |
1025 CompilationInfo info(&parse_info); | 1010 CompilationInfo info(&parse_info); |
1026 PostponeInterruptsScope postpone(info.isolate()); | 1011 PostponeInterruptsScope postpone(info.isolate()); |
1027 VMState<COMPILER> state(info.isolate()); | 1012 VMState<COMPILER> state(info.isolate()); |
1028 | 1013 |
1029 // Get rid of old list of shared function infos. | 1014 // Get rid of old list of shared function infos. |
1030 info.MarkAsFirstCompile(); | 1015 info.MarkAsFirstCompile(); |
(...skipping 27 matching lines...) Expand all Loading... | |
1058 DCHECK(parse_info->is_eval() || parse_info->is_global() || | 1043 DCHECK(parse_info->is_eval() || parse_info->is_global() || |
1059 parse_info->is_module()); | 1044 parse_info->is_module()); |
1060 | 1045 |
1061 parse_info->set_toplevel(); | 1046 parse_info->set_toplevel(); |
1062 | 1047 |
1063 Handle<SharedFunctionInfo> result; | 1048 Handle<SharedFunctionInfo> result; |
1064 | 1049 |
1065 { VMState<COMPILER> state(info->isolate()); | 1050 { VMState<COMPILER> state(info->isolate()); |
1066 if (parse_info->literal() == NULL) { | 1051 if (parse_info->literal() == NULL) { |
1067 // Parse the script if needed (if it's already parsed, function() is | 1052 // Parse the script if needed (if it's already parsed, function() is |
1068 // non-NULL). | 1053 // non-NULL). If compiling for debugging, we may eagerly compile inner |
1054 // functions, so do not parse lazily in that case. | |
1069 ScriptCompiler::CompileOptions options = parse_info->compile_options(); | 1055 ScriptCompiler::CompileOptions options = parse_info->compile_options(); |
1070 bool parse_allow_lazy = (options == ScriptCompiler::kConsumeParserCache || | 1056 bool parse_allow_lazy = (options == ScriptCompiler::kConsumeParserCache || |
1071 String::cast(script->source())->length() > | 1057 String::cast(script->source())->length() > |
1072 FLAG_min_preparse_length) && | 1058 FLAG_min_preparse_length) && |
1073 !Compiler::DebuggerWantsEagerCompilation(isolate); | 1059 !info->is_debug(); |
1074 | 1060 |
1075 parse_info->set_allow_lazy_parsing(parse_allow_lazy); | 1061 parse_info->set_allow_lazy_parsing(parse_allow_lazy); |
1076 if (!parse_allow_lazy && | 1062 if (!parse_allow_lazy && |
1077 (options == ScriptCompiler::kProduceParserCache || | 1063 (options == ScriptCompiler::kProduceParserCache || |
1078 options == ScriptCompiler::kConsumeParserCache)) { | 1064 options == ScriptCompiler::kConsumeParserCache)) { |
1079 // We are going to parse eagerly, but we either 1) have cached data | 1065 // We are going to parse eagerly, but we either 1) have cached data |
1080 // produced by lazy parsing or 2) are asked to generate cached data. | 1066 // produced by lazy parsing or 2) are asked to generate cached data. |
1081 // Eager parsing cannot benefit from cached data, and producing cached | 1067 // Eager parsing cannot benefit from cached data, and producing cached |
1082 // data while parsing eagerly is not implemented. | 1068 // data while parsing eagerly is not implemented. |
1083 parse_info->set_cached_data(nullptr); | 1069 parse_info->set_cached_data(nullptr); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1173 script->set_origin_options(options); | 1159 script->set_origin_options(options); |
1174 Zone zone; | 1160 Zone zone; |
1175 ParseInfo parse_info(&zone, script); | 1161 ParseInfo parse_info(&zone, script); |
1176 CompilationInfo info(&parse_info); | 1162 CompilationInfo info(&parse_info); |
1177 parse_info.set_eval(); | 1163 parse_info.set_eval(); |
1178 if (context->IsNativeContext()) parse_info.set_global(); | 1164 if (context->IsNativeContext()) parse_info.set_global(); |
1179 parse_info.set_language_mode(language_mode); | 1165 parse_info.set_language_mode(language_mode); |
1180 parse_info.set_parse_restriction(restriction); | 1166 parse_info.set_parse_restriction(restriction); |
1181 parse_info.set_context(context); | 1167 parse_info.set_context(context); |
1182 | 1168 |
1169 // If we eval from debug code, compile for debugging as well. | |
1170 if (outer_info->HasDebugCode()) info.MarkAsDebug(); | |
1183 Debug::RecordEvalCaller(script); | 1171 Debug::RecordEvalCaller(script); |
1184 | 1172 |
1185 shared_info = CompileToplevel(&info); | 1173 shared_info = CompileToplevel(&info); |
1186 | 1174 |
1187 if (shared_info.is_null()) { | 1175 if (shared_info.is_null()) { |
1188 return MaybeHandle<JSFunction>(); | 1176 return MaybeHandle<JSFunction>(); |
1189 } else { | 1177 } else { |
1190 // Explicitly disable optimization for eval code. We're not yet prepared | 1178 // Explicitly disable optimization for eval code. We're not yet prepared |
1191 // to handle eval-code in the optimizing compiler. | 1179 // to handle eval-code in the optimizing compiler. |
1192 if (restriction != ONLY_SINGLE_FUNCTION_LITERAL) { | 1180 if (restriction != ONLY_SINGLE_FUNCTION_LITERAL) { |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1364 // inner functions yet, so do not try to find them. All bets are off for | 1352 // inner functions yet, so do not try to find them. All bets are off for |
1365 // live edit though. | 1353 // live edit though. |
1366 DCHECK(script->FindSharedFunctionInfo(literal).is_null() || | 1354 DCHECK(script->FindSharedFunctionInfo(literal).is_null() || |
1367 isolate->debug()->live_edit_enabled()); | 1355 isolate->debug()->live_edit_enabled()); |
1368 } else { | 1356 } else { |
1369 maybe_existing = script->FindSharedFunctionInfo(literal); | 1357 maybe_existing = script->FindSharedFunctionInfo(literal); |
1370 } | 1358 } |
1371 // We found an existing shared function info. If it's already compiled, | 1359 // We found an existing shared function info. If it's already compiled, |
1372 // don't worry about compiling it, and simply return it. If it's not yet | 1360 // don't worry about compiling it, and simply return it. If it's not yet |
1373 // compiled, continue to decide whether to eagerly compile. | 1361 // compiled, continue to decide whether to eagerly compile. |
1362 // Carry on if we are compiling eager to obtain code for debugging, | |
1363 // unless we already have code with debut break slots. | |
1374 Handle<SharedFunctionInfo> existing; | 1364 Handle<SharedFunctionInfo> existing; |
1375 if (maybe_existing.ToHandle(&existing) && existing->is_compiled()) { | 1365 if (maybe_existing.ToHandle(&existing) && existing->is_compiled()) { |
1376 return existing; | 1366 if (!outer_info->is_debug() || existing->HasDebugCode()) { |
1367 return existing; | |
1368 } | |
1377 } | 1369 } |
1378 | 1370 |
1379 Zone zone; | 1371 Zone zone; |
1380 ParseInfo parse_info(&zone, script); | 1372 ParseInfo parse_info(&zone, script); |
1381 CompilationInfo info(&parse_info); | 1373 CompilationInfo info(&parse_info); |
1382 parse_info.set_literal(literal); | 1374 parse_info.set_literal(literal); |
1383 parse_info.set_scope(literal->scope()); | 1375 parse_info.set_scope(literal->scope()); |
1384 parse_info.set_language_mode(literal->scope()->language_mode()); | 1376 parse_info.set_language_mode(literal->scope()->language_mode()); |
1385 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 1377 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
1386 if (outer_info->is_first_compile()) info.MarkAsFirstCompile(); | 1378 if (outer_info->is_first_compile()) info.MarkAsFirstCompile(); |
1379 if (outer_info->is_debug()) info.MarkAsDebug(); | |
1387 | 1380 |
1388 LiveEditFunctionTracker live_edit_tracker(isolate, literal); | 1381 LiveEditFunctionTracker live_edit_tracker(isolate, literal); |
1389 // Determine if the function can be lazily compiled. This is necessary to | 1382 // Determine if the function can be lazily compiled. This is necessary to |
1390 // allow some of our builtin JS files to be lazily compiled. These | 1383 // allow some of our builtin JS files to be lazily compiled. These |
1391 // builtins cannot be handled lazily by the parser, since we have to know | 1384 // builtins cannot be handled lazily by the parser, since we have to know |
1392 // if a function uses the special natives syntax, which is something the | 1385 // if a function uses the special natives syntax, which is something the |
1393 // parser records. | 1386 // parser records. |
1394 // If the debugger requests compilation for break points, we cannot be | 1387 // If the debugger requests compilation for break points, we cannot be |
1395 // aggressive about lazy compilation, because it might trigger compilation | 1388 // aggressive about lazy compilation, because it might trigger compilation |
1396 // of functions without an outer context when setting a breakpoint through | 1389 // of functions without an outer context when setting a breakpoint through |
1397 // Debug::FindSharedFunctionInfoInScript. | 1390 // Debug::FindSharedFunctionInfoInScript. |
1398 bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext(); | 1391 bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext(); |
1399 bool allow_lazy = | 1392 bool allow_lazy = literal->AllowsLazyCompilation(); |
1400 literal->AllowsLazyCompilation() && | 1393 // Compile eagerly for live edit. |
1401 !DebuggerWantsEagerCompilation(isolate, allow_lazy_without_ctx); | 1394 allow_lazy &= !LiveEditFunctionTracker::IsActive(isolate); |
Michael Starzinger
2015/07/20 11:29:39
nit: Can we combine this into one big conjunction
Yang
2015/07/20 12:13:47
Done.
| |
1395 // When compiling debug code, eagerly compile unless we can lazily compile | |
1396 // without the context (SFI without a JSFunction). | |
1397 allow_lazy &= !info.is_debug() || allow_lazy_without_ctx; | |
1402 | 1398 |
1403 if (outer_info->parse_info()->is_toplevel() && outer_info->will_serialize()) { | 1399 if (outer_info->parse_info()->is_toplevel() && outer_info->will_serialize()) { |
1404 // Make sure that if the toplevel code (possibly to be serialized), | 1400 // Make sure that if the toplevel code (possibly to be serialized), |
1405 // the inner function must be allowed to be compiled lazily. | 1401 // the inner function must be allowed to be compiled lazily. |
1406 // This is necessary to serialize toplevel code without inner functions. | 1402 // This is necessary to serialize toplevel code without inner functions. |
1407 DCHECK(allow_lazy); | 1403 DCHECK(allow_lazy); |
1408 } | 1404 } |
1409 | 1405 |
1410 bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile(); | 1406 bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile(); |
1411 | 1407 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1456 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); | 1452 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); |
1457 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); | 1453 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); |
1458 | 1454 |
1459 // Set the expected number of properties for instances and return | 1455 // Set the expected number of properties for instances and return |
1460 // the resulting function. | 1456 // the resulting function. |
1461 SetExpectedNofPropertiesFromEstimate(result, | 1457 SetExpectedNofPropertiesFromEstimate(result, |
1462 literal->expected_property_count()); | 1458 literal->expected_property_count()); |
1463 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); | 1459 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); |
1464 return result; | 1460 return result; |
1465 } else if (!lazy) { | 1461 } else if (!lazy) { |
1466 // We have additional data from compilation now. | 1462 // We have additional data from compilation now. Upgrading from |
1467 DCHECK(!existing->is_compiled()); | 1463 // non-compiled code or in case of debugging, from non-debug code. |
1464 DCHECK(info.is_debug() ? !existing->HasDebugCode() | |
Michael Starzinger
2015/07/20 11:29:39
nit: Not sure exactly what this assertion is guard
Yang
2015/07/20 12:13:47
This is supposed to guard against replacing existi
| |
1465 : !existing->is_compiled()); | |
1468 existing->ReplaceCode(*info.code()); | 1466 existing->ReplaceCode(*info.code()); |
1469 existing->set_scope_info(*scope_info); | 1467 existing->set_scope_info(*scope_info); |
1470 existing->set_feedback_vector(*info.feedback_vector()); | 1468 existing->set_feedback_vector(*info.feedback_vector()); |
1471 } | 1469 } |
1472 return existing; | 1470 return existing; |
1473 } | 1471 } |
1474 | 1472 |
1475 | 1473 |
1476 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function, | 1474 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function, |
1477 Handle<Code> current_code, | 1475 Handle<Code> current_code, |
1478 ConcurrencyMode mode, | 1476 ConcurrencyMode mode, |
1479 BailoutId osr_ast_id, | 1477 BailoutId osr_ast_id, |
1480 JavaScriptFrame* osr_frame) { | 1478 JavaScriptFrame* osr_frame) { |
1479 Isolate* isolate = function->GetIsolate(); | |
1480 Handle<SharedFunctionInfo> shared(function->shared(), isolate); | |
1481 if (shared->HasDebugInfo()) return MaybeHandle<Code>(); | |
1482 | |
1481 Handle<Code> cached_code; | 1483 Handle<Code> cached_code; |
1482 if (GetCodeFromOptimizedCodeMap( | 1484 if (GetCodeFromOptimizedCodeMap( |
1483 function, osr_ast_id).ToHandle(&cached_code)) { | 1485 function, osr_ast_id).ToHandle(&cached_code)) { |
1484 if (FLAG_trace_opt) { | 1486 if (FLAG_trace_opt) { |
1485 PrintF("[found optimized code for "); | 1487 PrintF("[found optimized code for "); |
1486 function->ShortPrint(); | 1488 function->ShortPrint(); |
1487 if (!osr_ast_id.IsNone()) { | 1489 if (!osr_ast_id.IsNone()) { |
1488 PrintF(" at OSR AST id %d", osr_ast_id.ToInt()); | 1490 PrintF(" at OSR AST id %d", osr_ast_id.ToInt()); |
1489 } | 1491 } |
1490 PrintF("]\n"); | 1492 PrintF("]\n"); |
1491 } | 1493 } |
1492 return cached_code; | 1494 return cached_code; |
1493 } | 1495 } |
1494 | 1496 |
1495 Isolate* isolate = function->GetIsolate(); | |
1496 DCHECK(AllowCompilation::IsAllowed(isolate)); | 1497 DCHECK(AllowCompilation::IsAllowed(isolate)); |
1497 | 1498 |
1498 Handle<SharedFunctionInfo> shared(function->shared(), isolate); | |
1499 if (!shared->is_compiled() || | 1499 if (!shared->is_compiled() || |
1500 shared->scope_info() == ScopeInfo::Empty(isolate)) { | 1500 shared->scope_info() == ScopeInfo::Empty(isolate)) { |
1501 // The function was never compiled. Compile it unoptimized first. | 1501 // The function was never compiled. Compile it unoptimized first. |
1502 // TODO(titzer): reuse the AST and scope info from this compile. | 1502 // TODO(titzer): reuse the AST and scope info from this compile. |
1503 CompilationInfoWithZone unoptimized(function); | 1503 CompilationInfoWithZone unoptimized(function); |
1504 unoptimized.EnableDeoptimizationSupport(); | 1504 unoptimized.EnableDeoptimizationSupport(); |
1505 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(¤t_code)) { | 1505 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(¤t_code)) { |
1506 return MaybeHandle<Code>(); | 1506 return MaybeHandle<Code>(); |
1507 } | 1507 } |
1508 shared->ReplaceCode(*current_code); | 1508 shared->ReplaceCode(*current_code); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1550 // also tears down the zone and the recompile job. | 1550 // also tears down the zone and the recompile job. |
1551 base::SmartPointer<CompilationInfo> info(job->info()); | 1551 base::SmartPointer<CompilationInfo> info(job->info()); |
1552 Isolate* isolate = info->isolate(); | 1552 Isolate* isolate = info->isolate(); |
1553 | 1553 |
1554 VMState<COMPILER> state(isolate); | 1554 VMState<COMPILER> state(isolate); |
1555 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); | 1555 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
1556 | 1556 |
1557 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1557 Handle<SharedFunctionInfo> shared = info->shared_info(); |
1558 shared->code()->set_profiler_ticks(0); | 1558 shared->code()->set_profiler_ticks(0); |
1559 | 1559 |
1560 DCHECK(!shared->HasDebugInfo()); | |
Michael Starzinger
2015/07/20 11:29:39
What happens of a concurrent compile job for a fun
Yang
2015/07/20 12:13:47
Done. We flush the queue when preparing the functi
| |
1561 | |
1560 // 1) Optimization on the concurrent thread may have failed. | 1562 // 1) Optimization on the concurrent thread may have failed. |
1561 // 2) The function may have already been optimized by OSR. Simply continue. | 1563 // 2) The function may have already been optimized by OSR. Simply continue. |
1562 // Except when OSR already disabled optimization for some reason. | 1564 // Except when OSR already disabled optimization for some reason. |
1563 // 3) The code may have already been invalidated due to dependency change. | 1565 // 3) The code may have already been invalidated due to dependency change. |
1564 // 4) Debugger may have been activated. | 1566 // 4) Code generation may have failed. |
1565 // 5) Code generation may have failed. | |
1566 if (job->last_status() == OptimizedCompileJob::SUCCEEDED) { | 1567 if (job->last_status() == OptimizedCompileJob::SUCCEEDED) { |
1567 if (shared->optimization_disabled()) { | 1568 if (shared->optimization_disabled()) { |
1568 job->RetryOptimization(kOptimizationDisabled); | 1569 job->RetryOptimization(kOptimizationDisabled); |
1569 } else if (info->dependencies()->HasAborted()) { | 1570 } else if (info->dependencies()->HasAborted()) { |
1570 job->RetryOptimization(kBailedOutDueToDependencyChange); | 1571 job->RetryOptimization(kBailedOutDueToDependencyChange); |
1571 } else if (isolate->debug()->has_break_points()) { | |
1572 job->RetryOptimization(kDebuggerHasBreakPoints); | |
1573 } else if (job->GenerateCode() == OptimizedCompileJob::SUCCEEDED) { | 1572 } else if (job->GenerateCode() == OptimizedCompileJob::SUCCEEDED) { |
1574 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info.get(), shared); | 1573 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info.get(), shared); |
1575 if (shared->SearchOptimizedCodeMap(info->context()->native_context(), | 1574 if (shared->SearchOptimizedCodeMap(info->context()->native_context(), |
1576 info->osr_ast_id()).code == nullptr) { | 1575 info->osr_ast_id()).code == nullptr) { |
1577 InsertCodeIntoOptimizedCodeMap(info.get()); | 1576 InsertCodeIntoOptimizedCodeMap(info.get()); |
1578 } | 1577 } |
1579 if (FLAG_trace_opt) { | 1578 if (FLAG_trace_opt) { |
1580 PrintF("[completed optimizing "); | 1579 PrintF("[completed optimizing "); |
1581 info->closure()->ShortPrint(); | 1580 info->closure()->ShortPrint(); |
1582 PrintF("]\n"); | 1581 PrintF("]\n"); |
1583 } | 1582 } |
1584 return Handle<Code>(*info->code()); | 1583 return Handle<Code>(*info->code()); |
1585 } | 1584 } |
1586 } | 1585 } |
1587 | 1586 |
1588 DCHECK(job->last_status() != OptimizedCompileJob::SUCCEEDED); | 1587 DCHECK(job->last_status() != OptimizedCompileJob::SUCCEEDED); |
1589 if (FLAG_trace_opt) { | 1588 if (FLAG_trace_opt) { |
1590 PrintF("[aborted optimizing "); | 1589 PrintF("[aborted optimizing "); |
1591 info->closure()->ShortPrint(); | 1590 info->closure()->ShortPrint(); |
1592 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); | 1591 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
1593 } | 1592 } |
1594 return Handle<Code>::null(); | 1593 return Handle<Code>::null(); |
1595 } | 1594 } |
1596 | 1595 |
1597 | 1596 |
1598 bool Compiler::DebuggerWantsEagerCompilation(Isolate* isolate, | |
1599 bool allow_lazy_without_ctx) { | |
1600 if (LiveEditFunctionTracker::IsActive(isolate)) return true; | |
1601 Debug* debug = isolate->debug(); | |
1602 bool debugging = debug->is_active() || debug->has_break_points(); | |
1603 return debugging && !allow_lazy_without_ctx; | |
1604 } | |
1605 | |
1606 | |
1607 CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info) | 1597 CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info) |
1608 : name_(name), info_(info) { | 1598 : name_(name), info_(info) { |
1609 if (FLAG_hydrogen_stats) { | 1599 if (FLAG_hydrogen_stats) { |
1610 info_zone_start_allocation_size_ = info->zone()->allocation_size(); | 1600 info_zone_start_allocation_size_ = info->zone()->allocation_size(); |
1611 timer_.Start(); | 1601 timer_.Start(); |
1612 } | 1602 } |
1613 } | 1603 } |
1614 | 1604 |
1615 | 1605 |
1616 CompilationPhase::~CompilationPhase() { | 1606 CompilationPhase::~CompilationPhase() { |
(...skipping 19 matching lines...) Expand all Loading... | |
1636 | 1626 |
1637 | 1627 |
1638 #if DEBUG | 1628 #if DEBUG |
1639 void CompilationInfo::PrintAstForTesting() { | 1629 void CompilationInfo::PrintAstForTesting() { |
1640 PrintF("--- Source from AST ---\n%s\n", | 1630 PrintF("--- Source from AST ---\n%s\n", |
1641 PrettyPrinter(isolate(), zone()).PrintProgram(function())); | 1631 PrettyPrinter(isolate(), zone()).PrintProgram(function())); |
1642 } | 1632 } |
1643 #endif | 1633 #endif |
1644 } // namespace internal | 1634 } // namespace internal |
1645 } // namespace v8 | 1635 } // namespace v8 |
OLD | NEW |