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 |