| 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 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "src/asmjs/asm-js.h" | 10 #include "src/asmjs/asm-js.h" |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 for (auto it : *literals) { | 496 for (auto it : *literals) { |
| 497 FunctionLiteral* literal = it->value(); | 497 FunctionLiteral* literal = it->value(); |
| 498 Handle<SharedFunctionInfo> shared = | 498 Handle<SharedFunctionInfo> shared = |
| 499 Compiler::GetSharedFunctionInfo(literal, script, outer_info); | 499 Compiler::GetSharedFunctionInfo(literal, script, outer_info); |
| 500 if (shared->is_compiled()) continue; | 500 if (shared->is_compiled()) continue; |
| 501 | 501 |
| 502 // The {literal} has already been numbered because AstNumbering decends into | 502 // The {literal} has already been numbered because AstNumbering decends into |
| 503 // eagerly compiled function literals. | 503 // eagerly compiled function literals. |
| 504 SetSharedFunctionFlagsFromLiteral(literal, shared); | 504 SetSharedFunctionFlagsFromLiteral(literal, shared); |
| 505 | 505 |
| 506 ParseInfo parse_info(script); | 506 Zone zone(isolate->allocator(), ZONE_NAME); |
| 507 ParseInfo parse_info(&zone, script); |
| 507 parse_info.set_literal(literal); | 508 parse_info.set_literal(literal); |
| 508 parse_info.set_shared_info(shared); | 509 parse_info.set_shared_info(shared); |
| 509 parse_info.set_function_literal_id(shared->function_literal_id()); | 510 parse_info.set_function_literal_id(shared->function_literal_id()); |
| 510 parse_info.set_language_mode(literal->scope()->language_mode()); | 511 parse_info.set_language_mode(literal->scope()->language_mode()); |
| 511 parse_info.set_ast_value_factory( | 512 parse_info.set_ast_value_factory( |
| 512 outer_info->parse_info()->ast_value_factory()); | 513 outer_info->parse_info()->ast_value_factory()); |
| 513 parse_info.set_ast_value_factory_owned(false); | 514 parse_info.set_ast_value_factory_owned(false); |
| 514 | 515 |
| 515 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 516 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
| 516 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 517 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 880 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); | 881 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
| 881 } | 882 } |
| 882 info->closure()->ReplaceCode(shared->code()); | 883 info->closure()->ReplaceCode(shared->code()); |
| 883 return CompilationJob::FAILED; | 884 return CompilationJob::FAILED; |
| 884 } | 885 } |
| 885 | 886 |
| 886 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) { | 887 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) { |
| 887 Isolate* isolate = function->GetIsolate(); | 888 Isolate* isolate = function->GetIsolate(); |
| 888 VMState<COMPILER> state(isolate); | 889 VMState<COMPILER> state(isolate); |
| 889 PostponeInterruptsScope postpone(isolate); | 890 PostponeInterruptsScope postpone(isolate); |
| 890 ParseInfo parse_info(handle(function->shared())); | 891 Zone zone(isolate->allocator(), ZONE_NAME); |
| 892 ParseInfo parse_info(&zone, handle(function->shared())); |
| 891 CompilationInfo info(&parse_info, function); | 893 CompilationInfo info(&parse_info, function); |
| 892 | 894 |
| 893 DCHECK(function->shared()->is_compiled()); | 895 DCHECK(function->shared()->is_compiled()); |
| 894 | 896 |
| 895 // Function no longer needs to be tiered up | 897 // Function no longer needs to be tiered up |
| 896 function->shared()->set_marked_for_tier_up(false); | 898 function->shared()->set_marked_for_tier_up(false); |
| 897 | 899 |
| 898 // Reset profiler ticks, function is no longer considered hot. | 900 // Reset profiler ticks, function is no longer considered hot. |
| 899 if (function->shared()->HasBytecodeArray()) { | 901 if (function->shared()->HasBytecodeArray()) { |
| 900 function->shared()->set_profiler_ticks(0); | 902 function->shared()->set_profiler_ticks(0); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1013 if (function->shared()->is_compiled()) { | 1015 if (function->shared()->is_compiled()) { |
| 1014 return Handle<Code>(function->shared()->code()); | 1016 return Handle<Code>(function->shared()->code()); |
| 1015 } | 1017 } |
| 1016 | 1018 |
| 1017 if (function->shared()->HasBytecodeArray()) { | 1019 if (function->shared()->HasBytecodeArray()) { |
| 1018 Handle<Code> entry = isolate->builtins()->InterpreterEntryTrampoline(); | 1020 Handle<Code> entry = isolate->builtins()->InterpreterEntryTrampoline(); |
| 1019 function->shared()->ReplaceCode(*entry); | 1021 function->shared()->ReplaceCode(*entry); |
| 1020 return entry; | 1022 return entry; |
| 1021 } | 1023 } |
| 1022 | 1024 |
| 1023 ParseInfo parse_info(handle(function->shared())); | 1025 Zone zone(isolate->allocator(), ZONE_NAME); |
| 1026 ParseInfo parse_info(&zone, handle(function->shared())); |
| 1024 CompilationInfo info(&parse_info, function); | 1027 CompilationInfo info(&parse_info, function); |
| 1025 Handle<Code> result; | 1028 Handle<Code> result; |
| 1026 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCode(&info), Code); | 1029 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCode(&info), Code); |
| 1027 | 1030 |
| 1028 if (FLAG_always_opt && !info.shared_info()->HasAsmWasmData()) { | 1031 if (FLAG_always_opt && !info.shared_info()->HasAsmWasmData()) { |
| 1029 Handle<Code> opt_code; | 1032 Handle<Code> opt_code; |
| 1030 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) | 1033 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) |
| 1031 .ToHandle(&opt_code)) { | 1034 .ToHandle(&opt_code)) { |
| 1032 result = opt_code; | 1035 result = opt_code; |
| 1033 } | 1036 } |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1192 Handle<Code> code; | 1195 Handle<Code> code; |
| 1193 if (!GetOptimizedCode(function, mode).ToHandle(&code)) { | 1196 if (!GetOptimizedCode(function, mode).ToHandle(&code)) { |
| 1194 // Optimization failed, get unoptimized code. | 1197 // Optimization failed, get unoptimized code. |
| 1195 DCHECK(!isolate->has_pending_exception()); | 1198 DCHECK(!isolate->has_pending_exception()); |
| 1196 if (function->shared()->is_compiled()) { | 1199 if (function->shared()->is_compiled()) { |
| 1197 code = handle(function->shared()->code(), isolate); | 1200 code = handle(function->shared()->code(), isolate); |
| 1198 } else if (function->shared()->HasBytecodeArray()) { | 1201 } else if (function->shared()->HasBytecodeArray()) { |
| 1199 code = isolate->builtins()->InterpreterEntryTrampoline(); | 1202 code = isolate->builtins()->InterpreterEntryTrampoline(); |
| 1200 function->shared()->ReplaceCode(*code); | 1203 function->shared()->ReplaceCode(*code); |
| 1201 } else { | 1204 } else { |
| 1202 ParseInfo parse_info(handle(function->shared())); | 1205 Zone zone(isolate->allocator(), ZONE_NAME); |
| 1206 ParseInfo parse_info(&zone, handle(function->shared())); |
| 1203 CompilationInfo info(&parse_info, function); | 1207 CompilationInfo info(&parse_info, function); |
| 1204 if (!GetUnoptimizedCode(&info).ToHandle(&code)) { | 1208 if (!GetUnoptimizedCode(&info).ToHandle(&code)) { |
| 1205 return false; | 1209 return false; |
| 1206 } | 1210 } |
| 1207 } | 1211 } |
| 1208 } | 1212 } |
| 1209 | 1213 |
| 1210 // Install code on closure. | 1214 // Install code on closure. |
| 1211 function->ReplaceCode(*code); | 1215 function->ReplaceCode(*code); |
| 1212 JSFunction::EnsureLiterals(function); | 1216 JSFunction::EnsureLiterals(function); |
| 1213 | 1217 |
| 1214 // Check postconditions on success. | 1218 // Check postconditions on success. |
| 1215 DCHECK(!isolate->has_pending_exception()); | 1219 DCHECK(!isolate->has_pending_exception()); |
| 1216 DCHECK(function->shared()->is_compiled()); | 1220 DCHECK(function->shared()->is_compiled()); |
| 1217 DCHECK(function->is_compiled()); | 1221 DCHECK(function->is_compiled()); |
| 1218 return true; | 1222 return true; |
| 1219 } | 1223 } |
| 1220 | 1224 |
| 1221 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { | 1225 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { |
| 1222 Isolate* isolate = shared->GetIsolate(); | 1226 Isolate* isolate = shared->GetIsolate(); |
| 1223 DCHECK(AllowCompilation::IsAllowed(isolate)); | 1227 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1224 | 1228 |
| 1225 // Start a compilation. | 1229 // Start a compilation. |
| 1226 ParseInfo parse_info(shared); | 1230 Zone zone(isolate->allocator(), ZONE_NAME); |
| 1231 ParseInfo parse_info(&zone, shared); |
| 1227 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1232 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
| 1228 info.MarkAsDebug(); | 1233 info.MarkAsDebug(); |
| 1229 if (GetUnoptimizedCode(&info).is_null()) { | 1234 if (GetUnoptimizedCode(&info).is_null()) { |
| 1230 isolate->clear_pending_exception(); | 1235 isolate->clear_pending_exception(); |
| 1231 return false; | 1236 return false; |
| 1232 } | 1237 } |
| 1233 | 1238 |
| 1234 // Check postconditions on success. | 1239 // Check postconditions on success. |
| 1235 DCHECK(!isolate->has_pending_exception()); | 1240 DCHECK(!isolate->has_pending_exception()); |
| 1236 DCHECK(shared->is_compiled()); | 1241 DCHECK(shared->is_compiled()); |
| 1237 DCHECK(shared->HasDebugCode()); | 1242 DCHECK(shared->HasDebugCode()); |
| 1238 return true; | 1243 return true; |
| 1239 } | 1244 } |
| 1240 | 1245 |
| 1241 MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) { | 1246 MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) { |
| 1242 Isolate* isolate = script->GetIsolate(); | 1247 Isolate* isolate = script->GetIsolate(); |
| 1243 DCHECK(AllowCompilation::IsAllowed(isolate)); | 1248 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1244 | 1249 |
| 1245 // In order to ensure that live edit function info collection finds the newly | 1250 // In order to ensure that live edit function info collection finds the newly |
| 1246 // generated shared function infos, clear the script's list temporarily | 1251 // generated shared function infos, clear the script's list temporarily |
| 1247 // and restore it at the end of this method. | 1252 // and restore it at the end of this method. |
| 1248 Handle<FixedArray> old_function_infos(script->shared_function_infos(), | 1253 Handle<FixedArray> old_function_infos(script->shared_function_infos(), |
| 1249 isolate); | 1254 isolate); |
| 1250 script->set_shared_function_infos(isolate->heap()->empty_fixed_array()); | 1255 script->set_shared_function_infos(isolate->heap()->empty_fixed_array()); |
| 1251 | 1256 |
| 1252 // Start a compilation. | 1257 // Start a compilation. |
| 1253 ParseInfo parse_info(script); | 1258 Zone zone(isolate->allocator(), ZONE_NAME); |
| 1259 ParseInfo parse_info(&zone, script); |
| 1254 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1260 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
| 1255 info.MarkAsDebug(); | 1261 info.MarkAsDebug(); |
| 1256 | 1262 |
| 1257 // TODO(635): support extensions. | 1263 // TODO(635): support extensions. |
| 1258 const bool compilation_succeeded = !CompileToplevel(&info).is_null(); | 1264 const bool compilation_succeeded = !CompileToplevel(&info).is_null(); |
| 1259 Handle<JSArray> infos; | 1265 Handle<JSArray> infos; |
| 1260 if (compilation_succeeded) { | 1266 if (compilation_succeeded) { |
| 1261 // Check postconditions on success. | 1267 // Check postconditions on success. |
| 1262 DCHECK(!isolate->has_pending_exception()); | 1268 DCHECK(!isolate->has_pending_exception()); |
| 1263 infos = LiveEditFunctionTracker::Collect(parse_info.literal(), script, | 1269 infos = LiveEditFunctionTracker::Collect(parse_info.literal(), script, |
| 1264 parse_info.zone(), isolate); | 1270 &zone, isolate); |
| 1265 } | 1271 } |
| 1266 | 1272 |
| 1267 // Restore the original function info list in order to remain side-effect | 1273 // Restore the original function info list in order to remain side-effect |
| 1268 // free as much as possible, since some code expects the old shared function | 1274 // free as much as possible, since some code expects the old shared function |
| 1269 // infos to stick around. | 1275 // infos to stick around. |
| 1270 script->set_shared_function_infos(*old_function_infos); | 1276 script->set_shared_function_infos(*old_function_infos); |
| 1271 | 1277 |
| 1272 return infos; | 1278 return infos; |
| 1273 } | 1279 } |
| 1274 | 1280 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1378 } | 1384 } |
| 1379 if (!script_name.is_null()) { | 1385 if (!script_name.is_null()) { |
| 1380 script->set_name(*script_name); | 1386 script->set_name(*script_name); |
| 1381 script->set_line_offset(line_offset); | 1387 script->set_line_offset(line_offset); |
| 1382 script->set_column_offset(column_offset); | 1388 script->set_column_offset(column_offset); |
| 1383 } | 1389 } |
| 1384 script->set_origin_options(options); | 1390 script->set_origin_options(options); |
| 1385 script->set_compilation_type(Script::COMPILATION_TYPE_EVAL); | 1391 script->set_compilation_type(Script::COMPILATION_TYPE_EVAL); |
| 1386 Script::SetEvalOrigin(script, outer_info, eval_position); | 1392 Script::SetEvalOrigin(script, outer_info, eval_position); |
| 1387 | 1393 |
| 1388 ParseInfo parse_info(script); | 1394 Zone zone(isolate->allocator(), ZONE_NAME); |
| 1395 ParseInfo parse_info(&zone, script); |
| 1389 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1396 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
| 1390 parse_info.set_eval(); | 1397 parse_info.set_eval(); |
| 1391 parse_info.set_language_mode(language_mode); | 1398 parse_info.set_language_mode(language_mode); |
| 1392 parse_info.set_parse_restriction(restriction); | 1399 parse_info.set_parse_restriction(restriction); |
| 1393 if (!context->IsNativeContext()) { | 1400 if (!context->IsNativeContext()) { |
| 1394 parse_info.set_outer_scope_info(handle(context->scope_info())); | 1401 parse_info.set_outer_scope_info(handle(context->scope_info())); |
| 1395 } | 1402 } |
| 1396 | 1403 |
| 1397 shared_info = CompileToplevel(&info); | 1404 shared_info = CompileToplevel(&info); |
| 1398 | 1405 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1556 script->set_name(*script_name); | 1563 script->set_name(*script_name); |
| 1557 script->set_line_offset(line_offset); | 1564 script->set_line_offset(line_offset); |
| 1558 script->set_column_offset(column_offset); | 1565 script->set_column_offset(column_offset); |
| 1559 } | 1566 } |
| 1560 script->set_origin_options(resource_options); | 1567 script->set_origin_options(resource_options); |
| 1561 if (!source_map_url.is_null()) { | 1568 if (!source_map_url.is_null()) { |
| 1562 script->set_source_mapping_url(*source_map_url); | 1569 script->set_source_mapping_url(*source_map_url); |
| 1563 } | 1570 } |
| 1564 | 1571 |
| 1565 // Compile the function and add it to the cache. | 1572 // Compile the function and add it to the cache. |
| 1566 ParseInfo parse_info(script); | 1573 Zone zone(isolate->allocator(), ZONE_NAME); |
| 1574 ParseInfo parse_info(&zone, script); |
| 1567 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1575 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
| 1568 if (resource_options.IsModule()) parse_info.set_module(); | 1576 if (resource_options.IsModule()) parse_info.set_module(); |
| 1569 if (compile_options != ScriptCompiler::kNoCompileOptions) { | 1577 if (compile_options != ScriptCompiler::kNoCompileOptions) { |
| 1570 parse_info.set_cached_data(cached_data); | 1578 parse_info.set_cached_data(cached_data); |
| 1571 } | 1579 } |
| 1572 parse_info.set_compile_options(compile_options); | 1580 parse_info.set_compile_options(compile_options); |
| 1573 parse_info.set_extension(extension); | 1581 parse_info.set_extension(extension); |
| 1574 if (!context->IsNativeContext()) { | 1582 if (!context->IsNativeContext()) { |
| 1575 parse_info.set_outer_scope_info(handle(context->scope_info())); | 1583 parse_info.set_outer_scope_info(handle(context->scope_info())); |
| 1576 } | 1584 } |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1755 DCHECK(shared->is_compiled()); | 1763 DCHECK(shared->is_compiled()); |
| 1756 function->set_literals(cached.literals); | 1764 function->set_literals(cached.literals); |
| 1757 } else if (shared->is_compiled()) { | 1765 } else if (shared->is_compiled()) { |
| 1758 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1766 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
| 1759 JSFunction::EnsureLiterals(function); | 1767 JSFunction::EnsureLiterals(function); |
| 1760 } | 1768 } |
| 1761 } | 1769 } |
| 1762 | 1770 |
| 1763 } // namespace internal | 1771 } // namespace internal |
| 1764 } // namespace v8 | 1772 } // namespace v8 |
| OLD | NEW |