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