| 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 860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 | 1000 |
| 998 | 1001 |
| 999 void Compiler::CompileForLiveEdit(Handle<Script> script) { | 1002 void Compiler::CompileForLiveEdit(Handle<Script> script) { |
| 1000 // TODO(635): support extensions. | 1003 // TODO(635): support extensions. |
| 1001 Zone zone; | 1004 Zone zone; |
| 1002 ParseInfo parse_info(&zone, script); | 1005 ParseInfo parse_info(&zone, script); |
| 1003 CompilationInfo info(&parse_info); | 1006 CompilationInfo info(&parse_info); |
| 1004 PostponeInterruptsScope postpone(info.isolate()); | 1007 PostponeInterruptsScope postpone(info.isolate()); |
| 1005 VMState<COMPILER> state(info.isolate()); | 1008 VMState<COMPILER> state(info.isolate()); |
| 1006 | 1009 |
| 1010 // Get rid of old list of shared function infos. |
| 1011 script->set_shared_function_infos(Smi::FromInt(0)); |
| 1012 |
| 1007 info.parse_info()->set_global(); | 1013 info.parse_info()->set_global(); |
| 1008 if (!Parser::ParseStatic(info.parse_info())) return; | 1014 if (!Parser::ParseStatic(info.parse_info())) return; |
| 1009 | 1015 |
| 1010 LiveEditFunctionTracker tracker(info.isolate(), info.function()); | 1016 LiveEditFunctionTracker tracker(info.isolate(), info.function()); |
| 1011 if (!CompileUnoptimizedCode(&info)) return; | 1017 if (!CompileUnoptimizedCode(&info)) return; |
| 1012 if (info.has_shared_info()) { | 1018 if (info.has_shared_info()) { |
| 1013 Handle<ScopeInfo> scope_info = | 1019 Handle<ScopeInfo> scope_info = |
| 1014 ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); | 1020 ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
| 1015 info.shared_info()->set_scope_info(*scope_info); | 1021 info.shared_info()->set_scope_info(*scope_info); |
| 1016 } | 1022 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 // Eager parsing cannot benefit from cached data, and producing cached | 1063 // Eager parsing cannot benefit from cached data, and producing cached |
| 1058 // data while parsing eagerly is not implemented. | 1064 // data while parsing eagerly is not implemented. |
| 1059 parse_info->set_cached_data(nullptr); | 1065 parse_info->set_cached_data(nullptr); |
| 1060 parse_info->set_compile_options(ScriptCompiler::kNoCompileOptions); | 1066 parse_info->set_compile_options(ScriptCompiler::kNoCompileOptions); |
| 1061 } | 1067 } |
| 1062 if (!Parser::ParseStatic(parse_info)) { | 1068 if (!Parser::ParseStatic(parse_info)) { |
| 1063 return Handle<SharedFunctionInfo>::null(); | 1069 return Handle<SharedFunctionInfo>::null(); |
| 1064 } | 1070 } |
| 1065 } | 1071 } |
| 1066 | 1072 |
| 1073 info->MarkAsFirstCompile(); |
| 1074 |
| 1067 FunctionLiteral* lit = info->function(); | 1075 FunctionLiteral* lit = info->function(); |
| 1068 LiveEditFunctionTracker live_edit_tracker(isolate, lit); | 1076 LiveEditFunctionTracker live_edit_tracker(isolate, lit); |
| 1069 | 1077 |
| 1070 // Measure how long it takes to do the compilation; only take the | 1078 // Measure how long it takes to do the compilation; only take the |
| 1071 // rest of the function into account to avoid overlap with the | 1079 // rest of the function into account to avoid overlap with the |
| 1072 // parsing statistics. | 1080 // parsing statistics. |
| 1073 HistogramTimer* rate = info->is_eval() | 1081 HistogramTimer* rate = info->is_eval() |
| 1074 ? info->isolate()->counters()->compile_eval() | 1082 ? info->isolate()->counters()->compile_eval() |
| 1075 : info->isolate()->counters()->compile(); | 1083 : info->isolate()->counters()->compile(); |
| 1076 HistogramTimerScope timer(rate); | 1084 HistogramTimerScope timer(rate); |
| 1077 | 1085 |
| 1078 // Compile the code. | 1086 // Compile the code. |
| 1079 if (!CompileUnoptimizedCode(info)) { | 1087 if (!CompileUnoptimizedCode(info)) { |
| 1080 return Handle<SharedFunctionInfo>::null(); | 1088 return Handle<SharedFunctionInfo>::null(); |
| 1081 } | 1089 } |
| 1082 | 1090 |
| 1083 // Allocate function. | 1091 // Allocate function. |
| 1084 DCHECK(!info->code().is_null()); | 1092 DCHECK(!info->code().is_null()); |
| 1085 result = isolate->factory()->NewSharedFunctionInfo( | 1093 result = isolate->factory()->NewSharedFunctionInfo( |
| 1086 lit->name(), lit->materialized_literal_count(), lit->kind(), | 1094 lit->name(), lit->materialized_literal_count(), lit->kind(), |
| 1087 info->code(), | 1095 info->code(), |
| 1088 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), | 1096 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), |
| 1089 info->feedback_vector()); | 1097 info->feedback_vector()); |
| 1090 | 1098 |
| 1091 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); | 1099 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); |
| 1092 SharedFunctionInfo::InitFromFunctionLiteral(result, lit); | 1100 SharedFunctionInfo::InitFromFunctionLiteral(result, lit); |
| 1093 result->set_script(*script); | 1101 SharedFunctionInfo::SetScript(result, script); |
| 1094 result->set_is_toplevel(true); | 1102 result->set_is_toplevel(true); |
| 1095 | 1103 |
| 1096 Handle<String> script_name = script->name()->IsString() | 1104 Handle<String> script_name = script->name()->IsString() |
| 1097 ? Handle<String>(String::cast(script->name())) | 1105 ? Handle<String>(String::cast(script->name())) |
| 1098 : isolate->factory()->empty_string(); | 1106 : isolate->factory()->empty_string(); |
| 1099 Logger::LogEventsAndTags log_tag = info->is_eval() | 1107 Logger::LogEventsAndTags log_tag = info->is_eval() |
| 1100 ? Logger::EVAL_TAG | 1108 ? Logger::EVAL_TAG |
| 1101 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script); | 1109 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script); |
| 1102 | 1110 |
| 1103 PROFILE(isolate, CodeCreateEvent( | 1111 PROFILE(isolate, CodeCreateEvent( |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1313 parse_info->set_language_mode( | 1321 parse_info->set_language_mode( |
| 1314 static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); | 1322 static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); |
| 1315 | 1323 |
| 1316 CompilationInfo compile_info(parse_info); | 1324 CompilationInfo compile_info(parse_info); |
| 1317 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the | 1325 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the |
| 1318 // real code caching lands, streaming needs to be adapted to use it. | 1326 // real code caching lands, streaming needs to be adapted to use it. |
| 1319 return CompileToplevel(&compile_info); | 1327 return CompileToplevel(&compile_info); |
| 1320 } | 1328 } |
| 1321 | 1329 |
| 1322 | 1330 |
| 1323 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( | 1331 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( |
| 1324 FunctionLiteral* literal, Handle<Script> script, | 1332 FunctionLiteral* literal, Handle<Script> script, |
| 1325 CompilationInfo* outer_info) { | 1333 CompilationInfo* outer_info) { |
| 1326 // Precondition: code has been parsed and scopes have been analyzed. | 1334 // Precondition: code has been parsed and scopes have been analyzed. |
| 1335 MaybeHandle<SharedFunctionInfo> maybe_existing; |
| 1336 if (outer_info->is_first_compile()) { |
| 1337 // On the first compile, there are no existing shared function info for |
| 1338 // inner functions yet, so do not try to find them. |
| 1339 DCHECK(script->FindSharedFunctionInfo(literal).is_null()); |
| 1340 } else { |
| 1341 maybe_existing = script->FindSharedFunctionInfo(literal); |
| 1342 } |
| 1343 // We found an existing shared function info. If it's already compiled, |
| 1344 // don't worry about compiling it, and simply return it. If it's not yet |
| 1345 // compiled, continue to decide whether to eagerly compile. |
| 1346 Handle<SharedFunctionInfo> existing; |
| 1347 if (maybe_existing.ToHandle(&existing) && existing->is_compiled()) { |
| 1348 return existing; |
| 1349 } |
| 1350 |
| 1327 Zone zone; | 1351 Zone zone; |
| 1328 ParseInfo parse_info(&zone, script); | 1352 ParseInfo parse_info(&zone, script); |
| 1329 CompilationInfo info(&parse_info); | 1353 CompilationInfo info(&parse_info); |
| 1330 parse_info.set_literal(literal); | 1354 parse_info.set_literal(literal); |
| 1331 parse_info.set_scope(literal->scope()); | 1355 parse_info.set_scope(literal->scope()); |
| 1332 parse_info.set_language_mode(literal->scope()->language_mode()); | 1356 parse_info.set_language_mode(literal->scope()->language_mode()); |
| 1333 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 1357 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
| 1358 if (outer_info->is_first_compile()) info.MarkAsFirstCompile(); |
| 1334 | 1359 |
| 1335 Isolate* isolate = info.isolate(); | 1360 Isolate* isolate = info.isolate(); |
| 1336 Factory* factory = isolate->factory(); | 1361 Factory* factory = isolate->factory(); |
| 1337 LiveEditFunctionTracker live_edit_tracker(isolate, literal); | 1362 LiveEditFunctionTracker live_edit_tracker(isolate, literal); |
| 1338 // Determine if the function can be lazily compiled. This is necessary to | 1363 // Determine if the function can be lazily compiled. This is necessary to |
| 1339 // allow some of our builtin JS files to be lazily compiled. These | 1364 // allow some of our builtin JS files to be lazily compiled. These |
| 1340 // builtins cannot be handled lazily by the parser, since we have to know | 1365 // builtins cannot be handled lazily by the parser, since we have to know |
| 1341 // if a function uses the special natives syntax, which is something the | 1366 // if a function uses the special natives syntax, which is something the |
| 1342 // parser records. | 1367 // parser records. |
| 1343 // If the debugger requests compilation for break points, we cannot be | 1368 // If the debugger requests compilation for break points, we cannot be |
| 1344 // aggressive about lazy compilation, because it might trigger compilation | 1369 // aggressive about lazy compilation, because it might trigger compilation |
| 1345 // of functions without an outer context when setting a breakpoint through | 1370 // of functions without an outer context when setting a breakpoint through |
| 1346 // Debug::FindSharedFunctionInfoInScript. | 1371 // Debug::FindSharedFunctionInfoInScript. |
| 1347 bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext(); | 1372 bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext(); |
| 1348 bool allow_lazy = | 1373 bool allow_lazy = |
| 1349 literal->AllowsLazyCompilation() && | 1374 literal->AllowsLazyCompilation() && |
| 1350 !DebuggerWantsEagerCompilation(isolate, allow_lazy_without_ctx); | 1375 !DebuggerWantsEagerCompilation(isolate, allow_lazy_without_ctx); |
| 1351 | 1376 |
| 1352 if (outer_info->parse_info()->is_toplevel() && outer_info->will_serialize()) { | 1377 if (outer_info->parse_info()->is_toplevel() && outer_info->will_serialize()) { |
| 1353 // Make sure that if the toplevel code (possibly to be serialized), | 1378 // Make sure that if the toplevel code (possibly to be serialized), |
| 1354 // the inner function must be allowed to be compiled lazily. | 1379 // the inner function must be allowed to be compiled lazily. |
| 1355 // This is necessary to serialize toplevel code without inner functions. | 1380 // This is necessary to serialize toplevel code without inner functions. |
| 1356 DCHECK(allow_lazy); | 1381 DCHECK(allow_lazy); |
| 1357 } | 1382 } |
| 1358 | 1383 |
| 1384 bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile(); |
| 1385 |
| 1359 // Generate code | 1386 // Generate code |
| 1360 Handle<ScopeInfo> scope_info; | 1387 Handle<ScopeInfo> scope_info; |
| 1361 if (FLAG_lazy && allow_lazy && !literal->should_eager_compile()) { | 1388 if (lazy) { |
| 1362 Handle<Code> code = isolate->builtins()->CompileLazy(); | 1389 Handle<Code> code = isolate->builtins()->CompileLazy(); |
| 1363 info.SetCode(code); | 1390 info.SetCode(code); |
| 1364 // There's no need in theory for a lazy-compiled function to have a type | 1391 // There's no need in theory for a lazy-compiled function to have a type |
| 1365 // feedback vector, but some parts of the system expect all | 1392 // feedback vector, but some parts of the system expect all |
| 1366 // SharedFunctionInfo instances to have one. The size of the vector depends | 1393 // SharedFunctionInfo instances to have one. The size of the vector depends |
| 1367 // on how many feedback-needing nodes are in the tree, and when lazily | 1394 // on how many feedback-needing nodes are in the tree, and when lazily |
| 1368 // parsing we might not know that, if this function was never parsed before. | 1395 // parsing we might not know that, if this function was never parsed before. |
| 1369 // In that case the vector will be replaced the next time MakeCode is | 1396 // In that case the vector will be replaced the next time MakeCode is |
| 1370 // called. | 1397 // called. |
| 1371 info.EnsureFeedbackVector(); | 1398 info.EnsureFeedbackVector(); |
| 1372 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); | 1399 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); |
| 1373 } else if (Renumber(info.parse_info()) && | 1400 } else if (Renumber(info.parse_info()) && |
| 1374 FullCodeGenerator::MakeCode(&info)) { | 1401 FullCodeGenerator::MakeCode(&info)) { |
| 1375 // MakeCode will ensure that the feedback vector is present and | 1402 // MakeCode will ensure that the feedback vector is present and |
| 1376 // appropriately sized. | 1403 // appropriately sized. |
| 1377 DCHECK(!info.code().is_null()); | 1404 DCHECK(!info.code().is_null()); |
| 1378 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); | 1405 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
| 1379 if (literal->should_eager_compile() && | 1406 if (literal->should_eager_compile() && |
| 1380 literal->should_be_used_once_hint()) { | 1407 literal->should_be_used_once_hint()) { |
| 1381 info.code()->MarkToBeExecutedOnce(isolate); | 1408 info.code()->MarkToBeExecutedOnce(isolate); |
| 1382 } | 1409 } |
| 1383 } else { | 1410 } else { |
| 1384 return Handle<SharedFunctionInfo>::null(); | 1411 return Handle<SharedFunctionInfo>::null(); |
| 1385 } | 1412 } |
| 1386 | 1413 |
| 1387 // Create a shared function info object. | 1414 if (maybe_existing.is_null()) { |
| 1388 Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo( | 1415 // Create a shared function info object. |
| 1389 literal->name(), literal->materialized_literal_count(), literal->kind(), | 1416 Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo( |
| 1390 info.code(), scope_info, info.feedback_vector()); | 1417 literal->name(), literal->materialized_literal_count(), literal->kind(), |
| 1418 info.code(), scope_info, info.feedback_vector()); |
| 1391 | 1419 |
| 1392 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); | 1420 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); |
| 1393 result->set_script(*script); | 1421 SharedFunctionInfo::SetScript(result, script); |
| 1394 result->set_is_toplevel(false); | 1422 result->set_is_toplevel(false); |
| 1423 // If the outer function has been compiled before, we cannot be sure that |
| 1424 // shared function info for this function literal has been created for the |
| 1425 // first time. It may have already been compiled previously. |
| 1426 result->set_never_compiled(outer_info->is_first_compile() && lazy); |
| 1395 | 1427 |
| 1396 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); | 1428 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); |
| 1397 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); | 1429 result->set_allows_lazy_compilation(literal->AllowsLazyCompilation()); |
| 1398 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); | 1430 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); |
| 1399 | 1431 |
| 1400 // Set the expected number of properties for instances and return | 1432 // Set the expected number of properties for instances and return |
| 1401 // the resulting function. | 1433 // the resulting function. |
| 1402 SetExpectedNofPropertiesFromEstimate(result, | 1434 SetExpectedNofPropertiesFromEstimate(result, |
| 1403 literal->expected_property_count()); | 1435 literal->expected_property_count()); |
| 1404 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); | 1436 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); |
| 1405 return result; | 1437 return result; |
| 1438 } else { |
| 1439 // We may have additional data from compilation now. |
| 1440 DCHECK(!existing->is_compiled()); |
| 1441 existing->ReplaceCode(*info.code()); |
| 1442 existing->set_scope_info(*scope_info); |
| 1443 existing->set_feedback_vector(*info.feedback_vector()); |
| 1444 return existing; |
| 1445 } |
| 1406 } | 1446 } |
| 1407 | 1447 |
| 1408 | 1448 |
| 1409 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function, | 1449 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function, |
| 1410 Handle<Code> current_code, | 1450 Handle<Code> current_code, |
| 1411 ConcurrencyMode mode, | 1451 ConcurrencyMode mode, |
| 1412 BailoutId osr_ast_id) { | 1452 BailoutId osr_ast_id) { |
| 1413 Handle<Code> cached_code; | 1453 Handle<Code> cached_code; |
| 1414 if (GetCodeFromOptimizedCodeMap( | 1454 if (GetCodeFromOptimizedCodeMap( |
| 1415 function, osr_ast_id).ToHandle(&cached_code)) { | 1455 function, osr_ast_id).ToHandle(&cached_code)) { |
| 1416 if (FLAG_trace_opt) { | 1456 if (FLAG_trace_opt) { |
| 1417 PrintF("[found optimized code for "); | 1457 PrintF("[found optimized code for "); |
| 1418 function->ShortPrint(); | 1458 function->ShortPrint(); |
| 1419 if (!osr_ast_id.IsNone()) { | 1459 if (!osr_ast_id.IsNone()) { |
| 1420 PrintF(" at OSR AST id %d", osr_ast_id.ToInt()); | 1460 PrintF(" at OSR AST id %d", osr_ast_id.ToInt()); |
| 1421 } | 1461 } |
| 1422 PrintF("]\n"); | 1462 PrintF("]\n"); |
| 1423 } | 1463 } |
| 1424 return cached_code; | 1464 return cached_code; |
| 1425 } | 1465 } |
| 1426 | 1466 |
| 1427 SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(function)); | 1467 Isolate* isolate = function->GetIsolate(); |
| 1428 Isolate* isolate = info->isolate(); | |
| 1429 DCHECK(AllowCompilation::IsAllowed(isolate)); | 1468 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1430 VMState<COMPILER> state(isolate); | |
| 1431 DCHECK(!isolate->has_pending_exception()); | |
| 1432 PostponeInterruptsScope postpone(isolate); | |
| 1433 | 1469 |
| 1434 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1470 Handle<SharedFunctionInfo> shared(function->shared(), isolate); |
| 1435 if (shared->code()->kind() != Code::FUNCTION || | 1471 if (!shared->is_compiled() || |
| 1436 ScopeInfo::Empty(isolate) == shared->scope_info()) { | 1472 shared->scope_info() == ScopeInfo::Empty(isolate)) { |
| 1437 // The function was never compiled. Compile it unoptimized first. | 1473 // The function was never compiled. Compile it unoptimized first. |
| 1438 // TODO(titzer): reuse the AST and scope info from this compile. | 1474 // TODO(titzer): reuse the AST and scope info from this compile. |
| 1439 CompilationInfoWithZone nested(function); | 1475 CompilationInfoWithZone unoptimized(function); |
| 1440 nested.EnableDeoptimizationSupport(); | 1476 unoptimized.EnableDeoptimizationSupport(); |
| 1441 if (!GetUnoptimizedCodeCommon(&nested).ToHandle(¤t_code)) { | 1477 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(¤t_code)) { |
| 1442 return MaybeHandle<Code>(); | 1478 return MaybeHandle<Code>(); |
| 1443 } | 1479 } |
| 1444 shared->ReplaceCode(*current_code); | 1480 shared->ReplaceCode(*current_code); |
| 1445 } | 1481 } |
| 1482 |
| 1446 current_code->set_profiler_ticks(0); | 1483 current_code->set_profiler_ticks(0); |
| 1447 | 1484 |
| 1448 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing | 1485 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing |
| 1449 // an eval scope and hence would fail at parsing the eval source again. | 1486 // an eval scope and hence would fail at parsing the eval source again. |
| 1450 if (shared->disable_optimization_reason() == kEval) { | 1487 if (shared->disable_optimization_reason() == kEval) { |
| 1451 return MaybeHandle<Code>(); | 1488 return MaybeHandle<Code>(); |
| 1452 } | 1489 } |
| 1453 | 1490 |
| 1454 // TODO(mstarzinger): We cannot properly deserialize a scope chain for the | 1491 // TODO(mstarzinger): We cannot properly deserialize a scope chain for the |
| 1455 // builtin context, hence Genesis::InstallExperimentalNatives would fail. | 1492 // builtin context, hence Genesis::InstallExperimentalNatives would fail. |
| 1456 if (shared->is_toplevel() && isolate->bootstrapper()->IsActive()) { | 1493 if (shared->is_toplevel() && isolate->bootstrapper()->IsActive()) { |
| 1457 return MaybeHandle<Code>(); | 1494 return MaybeHandle<Code>(); |
| 1458 } | 1495 } |
| 1459 | 1496 |
| 1497 SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(function)); |
| 1498 VMState<COMPILER> state(isolate); |
| 1499 DCHECK(!isolate->has_pending_exception()); |
| 1500 PostponeInterruptsScope postpone(isolate); |
| 1501 |
| 1460 info->SetOptimizing(osr_ast_id, current_code); | 1502 info->SetOptimizing(osr_ast_id, current_code); |
| 1461 | 1503 |
| 1462 if (mode == CONCURRENT) { | 1504 if (mode == CONCURRENT) { |
| 1463 if (GetOptimizedCodeLater(info.get())) { | 1505 if (GetOptimizedCodeLater(info.get())) { |
| 1464 info.Detach(); // The background recompile job owns this now. | 1506 info.Detach(); // The background recompile job owns this now. |
| 1465 return isolate->builtins()->InOptimizationQueue(); | 1507 return isolate->builtins()->InOptimizationQueue(); |
| 1466 } | 1508 } |
| 1467 } else { | 1509 } else { |
| 1468 if (GetOptimizedCodeNow(info.get())) return info->code(); | 1510 if (GetOptimizedCodeNow(info.get())) return info->code(); |
| 1469 } | 1511 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1564 | 1606 |
| 1565 | 1607 |
| 1566 #if DEBUG | 1608 #if DEBUG |
| 1567 void CompilationInfo::PrintAstForTesting() { | 1609 void CompilationInfo::PrintAstForTesting() { |
| 1568 PrintF("--- Source from AST ---\n%s\n", | 1610 PrintF("--- Source from AST ---\n%s\n", |
| 1569 PrettyPrinter(isolate(), zone()).PrintProgram(function())); | 1611 PrettyPrinter(isolate(), zone()).PrintProgram(function())); |
| 1570 } | 1612 } |
| 1571 #endif | 1613 #endif |
| 1572 } // namespace internal | 1614 } // namespace internal |
| 1573 } // namespace v8 | 1615 } // namespace v8 |
| OLD | NEW |