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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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(¤t_code)) { | 1475 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(¤t_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 Loading... |
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 |
OLD | NEW |