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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
50 return parse_info() ? parse_info()->name() : def; \ | 50 return parse_info() ? parse_info()->name() : def; \ |
51 } | 51 } |
52 | 52 |
53 | 53 |
54 PARSE_INFO_GETTER(Handle<Script>, script) | 54 PARSE_INFO_GETTER(Handle<Script>, script) |
55 PARSE_INFO_GETTER(bool, is_eval) | 55 PARSE_INFO_GETTER(bool, is_eval) |
56 PARSE_INFO_GETTER(bool, is_native) | 56 PARSE_INFO_GETTER(bool, is_native) |
57 PARSE_INFO_GETTER(bool, is_module) | 57 PARSE_INFO_GETTER(bool, is_module) |
58 PARSE_INFO_GETTER(FunctionLiteral*, literal) | 58 PARSE_INFO_GETTER(FunctionLiteral*, literal) |
59 PARSE_INFO_GETTER_WITH_DEFAULT(LanguageMode, language_mode, STRICT) | 59 PARSE_INFO_GETTER_WITH_DEFAULT(LanguageMode, language_mode, STRICT) |
60 PARSE_INFO_GETTER_WITH_DEFAULT(Handle<JSFunction>, closure, | |
61 Handle<JSFunction>::null()) | |
62 PARSE_INFO_GETTER_WITH_DEFAULT(Scope*, scope, nullptr) | 60 PARSE_INFO_GETTER_WITH_DEFAULT(Scope*, scope, nullptr) |
63 PARSE_INFO_GETTER(Handle<Context>, context) | 61 PARSE_INFO_GETTER(Handle<Context>, context) |
64 PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info) | 62 PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info) |
65 | 63 |
66 #undef PARSE_INFO_GETTER | 64 #undef PARSE_INFO_GETTER |
67 #undef PARSE_INFO_GETTER_WITH_DEFAULT | 65 #undef PARSE_INFO_GETTER_WITH_DEFAULT |
68 | 66 |
69 // A wrapper around a CompilationInfo that detaches the Handles from | 67 // A wrapper around a CompilationInfo that detaches the Handles from |
70 // the underlying DeferredHandleScope and stores them in info_ on | 68 // the underlying DeferredHandleScope and stores them in info_ on |
71 // destruction. | 69 // destruction. |
72 class CompilationHandleScope BASE_EMBEDDED { | 70 class CompilationHandleScope BASE_EMBEDDED { |
73 public: | 71 public: |
74 explicit CompilationHandleScope(CompilationInfo* info) | 72 explicit CompilationHandleScope(CompilationInfo* info) |
75 : deferred_(info->isolate()), info_(info) {} | 73 : deferred_(info->isolate()), info_(info) {} |
76 ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); } | 74 ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); } |
77 | 75 |
78 private: | 76 private: |
79 DeferredHandleScope deferred_; | 77 DeferredHandleScope deferred_; |
80 CompilationInfo* info_; | 78 CompilationInfo* info_; |
81 }; | 79 }; |
82 | 80 |
83 // Exactly like a CompilationInfo, except being allocated via {new} and it also | 81 // Exactly like a CompilationInfo, except being allocated via {new} and it also |
84 // creates and enters a Zone on construction and deallocates it on destruction. | 82 // creates and enters a Zone on construction and deallocates it on destruction. |
85 class CompilationInfoWithZone : public CompilationInfo { | 83 class CompilationInfoWithZone : public CompilationInfo { |
86 public: | 84 public: |
87 explicit CompilationInfoWithZone(Handle<JSFunction> function) | 85 explicit CompilationInfoWithZone(Handle<JSFunction> function) |
88 : CompilationInfo(new ParseInfo(&zone_, function)), | 86 : CompilationInfo(new ParseInfo(&zone_, function), function), |
89 zone_(function->GetIsolate()->allocator()) {} | 87 zone_(function->GetIsolate()->allocator()) {} |
90 | 88 |
91 // Virtual destructor because a CompilationInfoWithZone has to exit the | 89 // Virtual destructor because a CompilationInfoWithZone has to exit the |
92 // zone scope and get rid of dependent maps even when the destructor is | 90 // zone scope and get rid of dependent maps even when the destructor is |
93 // called when cast as a CompilationInfo. | 91 // called when cast as a CompilationInfo. |
94 virtual ~CompilationInfoWithZone() { | 92 virtual ~CompilationInfoWithZone() { |
95 DisableFutureOptimization(); | 93 DisableFutureOptimization(); |
96 dependencies()->Rollback(); | 94 dependencies()->Rollback(); |
97 delete parse_info_; | 95 delete parse_info_; |
98 parse_info_ = nullptr; | 96 parse_info_ = nullptr; |
(...skipping 13 matching lines...) Expand all Loading... | |
112 | 110 |
113 bool CompilationInfo::has_context() const { | 111 bool CompilationInfo::has_context() const { |
114 return parse_info_ && !parse_info_->context().is_null(); | 112 return parse_info_ && !parse_info_->context().is_null(); |
115 } | 113 } |
116 | 114 |
117 | 115 |
118 bool CompilationInfo::has_scope() const { | 116 bool CompilationInfo::has_scope() const { |
119 return parse_info_ && parse_info_->scope() != nullptr; | 117 return parse_info_ && parse_info_->scope() != nullptr; |
120 } | 118 } |
121 | 119 |
122 | 120 CompilationInfo::CompilationInfo(ParseInfo* parse_info, |
123 CompilationInfo::CompilationInfo(ParseInfo* parse_info) | 121 Handle<JSFunction> closure) |
124 : CompilationInfo(parse_info, nullptr, Code::ComputeFlags(Code::FUNCTION), | 122 : CompilationInfo(parse_info, nullptr, Code::ComputeFlags(Code::FUNCTION), |
125 BASE, parse_info->isolate(), parse_info->zone()) { | 123 BASE, parse_info->isolate(), parse_info->zone()) { |
124 closure_ = closure; | |
125 | |
126 // Compiling for the snapshot typically results in different code than | 126 // Compiling for the snapshot typically results in different code than |
127 // compiling later on. This means that code recompiled with deoptimization | 127 // compiling later on. This means that code recompiled with deoptimization |
128 // support won't be "equivalent" (as defined by SharedFunctionInfo:: | 128 // support won't be "equivalent" (as defined by SharedFunctionInfo:: |
129 // EnableDeoptimizationSupport), so it will replace the old code and all | 129 // EnableDeoptimizationSupport), so it will replace the old code and all |
130 // its type feedback. To avoid this, always compile functions in the snapshot | 130 // its type feedback. To avoid this, always compile functions in the snapshot |
131 // with deoptimization support. | 131 // with deoptimization support. |
132 if (isolate_->serializer_enabled()) EnableDeoptimizationSupport(); | 132 if (isolate_->serializer_enabled()) EnableDeoptimizationSupport(); |
133 | 133 |
134 if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing(); | 134 if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing(); |
135 if (FLAG_turbo_inlining) MarkAsInliningEnabled(); | 135 if (FLAG_turbo_inlining) MarkAsInliningEnabled(); |
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1148 } | 1148 } |
1149 | 1149 |
1150 | 1150 |
1151 bool CompileEvalForDebugging(Handle<JSFunction> function, | 1151 bool CompileEvalForDebugging(Handle<JSFunction> function, |
1152 Handle<SharedFunctionInfo> shared) { | 1152 Handle<SharedFunctionInfo> shared) { |
1153 Handle<Script> script(Script::cast(shared->script())); | 1153 Handle<Script> script(Script::cast(shared->script())); |
1154 Handle<Context> context(function->context()); | 1154 Handle<Context> context(function->context()); |
1155 | 1155 |
1156 Zone zone(function->GetIsolate()->allocator()); | 1156 Zone zone(function->GetIsolate()->allocator()); |
1157 ParseInfo parse_info(&zone, script); | 1157 ParseInfo parse_info(&zone, script); |
1158 CompilationInfo info(&parse_info); | 1158 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
rossberg
2016/04/06 14:57:32
Given the frequency of this case, why not make nul
Michael Starzinger
2016/04/06 16:13:59
The frequency of this case is _only_ in compiler.c
| |
1159 Isolate* isolate = info.isolate(); | 1159 Isolate* isolate = info.isolate(); |
1160 | 1160 |
1161 parse_info.set_eval(); | 1161 parse_info.set_eval(); |
1162 parse_info.set_context(context); | 1162 parse_info.set_context(context); |
1163 if (context->IsNativeContext()) parse_info.set_global(); | 1163 if (context->IsNativeContext()) parse_info.set_global(); |
1164 parse_info.set_toplevel(); | 1164 parse_info.set_toplevel(); |
1165 parse_info.set_allow_lazy_parsing(false); | 1165 parse_info.set_allow_lazy_parsing(false); |
1166 parse_info.set_language_mode(shared->language_mode()); | 1166 parse_info.set_language_mode(shared->language_mode()); |
1167 parse_info.set_parse_restriction(NO_PARSE_RESTRICTION); | 1167 parse_info.set_parse_restriction(NO_PARSE_RESTRICTION); |
1168 info.MarkAsDebug(); | 1168 info.MarkAsDebug(); |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1404 CompilationInfoWithZone info(function); | 1404 CompilationInfoWithZone info(function); |
1405 return CompileForDebugging(&info); | 1405 return CompileForDebugging(&info); |
1406 } | 1406 } |
1407 } | 1407 } |
1408 | 1408 |
1409 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { | 1409 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { |
1410 DCHECK(shared->allows_lazy_compilation_without_context()); | 1410 DCHECK(shared->allows_lazy_compilation_without_context()); |
1411 DCHECK(!IsEvalToplevel(shared)); | 1411 DCHECK(!IsEvalToplevel(shared)); |
1412 Zone zone(shared->GetIsolate()->allocator()); | 1412 Zone zone(shared->GetIsolate()->allocator()); |
1413 ParseInfo parse_info(&zone, shared); | 1413 ParseInfo parse_info(&zone, shared); |
1414 CompilationInfo info(&parse_info); | 1414 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1415 return CompileForDebugging(&info); | 1415 return CompileForDebugging(&info); |
1416 } | 1416 } |
1417 | 1417 |
1418 // TODO(turbofan): In the future, unoptimized code with deopt support could | 1418 // TODO(turbofan): In the future, unoptimized code with deopt support could |
1419 // be generated lazily once deopt is triggered. | 1419 // be generated lazily once deopt is triggered. |
1420 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 1420 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
1421 DCHECK_NOT_NULL(info->literal()); | 1421 DCHECK_NOT_NULL(info->literal()); |
1422 DCHECK(info->has_scope()); | 1422 DCHECK(info->has_scope()); |
1423 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1423 Handle<SharedFunctionInfo> shared = info->shared_info(); |
1424 if (!shared->has_deoptimization_support()) { | 1424 if (!shared->has_deoptimization_support()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1456 // The existing unoptimized code was replaced with the new one. | 1456 // The existing unoptimized code was replaced with the new one. |
1457 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized, shared); | 1457 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized, shared); |
1458 } | 1458 } |
1459 return true; | 1459 return true; |
1460 } | 1460 } |
1461 | 1461 |
1462 void Compiler::CompileForLiveEdit(Handle<Script> script) { | 1462 void Compiler::CompileForLiveEdit(Handle<Script> script) { |
1463 // TODO(635): support extensions. | 1463 // TODO(635): support extensions. |
1464 Zone zone(script->GetIsolate()->allocator()); | 1464 Zone zone(script->GetIsolate()->allocator()); |
1465 ParseInfo parse_info(&zone, script); | 1465 ParseInfo parse_info(&zone, script); |
1466 CompilationInfo info(&parse_info); | 1466 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1467 PostponeInterruptsScope postpone(info.isolate()); | 1467 PostponeInterruptsScope postpone(info.isolate()); |
1468 VMState<COMPILER> state(info.isolate()); | 1468 VMState<COMPILER> state(info.isolate()); |
1469 | 1469 |
1470 // Get rid of old list of shared function infos. | 1470 // Get rid of old list of shared function infos. |
1471 info.MarkAsFirstCompile(); | 1471 info.MarkAsFirstCompile(); |
1472 info.MarkAsDebug(); | 1472 info.MarkAsDebug(); |
1473 info.parse_info()->set_global(); | 1473 info.parse_info()->set_global(); |
1474 if (!Parser::ParseStatic(info.parse_info())) return; | 1474 if (!Parser::ParseStatic(info.parse_info())) return; |
1475 | 1475 |
1476 LiveEditFunctionTracker tracker(info.isolate(), parse_info.literal()); | 1476 LiveEditFunctionTracker tracker(info.isolate(), parse_info.literal()); |
(...skipping 21 matching lines...) Expand all Loading... | |
1498 if (!maybe_shared_info.ToHandle(&shared_info)) { | 1498 if (!maybe_shared_info.ToHandle(&shared_info)) { |
1499 script = isolate->factory()->NewScript(source); | 1499 script = isolate->factory()->NewScript(source); |
1500 if (!script_name.is_null()) { | 1500 if (!script_name.is_null()) { |
1501 script->set_name(*script_name); | 1501 script->set_name(*script_name); |
1502 script->set_line_offset(line_offset); | 1502 script->set_line_offset(line_offset); |
1503 script->set_column_offset(column_offset); | 1503 script->set_column_offset(column_offset); |
1504 } | 1504 } |
1505 script->set_origin_options(options); | 1505 script->set_origin_options(options); |
1506 Zone zone(isolate->allocator()); | 1506 Zone zone(isolate->allocator()); |
1507 ParseInfo parse_info(&zone, script); | 1507 ParseInfo parse_info(&zone, script); |
1508 CompilationInfo info(&parse_info); | 1508 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1509 parse_info.set_eval(); | 1509 parse_info.set_eval(); |
1510 if (context->IsNativeContext()) parse_info.set_global(); | 1510 if (context->IsNativeContext()) parse_info.set_global(); |
1511 parse_info.set_language_mode(language_mode); | 1511 parse_info.set_language_mode(language_mode); |
1512 parse_info.set_parse_restriction(restriction); | 1512 parse_info.set_parse_restriction(restriction); |
1513 parse_info.set_context(context); | 1513 parse_info.set_context(context); |
1514 | 1514 |
1515 Debug::RecordEvalCaller(script); | 1515 Debug::RecordEvalCaller(script); |
1516 | 1516 |
1517 shared_info = CompileToplevel(&info); | 1517 shared_info = CompileToplevel(&info); |
1518 | 1518 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1622 script->set_column_offset(column_offset); | 1622 script->set_column_offset(column_offset); |
1623 } | 1623 } |
1624 script->set_origin_options(resource_options); | 1624 script->set_origin_options(resource_options); |
1625 if (!source_map_url.is_null()) { | 1625 if (!source_map_url.is_null()) { |
1626 script->set_source_mapping_url(*source_map_url); | 1626 script->set_source_mapping_url(*source_map_url); |
1627 } | 1627 } |
1628 | 1628 |
1629 // Compile the function and add it to the cache. | 1629 // Compile the function and add it to the cache. |
1630 Zone zone(isolate->allocator()); | 1630 Zone zone(isolate->allocator()); |
1631 ParseInfo parse_info(&zone, script); | 1631 ParseInfo parse_info(&zone, script); |
1632 CompilationInfo info(&parse_info); | 1632 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1633 if (is_module) { | 1633 if (is_module) { |
1634 parse_info.set_module(); | 1634 parse_info.set_module(); |
1635 } else { | 1635 } else { |
1636 parse_info.set_global(); | 1636 parse_info.set_global(); |
1637 } | 1637 } |
1638 if (compile_options != ScriptCompiler::kNoCompileOptions) { | 1638 if (compile_options != ScriptCompiler::kNoCompileOptions) { |
1639 parse_info.set_cached_data(cached_data); | 1639 parse_info.set_cached_data(cached_data); |
1640 } | 1640 } |
1641 parse_info.set_compile_options(compile_options); | 1641 parse_info.set_compile_options(compile_options); |
1642 parse_info.set_extension(extension); | 1642 parse_info.set_extension(extension); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1679 Handle<Script> script, ParseInfo* parse_info, int source_length) { | 1679 Handle<Script> script, ParseInfo* parse_info, int source_length) { |
1680 Isolate* isolate = script->GetIsolate(); | 1680 Isolate* isolate = script->GetIsolate(); |
1681 // TODO(titzer): increment the counters in caller. | 1681 // TODO(titzer): increment the counters in caller. |
1682 isolate->counters()->total_load_size()->Increment(source_length); | 1682 isolate->counters()->total_load_size()->Increment(source_length); |
1683 isolate->counters()->total_compile_size()->Increment(source_length); | 1683 isolate->counters()->total_compile_size()->Increment(source_length); |
1684 | 1684 |
1685 LanguageMode language_mode = construct_language_mode(FLAG_use_strict); | 1685 LanguageMode language_mode = construct_language_mode(FLAG_use_strict); |
1686 parse_info->set_language_mode( | 1686 parse_info->set_language_mode( |
1687 static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); | 1687 static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); |
1688 | 1688 |
1689 CompilationInfo compile_info(parse_info); | 1689 CompilationInfo compile_info(parse_info, Handle<JSFunction>::null()); |
1690 | 1690 |
1691 // The source was parsed lazily, so compiling for debugging is not possible. | 1691 // The source was parsed lazily, so compiling for debugging is not possible. |
1692 DCHECK(!compile_info.is_debug()); | 1692 DCHECK(!compile_info.is_debug()); |
1693 | 1693 |
1694 Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info); | 1694 Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info); |
1695 if (!result.is_null()) isolate->debug()->OnAfterCompile(script); | 1695 if (!result.is_null()) isolate->debug()->OnAfterCompile(script); |
1696 return result; | 1696 return result; |
1697 } | 1697 } |
1698 | 1698 |
1699 | 1699 |
(...skipping 26 matching lines...) Expand all Loading... | |
1726 | 1726 |
1727 // Allocate a shared function info object. | 1727 // Allocate a shared function info object. |
1728 Handle<SharedFunctionInfo> result; | 1728 Handle<SharedFunctionInfo> result; |
1729 if (!maybe_existing.ToHandle(&result)) { | 1729 if (!maybe_existing.ToHandle(&result)) { |
1730 result = NewSharedFunctionInfoForLiteral(isolate, literal, script); | 1730 result = NewSharedFunctionInfoForLiteral(isolate, literal, script); |
1731 result->set_is_toplevel(false); | 1731 result->set_is_toplevel(false); |
1732 } | 1732 } |
1733 | 1733 |
1734 Zone zone(isolate->allocator()); | 1734 Zone zone(isolate->allocator()); |
1735 ParseInfo parse_info(&zone, script); | 1735 ParseInfo parse_info(&zone, script); |
1736 CompilationInfo info(&parse_info); | 1736 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1737 parse_info.set_literal(literal); | 1737 parse_info.set_literal(literal); |
1738 parse_info.set_shared_info(result); | 1738 parse_info.set_shared_info(result); |
1739 parse_info.set_scope(literal->scope()); | 1739 parse_info.set_scope(literal->scope()); |
1740 parse_info.set_language_mode(literal->scope()->language_mode()); | 1740 parse_info.set_language_mode(literal->scope()->language_mode()); |
1741 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 1741 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
1742 if (outer_info->is_first_compile()) info.MarkAsFirstCompile(); | 1742 if (outer_info->is_first_compile()) info.MarkAsFirstCompile(); |
1743 if (outer_info->is_debug()) info.MarkAsDebug(); | 1743 if (outer_info->is_debug()) info.MarkAsDebug(); |
1744 | 1744 |
1745 LiveEditFunctionTracker live_edit_tracker(isolate, literal); | 1745 LiveEditFunctionTracker live_edit_tracker(isolate, literal); |
1746 // Determine if the function can be lazily compiled. This is necessary to | 1746 // Determine if the function can be lazily compiled. This is necessary to |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1930 MaybeHandle<Code> code; | 1930 MaybeHandle<Code> code; |
1931 if (cached.code != nullptr) code = handle(cached.code); | 1931 if (cached.code != nullptr) code = handle(cached.code); |
1932 Handle<Context> native_context(function->context()->native_context()); | 1932 Handle<Context> native_context(function->context()->native_context()); |
1933 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | 1933 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, |
1934 literals, BailoutId::None()); | 1934 literals, BailoutId::None()); |
1935 } | 1935 } |
1936 } | 1936 } |
1937 | 1937 |
1938 } // namespace internal | 1938 } // namespace internal |
1939 } // namespace v8 | 1939 } // namespace v8 |
OLD | NEW |