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 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 // to prevent switching the given function to baseline code in those cases. | 859 // to prevent switching the given function to baseline code in those cases. |
860 Deoptimizer::VisitAllOptimizedFunctions(isolate, activations_finder); | 860 Deoptimizer::VisitAllOptimizedFunctions(isolate, activations_finder); |
861 } | 861 } |
862 return activations_finder->has_activations(); | 862 return activations_finder->has_activations(); |
863 } | 863 } |
864 | 864 |
865 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) { | 865 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) { |
866 Isolate* isolate = function->GetIsolate(); | 866 Isolate* isolate = function->GetIsolate(); |
867 VMState<COMPILER> state(isolate); | 867 VMState<COMPILER> state(isolate); |
868 PostponeInterruptsScope postpone(isolate); | 868 PostponeInterruptsScope postpone(isolate); |
869 Zone zone(isolate->allocator()); | 869 Zone zone(isolate->allocator(), ZONE_NAME); |
870 ParseInfo parse_info(&zone, handle(function->shared())); | 870 ParseInfo parse_info(&zone, handle(function->shared())); |
871 CompilationInfo info(&parse_info, function); | 871 CompilationInfo info(&parse_info, function); |
872 | 872 |
873 // Reset profiler ticks, function is no longer considered hot. | 873 // Reset profiler ticks, function is no longer considered hot. |
874 if (function->shared()->HasBytecodeArray()) { | 874 if (function->shared()->HasBytecodeArray()) { |
875 function->shared()->set_profiler_ticks(0); | 875 function->shared()->set_profiler_ticks(0); |
876 } | 876 } |
877 | 877 |
878 // Nothing left to do if the function already has baseline code. | 878 // Nothing left to do if the function already has baseline code. |
879 if (function->shared()->code()->kind() == Code::FUNCTION) { | 879 if (function->shared()->code()->kind() == Code::FUNCTION) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 if (function->shared()->is_compiled()) { | 980 if (function->shared()->is_compiled()) { |
981 return Handle<Code>(function->shared()->code()); | 981 return Handle<Code>(function->shared()->code()); |
982 } | 982 } |
983 | 983 |
984 if (function->shared()->HasBytecodeArray()) { | 984 if (function->shared()->HasBytecodeArray()) { |
985 Handle<Code> entry = isolate->builtins()->InterpreterEntryTrampoline(); | 985 Handle<Code> entry = isolate->builtins()->InterpreterEntryTrampoline(); |
986 function->shared()->ReplaceCode(*entry); | 986 function->shared()->ReplaceCode(*entry); |
987 return entry; | 987 return entry; |
988 } | 988 } |
989 | 989 |
990 Zone zone(isolate->allocator()); | 990 Zone zone(isolate->allocator(), ZONE_NAME); |
991 ParseInfo parse_info(&zone, handle(function->shared())); | 991 ParseInfo parse_info(&zone, handle(function->shared())); |
992 CompilationInfo info(&parse_info, function); | 992 CompilationInfo info(&parse_info, function); |
993 Handle<Code> result; | 993 Handle<Code> result; |
994 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCode(&info), Code); | 994 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCode(&info), Code); |
995 | 995 |
996 if (FLAG_always_opt) { | 996 if (FLAG_always_opt) { |
997 Handle<Code> opt_code; | 997 Handle<Code> opt_code; |
998 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) | 998 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) |
999 .ToHandle(&opt_code)) { | 999 .ToHandle(&opt_code)) { |
1000 result = opt_code; | 1000 result = opt_code; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1166 Handle<Code> code; | 1166 Handle<Code> code; |
1167 if (!GetOptimizedCode(function, mode).ToHandle(&code)) { | 1167 if (!GetOptimizedCode(function, mode).ToHandle(&code)) { |
1168 // Optimization failed, get unoptimized code. | 1168 // Optimization failed, get unoptimized code. |
1169 DCHECK(!isolate->has_pending_exception()); | 1169 DCHECK(!isolate->has_pending_exception()); |
1170 if (function->shared()->is_compiled()) { | 1170 if (function->shared()->is_compiled()) { |
1171 code = handle(function->shared()->code(), isolate); | 1171 code = handle(function->shared()->code(), isolate); |
1172 } else if (function->shared()->HasBytecodeArray()) { | 1172 } else if (function->shared()->HasBytecodeArray()) { |
1173 code = isolate->builtins()->InterpreterEntryTrampoline(); | 1173 code = isolate->builtins()->InterpreterEntryTrampoline(); |
1174 function->shared()->ReplaceCode(*code); | 1174 function->shared()->ReplaceCode(*code); |
1175 } else { | 1175 } else { |
1176 Zone zone(isolate->allocator()); | 1176 Zone zone(isolate->allocator(), ZONE_NAME); |
1177 ParseInfo parse_info(&zone, handle(function->shared())); | 1177 ParseInfo parse_info(&zone, handle(function->shared())); |
1178 CompilationInfo info(&parse_info, function); | 1178 CompilationInfo info(&parse_info, function); |
1179 if (!GetUnoptimizedCode(&info).ToHandle(&code)) { | 1179 if (!GetUnoptimizedCode(&info).ToHandle(&code)) { |
1180 return false; | 1180 return false; |
1181 } | 1181 } |
1182 } | 1182 } |
1183 } | 1183 } |
1184 | 1184 |
1185 // Install code on closure. | 1185 // Install code on closure. |
1186 function->ReplaceCode(*code); | 1186 function->ReplaceCode(*code); |
1187 JSFunction::EnsureLiterals(function); | 1187 JSFunction::EnsureLiterals(function); |
1188 | 1188 |
1189 // Check postconditions on success. | 1189 // Check postconditions on success. |
1190 DCHECK(!isolate->has_pending_exception()); | 1190 DCHECK(!isolate->has_pending_exception()); |
1191 DCHECK(function->shared()->is_compiled()); | 1191 DCHECK(function->shared()->is_compiled()); |
1192 DCHECK(function->is_compiled()); | 1192 DCHECK(function->is_compiled()); |
1193 return true; | 1193 return true; |
1194 } | 1194 } |
1195 | 1195 |
1196 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { | 1196 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { |
1197 Isolate* isolate = function->GetIsolate(); | 1197 Isolate* isolate = function->GetIsolate(); |
1198 DCHECK(AllowCompilation::IsAllowed(isolate)); | 1198 DCHECK(AllowCompilation::IsAllowed(isolate)); |
1199 | 1199 |
1200 // Start a compilation. | 1200 // Start a compilation. |
1201 Zone zone(isolate->allocator()); | 1201 Zone zone(isolate->allocator(), ZONE_NAME); |
1202 ParseInfo parse_info(&zone, handle(function->shared())); | 1202 ParseInfo parse_info(&zone, handle(function->shared())); |
1203 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1203 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1204 info.MarkAsDebug(); | 1204 info.MarkAsDebug(); |
1205 if (GetUnoptimizedCode(&info).is_null()) { | 1205 if (GetUnoptimizedCode(&info).is_null()) { |
1206 isolate->clear_pending_exception(); | 1206 isolate->clear_pending_exception(); |
1207 return false; | 1207 return false; |
1208 } | 1208 } |
1209 | 1209 |
1210 // Check postconditions on success. | 1210 // Check postconditions on success. |
1211 DCHECK(!isolate->has_pending_exception()); | 1211 DCHECK(!isolate->has_pending_exception()); |
1212 DCHECK(function->shared()->is_compiled()); | 1212 DCHECK(function->shared()->is_compiled()); |
1213 DCHECK(function->shared()->HasDebugCode()); | 1213 DCHECK(function->shared()->HasDebugCode()); |
1214 return true; | 1214 return true; |
1215 } | 1215 } |
1216 | 1216 |
1217 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { | 1217 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { |
1218 Isolate* isolate = shared->GetIsolate(); | 1218 Isolate* isolate = shared->GetIsolate(); |
1219 DCHECK(AllowCompilation::IsAllowed(isolate)); | 1219 DCHECK(AllowCompilation::IsAllowed(isolate)); |
1220 | 1220 |
1221 // Start a compilation. | 1221 // Start a compilation. |
1222 Zone zone(isolate->allocator()); | 1222 Zone zone(isolate->allocator(), ZONE_NAME); |
1223 ParseInfo parse_info(&zone, shared); | 1223 ParseInfo parse_info(&zone, shared); |
1224 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1224 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1225 info.MarkAsDebug(); | 1225 info.MarkAsDebug(); |
1226 if (GetUnoptimizedCode(&info).is_null()) { | 1226 if (GetUnoptimizedCode(&info).is_null()) { |
1227 isolate->clear_pending_exception(); | 1227 isolate->clear_pending_exception(); |
1228 return false; | 1228 return false; |
1229 } | 1229 } |
1230 | 1230 |
1231 // Check postconditions on success. | 1231 // Check postconditions on success. |
1232 DCHECK(!isolate->has_pending_exception()); | 1232 DCHECK(!isolate->has_pending_exception()); |
1233 DCHECK(shared->is_compiled()); | 1233 DCHECK(shared->is_compiled()); |
1234 DCHECK(shared->HasDebugCode()); | 1234 DCHECK(shared->HasDebugCode()); |
1235 return true; | 1235 return true; |
1236 } | 1236 } |
1237 | 1237 |
1238 MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) { | 1238 MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) { |
1239 Isolate* isolate = script->GetIsolate(); | 1239 Isolate* isolate = script->GetIsolate(); |
1240 DCHECK(AllowCompilation::IsAllowed(isolate)); | 1240 DCHECK(AllowCompilation::IsAllowed(isolate)); |
1241 | 1241 |
1242 // In order to ensure that live edit function info collection finds the newly | 1242 // In order to ensure that live edit function info collection finds the newly |
1243 // generated shared function infos, clear the script's list temporarily | 1243 // generated shared function infos, clear the script's list temporarily |
1244 // and restore it at the end of this method. | 1244 // and restore it at the end of this method. |
1245 Handle<Object> old_function_infos(script->shared_function_infos(), isolate); | 1245 Handle<Object> old_function_infos(script->shared_function_infos(), isolate); |
1246 script->set_shared_function_infos(Smi::kZero); | 1246 script->set_shared_function_infos(Smi::kZero); |
1247 | 1247 |
1248 // Start a compilation. | 1248 // Start a compilation. |
1249 Zone zone(isolate->allocator()); | 1249 Zone zone(isolate->allocator(), ZONE_NAME); |
1250 ParseInfo parse_info(&zone, script); | 1250 ParseInfo parse_info(&zone, script); |
1251 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1251 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1252 info.MarkAsDebug(); | 1252 info.MarkAsDebug(); |
1253 | 1253 |
1254 // TODO(635): support extensions. | 1254 // TODO(635): support extensions. |
1255 const bool compilation_succeeded = !CompileToplevel(&info).is_null(); | 1255 const bool compilation_succeeded = !CompileToplevel(&info).is_null(); |
1256 Handle<JSArray> infos; | 1256 Handle<JSArray> infos; |
1257 if (compilation_succeeded) { | 1257 if (compilation_succeeded) { |
1258 // Check postconditions on success. | 1258 // Check postconditions on success. |
1259 DCHECK(!isolate->has_pending_exception()); | 1259 DCHECK(!isolate->has_pending_exception()); |
(...skipping 27 matching lines...) Expand all Loading... |
1287 return true; | 1287 return true; |
1288 } | 1288 } |
1289 | 1289 |
1290 // TODO(turbofan): In the future, unoptimized code with deopt support could | 1290 // TODO(turbofan): In the future, unoptimized code with deopt support could |
1291 // be generated lazily once deopt is triggered. | 1291 // be generated lazily once deopt is triggered. |
1292 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 1292 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
1293 DCHECK_NOT_NULL(info->literal()); | 1293 DCHECK_NOT_NULL(info->literal()); |
1294 DCHECK_NOT_NULL(info->scope()); | 1294 DCHECK_NOT_NULL(info->scope()); |
1295 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1295 Handle<SharedFunctionInfo> shared = info->shared_info(); |
1296 if (!shared->has_deoptimization_support()) { | 1296 if (!shared->has_deoptimization_support()) { |
1297 Zone zone(info->isolate()->allocator()); | 1297 Zone zone(info->isolate()->allocator(), ZONE_NAME); |
1298 CompilationInfo unoptimized(info->parse_info(), info->closure()); | 1298 CompilationInfo unoptimized(info->parse_info(), info->closure()); |
1299 unoptimized.EnableDeoptimizationSupport(); | 1299 unoptimized.EnableDeoptimizationSupport(); |
1300 | 1300 |
1301 // TODO(4280): For now we do not switch generators or async functions to | 1301 // TODO(4280): For now we do not switch generators or async functions to |
1302 // baseline code because there might be suspended activations stored in | 1302 // baseline code because there might be suspended activations stored in |
1303 // generator objects on the heap. We could eventually go directly to | 1303 // generator objects on the heap. We could eventually go directly to |
1304 // TurboFan in this case. | 1304 // TurboFan in this case. |
1305 if (IsResumableFunction(shared->kind())) return false; | 1305 if (IsResumableFunction(shared->kind())) return false; |
1306 | 1306 |
1307 // TODO(4280): For now we disable switching to baseline code in the presence | 1307 // TODO(4280): For now we disable switching to baseline code in the presence |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1393 script = isolate->factory()->NewScript(source); | 1393 script = isolate->factory()->NewScript(source); |
1394 if (!script_name.is_null()) { | 1394 if (!script_name.is_null()) { |
1395 script->set_name(*script_name); | 1395 script->set_name(*script_name); |
1396 script->set_line_offset(line_offset); | 1396 script->set_line_offset(line_offset); |
1397 script->set_column_offset(column_offset); | 1397 script->set_column_offset(column_offset); |
1398 } | 1398 } |
1399 script->set_origin_options(options); | 1399 script->set_origin_options(options); |
1400 script->set_compilation_type(Script::COMPILATION_TYPE_EVAL); | 1400 script->set_compilation_type(Script::COMPILATION_TYPE_EVAL); |
1401 Script::SetEvalOrigin(script, outer_info, eval_position); | 1401 Script::SetEvalOrigin(script, outer_info, eval_position); |
1402 | 1402 |
1403 Zone zone(isolate->allocator()); | 1403 Zone zone(isolate->allocator(), ZONE_NAME); |
1404 ParseInfo parse_info(&zone, script); | 1404 ParseInfo parse_info(&zone, script); |
1405 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1405 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1406 parse_info.set_eval(); | 1406 parse_info.set_eval(); |
1407 parse_info.set_language_mode(language_mode); | 1407 parse_info.set_language_mode(language_mode); |
1408 parse_info.set_parse_restriction(restriction); | 1408 parse_info.set_parse_restriction(restriction); |
1409 if (!context->IsNativeContext()) { | 1409 if (!context->IsNativeContext()) { |
1410 parse_info.set_outer_scope_info(handle(context->scope_info())); | 1410 parse_info.set_outer_scope_info(handle(context->scope_info())); |
1411 } | 1411 } |
1412 | 1412 |
1413 shared_info = CompileToplevel(&info); | 1413 shared_info = CompileToplevel(&info); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1561 script->set_name(*script_name); | 1561 script->set_name(*script_name); |
1562 script->set_line_offset(line_offset); | 1562 script->set_line_offset(line_offset); |
1563 script->set_column_offset(column_offset); | 1563 script->set_column_offset(column_offset); |
1564 } | 1564 } |
1565 script->set_origin_options(resource_options); | 1565 script->set_origin_options(resource_options); |
1566 if (!source_map_url.is_null()) { | 1566 if (!source_map_url.is_null()) { |
1567 script->set_source_mapping_url(*source_map_url); | 1567 script->set_source_mapping_url(*source_map_url); |
1568 } | 1568 } |
1569 | 1569 |
1570 // Compile the function and add it to the cache. | 1570 // Compile the function and add it to the cache. |
1571 Zone zone(isolate->allocator()); | 1571 Zone zone(isolate->allocator(), ZONE_NAME); |
1572 ParseInfo parse_info(&zone, script); | 1572 ParseInfo parse_info(&zone, script); |
1573 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1573 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1574 if (is_module) parse_info.set_module(); | 1574 if (is_module) parse_info.set_module(); |
1575 if (compile_options != ScriptCompiler::kNoCompileOptions) { | 1575 if (compile_options != ScriptCompiler::kNoCompileOptions) { |
1576 parse_info.set_cached_data(cached_data); | 1576 parse_info.set_cached_data(cached_data); |
1577 } | 1577 } |
1578 parse_info.set_compile_options(compile_options); | 1578 parse_info.set_compile_options(compile_options); |
1579 parse_info.set_extension(extension); | 1579 parse_info.set_extension(extension); |
1580 if (!context->IsNativeContext()) { | 1580 if (!context->IsNativeContext()) { |
1581 parse_info.set_outer_scope_info(handle(context->scope_info())); | 1581 parse_info.set_outer_scope_info(handle(context->scope_info())); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1677 if (!maybe_existing.ToHandle(&result)) { | 1677 if (!maybe_existing.ToHandle(&result)) { |
1678 result = NewSharedFunctionInfoForLiteral(isolate, literal, script); | 1678 result = NewSharedFunctionInfoForLiteral(isolate, literal, script); |
1679 result->set_is_toplevel(false); | 1679 result->set_is_toplevel(false); |
1680 | 1680 |
1681 // If the outer function has been compiled before, we cannot be sure that | 1681 // If the outer function has been compiled before, we cannot be sure that |
1682 // shared function info for this function literal has been created for the | 1682 // shared function info for this function literal has been created for the |
1683 // first time. It may have already been compiled previously. | 1683 // first time. It may have already been compiled previously. |
1684 result->set_never_compiled(outer_info->shared_info()->never_compiled()); | 1684 result->set_never_compiled(outer_info->shared_info()->never_compiled()); |
1685 } | 1685 } |
1686 | 1686 |
1687 Zone zone(isolate->allocator()); | 1687 Zone zone(isolate->allocator(), ZONE_NAME); |
1688 ParseInfo parse_info(&zone, script); | 1688 ParseInfo parse_info(&zone, script); |
1689 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1689 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1690 parse_info.set_literal(literal); | 1690 parse_info.set_literal(literal); |
1691 parse_info.set_shared_info(result); | 1691 parse_info.set_shared_info(result); |
1692 parse_info.set_language_mode(literal->scope()->language_mode()); | 1692 parse_info.set_language_mode(literal->scope()->language_mode()); |
1693 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 1693 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
1694 if (outer_info->is_debug()) info.MarkAsDebug(); | 1694 if (outer_info->is_debug()) info.MarkAsDebug(); |
1695 | 1695 |
1696 // Generate code | 1696 // Generate code |
1697 TimerEventScope<TimerEventCompileCode> timer(isolate); | 1697 TimerEventScope<TimerEventCompileCode> timer(isolate); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1812 DCHECK(shared->is_compiled()); | 1812 DCHECK(shared->is_compiled()); |
1813 function->set_literals(cached.literals); | 1813 function->set_literals(cached.literals); |
1814 } else if (shared->is_compiled()) { | 1814 } else if (shared->is_compiled()) { |
1815 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1815 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
1816 JSFunction::EnsureLiterals(function); | 1816 JSFunction::EnsureLiterals(function); |
1817 } | 1817 } |
1818 } | 1818 } |
1819 | 1819 |
1820 } // namespace internal | 1820 } // namespace internal |
1821 } // namespace v8 | 1821 } // namespace v8 |
OLD | NEW |