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 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) | 909 if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT) |
910 .ToHandle(&opt_code)) { | 910 .ToHandle(&opt_code)) { |
911 result = opt_code; | 911 result = opt_code; |
912 } | 912 } |
913 } | 913 } |
914 | 914 |
915 return result; | 915 return result; |
916 } | 916 } |
917 | 917 |
918 | 918 |
919 bool CompileForDebugging(CompilationInfo* info) { | |
920 info->MarkAsDebug(); | |
921 if (GetUnoptimizedCode(info).is_null()) { | |
922 info->isolate()->clear_pending_exception(); | |
923 return false; | |
924 } | |
925 return true; | |
926 } | |
927 | |
928 inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { | 919 inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) { |
929 return shared->is_toplevel() && shared->script()->IsScript() && | 920 return shared->is_toplevel() && shared->script()->IsScript() && |
930 Script::cast(shared->script())->compilation_type() == | 921 Script::cast(shared->script())->compilation_type() == |
931 Script::COMPILATION_TYPE_EVAL; | 922 Script::COMPILATION_TYPE_EVAL; |
932 } | 923 } |
933 | 924 |
934 Handle<SharedFunctionInfo> NewSharedFunctionInfoForLiteral( | 925 Handle<SharedFunctionInfo> NewSharedFunctionInfoForLiteral( |
935 Isolate* isolate, FunctionLiteral* literal, Handle<Script> script) { | 926 Isolate* isolate, FunctionLiteral* literal, Handle<Script> script) { |
936 Handle<Code> code = isolate->builtins()->CompileLazy(); | 927 Handle<Code> code = isolate->builtins()->CompileLazy(); |
937 Handle<ScopeInfo> scope_info = handle(ScopeInfo::Empty(isolate)); | 928 Handle<ScopeInfo> scope_info = handle(ScopeInfo::Empty(isolate)); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 bool Compiler::ParseAndAnalyze(ParseInfo* info) { | 1061 bool Compiler::ParseAndAnalyze(ParseInfo* info) { |
1071 if (!Parser::ParseStatic(info)) return false; | 1062 if (!Parser::ParseStatic(info)) return false; |
1072 if (!Compiler::Analyze(info)) return false; | 1063 if (!Compiler::Analyze(info)) return false; |
1073 DCHECK_NOT_NULL(info->literal()); | 1064 DCHECK_NOT_NULL(info->literal()); |
1074 DCHECK_NOT_NULL(info->scope()); | 1065 DCHECK_NOT_NULL(info->scope()); |
1075 return true; | 1066 return true; |
1076 } | 1067 } |
1077 | 1068 |
1078 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { | 1069 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { |
1079 if (function->is_compiled()) return true; | 1070 if (function->is_compiled()) return true; |
| 1071 Isolate* isolate = function->GetIsolate(); |
| 1072 DCHECK(AllowCompilation::IsAllowed(isolate)); |
1080 | 1073 |
1081 MaybeHandle<Code> maybe_code = GetLazyCode(function); | 1074 // Start a compilation. |
1082 Handle<Code> code; | 1075 Handle<Code> code; |
1083 if (!maybe_code.ToHandle(&code)) { | 1076 if (!GetLazyCode(function).ToHandle(&code)) { |
1084 if (flag == CLEAR_EXCEPTION) { | 1077 if (flag == CLEAR_EXCEPTION) { |
1085 function->GetIsolate()->clear_pending_exception(); | 1078 isolate->clear_pending_exception(); |
1086 } | 1079 } |
1087 return false; | 1080 return false; |
1088 } | 1081 } |
1089 | 1082 |
| 1083 // Install code on closure. |
1090 function->ReplaceCode(*code); | 1084 function->ReplaceCode(*code); |
| 1085 |
| 1086 // Check postconditions on success. |
| 1087 DCHECK(!isolate->has_pending_exception()); |
| 1088 DCHECK(function->shared()->is_compiled()); |
1091 DCHECK(function->is_compiled()); | 1089 DCHECK(function->is_compiled()); |
1092 return true; | 1090 return true; |
1093 } | 1091 } |
1094 | 1092 |
1095 bool Compiler::CompileOptimized(Handle<JSFunction> function, | 1093 bool Compiler::CompileOptimized(Handle<JSFunction> function, |
1096 ConcurrencyMode mode) { | 1094 ConcurrencyMode mode) { |
| 1095 if (function->IsOptimized()) return true; |
| 1096 Isolate* isolate = function->GetIsolate(); |
| 1097 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1098 |
| 1099 // Start a compilation. |
1097 Handle<Code> code; | 1100 Handle<Code> code; |
1098 if (GetOptimizedCode(function, mode).ToHandle(&code)) { | 1101 if (!GetOptimizedCode(function, mode).ToHandle(&code)) { |
1099 // Optimization succeeded, return optimized code. | |
1100 function->ReplaceCode(*code); | |
1101 } else { | |
1102 // Optimization failed, get unoptimized code. | 1102 // Optimization failed, get unoptimized code. |
1103 Isolate* isolate = function->GetIsolate(); | 1103 DCHECK(!isolate->has_pending_exception()); |
1104 if (isolate->has_pending_exception()) { // Possible stack overflow. | 1104 if (function->shared()->is_compiled()) { |
1105 return false; | 1105 code = handle(function->shared()->code(), isolate); |
1106 } | 1106 } else { |
1107 code = Handle<Code>(function->shared()->code(), isolate); | 1107 CompilationInfoWithZone info(function); |
1108 if (code->kind() != Code::FUNCTION && | 1108 if (!GetUnoptimizedCode(&info).ToHandle(&code)) { |
1109 code->kind() != Code::OPTIMIZED_FUNCTION) { | 1109 return false; |
1110 DCHECK(!isolate->has_pending_exception()); | |
1111 DCHECK(!function->is_compiled()); | |
1112 if (!function->shared()->is_compiled()) { | |
1113 CompilationInfoWithZone info(function); | |
1114 if (!GetUnoptimizedCode(&info).ToHandle(&code)) { | |
1115 return false; | |
1116 } | |
1117 } | 1110 } |
1118 } | 1111 } |
1119 function->ReplaceCode(*code); | |
1120 } | 1112 } |
1121 | 1113 |
1122 DCHECK(function->code()->kind() == Code::FUNCTION || | 1114 // Install code on closure. |
1123 function->code()->kind() == Code::OPTIMIZED_FUNCTION || | 1115 function->ReplaceCode(*code); |
1124 (function->code()->is_interpreter_entry_trampoline() && | 1116 |
1125 function->shared()->HasBytecodeArray()) || | 1117 // Check postconditions on success. |
1126 function->IsInOptimizationQueue()); | 1118 DCHECK(!isolate->has_pending_exception()); |
| 1119 DCHECK(function->shared()->is_compiled()); |
| 1120 DCHECK(function->is_compiled()); |
1127 return true; | 1121 return true; |
1128 } | 1122 } |
1129 | 1123 |
1130 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { | 1124 bool Compiler::CompileDebugCode(Handle<JSFunction> function) { |
1131 Zone zone(function->GetIsolate()->allocator()); | 1125 Isolate* isolate = function->GetIsolate(); |
| 1126 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1127 |
| 1128 // Start a compilation. |
| 1129 Zone zone(isolate->allocator()); |
1132 ParseInfo parse_info(&zone, function); | 1130 ParseInfo parse_info(&zone, function); |
1133 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1131 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1134 if (IsEvalToplevel(handle(function->shared()))) { | 1132 if (IsEvalToplevel(handle(function->shared()))) { |
1135 parse_info.set_eval(); | 1133 parse_info.set_eval(); |
1136 if (function->context()->IsNativeContext()) parse_info.set_global(); | 1134 if (function->context()->IsNativeContext()) parse_info.set_global(); |
1137 parse_info.set_toplevel(); | 1135 parse_info.set_toplevel(); |
1138 parse_info.set_allow_lazy_parsing(false); | 1136 parse_info.set_allow_lazy_parsing(false); |
1139 parse_info.set_lazy(false); | 1137 parse_info.set_lazy(false); |
1140 } | 1138 } |
1141 return CompileForDebugging(&info); | 1139 info.MarkAsDebug(); |
| 1140 if (GetUnoptimizedCode(&info).is_null()) { |
| 1141 isolate->clear_pending_exception(); |
| 1142 return false; |
| 1143 } |
| 1144 |
| 1145 // Check postconditions on success. |
| 1146 DCHECK(!isolate->has_pending_exception()); |
| 1147 DCHECK(function->shared()->is_compiled()); |
| 1148 DCHECK(function->shared()->HasDebugCode()); |
| 1149 return true; |
1142 } | 1150 } |
1143 | 1151 |
1144 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { | 1152 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { |
| 1153 Isolate* isolate = shared->GetIsolate(); |
| 1154 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1155 |
| 1156 // Start a compilation. |
| 1157 Zone zone(isolate->allocator()); |
| 1158 ParseInfo parse_info(&zone, shared); |
| 1159 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1145 DCHECK(shared->allows_lazy_compilation_without_context()); | 1160 DCHECK(shared->allows_lazy_compilation_without_context()); |
1146 DCHECK(!IsEvalToplevel(shared)); | 1161 DCHECK(!IsEvalToplevel(shared)); |
1147 Zone zone(shared->GetIsolate()->allocator()); | 1162 info.MarkAsDebug(); |
1148 ParseInfo parse_info(&zone, shared); | 1163 if (GetUnoptimizedCode(&info).is_null()) { |
| 1164 isolate->clear_pending_exception(); |
| 1165 return false; |
| 1166 } |
| 1167 |
| 1168 // Check postconditions on success. |
| 1169 DCHECK(!isolate->has_pending_exception()); |
| 1170 DCHECK(shared->is_compiled()); |
| 1171 DCHECK(shared->HasDebugCode()); |
| 1172 return true; |
| 1173 } |
| 1174 |
| 1175 void Compiler::CompileForLiveEdit(Handle<Script> script) { |
| 1176 Isolate* isolate = script->GetIsolate(); |
| 1177 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1178 |
| 1179 // Start a compilation. |
| 1180 // TODO(635): support extensions. |
| 1181 Zone zone(isolate->allocator()); |
| 1182 ParseInfo parse_info(&zone, script); |
1149 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1183 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1150 return CompileForDebugging(&info); | 1184 PostponeInterruptsScope postpone(isolate); |
| 1185 VMState<COMPILER> state(isolate); |
| 1186 |
| 1187 info.MarkAsDebug(); |
| 1188 info.parse_info()->set_global(); |
| 1189 if (!Parser::ParseStatic(info.parse_info())) return; |
| 1190 |
| 1191 LiveEditFunctionTracker tracker(isolate, parse_info.literal()); |
| 1192 if (!CompileBaselineCode(&info)) return; |
| 1193 tracker.RecordRootFunctionInfo(info.code()); |
1151 } | 1194 } |
1152 | 1195 |
1153 // TODO(turbofan): In the future, unoptimized code with deopt support could | 1196 // TODO(turbofan): In the future, unoptimized code with deopt support could |
1154 // be generated lazily once deopt is triggered. | 1197 // be generated lazily once deopt is triggered. |
1155 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 1198 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
1156 DCHECK_NOT_NULL(info->literal()); | 1199 DCHECK_NOT_NULL(info->literal()); |
1157 DCHECK_NOT_NULL(info->scope()); | 1200 DCHECK_NOT_NULL(info->scope()); |
1158 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1201 Handle<SharedFunctionInfo> shared = info->shared_info(); |
1159 if (!shared->has_deoptimization_support()) { | 1202 if (!shared->has_deoptimization_support()) { |
1160 // TODO(titzer): just reuse the ParseInfo for the unoptimized compile. | 1203 // TODO(titzer): just reuse the ParseInfo for the unoptimized compile. |
(...skipping 24 matching lines...) Expand all Loading... |
1185 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); | 1228 ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); |
1186 shared->set_scope_info(*target_scope_info); | 1229 shared->set_scope_info(*target_scope_info); |
1187 } | 1230 } |
1188 | 1231 |
1189 // The existing unoptimized code was replaced with the new one. | 1232 // The existing unoptimized code was replaced with the new one. |
1190 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized, shared); | 1233 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized, shared); |
1191 } | 1234 } |
1192 return true; | 1235 return true; |
1193 } | 1236 } |
1194 | 1237 |
1195 void Compiler::CompileForLiveEdit(Handle<Script> script) { | |
1196 // TODO(635): support extensions. | |
1197 Zone zone(script->GetIsolate()->allocator()); | |
1198 ParseInfo parse_info(&zone, script); | |
1199 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | |
1200 PostponeInterruptsScope postpone(info.isolate()); | |
1201 VMState<COMPILER> state(info.isolate()); | |
1202 | |
1203 info.MarkAsDebug(); | |
1204 info.parse_info()->set_global(); | |
1205 if (!Parser::ParseStatic(info.parse_info())) return; | |
1206 | |
1207 LiveEditFunctionTracker tracker(info.isolate(), parse_info.literal()); | |
1208 if (!CompileBaselineCode(&info)) return; | |
1209 tracker.RecordRootFunctionInfo(info.code()); | |
1210 } | |
1211 | |
1212 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( | 1238 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( |
1213 Handle<String> source, Handle<SharedFunctionInfo> outer_info, | 1239 Handle<String> source, Handle<SharedFunctionInfo> outer_info, |
1214 Handle<Context> context, LanguageMode language_mode, | 1240 Handle<Context> context, LanguageMode language_mode, |
1215 ParseRestriction restriction, int line_offset, int column_offset, | 1241 ParseRestriction restriction, int line_offset, int column_offset, |
1216 Handle<Object> script_name, ScriptOriginOptions options) { | 1242 Handle<Object> script_name, ScriptOriginOptions options) { |
1217 Isolate* isolate = source->GetIsolate(); | 1243 Isolate* isolate = source->GetIsolate(); |
1218 int source_length = source->length(); | 1244 int source_length = source->length(); |
1219 isolate->counters()->total_eval_size()->Increment(source_length); | 1245 isolate->counters()->total_eval_size()->Increment(source_length); |
1220 isolate->counters()->total_compile_size()->Increment(source_length); | 1246 isolate->counters()->total_compile_size()->Increment(source_length); |
1221 | 1247 |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1669 MaybeHandle<Code> code; | 1695 MaybeHandle<Code> code; |
1670 if (cached.code != nullptr) code = handle(cached.code); | 1696 if (cached.code != nullptr) code = handle(cached.code); |
1671 Handle<Context> native_context(function->context()->native_context()); | 1697 Handle<Context> native_context(function->context()->native_context()); |
1672 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | 1698 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, |
1673 literals, BailoutId::None()); | 1699 literals, BailoutId::None()); |
1674 } | 1700 } |
1675 } | 1701 } |
1676 | 1702 |
1677 } // namespace internal | 1703 } // namespace internal |
1678 } // namespace v8 | 1704 } // namespace v8 |
OLD | NEW |