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

Side by Side Diff: src/compiler.cc

Issue 1211453002: Reland "Keep a canonical list of shared function infos." (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix alwaysopt Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler.h ('k') | src/compiler/ast-graph-builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler.h" 5 #include "src/compiler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "src/ast-numbering.h" 9 #include "src/ast-numbering.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 // with deoptimization support. 112 // with deoptimization support.
113 if (isolate_->serializer_enabled()) EnableDeoptimizationSupport(); 113 if (isolate_->serializer_enabled()) EnableDeoptimizationSupport();
114 114
115 if (isolate_->debug()->is_active()) MarkAsDebug(); 115 if (isolate_->debug()->is_active()) MarkAsDebug();
116 if (FLAG_context_specialization) MarkAsContextSpecializing(); 116 if (FLAG_context_specialization) MarkAsContextSpecializing();
117 if (FLAG_turbo_inlining) MarkAsInliningEnabled(); 117 if (FLAG_turbo_inlining) MarkAsInliningEnabled();
118 if (FLAG_turbo_source_positions) MarkAsSourcePositionsEnabled(); 118 if (FLAG_turbo_source_positions) MarkAsSourcePositionsEnabled();
119 if (FLAG_turbo_splitting) MarkAsSplittingEnabled(); 119 if (FLAG_turbo_splitting) MarkAsSplittingEnabled();
120 if (FLAG_turbo_types) MarkAsTypingEnabled(); 120 if (FLAG_turbo_types) MarkAsTypingEnabled();
121 121
122 if (has_shared_info() && shared_info()->is_compiled()) { 122 if (has_shared_info()) {
123 // We should initialize the CompilationInfo feedback vector from the 123 if (shared_info()->is_compiled()) {
124 // passed in shared info, rather than creating a new one. 124 // We should initialize the CompilationInfo feedback vector from the
125 feedback_vector_ = Handle<TypeFeedbackVector>( 125 // passed in shared info, rather than creating a new one.
126 shared_info()->feedback_vector(), parse_info->isolate()); 126 feedback_vector_ = Handle<TypeFeedbackVector>(
127 shared_info()->feedback_vector(), parse_info->isolate());
128 }
129 if (shared_info()->never_compiled()) MarkAsFirstCompile();
127 } 130 }
128 } 131 }
129 132
130 133
131 CompilationInfo::CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone) 134 CompilationInfo::CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone)
132 : CompilationInfo(nullptr, stub, STUB, isolate, zone) {} 135 : CompilationInfo(nullptr, stub, STUB, isolate, zone) {}
133 136
134 137
135 CompilationInfo::CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub, 138 CompilationInfo::CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub,
136 Mode mode, Isolate* isolate, Zone* zone) 139 Mode mode, Isolate* isolate, Zone* zone)
(...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 1012
1010 1013
1011 void Compiler::CompileForLiveEdit(Handle<Script> script) { 1014 void Compiler::CompileForLiveEdit(Handle<Script> script) {
1012 // TODO(635): support extensions. 1015 // TODO(635): support extensions.
1013 Zone zone; 1016 Zone zone;
1014 ParseInfo parse_info(&zone, script); 1017 ParseInfo parse_info(&zone, script);
1015 CompilationInfo info(&parse_info); 1018 CompilationInfo info(&parse_info);
1016 PostponeInterruptsScope postpone(info.isolate()); 1019 PostponeInterruptsScope postpone(info.isolate());
1017 VMState<COMPILER> state(info.isolate()); 1020 VMState<COMPILER> state(info.isolate());
1018 1021
1022 // Get rid of old list of shared function infos.
1023 script->set_shared_function_infos(Smi::FromInt(0));
1024
1019 info.parse_info()->set_global(); 1025 info.parse_info()->set_global();
1020 if (!Parser::ParseStatic(info.parse_info())) return; 1026 if (!Parser::ParseStatic(info.parse_info())) return;
1021 1027
1022 LiveEditFunctionTracker tracker(info.isolate(), info.function()); 1028 LiveEditFunctionTracker tracker(info.isolate(), info.function());
1023 if (!CompileUnoptimizedCode(&info)) return; 1029 if (!CompileUnoptimizedCode(&info)) return;
1024 if (info.has_shared_info()) { 1030 if (info.has_shared_info()) {
1025 Handle<ScopeInfo> scope_info = 1031 Handle<ScopeInfo> scope_info =
1026 ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); 1032 ScopeInfo::Create(info.isolate(), info.zone(), info.scope());
1027 info.shared_info()->set_scope_info(*scope_info); 1033 info.shared_info()->set_scope_info(*scope_info);
1028 } 1034 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 // Eager parsing cannot benefit from cached data, and producing cached 1075 // Eager parsing cannot benefit from cached data, and producing cached
1070 // data while parsing eagerly is not implemented. 1076 // data while parsing eagerly is not implemented.
1071 parse_info->set_cached_data(nullptr); 1077 parse_info->set_cached_data(nullptr);
1072 parse_info->set_compile_options(ScriptCompiler::kNoCompileOptions); 1078 parse_info->set_compile_options(ScriptCompiler::kNoCompileOptions);
1073 } 1079 }
1074 if (!Parser::ParseStatic(parse_info)) { 1080 if (!Parser::ParseStatic(parse_info)) {
1075 return Handle<SharedFunctionInfo>::null(); 1081 return Handle<SharedFunctionInfo>::null();
1076 } 1082 }
1077 } 1083 }
1078 1084
1085 info->MarkAsFirstCompile();
1086
1079 FunctionLiteral* lit = info->function(); 1087 FunctionLiteral* lit = info->function();
1080 LiveEditFunctionTracker live_edit_tracker(isolate, lit); 1088 LiveEditFunctionTracker live_edit_tracker(isolate, lit);
1081 1089
1082 // Measure how long it takes to do the compilation; only take the 1090 // Measure how long it takes to do the compilation; only take the
1083 // rest of the function into account to avoid overlap with the 1091 // rest of the function into account to avoid overlap with the
1084 // parsing statistics. 1092 // parsing statistics.
1085 HistogramTimer* rate = info->is_eval() 1093 HistogramTimer* rate = info->is_eval()
1086 ? info->isolate()->counters()->compile_eval() 1094 ? info->isolate()->counters()->compile_eval()
1087 : info->isolate()->counters()->compile(); 1095 : info->isolate()->counters()->compile();
1088 HistogramTimerScope timer(rate); 1096 HistogramTimerScope timer(rate);
1089 1097
1090 // Compile the code. 1098 // Compile the code.
1091 if (!CompileUnoptimizedCode(info)) { 1099 if (!CompileUnoptimizedCode(info)) {
1092 return Handle<SharedFunctionInfo>::null(); 1100 return Handle<SharedFunctionInfo>::null();
1093 } 1101 }
1094 1102
1095 // Allocate function. 1103 // Allocate function.
1096 DCHECK(!info->code().is_null()); 1104 DCHECK(!info->code().is_null());
1097 result = isolate->factory()->NewSharedFunctionInfo( 1105 result = isolate->factory()->NewSharedFunctionInfo(
1098 lit->name(), lit->materialized_literal_count(), lit->kind(), 1106 lit->name(), lit->materialized_literal_count(), lit->kind(),
1099 info->code(), 1107 info->code(),
1100 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), 1108 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()),
1101 info->feedback_vector()); 1109 info->feedback_vector());
1102 1110
1103 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); 1111 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position());
1104 SharedFunctionInfo::InitFromFunctionLiteral(result, lit); 1112 SharedFunctionInfo::InitFromFunctionLiteral(result, lit);
1105 result->set_script(*script); 1113 SharedFunctionInfo::SetScript(result, script);
1106 result->set_is_toplevel(true); 1114 result->set_is_toplevel(true);
1107 1115
1108 Handle<String> script_name = script->name()->IsString() 1116 Handle<String> script_name = script->name()->IsString()
1109 ? Handle<String>(String::cast(script->name())) 1117 ? Handle<String>(String::cast(script->name()))
1110 : isolate->factory()->empty_string(); 1118 : isolate->factory()->empty_string();
1111 Logger::LogEventsAndTags log_tag = info->is_eval() 1119 Logger::LogEventsAndTags log_tag = info->is_eval()
1112 ? Logger::EVAL_TAG 1120 ? Logger::EVAL_TAG
1113 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script); 1121 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script);
1114 1122
1115 PROFILE(isolate, CodeCreateEvent( 1123 PROFILE(isolate, CodeCreateEvent(
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 parse_info->set_language_mode( 1333 parse_info->set_language_mode(
1326 static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); 1334 static_cast<LanguageMode>(parse_info->language_mode() | language_mode));
1327 1335
1328 CompilationInfo compile_info(parse_info); 1336 CompilationInfo compile_info(parse_info);
1329 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the 1337 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the
1330 // real code caching lands, streaming needs to be adapted to use it. 1338 // real code caching lands, streaming needs to be adapted to use it.
1331 return CompileToplevel(&compile_info); 1339 return CompileToplevel(&compile_info);
1332 } 1340 }
1333 1341
1334 1342
1335 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( 1343 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
1336 FunctionLiteral* literal, Handle<Script> script, 1344 FunctionLiteral* literal, Handle<Script> script,
1337 CompilationInfo* outer_info) { 1345 CompilationInfo* outer_info) {
1338 // Precondition: code has been parsed and scopes have been analyzed. 1346 // Precondition: code has been parsed and scopes have been analyzed.
1347 MaybeHandle<SharedFunctionInfo> maybe_existing;
1348 if (outer_info->is_first_compile()) {
1349 // On the first compile, there are no existing shared function info for
1350 // inner functions yet, so do not try to find them.
1351 DCHECK(script->FindSharedFunctionInfo(literal).is_null());
1352 } else {
1353 maybe_existing = script->FindSharedFunctionInfo(literal);
1354 }
1355 // We found an existing shared function info. If it's already compiled,
1356 // don't worry about compiling it, and simply return it. If it's not yet
1357 // compiled, continue to decide whether to eagerly compile.
1358 Handle<SharedFunctionInfo> existing;
1359 if (maybe_existing.ToHandle(&existing) && existing->is_compiled()) {
1360 return existing;
1361 }
1362
1339 Zone zone; 1363 Zone zone;
1340 ParseInfo parse_info(&zone, script); 1364 ParseInfo parse_info(&zone, script);
1341 CompilationInfo info(&parse_info); 1365 CompilationInfo info(&parse_info);
1342 parse_info.set_literal(literal); 1366 parse_info.set_literal(literal);
1343 parse_info.set_scope(literal->scope()); 1367 parse_info.set_scope(literal->scope());
1344 parse_info.set_language_mode(literal->scope()->language_mode()); 1368 parse_info.set_language_mode(literal->scope()->language_mode());
1345 if (outer_info->will_serialize()) info.PrepareForSerializing(); 1369 if (outer_info->will_serialize()) info.PrepareForSerializing();
1370 if (outer_info->is_first_compile()) info.MarkAsFirstCompile();
1346 1371
1347 Isolate* isolate = info.isolate(); 1372 Isolate* isolate = info.isolate();
1348 Factory* factory = isolate->factory(); 1373 Factory* factory = isolate->factory();
1349 LiveEditFunctionTracker live_edit_tracker(isolate, literal); 1374 LiveEditFunctionTracker live_edit_tracker(isolate, literal);
1350 // Determine if the function can be lazily compiled. This is necessary to 1375 // Determine if the function can be lazily compiled. This is necessary to
1351 // allow some of our builtin JS files to be lazily compiled. These 1376 // allow some of our builtin JS files to be lazily compiled. These
1352 // builtins cannot be handled lazily by the parser, since we have to know 1377 // builtins cannot be handled lazily by the parser, since we have to know
1353 // if a function uses the special natives syntax, which is something the 1378 // if a function uses the special natives syntax, which is something the
1354 // parser records. 1379 // parser records.
1355 // If the debugger requests compilation for break points, we cannot be 1380 // If the debugger requests compilation for break points, we cannot be
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1389 DCHECK(!info.code().is_null()); 1414 DCHECK(!info.code().is_null());
1390 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); 1415 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope());
1391 if (literal->should_eager_compile() && 1416 if (literal->should_eager_compile() &&
1392 literal->should_be_used_once_hint()) { 1417 literal->should_be_used_once_hint()) {
1393 info.code()->MarkToBeExecutedOnce(isolate); 1418 info.code()->MarkToBeExecutedOnce(isolate);
1394 } 1419 }
1395 } else { 1420 } else {
1396 return Handle<SharedFunctionInfo>::null(); 1421 return Handle<SharedFunctionInfo>::null();
1397 } 1422 }
1398 1423
1399 // Create a shared function info object. 1424 if (maybe_existing.is_null()) {
1400 Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo( 1425 // Create a shared function info object.
1401 literal->name(), literal->materialized_literal_count(), literal->kind(), 1426 Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo(
1402 info.code(), scope_info, info.feedback_vector()); 1427 literal->name(), literal->materialized_literal_count(), literal->kind(),
1428 info.code(), scope_info, info.feedback_vector());
1403 1429
1404 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); 1430 SharedFunctionInfo::InitFromFunctionLiteral(result, literal);
1405 result->set_script(*script); 1431 SharedFunctionInfo::SetScript(result, script);
1406 result->set_is_toplevel(false); 1432 result->set_is_toplevel(false);
1407 1433
1408 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); 1434 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
1409 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); 1435 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation());
1410 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); 1436 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx);
1411 1437
1412 // Set the expected number of properties for instances and return 1438 // Set the expected number of properties for instances and return
1413 // the resulting function. 1439 // the resulting function.
1414 SetExpectedNofPropertiesFromEstimate(result, 1440 SetExpectedNofPropertiesFromEstimate(result,
1415 literal->expected_property_count()); 1441 literal->expected_property_count());
1416 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); 1442 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone());
1417 return result; 1443 return result;
1444 } else {
1445 // We may have additional data from compilation now.
1446 DCHECK(!existing->is_compiled());
1447 existing->ReplaceCode(*info.code());
1448 existing->set_scope_info(*scope_info);
1449 existing->set_feedback_vector(*info.feedback_vector());
1450 return existing;
1451 }
1418 } 1452 }
1419 1453
1420 1454
1421 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function, 1455 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function,
1422 Handle<Code> current_code, 1456 Handle<Code> current_code,
1423 ConcurrencyMode mode, 1457 ConcurrencyMode mode,
1424 BailoutId osr_ast_id) { 1458 BailoutId osr_ast_id) {
1425 Handle<Code> cached_code; 1459 Handle<Code> cached_code;
1426 if (GetCodeFromOptimizedCodeMap( 1460 if (GetCodeFromOptimizedCodeMap(
1427 function, osr_ast_id).ToHandle(&cached_code)) { 1461 function, osr_ast_id).ToHandle(&cached_code)) {
1428 return cached_code; 1462 return cached_code;
1429 } 1463 }
1430 1464
1431 SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(function)); 1465 Isolate* isolate = function->GetIsolate();
1432 Isolate* isolate = info->isolate();
1433 DCHECK(AllowCompilation::IsAllowed(isolate)); 1466 DCHECK(AllowCompilation::IsAllowed(isolate));
1434 VMState<COMPILER> state(isolate);
1435 DCHECK(!isolate->has_pending_exception());
1436 PostponeInterruptsScope postpone(isolate);
1437 1467
1438 Handle<SharedFunctionInfo> shared = info->shared_info(); 1468 Handle<SharedFunctionInfo> shared(function->shared(), isolate);
1439 if (shared->code()->kind() != Code::FUNCTION || 1469 if (!shared->is_compiled() ||
1440 ScopeInfo::Empty(isolate) == shared->scope_info()) { 1470 shared->scope_info() == ScopeInfo::Empty(isolate)) {
1441 // The function was never compiled. Compile it unoptimized first. 1471 // The function was never compiled. Compile it unoptimized first.
1442 // TODO(titzer): reuse the AST and scope info from this compile. 1472 // TODO(titzer): reuse the AST and scope info from this compile.
1443 CompilationInfoWithZone nested(function); 1473 CompilationInfoWithZone unoptimized(function);
1444 nested.EnableDeoptimizationSupport(); 1474 unoptimized.EnableDeoptimizationSupport();
1445 if (!GetUnoptimizedCodeCommon(&nested).ToHandle(&current_code)) { 1475 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(&current_code)) {
1446 return MaybeHandle<Code>(); 1476 return MaybeHandle<Code>();
1447 } 1477 }
1448 shared->ReplaceCode(*current_code); 1478 shared->ReplaceCode(*current_code);
1449 } 1479 }
1480
1450 current_code->set_profiler_ticks(0); 1481 current_code->set_profiler_ticks(0);
1451 1482
1452 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing 1483 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing
1453 // an eval scope and hence would fail at parsing the eval source again. 1484 // an eval scope and hence would fail at parsing the eval source again.
1454 if (shared->disable_optimization_reason() == kEval) { 1485 if (shared->disable_optimization_reason() == kEval) {
1455 return MaybeHandle<Code>(); 1486 return MaybeHandle<Code>();
1456 } 1487 }
1457 1488
1458 // TODO(mstarzinger): We cannot properly deserialize a scope chain for the 1489 // TODO(mstarzinger): We cannot properly deserialize a scope chain for the
1459 // builtin context, hence Genesis::InstallExperimentalNatives would fail. 1490 // builtin context, hence Genesis::InstallExperimentalNatives would fail.
1460 if (shared->is_toplevel() && isolate->bootstrapper()->IsActive()) { 1491 if (shared->is_toplevel() && isolate->bootstrapper()->IsActive()) {
1461 return MaybeHandle<Code>(); 1492 return MaybeHandle<Code>();
1462 } 1493 }
1463 1494
1495 SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(function));
1496 VMState<COMPILER> state(isolate);
1497 DCHECK(!isolate->has_pending_exception());
1498 PostponeInterruptsScope postpone(isolate);
1499
1464 info->SetOptimizing(osr_ast_id, current_code); 1500 info->SetOptimizing(osr_ast_id, current_code);
1465 1501
1466 if (mode == CONCURRENT) { 1502 if (mode == CONCURRENT) {
1467 if (GetOptimizedCodeLater(info.get())) { 1503 if (GetOptimizedCodeLater(info.get())) {
1468 info.Detach(); // The background recompile job owns this now. 1504 info.Detach(); // The background recompile job owns this now.
1469 return isolate->builtins()->InOptimizationQueue(); 1505 return isolate->builtins()->InOptimizationQueue();
1470 } 1506 }
1471 } else { 1507 } else {
1472 if (GetOptimizedCodeNow(info.get())) return info->code(); 1508 if (GetOptimizedCodeNow(info.get())) return info->code();
1473 } 1509 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 1604
1569 1605
1570 #if DEBUG 1606 #if DEBUG
1571 void CompilationInfo::PrintAstForTesting() { 1607 void CompilationInfo::PrintAstForTesting() {
1572 PrintF("--- Source from AST ---\n%s\n", 1608 PrintF("--- Source from AST ---\n%s\n",
1573 PrettyPrinter(isolate(), zone()).PrintProgram(function())); 1609 PrettyPrinter(isolate(), zone()).PrintProgram(function()));
1574 } 1610 }
1575 #endif 1611 #endif
1576 } // namespace internal 1612 } // namespace internal
1577 } // namespace v8 1613 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/compiler/ast-graph-builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698