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 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1008 | 1008 |
1009 | 1009 |
1010 void Compiler::CompileForLiveEdit(Handle<Script> script) { | 1010 void Compiler::CompileForLiveEdit(Handle<Script> script) { |
1011 // TODO(635): support extensions. | 1011 // TODO(635): support extensions. |
1012 Zone zone; | 1012 Zone zone; |
1013 ParseInfo parse_info(&zone, script); | 1013 ParseInfo parse_info(&zone, script); |
1014 CompilationInfo info(&parse_info); | 1014 CompilationInfo info(&parse_info); |
1015 PostponeInterruptsScope postpone(info.isolate()); | 1015 PostponeInterruptsScope postpone(info.isolate()); |
1016 VMState<COMPILER> state(info.isolate()); | 1016 VMState<COMPILER> state(info.isolate()); |
1017 | 1017 |
1018 // Get rid of old list of shared function infos. | |
1019 script->set_shared_function_infos(Smi::FromInt(0)); | |
1020 | |
1021 info.parse_info()->set_global(); | 1018 info.parse_info()->set_global(); |
1022 if (!Parser::ParseStatic(info.parse_info())) return; | 1019 if (!Parser::ParseStatic(info.parse_info())) return; |
1023 | 1020 |
1024 LiveEditFunctionTracker tracker(info.isolate(), info.function()); | 1021 LiveEditFunctionTracker tracker(info.isolate(), info.function()); |
1025 if (!CompileUnoptimizedCode(&info)) return; | 1022 if (!CompileUnoptimizedCode(&info)) return; |
1026 if (info.has_shared_info()) { | 1023 if (info.has_shared_info()) { |
1027 Handle<ScopeInfo> scope_info = | 1024 Handle<ScopeInfo> scope_info = |
1028 ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); | 1025 ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
1029 info.shared_info()->set_scope_info(*scope_info); | 1026 info.shared_info()->set_scope_info(*scope_info); |
1030 } | 1027 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 // Eager parsing cannot benefit from cached data, and producing cached | 1068 // Eager parsing cannot benefit from cached data, and producing cached |
1072 // data while parsing eagerly is not implemented. | 1069 // data while parsing eagerly is not implemented. |
1073 parse_info->set_cached_data(nullptr); | 1070 parse_info->set_cached_data(nullptr); |
1074 parse_info->set_compile_options(ScriptCompiler::kNoCompileOptions); | 1071 parse_info->set_compile_options(ScriptCompiler::kNoCompileOptions); |
1075 } | 1072 } |
1076 if (!Parser::ParseStatic(parse_info)) { | 1073 if (!Parser::ParseStatic(parse_info)) { |
1077 return Handle<SharedFunctionInfo>::null(); | 1074 return Handle<SharedFunctionInfo>::null(); |
1078 } | 1075 } |
1079 } | 1076 } |
1080 | 1077 |
1081 info->MarkAsNewScript(); | |
1082 | |
1083 FunctionLiteral* lit = info->function(); | 1078 FunctionLiteral* lit = info->function(); |
1084 LiveEditFunctionTracker live_edit_tracker(isolate, lit); | 1079 LiveEditFunctionTracker live_edit_tracker(isolate, lit); |
1085 | 1080 |
1086 // Measure how long it takes to do the compilation; only take the | 1081 // Measure how long it takes to do the compilation; only take the |
1087 // rest of the function into account to avoid overlap with the | 1082 // rest of the function into account to avoid overlap with the |
1088 // parsing statistics. | 1083 // parsing statistics. |
1089 HistogramTimer* rate = info->is_eval() | 1084 HistogramTimer* rate = info->is_eval() |
1090 ? info->isolate()->counters()->compile_eval() | 1085 ? info->isolate()->counters()->compile_eval() |
1091 : info->isolate()->counters()->compile(); | 1086 : info->isolate()->counters()->compile(); |
1092 HistogramTimerScope timer(rate); | 1087 HistogramTimerScope timer(rate); |
1093 | 1088 |
1094 // Compile the code. | 1089 // Compile the code. |
1095 if (!CompileUnoptimizedCode(info)) { | 1090 if (!CompileUnoptimizedCode(info)) { |
1096 return Handle<SharedFunctionInfo>::null(); | 1091 return Handle<SharedFunctionInfo>::null(); |
1097 } | 1092 } |
1098 | 1093 |
1099 // Allocate function. | 1094 // Allocate function. |
1100 DCHECK(!info->code().is_null()); | 1095 DCHECK(!info->code().is_null()); |
1101 result = isolate->factory()->NewSharedFunctionInfo( | 1096 result = isolate->factory()->NewSharedFunctionInfo( |
1102 lit->name(), lit->materialized_literal_count(), lit->kind(), | 1097 lit->name(), lit->materialized_literal_count(), lit->kind(), |
1103 info->code(), | 1098 info->code(), |
1104 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), | 1099 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), |
1105 info->feedback_vector()); | 1100 info->feedback_vector()); |
1106 | 1101 |
1107 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); | 1102 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); |
1108 SharedFunctionInfo::InitFromFunctionLiteral(result, lit); | 1103 SharedFunctionInfo::InitFromFunctionLiteral(result, lit); |
1109 SharedFunctionInfo::SetScript(result, script); | 1104 result->set_script(*script); |
1110 result->set_is_toplevel(true); | 1105 result->set_is_toplevel(true); |
1111 | 1106 |
1112 Handle<String> script_name = script->name()->IsString() | 1107 Handle<String> script_name = script->name()->IsString() |
1113 ? Handle<String>(String::cast(script->name())) | 1108 ? Handle<String>(String::cast(script->name())) |
1114 : isolate->factory()->empty_string(); | 1109 : isolate->factory()->empty_string(); |
1115 Logger::LogEventsAndTags log_tag = info->is_eval() | 1110 Logger::LogEventsAndTags log_tag = info->is_eval() |
1116 ? Logger::EVAL_TAG | 1111 ? Logger::EVAL_TAG |
1117 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script); | 1112 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script); |
1118 | 1113 |
1119 PROFILE(isolate, CodeCreateEvent( | 1114 PROFILE(isolate, CodeCreateEvent( |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1329 parse_info->set_language_mode( | 1324 parse_info->set_language_mode( |
1330 static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); | 1325 static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); |
1331 | 1326 |
1332 CompilationInfo compile_info(parse_info); | 1327 CompilationInfo compile_info(parse_info); |
1333 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the | 1328 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the |
1334 // real code caching lands, streaming needs to be adapted to use it. | 1329 // real code caching lands, streaming needs to be adapted to use it. |
1335 return CompileToplevel(&compile_info); | 1330 return CompileToplevel(&compile_info); |
1336 } | 1331 } |
1337 | 1332 |
1338 | 1333 |
1339 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( | 1334 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( |
1340 FunctionLiteral* literal, Handle<Script> script, | 1335 FunctionLiteral* literal, Handle<Script> script, |
1341 CompilationInfo* outer_info) { | 1336 CompilationInfo* outer_info) { |
1342 // Precondition: code has been parsed and scopes have been analyzed. | 1337 // Precondition: code has been parsed and scopes have been analyzed. |
1343 MaybeHandle<SharedFunctionInfo> maybe_existing; | |
1344 if (outer_info->is_new_script()) { | |
1345 // There is no existing shared function info when compiling a new script. | |
1346 DCHECK(script->FindSharedFunctionInfo(literal).is_null()); | |
1347 } else { | |
1348 maybe_existing = script->FindSharedFunctionInfo(literal); | |
1349 } | |
1350 // We found an existing shared function info. If it's already compiled, | |
1351 // don't worry about compiling it, and simply return it. If it's not yet | |
1352 // compiled, continue to decide whether to eagerly compile. | |
1353 Handle<SharedFunctionInfo> existing; | |
1354 if (maybe_existing.ToHandle(&existing) && existing->is_compiled()) { | |
1355 return existing; | |
1356 } | |
1357 | |
1358 Zone zone; | 1338 Zone zone; |
1359 ParseInfo parse_info(&zone, script); | 1339 ParseInfo parse_info(&zone, script); |
1360 CompilationInfo info(&parse_info); | 1340 CompilationInfo info(&parse_info); |
1361 parse_info.set_literal(literal); | 1341 parse_info.set_literal(literal); |
1362 parse_info.set_scope(literal->scope()); | 1342 parse_info.set_scope(literal->scope()); |
1363 parse_info.set_language_mode(literal->scope()->language_mode()); | 1343 parse_info.set_language_mode(literal->scope()->language_mode()); |
1364 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 1344 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
1365 if (outer_info->is_new_script()) info.MarkAsNewScript(); | |
1366 | 1345 |
1367 Isolate* isolate = info.isolate(); | 1346 Isolate* isolate = info.isolate(); |
1368 Factory* factory = isolate->factory(); | 1347 Factory* factory = isolate->factory(); |
1369 LiveEditFunctionTracker live_edit_tracker(isolate, literal); | 1348 LiveEditFunctionTracker live_edit_tracker(isolate, literal); |
1370 // Determine if the function can be lazily compiled. This is necessary to | 1349 // Determine if the function can be lazily compiled. This is necessary to |
1371 // allow some of our builtin JS files to be lazily compiled. These | 1350 // allow some of our builtin JS files to be lazily compiled. These |
1372 // builtins cannot be handled lazily by the parser, since we have to know | 1351 // builtins cannot be handled lazily by the parser, since we have to know |
1373 // if a function uses the special natives syntax, which is something the | 1352 // if a function uses the special natives syntax, which is something the |
1374 // parser records. | 1353 // parser records. |
1375 // If the debugger requests compilation for break points, we cannot be | 1354 // If the debugger requests compilation for break points, we cannot be |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 DCHECK(!info.code().is_null()); | 1388 DCHECK(!info.code().is_null()); |
1410 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); | 1389 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
1411 if (literal->should_eager_compile() && | 1390 if (literal->should_eager_compile() && |
1412 literal->should_be_used_once_hint()) { | 1391 literal->should_be_used_once_hint()) { |
1413 info.code()->MarkToBeExecutedOnce(isolate); | 1392 info.code()->MarkToBeExecutedOnce(isolate); |
1414 } | 1393 } |
1415 } else { | 1394 } else { |
1416 return Handle<SharedFunctionInfo>::null(); | 1395 return Handle<SharedFunctionInfo>::null(); |
1417 } | 1396 } |
1418 | 1397 |
1419 if (maybe_existing.is_null()) { | 1398 // Create a shared function info object. |
1420 // Create a shared function info object. | 1399 Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo( |
1421 Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo( | 1400 literal->name(), literal->materialized_literal_count(), literal->kind(), |
1422 literal->name(), literal->materialized_literal_count(), literal->kind(), | 1401 info.code(), scope_info, info.feedback_vector()); |
1423 info.code(), scope_info, info.feedback_vector()); | |
1424 | 1402 |
1425 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); | 1403 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); |
1426 SharedFunctionInfo::SetScript(result, script); | 1404 result->set_script(*script); |
1427 result->set_is_toplevel(false); | 1405 result->set_is_toplevel(false); |
1428 | 1406 |
1429 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); | 1407 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); |
1430 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); | 1408 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); |
1431 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); | 1409 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); |
1432 | 1410 |
1433 // Set the expected number of properties for instances and return | 1411 // Set the expected number of properties for instances and return |
1434 // the resulting function. | 1412 // the resulting function. |
1435 SetExpectedNofPropertiesFromEstimate(result, | 1413 SetExpectedNofPropertiesFromEstimate(result, |
1436 literal->expected_property_count()); | 1414 literal->expected_property_count()); |
1437 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); | 1415 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); |
1438 return result; | 1416 return result; |
1439 } else { | |
1440 // We may have additional data from compilation now. | |
1441 DCHECK(!existing->is_compiled()); | |
1442 existing->ReplaceCode(*info.code()); | |
1443 existing->set_scope_info(*scope_info); | |
1444 existing->set_feedback_vector(*info.feedback_vector()); | |
1445 return existing; | |
1446 } | |
1447 } | 1417 } |
1448 | 1418 |
1449 | 1419 |
1450 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function, | 1420 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function, |
1451 Handle<Code> current_code, | 1421 Handle<Code> current_code, |
1452 ConcurrencyMode mode, | 1422 ConcurrencyMode mode, |
1453 BailoutId osr_ast_id) { | 1423 BailoutId osr_ast_id) { |
1454 Handle<Code> cached_code; | 1424 Handle<Code> cached_code; |
1455 if (GetCodeFromOptimizedCodeMap( | 1425 if (GetCodeFromOptimizedCodeMap( |
1456 function, osr_ast_id).ToHandle(&cached_code)) { | 1426 function, osr_ast_id).ToHandle(&cached_code)) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1597 | 1567 |
1598 | 1568 |
1599 #if DEBUG | 1569 #if DEBUG |
1600 void CompilationInfo::PrintAstForTesting() { | 1570 void CompilationInfo::PrintAstForTesting() { |
1601 PrintF("--- Source from AST ---\n%s\n", | 1571 PrintF("--- Source from AST ---\n%s\n", |
1602 PrettyPrinter(isolate(), zone()).PrintProgram(function())); | 1572 PrettyPrinter(isolate(), zone()).PrintProgram(function())); |
1603 } | 1573 } |
1604 #endif | 1574 #endif |
1605 } // namespace internal | 1575 } // namespace internal |
1606 } // namespace v8 | 1576 } // namespace v8 |
OLD | NEW |