| 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/ast-numbering.h" | 9 #include "src/ast/ast-numbering.h" |
| 10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
| (...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1023 } | 1023 } |
| 1024 | 1024 |
| 1025 CompilationInfoWithZone info(function); | 1025 CompilationInfoWithZone info(function); |
| 1026 Handle<Code> result; | 1026 Handle<Code> result; |
| 1027 ASSIGN_RETURN_ON_EXCEPTION(info.isolate(), result, | 1027 ASSIGN_RETURN_ON_EXCEPTION(info.isolate(), result, |
| 1028 GetUnoptimizedCodeCommon(&info), | 1028 GetUnoptimizedCodeCommon(&info), |
| 1029 Code); | 1029 Code); |
| 1030 return result; | 1030 return result; |
| 1031 } | 1031 } |
| 1032 | 1032 |
| 1033 MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, |
| 1034 Compiler::ConcurrencyMode mode, |
| 1035 BailoutId osr_ast_id = BailoutId::None(), |
| 1036 JavaScriptFrame* osr_frame = nullptr) { |
| 1037 Isolate* isolate = function->GetIsolate(); |
| 1038 Handle<SharedFunctionInfo> shared(function->shared(), isolate); |
| 1039 if (shared->HasDebugInfo()) return MaybeHandle<Code>(); |
| 1040 |
| 1041 Handle<Code> cached_code; |
| 1042 if (GetCodeFromOptimizedCodeMap(function, osr_ast_id) |
| 1043 .ToHandle(&cached_code)) { |
| 1044 if (FLAG_trace_opt) { |
| 1045 PrintF("[found optimized code for "); |
| 1046 function->ShortPrint(); |
| 1047 if (!osr_ast_id.IsNone()) { |
| 1048 PrintF(" at OSR AST id %d", osr_ast_id.ToInt()); |
| 1049 } |
| 1050 PrintF("]\n"); |
| 1051 } |
| 1052 return cached_code; |
| 1053 } |
| 1054 |
| 1055 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1056 |
| 1057 Handle<Code> current_code(shared->code()); |
| 1058 if (!shared->is_compiled() || |
| 1059 shared->scope_info() == ScopeInfo::Empty(isolate)) { |
| 1060 // The function was never compiled. Compile it unoptimized first. |
| 1061 // TODO(titzer): reuse the AST and scope info from this compile. |
| 1062 CompilationInfoWithZone unoptimized(function); |
| 1063 unoptimized.EnableDeoptimizationSupport(); |
| 1064 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(¤t_code)) { |
| 1065 return MaybeHandle<Code>(); |
| 1066 } |
| 1067 shared->ReplaceCode(*current_code); |
| 1068 } |
| 1069 |
| 1070 current_code->set_profiler_ticks(0); |
| 1071 |
| 1072 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing |
| 1073 // an eval scope and hence would fail at parsing the eval source again. |
| 1074 if (shared->disable_optimization_reason() == kEval) { |
| 1075 return MaybeHandle<Code>(); |
| 1076 } |
| 1077 |
| 1078 // TODO(mstarzinger): We cannot properly deserialize a scope chain for the |
| 1079 // builtin context, hence Genesis::InstallExperimentalNatives would fail. |
| 1080 if (shared->is_toplevel() && isolate->bootstrapper()->IsActive()) { |
| 1081 return MaybeHandle<Code>(); |
| 1082 } |
| 1083 |
| 1084 base::SmartPointer<CompilationInfo> info( |
| 1085 new CompilationInfoWithZone(function)); |
| 1086 VMState<COMPILER> state(isolate); |
| 1087 DCHECK(!isolate->has_pending_exception()); |
| 1088 PostponeInterruptsScope postpone(isolate); |
| 1089 |
| 1090 info->SetOptimizingForOsr(osr_ast_id, current_code); |
| 1091 |
| 1092 if (mode == Compiler::CONCURRENT) { |
| 1093 if (GetOptimizedCodeLater(info.get())) { |
| 1094 info.Detach(); // The background recompile job owns this now. |
| 1095 return isolate->builtins()->InOptimizationQueue(); |
| 1096 } |
| 1097 } else { |
| 1098 info->set_osr_frame(osr_frame); |
| 1099 if (GetOptimizedCodeNow(info.get())) return info->code(); |
| 1100 } |
| 1101 |
| 1102 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); |
| 1103 return MaybeHandle<Code>(); |
| 1104 } |
| 1105 |
| 1033 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { | 1106 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { |
| 1034 Isolate* isolate = function->GetIsolate(); | 1107 Isolate* isolate = function->GetIsolate(); |
| 1035 DCHECK(!isolate->has_pending_exception()); | 1108 DCHECK(!isolate->has_pending_exception()); |
| 1036 DCHECK(!function->is_compiled()); | 1109 DCHECK(!function->is_compiled()); |
| 1037 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); | 1110 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); |
| 1038 TRACE_EVENT0("v8", "V8.CompileCode"); | 1111 TRACE_EVENT0("v8", "V8.CompileCode"); |
| 1039 AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy()); | 1112 AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy()); |
| 1040 // If the debugger is active, do not compile with turbofan unless we can | 1113 // If the debugger is active, do not compile with turbofan unless we can |
| 1041 // deopt from turbofan code. | 1114 // deopt from turbofan code. |
| 1042 if (FLAG_turbo_asm && function->shared()->asm_function() && | 1115 if (FLAG_turbo_asm && function->shared()->asm_function() && |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1062 return Handle<Code>(function->shared()->code()); | 1135 return Handle<Code>(function->shared()->code()); |
| 1063 } | 1136 } |
| 1064 | 1137 |
| 1065 CompilationInfoWithZone info(function); | 1138 CompilationInfoWithZone info(function); |
| 1066 Handle<Code> result; | 1139 Handle<Code> result; |
| 1067 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCodeCommon(&info), | 1140 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCodeCommon(&info), |
| 1068 Code); | 1141 Code); |
| 1069 | 1142 |
| 1070 if (FLAG_always_opt) { | 1143 if (FLAG_always_opt) { |
| 1071 Handle<Code> opt_code; | 1144 Handle<Code> opt_code; |
| 1072 if (Compiler::GetOptimizedCode(function, Compiler::NOT_CONCURRENT) | 1145 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) |
| 1073 .ToHandle(&opt_code)) { | 1146 .ToHandle(&opt_code)) { |
| 1074 result = opt_code; | 1147 result = opt_code; |
| 1075 } | 1148 } |
| 1076 } | 1149 } |
| 1077 | 1150 |
| 1078 return result; | 1151 return result; |
| 1079 } | 1152 } |
| 1080 | 1153 |
| 1081 } // namespace | 1154 } // namespace |
| 1082 | 1155 |
| 1083 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { | 1156 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { |
| 1084 if (function->is_compiled()) return true; | 1157 if (function->is_compiled()) return true; |
| 1085 MaybeHandle<Code> maybe_code = GetLazyCode(function); | 1158 MaybeHandle<Code> maybe_code = GetLazyCode(function); |
| 1086 Handle<Code> code; | 1159 Handle<Code> code; |
| 1087 if (!maybe_code.ToHandle(&code)) { | 1160 if (!maybe_code.ToHandle(&code)) { |
| 1088 if (flag == CLEAR_EXCEPTION) { | 1161 if (flag == CLEAR_EXCEPTION) { |
| 1089 function->GetIsolate()->clear_pending_exception(); | 1162 function->GetIsolate()->clear_pending_exception(); |
| 1090 } | 1163 } |
| 1091 return false; | 1164 return false; |
| 1092 } | 1165 } |
| 1093 DCHECK(code->IsJavaScriptCode()); | 1166 DCHECK(code->IsJavaScriptCode()); |
| 1094 function->ReplaceCode(*code); | 1167 function->ReplaceCode(*code); |
| 1095 DCHECK(function->is_compiled()); | 1168 DCHECK(function->is_compiled()); |
| 1096 return true; | 1169 return true; |
| 1097 } | 1170 } |
| 1098 | 1171 |
| 1099 bool Compiler::CompileOptimized(Handle<JSFunction> function, | 1172 bool Compiler::CompileOptimized(Handle<JSFunction> function, |
| 1100 ConcurrencyMode mode) { | 1173 ConcurrencyMode mode) { |
| 1101 Handle<Code> code; | 1174 Handle<Code> code; |
| 1102 if (Compiler::GetOptimizedCode(function, mode).ToHandle(&code)) { | 1175 if (GetOptimizedCode(function, mode).ToHandle(&code)) { |
| 1103 // Optimization succeeded, return optimized code. | 1176 // Optimization succeeded, return optimized code. |
| 1104 function->ReplaceCode(*code); | 1177 function->ReplaceCode(*code); |
| 1105 } else { | 1178 } else { |
| 1106 // Optimization failed, get unoptimized code. | 1179 // Optimization failed, get unoptimized code. |
| 1107 Isolate* isolate = function->GetIsolate(); | 1180 Isolate* isolate = function->GetIsolate(); |
| 1108 if (isolate->has_pending_exception()) { // Possible stack overflow. | 1181 if (isolate->has_pending_exception()) { // Possible stack overflow. |
| 1109 return false; | 1182 return false; |
| 1110 } | 1183 } |
| 1111 code = Handle<Code>(function->shared()->code(), isolate); | 1184 code = Handle<Code>(function->shared()->code(), isolate); |
| 1112 if (code->kind() != Code::FUNCTION && | 1185 if (code->kind() != Code::FUNCTION && |
| (...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1768 shared->set_construct_stub(*construct_stub); | 1841 shared->set_construct_stub(*construct_stub); |
| 1769 | 1842 |
| 1770 // Copy the function data to the shared function info. | 1843 // Copy the function data to the shared function info. |
| 1771 shared->set_function_data(fun->shared()->function_data()); | 1844 shared->set_function_data(fun->shared()->function_data()); |
| 1772 int parameters = fun->shared()->internal_formal_parameter_count(); | 1845 int parameters = fun->shared()->internal_formal_parameter_count(); |
| 1773 shared->set_internal_formal_parameter_count(parameters); | 1846 shared->set_internal_formal_parameter_count(parameters); |
| 1774 | 1847 |
| 1775 return shared; | 1848 return shared; |
| 1776 } | 1849 } |
| 1777 | 1850 |
| 1778 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function, | 1851 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR( |
| 1779 ConcurrencyMode mode, | 1852 Handle<JSFunction> function, Compiler::ConcurrencyMode mode, |
| 1780 BailoutId osr_ast_id, | 1853 BailoutId osr_ast_id, JavaScriptFrame* osr_frame) { |
| 1781 JavaScriptFrame* osr_frame) { | 1854 DCHECK(!osr_ast_id.IsNone()); |
| 1782 Isolate* isolate = function->GetIsolate(); | 1855 // TODO(mstarzinger): Once concurrent OSR is removed, the following check |
| 1783 Handle<SharedFunctionInfo> shared(function->shared(), isolate); | 1856 // should hold and can be enabled. |
| 1784 if (shared->HasDebugInfo()) return MaybeHandle<Code>(); | 1857 // DCHECK_NOT_NULL(osr_frame); |
| 1785 | 1858 return GetOptimizedCode(function, mode, osr_ast_id, osr_frame); |
| 1786 Handle<Code> cached_code; | |
| 1787 if (GetCodeFromOptimizedCodeMap( | |
| 1788 function, osr_ast_id).ToHandle(&cached_code)) { | |
| 1789 if (FLAG_trace_opt) { | |
| 1790 PrintF("[found optimized code for "); | |
| 1791 function->ShortPrint(); | |
| 1792 if (!osr_ast_id.IsNone()) { | |
| 1793 PrintF(" at OSR AST id %d", osr_ast_id.ToInt()); | |
| 1794 } | |
| 1795 PrintF("]\n"); | |
| 1796 } | |
| 1797 return cached_code; | |
| 1798 } | |
| 1799 | |
| 1800 DCHECK(AllowCompilation::IsAllowed(isolate)); | |
| 1801 | |
| 1802 Handle<Code> current_code(shared->code()); | |
| 1803 if (!shared->is_compiled() || | |
| 1804 shared->scope_info() == ScopeInfo::Empty(isolate)) { | |
| 1805 // The function was never compiled. Compile it unoptimized first. | |
| 1806 // TODO(titzer): reuse the AST and scope info from this compile. | |
| 1807 CompilationInfoWithZone unoptimized(function); | |
| 1808 unoptimized.EnableDeoptimizationSupport(); | |
| 1809 if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(¤t_code)) { | |
| 1810 return MaybeHandle<Code>(); | |
| 1811 } | |
| 1812 shared->ReplaceCode(*current_code); | |
| 1813 } | |
| 1814 | |
| 1815 current_code->set_profiler_ticks(0); | |
| 1816 | |
| 1817 // TODO(mstarzinger): We cannot properly deserialize a scope chain containing | |
| 1818 // an eval scope and hence would fail at parsing the eval source again. | |
| 1819 if (shared->disable_optimization_reason() == kEval) { | |
| 1820 return MaybeHandle<Code>(); | |
| 1821 } | |
| 1822 | |
| 1823 // TODO(mstarzinger): We cannot properly deserialize a scope chain for the | |
| 1824 // builtin context, hence Genesis::InstallExperimentalNatives would fail. | |
| 1825 if (shared->is_toplevel() && isolate->bootstrapper()->IsActive()) { | |
| 1826 return MaybeHandle<Code>(); | |
| 1827 } | |
| 1828 | |
| 1829 base::SmartPointer<CompilationInfo> info( | |
| 1830 new CompilationInfoWithZone(function)); | |
| 1831 VMState<COMPILER> state(isolate); | |
| 1832 DCHECK(!isolate->has_pending_exception()); | |
| 1833 PostponeInterruptsScope postpone(isolate); | |
| 1834 | |
| 1835 info->SetOptimizingForOsr(osr_ast_id, current_code); | |
| 1836 | |
| 1837 if (mode == CONCURRENT) { | |
| 1838 if (GetOptimizedCodeLater(info.get())) { | |
| 1839 info.Detach(); // The background recompile job owns this now. | |
| 1840 return isolate->builtins()->InOptimizationQueue(); | |
| 1841 } | |
| 1842 } else { | |
| 1843 info->set_osr_frame(osr_frame); | |
| 1844 if (GetOptimizedCodeNow(info.get())) return info->code(); | |
| 1845 } | |
| 1846 | |
| 1847 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); | |
| 1848 return MaybeHandle<Code>(); | |
| 1849 } | 1859 } |
| 1850 | 1860 |
| 1851 MaybeHandle<Code> Compiler::GetConcurrentlyOptimizedCode( | 1861 MaybeHandle<Code> Compiler::GetConcurrentlyOptimizedCode( |
| 1852 OptimizedCompileJob* job) { | 1862 OptimizedCompileJob* job) { |
| 1853 // Take ownership of compilation info. Deleting compilation info | 1863 // Take ownership of compilation info. Deleting compilation info |
| 1854 // also tears down the zone and the recompile job. | 1864 // also tears down the zone and the recompile job. |
| 1855 base::SmartPointer<CompilationInfo> info(job->info()); | 1865 base::SmartPointer<CompilationInfo> info(job->info()); |
| 1856 Isolate* isolate = info->isolate(); | 1866 Isolate* isolate = info->isolate(); |
| 1857 | 1867 |
| 1858 VMState<COMPILER> state(isolate); | 1868 VMState<COMPILER> state(isolate); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 | 1911 |
| 1902 #if DEBUG | 1912 #if DEBUG |
| 1903 void CompilationInfo::PrintAstForTesting() { | 1913 void CompilationInfo::PrintAstForTesting() { |
| 1904 PrintF("--- Source from AST ---\n%s\n", | 1914 PrintF("--- Source from AST ---\n%s\n", |
| 1905 PrettyPrinter(isolate()).PrintProgram(literal())); | 1915 PrettyPrinter(isolate()).PrintProgram(literal())); |
| 1906 } | 1916 } |
| 1907 #endif | 1917 #endif |
| 1908 | 1918 |
| 1909 } // namespace internal | 1919 } // namespace internal |
| 1910 } // namespace v8 | 1920 } // namespace v8 |
| OLD | NEW |