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-numbering.h" | 9 #include "src/ast-numbering.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 Handle<JSFunction>::null()) | 67 Handle<JSFunction>::null()) |
68 PARSE_INFO_GETTER(FunctionLiteral*, function) | 68 PARSE_INFO_GETTER(FunctionLiteral*, function) |
69 PARSE_INFO_GETTER_WITH_DEFAULT(Scope*, scope, nullptr) | 69 PARSE_INFO_GETTER_WITH_DEFAULT(Scope*, scope, nullptr) |
70 PARSE_INFO_GETTER(Handle<Context>, context) | 70 PARSE_INFO_GETTER(Handle<Context>, context) |
71 PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info) | 71 PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info) |
72 | 72 |
73 #undef PARSE_INFO_GETTER | 73 #undef PARSE_INFO_GETTER |
74 #undef PARSE_INFO_GETTER_WITH_DEFAULT | 74 #undef PARSE_INFO_GETTER_WITH_DEFAULT |
75 | 75 |
76 | 76 |
| 77 // Exactly like a CompilationInfo, except being allocated via {new} and it also |
| 78 // creates and enters a Zone on construction and deallocates it on destruction. |
| 79 class CompilationInfoWithZone : public CompilationInfo { |
| 80 public: |
| 81 explicit CompilationInfoWithZone(Handle<JSFunction> function) |
| 82 : CompilationInfo(new ParseInfo(&zone_, function)) {} |
| 83 |
| 84 // Virtual destructor because a CompilationInfoWithZone has to exit the |
| 85 // zone scope and get rid of dependent maps even when the destructor is |
| 86 // called when cast as a CompilationInfo. |
| 87 virtual ~CompilationInfoWithZone() { |
| 88 DisableFutureOptimization(); |
| 89 RollbackDependencies(); |
| 90 delete parse_info_; |
| 91 parse_info_ = nullptr; |
| 92 } |
| 93 |
| 94 private: |
| 95 Zone zone_; |
| 96 }; |
| 97 |
| 98 |
77 bool CompilationInfo::has_shared_info() const { | 99 bool CompilationInfo::has_shared_info() const { |
78 return parse_info_ && !parse_info_->shared_info().is_null(); | 100 return parse_info_ && !parse_info_->shared_info().is_null(); |
79 } | 101 } |
80 | 102 |
81 | 103 |
82 CompilationInfo::CompilationInfo(ParseInfo* parse_info) | 104 CompilationInfo::CompilationInfo(ParseInfo* parse_info) |
83 : CompilationInfo(parse_info, nullptr, BASE, parse_info->isolate(), | 105 : CompilationInfo(parse_info, nullptr, BASE, parse_info->isolate(), |
84 parse_info->zone()) { | 106 parse_info->zone()) { |
85 // Compiling for the snapshot typically results in different code than | 107 // Compiling for the snapshot typically results in different code than |
86 // compiling later on. This means that code recompiled with deoptimization | 108 // compiling later on. This means that code recompiled with deoptimization |
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 } else { | 1022 } else { |
1001 DCHECK_EQ(old_code->is_compiled_optimizable(), | 1023 DCHECK_EQ(old_code->is_compiled_optimizable(), |
1002 new_code->is_compiled_optimizable()); | 1024 new_code->is_compiled_optimizable()); |
1003 } | 1025 } |
1004 return maybe_new_code; | 1026 return maybe_new_code; |
1005 } | 1027 } |
1006 | 1028 |
1007 | 1029 |
1008 void Compiler::CompileForLiveEdit(Handle<Script> script) { | 1030 void Compiler::CompileForLiveEdit(Handle<Script> script) { |
1009 // TODO(635): support extensions. | 1031 // TODO(635): support extensions. |
1010 CompilationInfoWithZone info(script); | 1032 Zone zone; |
| 1033 ParseInfo parse_info(&zone, script); |
| 1034 CompilationInfo info(&parse_info); |
1011 PostponeInterruptsScope postpone(info.isolate()); | 1035 PostponeInterruptsScope postpone(info.isolate()); |
1012 VMState<COMPILER> state(info.isolate()); | 1036 VMState<COMPILER> state(info.isolate()); |
1013 | 1037 |
1014 info.parse_info()->set_global(); | 1038 info.parse_info()->set_global(); |
1015 if (!Parser::ParseStatic(info.parse_info())) return; | 1039 if (!Parser::ParseStatic(info.parse_info())) return; |
1016 | 1040 |
1017 LiveEditFunctionTracker tracker(info.isolate(), info.function()); | 1041 LiveEditFunctionTracker tracker(info.isolate(), info.function()); |
1018 if (!CompileUnoptimizedCode(&info)) return; | 1042 if (!CompileUnoptimizedCode(&info)) return; |
1019 if (info.has_shared_info()) { | 1043 if (info.has_shared_info()) { |
1020 Handle<ScopeInfo> scope_info = | 1044 Handle<ScopeInfo> scope_info = |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1138 isolate->counters()->total_compile_size()->Increment(source_length); | 1162 isolate->counters()->total_compile_size()->Increment(source_length); |
1139 | 1163 |
1140 CompilationCache* compilation_cache = isolate->compilation_cache(); | 1164 CompilationCache* compilation_cache = isolate->compilation_cache(); |
1141 MaybeHandle<SharedFunctionInfo> maybe_shared_info = | 1165 MaybeHandle<SharedFunctionInfo> maybe_shared_info = |
1142 compilation_cache->LookupEval(source, outer_info, context, language_mode, | 1166 compilation_cache->LookupEval(source, outer_info, context, language_mode, |
1143 scope_position); | 1167 scope_position); |
1144 Handle<SharedFunctionInfo> shared_info; | 1168 Handle<SharedFunctionInfo> shared_info; |
1145 | 1169 |
1146 if (!maybe_shared_info.ToHandle(&shared_info)) { | 1170 if (!maybe_shared_info.ToHandle(&shared_info)) { |
1147 Handle<Script> script = isolate->factory()->NewScript(source); | 1171 Handle<Script> script = isolate->factory()->NewScript(source); |
1148 CompilationInfoWithZone info(script); | 1172 Zone zone; |
1149 ParseInfo* parse_info = info.parse_info(); | 1173 ParseInfo parse_info(&zone, script); |
1150 parse_info->set_eval(); | 1174 CompilationInfo info(&parse_info); |
1151 if (context->IsNativeContext()) parse_info->set_global(); | 1175 parse_info.set_eval(); |
1152 parse_info->set_language_mode(language_mode); | 1176 if (context->IsNativeContext()) parse_info.set_global(); |
1153 parse_info->set_parse_restriction(restriction); | 1177 parse_info.set_language_mode(language_mode); |
1154 parse_info->set_context(context); | 1178 parse_info.set_parse_restriction(restriction); |
| 1179 parse_info.set_context(context); |
1155 | 1180 |
1156 Debug::RecordEvalCaller(script); | 1181 Debug::RecordEvalCaller(script); |
1157 | 1182 |
1158 shared_info = CompileToplevel(&info); | 1183 shared_info = CompileToplevel(&info); |
1159 | 1184 |
1160 if (shared_info.is_null()) { | 1185 if (shared_info.is_null()) { |
1161 return MaybeHandle<JSFunction>(); | 1186 return MaybeHandle<JSFunction>(); |
1162 } else { | 1187 } else { |
1163 // Explicitly disable optimization for eval code. We're not yet prepared | 1188 // Explicitly disable optimization for eval code. We're not yet prepared |
1164 // to handle eval-code in the optimizing compiler. | 1189 // to handle eval-code in the optimizing compiler. |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1261 script->set_line_offset(Smi::FromInt(line_offset)); | 1286 script->set_line_offset(Smi::FromInt(line_offset)); |
1262 script->set_column_offset(Smi::FromInt(column_offset)); | 1287 script->set_column_offset(Smi::FromInt(column_offset)); |
1263 } | 1288 } |
1264 script->set_is_shared_cross_origin(is_shared_cross_origin); | 1289 script->set_is_shared_cross_origin(is_shared_cross_origin); |
1265 script->set_is_embedder_debug_script(is_embedder_debug_script); | 1290 script->set_is_embedder_debug_script(is_embedder_debug_script); |
1266 if (!source_map_url.is_null()) { | 1291 if (!source_map_url.is_null()) { |
1267 script->set_source_mapping_url(*source_map_url); | 1292 script->set_source_mapping_url(*source_map_url); |
1268 } | 1293 } |
1269 | 1294 |
1270 // Compile the function and add it to the cache. | 1295 // Compile the function and add it to the cache. |
1271 CompilationInfoWithZone info(script); | 1296 Zone zone; |
1272 ParseInfo* parse_info = info.parse_info(); | 1297 ParseInfo parse_info(&zone, script); |
| 1298 CompilationInfo info(&parse_info); |
1273 if (FLAG_harmony_modules && is_module) { | 1299 if (FLAG_harmony_modules && is_module) { |
1274 parse_info->set_module(); | 1300 parse_info.set_module(); |
1275 } else { | 1301 } else { |
1276 parse_info->set_global(); | 1302 parse_info.set_global(); |
1277 } | 1303 } |
1278 if (compile_options != ScriptCompiler::kNoCompileOptions) { | 1304 if (compile_options != ScriptCompiler::kNoCompileOptions) { |
1279 parse_info->set_cached_data(cached_data); | 1305 parse_info.set_cached_data(cached_data); |
1280 } | 1306 } |
1281 parse_info->set_compile_options(compile_options); | 1307 parse_info.set_compile_options(compile_options); |
1282 parse_info->set_extension(extension); | 1308 parse_info.set_extension(extension); |
1283 parse_info->set_context(context); | 1309 parse_info.set_context(context); |
1284 if (FLAG_serialize_toplevel && | 1310 if (FLAG_serialize_toplevel && |
1285 compile_options == ScriptCompiler::kProduceCodeCache) { | 1311 compile_options == ScriptCompiler::kProduceCodeCache) { |
1286 info.PrepareForSerializing(); | 1312 info.PrepareForSerializing(); |
1287 } | 1313 } |
1288 | 1314 |
1289 parse_info->set_language_mode( | 1315 parse_info.set_language_mode( |
1290 static_cast<LanguageMode>(info.language_mode() | language_mode)); | 1316 static_cast<LanguageMode>(info.language_mode() | language_mode)); |
1291 result = CompileToplevel(&info); | 1317 result = CompileToplevel(&info); |
1292 if (extension == NULL && !result.is_null() && !result->dont_cache()) { | 1318 if (extension == NULL && !result.is_null() && !result->dont_cache()) { |
1293 compilation_cache->PutScript(source, context, language_mode, result); | 1319 compilation_cache->PutScript(source, context, language_mode, result); |
1294 if (FLAG_serialize_toplevel && | 1320 if (FLAG_serialize_toplevel && |
1295 compile_options == ScriptCompiler::kProduceCodeCache) { | 1321 compile_options == ScriptCompiler::kProduceCodeCache) { |
1296 HistogramTimerScope histogram_timer( | 1322 HistogramTimerScope histogram_timer( |
1297 isolate->counters()->compile_serialize()); | 1323 isolate->counters()->compile_serialize()); |
1298 *cached_data = CodeSerializer::Serialize(isolate, result, source); | 1324 *cached_data = CodeSerializer::Serialize(isolate, result, source); |
1299 if (FLAG_profile_deserialization) { | 1325 if (FLAG_profile_deserialization) { |
(...skipping 27 matching lines...) Expand all Loading... |
1327 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the | 1353 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the |
1328 // real code caching lands, streaming needs to be adapted to use it. | 1354 // real code caching lands, streaming needs to be adapted to use it. |
1329 return CompileToplevel(&compile_info); | 1355 return CompileToplevel(&compile_info); |
1330 } | 1356 } |
1331 | 1357 |
1332 | 1358 |
1333 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( | 1359 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( |
1334 FunctionLiteral* literal, Handle<Script> script, | 1360 FunctionLiteral* literal, Handle<Script> script, |
1335 CompilationInfo* outer_info) { | 1361 CompilationInfo* outer_info) { |
1336 // Precondition: code has been parsed and scopes have been analyzed. | 1362 // Precondition: code has been parsed and scopes have been analyzed. |
1337 CompilationInfoWithZone info(script); | 1363 Zone zone; |
1338 ParseInfo* parse_info = info.parse_info(); | 1364 ParseInfo parse_info(&zone, script); |
1339 parse_info->set_literal(literal); | 1365 CompilationInfo info(&parse_info); |
1340 parse_info->set_scope(literal->scope()); | 1366 parse_info.set_literal(literal); |
1341 parse_info->set_language_mode(literal->scope()->language_mode()); | 1367 parse_info.set_scope(literal->scope()); |
| 1368 parse_info.set_language_mode(literal->scope()->language_mode()); |
1342 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 1369 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
1343 | 1370 |
1344 Isolate* isolate = info.isolate(); | 1371 Isolate* isolate = info.isolate(); |
1345 Factory* factory = isolate->factory(); | 1372 Factory* factory = isolate->factory(); |
1346 LiveEditFunctionTracker live_edit_tracker(isolate, literal); | 1373 LiveEditFunctionTracker live_edit_tracker(isolate, literal); |
1347 // Determine if the function can be lazily compiled. This is necessary to | 1374 // Determine if the function can be lazily compiled. This is necessary to |
1348 // allow some of our builtin JS files to be lazily compiled. These | 1375 // allow some of our builtin JS files to be lazily compiled. These |
1349 // builtins cannot be handled lazily by the parser, since we have to know | 1376 // builtins cannot be handled lazily by the parser, since we have to know |
1350 // if a function uses the special natives syntax, which is something the | 1377 // if a function uses the special natives syntax, which is something the |
1351 // parser records. | 1378 // parser records. |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1541 AllowHandleDereference allow_deref; | 1568 AllowHandleDereference allow_deref; |
1542 bool tracing_on = info()->IsStub() | 1569 bool tracing_on = info()->IsStub() |
1543 ? FLAG_trace_hydrogen_stubs | 1570 ? FLAG_trace_hydrogen_stubs |
1544 : (FLAG_trace_hydrogen && | 1571 : (FLAG_trace_hydrogen && |
1545 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); | 1572 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); |
1546 return (tracing_on && | 1573 return (tracing_on && |
1547 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); | 1574 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); |
1548 } | 1575 } |
1549 | 1576 |
1550 | 1577 |
1551 CompilationInfoWithZone::CompilationInfoWithZone(Handle<Script> script) | |
1552 : CompilationInfo(new ParseInfo(&zone_, script)) {} | |
1553 | |
1554 | |
1555 CompilationInfoWithZone::CompilationInfoWithZone(Handle<JSFunction> function) | |
1556 : CompilationInfo(new ParseInfo(&zone_, function)) {} | |
1557 | |
1558 | |
1559 CompilationInfoWithZone::~CompilationInfoWithZone() { | |
1560 DisableFutureOptimization(); | |
1561 RollbackDependencies(); | |
1562 delete parse_info_; | |
1563 parse_info_ = nullptr; | |
1564 } | |
1565 | |
1566 #if DEBUG | 1578 #if DEBUG |
1567 void CompilationInfo::PrintAstForTesting() { | 1579 void CompilationInfo::PrintAstForTesting() { |
1568 PrintF("--- Source from AST ---\n%s\n", | 1580 PrintF("--- Source from AST ---\n%s\n", |
1569 PrettyPrinter(isolate(), zone()).PrintProgram(function())); | 1581 PrettyPrinter(isolate(), zone()).PrintProgram(function())); |
1570 } | 1582 } |
1571 #endif | 1583 #endif |
1572 } } // namespace v8::internal | 1584 } } // namespace v8::internal |
OLD | NEW |