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

Side by Side Diff: src/compiler.cc

Issue 1233073005: Debugger: prepare code for debugging on a per-function basis. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler.h" 5 #include "src/compiler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "src/ast-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
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
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
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
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
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
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
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
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(&current_code)) { 1505 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(&current_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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698