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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
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 16 matching lines...) Expand all Loading... |
27 #include "src/runtime-profiler.h" | 27 #include "src/runtime-profiler.h" |
28 #include "src/scanner-character-streams.h" | 28 #include "src/scanner-character-streams.h" |
29 #include "src/scopeinfo.h" | 29 #include "src/scopeinfo.h" |
30 #include "src/scopes.h" | 30 #include "src/scopes.h" |
31 #include "src/typing.h" | 31 #include "src/typing.h" |
32 #include "src/vm-state-inl.h" | 32 #include "src/vm-state-inl.h" |
33 | 33 |
34 namespace v8 { | 34 namespace v8 { |
35 namespace internal { | 35 namespace internal { |
36 | 36 |
37 | |
38 std::ostream& operator<<(std::ostream& os, const SourcePosition& p) { | 37 std::ostream& operator<<(std::ostream& os, const SourcePosition& p) { |
39 if (p.IsUnknown()) { | 38 if (p.IsUnknown()) { |
40 return os << "<?>"; | 39 return os << "<?>"; |
41 } else if (FLAG_hydrogen_track_positions) { | 40 } else if (FLAG_hydrogen_track_positions) { |
42 return os << "<" << p.inlining_id() << ":" << p.position() << ">"; | 41 return os << "<" << p.inlining_id() << ":" << p.position() << ">"; |
43 } else { | 42 } else { |
44 return os << "<0:" << p.raw() << ">"; | 43 return os << "<0:" << p.raw() << ">"; |
45 } | 44 } |
46 } | 45 } |
47 | 46 |
48 | 47 |
49 ScriptData::ScriptData(const byte* data, int length) | 48 #define PARSE_INFO_GETTER(type, name) \ |
50 : owns_data_(false), rejected_(false), data_(data), length_(length) { | 49 type CompilationInfo::name() const { \ |
51 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) { | 50 CHECK(parse_info()); \ |
52 byte* copy = NewArray<byte>(length); | 51 return parse_info()->name(); \ |
53 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment)); | |
54 CopyBytes(copy, data, length); | |
55 data_ = copy; | |
56 AcquireDataOwnership(); | |
57 } | 52 } |
| 53 |
| 54 |
| 55 #define PARSE_INFO_GETTER_WITH_DEFAULT(type, name, def) \ |
| 56 type CompilationInfo::name() const { \ |
| 57 return parse_info() ? parse_info()->name() : def; \ |
| 58 } |
| 59 |
| 60 |
| 61 PARSE_INFO_GETTER(Handle<Script>, script) |
| 62 PARSE_INFO_GETTER(bool, is_eval) |
| 63 PARSE_INFO_GETTER(bool, is_native) |
| 64 PARSE_INFO_GETTER(bool, is_module) |
| 65 PARSE_INFO_GETTER(bool, this_has_uses) |
| 66 PARSE_INFO_GETTER(LanguageMode, language_mode) |
| 67 PARSE_INFO_GETTER_WITH_DEFAULT(Handle<JSFunction>, closure, |
| 68 Handle<JSFunction>::null()) |
| 69 PARSE_INFO_GETTER(FunctionLiteral*, function) |
| 70 PARSE_INFO_GETTER_WITH_DEFAULT(Scope*, scope, nullptr) |
| 71 PARSE_INFO_GETTER(Handle<Context>, context) |
| 72 PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info) |
| 73 |
| 74 #undef PARSE_INFO_GETTER |
| 75 #undef PARSE_INFO_GETTER_WITH_DEFAULT |
| 76 |
| 77 |
| 78 bool CompilationInfo::has_shared_info() const { |
| 79 return parse_info_ && !parse_info_->shared_info().is_null(); |
58 } | 80 } |
59 | 81 |
60 | 82 |
61 CompilationInfo::CompilationInfo(Handle<Script> script, Zone* zone) | 83 CompilationInfo::CompilationInfo(ParseInfo* parse_info) |
62 : flags_(kThisHasUses), | 84 : parse_info_(parse_info), |
63 script_(script), | 85 flags_(0), |
64 source_stream_(NULL), | |
65 osr_ast_id_(BailoutId::None()), | 86 osr_ast_id_(BailoutId::None()), |
66 parameter_count_(0), | 87 parameter_count_(0), |
67 optimization_id_(-1), | 88 optimization_id_(-1), |
68 ast_value_factory_(NULL), | |
69 ast_value_factory_owned_(false), | |
70 aborted_due_to_dependency_change_(false), | 89 aborted_due_to_dependency_change_(false), |
71 osr_expr_stack_height_(0) { | 90 osr_expr_stack_height_(0) { |
72 Initialize(script->GetIsolate(), BASE, zone); | 91 Initialize(parse_info->isolate(), BASE, parse_info->zone()); |
73 } | |
74 | |
75 | |
76 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, | |
77 Zone* zone) | |
78 : flags_(kLazy | kThisHasUses), | |
79 shared_info_(shared_info), | |
80 script_(Handle<Script>(Script::cast(shared_info->script()))), | |
81 source_stream_(NULL), | |
82 osr_ast_id_(BailoutId::None()), | |
83 parameter_count_(0), | |
84 optimization_id_(-1), | |
85 ast_value_factory_(NULL), | |
86 ast_value_factory_owned_(false), | |
87 aborted_due_to_dependency_change_(false), | |
88 osr_expr_stack_height_(0) { | |
89 Initialize(script_->GetIsolate(), BASE, zone); | |
90 } | |
91 | |
92 | |
93 CompilationInfo::CompilationInfo(Handle<JSFunction> closure, Zone* zone) | |
94 : flags_(kLazy | kThisHasUses), | |
95 closure_(closure), | |
96 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), | |
97 script_(Handle<Script>(Script::cast(shared_info_->script()))), | |
98 source_stream_(NULL), | |
99 context_(closure->context()), | |
100 osr_ast_id_(BailoutId::None()), | |
101 parameter_count_(0), | |
102 optimization_id_(-1), | |
103 ast_value_factory_(NULL), | |
104 ast_value_factory_owned_(false), | |
105 aborted_due_to_dependency_change_(false), | |
106 osr_expr_stack_height_(0) { | |
107 Initialize(script_->GetIsolate(), BASE, zone); | |
108 } | 92 } |
109 | 93 |
110 | 94 |
111 CompilationInfo::CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone) | 95 CompilationInfo::CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone) |
112 : flags_(kLazy | kThisHasUses), | 96 : parse_info_(nullptr), |
113 source_stream_(NULL), | 97 flags_(0), |
114 osr_ast_id_(BailoutId::None()), | 98 osr_ast_id_(BailoutId::None()), |
115 parameter_count_(0), | 99 parameter_count_(0), |
116 optimization_id_(-1), | 100 optimization_id_(-1), |
117 ast_value_factory_(NULL), | |
118 ast_value_factory_owned_(false), | |
119 aborted_due_to_dependency_change_(false), | 101 aborted_due_to_dependency_change_(false), |
120 osr_expr_stack_height_(0) { | 102 osr_expr_stack_height_(0) { |
121 Initialize(isolate, STUB, zone); | 103 Initialize(isolate, STUB, zone); |
122 code_stub_ = stub; | 104 code_stub_ = stub; |
123 } | 105 } |
124 | 106 |
125 | 107 |
126 CompilationInfo::CompilationInfo( | |
127 ScriptCompiler::ExternalSourceStream* stream, | |
128 ScriptCompiler::StreamedSource::Encoding encoding, Isolate* isolate, | |
129 Zone* zone) | |
130 : flags_(kThisHasUses), | |
131 source_stream_(stream), | |
132 source_stream_encoding_(encoding), | |
133 osr_ast_id_(BailoutId::None()), | |
134 parameter_count_(0), | |
135 optimization_id_(-1), | |
136 ast_value_factory_(NULL), | |
137 ast_value_factory_owned_(false), | |
138 aborted_due_to_dependency_change_(false), | |
139 osr_expr_stack_height_(0) { | |
140 Initialize(isolate, BASE, zone); | |
141 } | |
142 | |
143 | |
144 void CompilationInfo::Initialize(Isolate* isolate, | 108 void CompilationInfo::Initialize(Isolate* isolate, |
145 Mode mode, | 109 Mode mode, |
146 Zone* zone) { | 110 Zone* zone) { |
147 isolate_ = isolate; | 111 isolate_ = isolate; |
148 function_ = NULL; | |
149 scope_ = NULL; | |
150 script_scope_ = NULL; | |
151 extension_ = NULL; | |
152 cached_data_ = NULL; | |
153 compile_options_ = ScriptCompiler::kNoCompileOptions; | |
154 zone_ = zone; | 112 zone_ = zone; |
155 deferred_handles_ = NULL; | 113 deferred_handles_ = NULL; |
156 code_stub_ = NULL; | 114 code_stub_ = NULL; |
157 prologue_offset_ = Code::kPrologueOffsetNotSet; | 115 prologue_offset_ = Code::kPrologueOffsetNotSet; |
158 opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count(); | 116 opt_count_ = has_shared_info() ? shared_info()->opt_count() : 0; |
159 no_frame_ranges_ = isolate->cpu_profiler()->is_profiling() | 117 no_frame_ranges_ = isolate->cpu_profiler()->is_profiling() |
160 ? new List<OffsetRange>(2) : NULL; | 118 ? new List<OffsetRange>(2) : NULL; |
161 if (FLAG_hydrogen_track_positions) { | 119 if (FLAG_hydrogen_track_positions) { |
162 inlined_function_infos_ = new List<InlinedFunctionInfo>(5); | 120 inlined_function_infos_ = new List<InlinedFunctionInfo>(5); |
163 inlining_id_to_function_id_ = new List<int>(5); | 121 inlining_id_to_function_id_ = new List<int>(5); |
164 } else { | 122 } else { |
165 inlined_function_infos_ = NULL; | 123 inlined_function_infos_ = NULL; |
166 inlining_id_to_function_id_ = NULL; | 124 inlining_id_to_function_id_ = NULL; |
167 } | 125 } |
168 | 126 |
169 for (int i = 0; i < DependentCode::kGroupCount; i++) { | 127 for (int i = 0; i < DependentCode::kGroupCount; i++) { |
170 dependencies_[i] = NULL; | 128 dependencies_[i] = NULL; |
171 } | 129 } |
172 if (mode == STUB) { | 130 if (mode == STUB) { |
173 mode_ = STUB; | 131 mode_ = STUB; |
174 return; | 132 return; |
175 } | 133 } |
176 mode_ = mode; | 134 mode_ = mode; |
177 if (!script_.is_null() && script_->type()->value() == Script::TYPE_NATIVE) { | |
178 MarkAsNative(); | |
179 } | |
180 // Compiling for the snapshot typically results in different code than | 135 // Compiling for the snapshot typically results in different code than |
181 // compiling later on. This means that code recompiled with deoptimization | 136 // compiling later on. This means that code recompiled with deoptimization |
182 // support won't be "equivalent" (as defined by SharedFunctionInfo:: | 137 // support won't be "equivalent" (as defined by SharedFunctionInfo:: |
183 // EnableDeoptimizationSupport), so it will replace the old code and all | 138 // EnableDeoptimizationSupport), so it will replace the old code and all |
184 // its type feedback. To avoid this, always compile functions in the snapshot | 139 // its type feedback. To avoid this, always compile functions in the snapshot |
185 // with deoptimization support. | 140 // with deoptimization support. |
186 if (isolate_->serializer_enabled()) EnableDeoptimizationSupport(); | 141 if (isolate_->serializer_enabled()) EnableDeoptimizationSupport(); |
187 | 142 |
188 if (isolate_->debug()->is_active()) MarkAsDebug(); | 143 if (isolate_->debug()->is_active()) MarkAsDebug(); |
189 if (FLAG_context_specialization) MarkAsContextSpecializing(); | 144 if (FLAG_context_specialization) MarkAsContextSpecializing(); |
190 if (FLAG_turbo_builtin_inlining) MarkAsBuiltinInliningEnabled(); | 145 if (FLAG_turbo_builtin_inlining) MarkAsBuiltinInliningEnabled(); |
191 if (FLAG_turbo_inlining) MarkAsInliningEnabled(); | 146 if (FLAG_turbo_inlining) MarkAsInliningEnabled(); |
192 if (FLAG_turbo_splitting) MarkAsSplittingEnabled(); | 147 if (FLAG_turbo_splitting) MarkAsSplittingEnabled(); |
193 if (FLAG_turbo_types) MarkAsTypingEnabled(); | 148 if (FLAG_turbo_types) MarkAsTypingEnabled(); |
194 | 149 |
195 if (!shared_info_.is_null()) { | |
196 DCHECK(is_sloppy(language_mode())); | |
197 SetLanguageMode(shared_info_->language_mode()); | |
198 } | |
199 bailout_reason_ = kNoReason; | 150 bailout_reason_ = kNoReason; |
200 | 151 |
201 if (!shared_info().is_null() && shared_info()->is_compiled()) { | 152 if (has_shared_info() && shared_info()->is_compiled()) { |
202 // We should initialize the CompilationInfo feedback vector from the | 153 // We should initialize the CompilationInfo feedback vector from the |
203 // passed in shared info, rather than creating a new one. | 154 // passed in shared info, rather than creating a new one. |
204 feedback_vector_ = | 155 feedback_vector_ = |
205 Handle<TypeFeedbackVector>(shared_info()->feedback_vector(), isolate); | 156 Handle<TypeFeedbackVector>(shared_info()->feedback_vector(), isolate); |
206 } | 157 } |
207 } | 158 } |
208 | 159 |
209 | 160 |
210 CompilationInfo::~CompilationInfo() { | 161 CompilationInfo::~CompilationInfo() { |
211 if (GetFlag(kDisableFutureOptimization)) { | 162 DisableFutureOptimization(); |
212 shared_info()->DisableOptimization(bailout_reason()); | |
213 } | |
214 delete deferred_handles_; | 163 delete deferred_handles_; |
215 delete no_frame_ranges_; | 164 delete no_frame_ranges_; |
216 delete inlined_function_infos_; | 165 delete inlined_function_infos_; |
217 delete inlining_id_to_function_id_; | 166 delete inlining_id_to_function_id_; |
218 if (ast_value_factory_owned_) delete ast_value_factory_; | |
219 #ifdef DEBUG | 167 #ifdef DEBUG |
220 // Check that no dependent maps have been added or added dependent maps have | 168 // Check that no dependent maps have been added or added dependent maps have |
221 // been rolled back or committed. | 169 // been rolled back or committed. |
222 for (int i = 0; i < DependentCode::kGroupCount; i++) { | 170 for (int i = 0; i < DependentCode::kGroupCount; i++) { |
223 DCHECK(!dependencies_[i]); | 171 DCHECK(!dependencies_[i]); |
224 } | 172 } |
225 #endif // DEBUG | 173 #endif // DEBUG |
226 } | 174 } |
227 | 175 |
228 | 176 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 } else { | 249 } else { |
302 return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); | 250 return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); |
303 } | 251 } |
304 } | 252 } |
305 | 253 |
306 | 254 |
307 // Primitive functions are unlikely to be picked up by the stack-walking | 255 // Primitive functions are unlikely to be picked up by the stack-walking |
308 // profiler, so they trigger their own optimization when they're called | 256 // profiler, so they trigger their own optimization when they're called |
309 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. | 257 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. |
310 bool CompilationInfo::ShouldSelfOptimize() { | 258 bool CompilationInfo::ShouldSelfOptimize() { |
311 return FLAG_crankshaft && | 259 return FLAG_crankshaft && !function()->flags()->Contains(kDontSelfOptimize) && |
312 !function()->flags()->Contains(kDontSelfOptimize) && | 260 !function()->dont_optimize() && |
313 !function()->dont_optimize() && | 261 function()->scope()->AllowsLazyCompilation() && |
314 function()->scope()->AllowsLazyCompilation() && | 262 (!has_shared_info() || !shared_info()->optimization_disabled()); |
315 (shared_info().is_null() || !shared_info()->optimization_disabled()); | |
316 } | 263 } |
317 | 264 |
318 | 265 |
319 void CompilationInfo::PrepareForCompilation(Scope* scope) { | |
320 DCHECK(scope_ == NULL); | |
321 scope_ = scope; | |
322 } | |
323 | |
324 | |
325 void CompilationInfo::EnsureFeedbackVector() { | 266 void CompilationInfo::EnsureFeedbackVector() { |
326 if (feedback_vector_.is_null()) { | 267 if (feedback_vector_.is_null()) { |
327 feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector( | 268 feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector( |
328 function()->feedback_vector_spec()); | 269 function()->feedback_vector_spec()); |
329 } | 270 } |
330 } | 271 } |
331 | 272 |
332 | 273 |
333 bool CompilationInfo::is_simple_parameter_list() { | 274 bool CompilationInfo::is_simple_parameter_list() { |
334 return scope_->is_simple_parameter_list(); | 275 return scope()->is_simple_parameter_list(); |
335 } | 276 } |
336 | 277 |
337 | 278 |
338 int CompilationInfo::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, | 279 int CompilationInfo::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, |
339 SourcePosition position) { | 280 SourcePosition position) { |
340 DCHECK(FLAG_hydrogen_track_positions); | 281 DCHECK(FLAG_hydrogen_track_positions); |
341 | 282 |
342 DCHECK(inlined_function_infos_); | 283 DCHECK(inlined_function_infos_); |
343 DCHECK(inlining_id_to_function_id_); | 284 DCHECK(inlining_id_to_function_id_); |
344 int id = 0; | 285 int id = 0; |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 if (info()->shared_info()->optimization_disabled()) { | 487 if (info()->shared_info()->optimization_disabled()) { |
547 return AbortOptimization( | 488 return AbortOptimization( |
548 info()->shared_info()->disable_optimization_reason()); | 489 info()->shared_info()->disable_optimization_reason()); |
549 } | 490 } |
550 | 491 |
551 graph_builder_ = (FLAG_hydrogen_track_positions || FLAG_trace_ic) | 492 graph_builder_ = (FLAG_hydrogen_track_positions || FLAG_trace_ic) |
552 ? new(info()->zone()) HOptimizedGraphBuilderWithPositions(info()) | 493 ? new(info()->zone()) HOptimizedGraphBuilderWithPositions(info()) |
553 : new(info()->zone()) HOptimizedGraphBuilder(info()); | 494 : new(info()->zone()) HOptimizedGraphBuilder(info()); |
554 | 495 |
555 Timer t(this, &time_taken_to_create_graph_); | 496 Timer t(this, &time_taken_to_create_graph_); |
556 info()->set_this_has_uses(false); | 497 // TODO(titzer): ParseInfo::this_has_uses is only used by Crankshaft. Move. |
| 498 info()->parse_info()->set_this_has_uses(false); |
557 graph_ = graph_builder_->CreateGraph(); | 499 graph_ = graph_builder_->CreateGraph(); |
558 | 500 |
559 if (isolate()->has_pending_exception()) { | 501 if (isolate()->has_pending_exception()) { |
560 return SetLastStatus(FAILED); | 502 return SetLastStatus(FAILED); |
561 } | 503 } |
562 | 504 |
563 if (graph_ == NULL) return SetLastStatus(BAILED_OUT); | 505 if (graph_ == NULL) return SetLastStatus(BAILED_OUT); |
564 | 506 |
565 if (info()->HasAbortedDueToDependencyChange()) { | 507 if (info()->HasAbortedDueToDependencyChange()) { |
566 // Dependency has changed during graph creation. Let's try again later. | 508 // Dependency has changed during graph creation. Let's try again later. |
(...skipping 29 matching lines...) Expand all Loading... |
596 | 538 |
597 return SetLastStatus(BAILED_OUT); | 539 return SetLastStatus(BAILED_OUT); |
598 } | 540 } |
599 | 541 |
600 | 542 |
601 OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() { | 543 OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() { |
602 DCHECK(last_status() == SUCCEEDED); | 544 DCHECK(last_status() == SUCCEEDED); |
603 // TODO(turbofan): Currently everything is done in the first phase. | 545 // TODO(turbofan): Currently everything is done in the first phase. |
604 if (!info()->code().is_null()) { | 546 if (!info()->code().is_null()) { |
605 if (FLAG_turbo_deoptimization) { | 547 if (FLAG_turbo_deoptimization) { |
606 info()->context()->native_context()->AddOptimizedCode(*info()->code()); | 548 info()->parse_info()->context()->native_context()->AddOptimizedCode( |
| 549 *info()->code()); |
607 } | 550 } |
608 RecordOptimizationStats(); | 551 RecordOptimizationStats(); |
609 return last_status(); | 552 return last_status(); |
610 } | 553 } |
611 | 554 |
612 DCHECK(!info()->HasAbortedDueToDependencyChange()); | 555 DCHECK(!info()->HasAbortedDueToDependencyChange()); |
613 DisallowCodeDependencyChange no_dependency_change; | 556 DisallowCodeDependencyChange no_dependency_change; |
614 DisallowJavascriptExecution no_js(isolate()); | 557 DisallowJavascriptExecution no_js(isolate()); |
615 { // Scope for timer. | 558 { // Scope for timer. |
616 Timer timer(this, &time_taken_to_codegen_); | 559 Timer timer(this, &time_taken_to_codegen_); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 CompilationInfo* info, | 651 CompilationInfo* info, |
709 Handle<SharedFunctionInfo> shared) { | 652 Handle<SharedFunctionInfo> shared) { |
710 // SharedFunctionInfo is passed separately, because if CompilationInfo | 653 // SharedFunctionInfo is passed separately, because if CompilationInfo |
711 // was created using Script object, it will not have it. | 654 // was created using Script object, it will not have it. |
712 | 655 |
713 // Log the code generation. If source information is available include | 656 // Log the code generation. If source information is available include |
714 // script name and line number. Check explicitly whether logging is | 657 // script name and line number. Check explicitly whether logging is |
715 // enabled as finding the line number is not free. | 658 // enabled as finding the line number is not free. |
716 if (info->isolate()->logger()->is_logging_code_events() || | 659 if (info->isolate()->logger()->is_logging_code_events() || |
717 info->isolate()->cpu_profiler()->is_profiling()) { | 660 info->isolate()->cpu_profiler()->is_profiling()) { |
718 Handle<Script> script = info->script(); | 661 Handle<Script> script = info->parse_info()->script(); |
719 Handle<Code> code = info->code(); | 662 Handle<Code> code = info->code(); |
720 if (code.is_identical_to(info->isolate()->builtins()->CompileLazy())) { | 663 if (code.is_identical_to(info->isolate()->builtins()->CompileLazy())) { |
721 return; | 664 return; |
722 } | 665 } |
723 int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; | 666 int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; |
724 int column_num = | 667 int column_num = |
725 Script::GetColumnNumber(script, shared->start_position()) + 1; | 668 Script::GetColumnNumber(script, shared->start_position()) + 1; |
726 String* script_name = script->name()->IsString() | 669 String* script_name = script->name()->IsString() |
727 ? String::cast(script->name()) | 670 ? String::cast(script->name()) |
728 : info->isolate()->heap()->empty_string(); | 671 : info->isolate()->heap()->empty_string(); |
729 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script); | 672 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script); |
730 PROFILE(info->isolate(), | 673 PROFILE(info->isolate(), |
731 CodeCreateEvent(log_tag, *code, *shared, info, script_name, | 674 CodeCreateEvent(log_tag, *code, *shared, info, script_name, |
732 line_num, column_num)); | 675 line_num, column_num)); |
733 } | 676 } |
734 } | 677 } |
735 | 678 |
736 | 679 |
737 static bool CompileUnoptimizedCode(CompilationInfo* info) { | 680 static bool CompileUnoptimizedCode(CompilationInfo* info) { |
738 DCHECK(AllowCompilation::IsAllowed(info->isolate())); | 681 DCHECK(AllowCompilation::IsAllowed(info->isolate())); |
739 if (!Compiler::Analyze(info) || !FullCodeGenerator::MakeCode(info)) { | 682 if (!Compiler::Analyze(info->parse_info()) || |
| 683 !FullCodeGenerator::MakeCode(info)) { |
740 Isolate* isolate = info->isolate(); | 684 Isolate* isolate = info->isolate(); |
741 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 685 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
742 return false; | 686 return false; |
743 } | 687 } |
744 return true; | 688 return true; |
745 } | 689 } |
746 | 690 |
747 | 691 |
748 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( | 692 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( |
749 CompilationInfo* info) { | 693 CompilationInfo* info) { |
750 VMState<COMPILER> state(info->isolate()); | 694 VMState<COMPILER> state(info->isolate()); |
751 PostponeInterruptsScope postpone(info->isolate()); | 695 PostponeInterruptsScope postpone(info->isolate()); |
752 | 696 |
753 // Parse and update CompilationInfo with the results. | 697 // Parse and update CompilationInfo with the results. |
754 if (!Parser::ParseStatic(info)) return MaybeHandle<Code>(); | 698 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); |
755 Handle<SharedFunctionInfo> shared = info->shared_info(); | 699 Handle<SharedFunctionInfo> shared = info->shared_info(); |
756 FunctionLiteral* lit = info->function(); | 700 FunctionLiteral* lit = info->function(); |
757 shared->set_language_mode(lit->language_mode()); | 701 shared->set_language_mode(lit->language_mode()); |
758 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); | 702 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); |
759 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); | 703 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); |
760 | 704 |
761 // Compile unoptimized code. | 705 // Compile unoptimized code. |
762 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); | 706 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
763 | 707 |
764 CHECK_EQ(Code::FUNCTION, info->code()->kind()); | 708 CHECK_EQ(Code::FUNCTION, info->code()->kind()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 // Do not cache bound functions. | 764 // Do not cache bound functions. |
821 if (shared->bound()) return; | 765 if (shared->bound()) return; |
822 Handle<FixedArray> literals(function->literals()); | 766 Handle<FixedArray> literals(function->literals()); |
823 Handle<Context> native_context(function->context()->native_context()); | 767 Handle<Context> native_context(function->context()->native_context()); |
824 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | 768 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, |
825 literals, info->osr_ast_id()); | 769 literals, info->osr_ast_id()); |
826 } | 770 } |
827 } | 771 } |
828 | 772 |
829 | 773 |
830 static bool Renumber(CompilationInfo* info) { | 774 static bool Renumber(ParseInfo* parse_info) { |
831 if (!AstNumbering::Renumber(info->isolate(), info->zone(), | 775 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), |
832 info->function())) { | 776 parse_info->function())) { |
833 return false; | 777 return false; |
834 } | 778 } |
835 if (!info->shared_info().is_null()) { | 779 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); |
836 FunctionLiteral* lit = info->function(); | 780 if (!shared_info.is_null()) { |
837 info->shared_info()->set_ast_node_count(lit->ast_node_count()); | 781 FunctionLiteral* lit = parse_info->function(); |
838 MaybeDisableOptimization(info->shared_info(), lit->dont_optimize_reason()); | 782 shared_info->set_ast_node_count(lit->ast_node_count()); |
839 info->shared_info()->set_dont_cache(lit->flags()->Contains(kDontCache)); | 783 MaybeDisableOptimization(shared_info, lit->dont_optimize_reason()); |
| 784 shared_info->set_dont_cache(lit->flags()->Contains(kDontCache)); |
840 } | 785 } |
841 return true; | 786 return true; |
842 } | 787 } |
843 | 788 |
844 | 789 |
845 bool Compiler::Analyze(CompilationInfo* info) { | 790 bool Compiler::Analyze(ParseInfo* info) { |
846 DCHECK(info->function() != NULL); | 791 DCHECK(info->function() != NULL); |
847 if (!Rewriter::Rewrite(info)) return false; | 792 if (!Rewriter::Rewrite(info)) return false; |
848 if (!Scope::Analyze(info)) return false; | 793 if (!Scope::Analyze(info)) return false; |
849 if (!Renumber(info)) return false; | 794 if (!Renumber(info)) return false; |
850 DCHECK(info->scope() != NULL); | 795 DCHECK(info->scope() != NULL); |
851 return true; | 796 return true; |
852 } | 797 } |
853 | 798 |
854 | 799 |
855 bool Compiler::ParseAndAnalyze(CompilationInfo* info) { | 800 bool Compiler::ParseAndAnalyze(ParseInfo* info) { |
856 if (!Parser::ParseStatic(info)) return false; | 801 if (!Parser::ParseStatic(info)) return false; |
857 return Compiler::Analyze(info); | 802 return Compiler::Analyze(info); |
858 } | 803 } |
859 | 804 |
860 | 805 |
861 static bool GetOptimizedCodeNow(CompilationInfo* info) { | 806 static bool GetOptimizedCodeNow(CompilationInfo* info) { |
862 if (!Compiler::ParseAndAnalyze(info)) return false; | 807 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
863 | 808 |
864 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); | 809 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
865 | 810 |
866 OptimizedCompileJob job(info); | 811 OptimizedCompileJob job(info); |
867 if (job.CreateGraph() != OptimizedCompileJob::SUCCEEDED || | 812 if (job.CreateGraph() != OptimizedCompileJob::SUCCEEDED || |
868 job.OptimizeGraph() != OptimizedCompileJob::SUCCEEDED || | 813 job.OptimizeGraph() != OptimizedCompileJob::SUCCEEDED || |
869 job.GenerateCode() != OptimizedCompileJob::SUCCEEDED) { | 814 job.GenerateCode() != OptimizedCompileJob::SUCCEEDED) { |
870 if (FLAG_trace_opt) { | 815 if (FLAG_trace_opt) { |
871 PrintF("[aborted optimizing "); | 816 PrintF("[aborted optimizing "); |
872 info->closure()->ShortPrint(); | 817 info->closure()->ShortPrint(); |
(...skipping 16 matching lines...) Expand all Loading... |
889 if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) { | 834 if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) { |
890 if (FLAG_trace_concurrent_recompilation) { | 835 if (FLAG_trace_concurrent_recompilation) { |
891 PrintF(" ** Compilation queue full, will retry optimizing "); | 836 PrintF(" ** Compilation queue full, will retry optimizing "); |
892 info->closure()->ShortPrint(); | 837 info->closure()->ShortPrint(); |
893 PrintF(" later.\n"); | 838 PrintF(" later.\n"); |
894 } | 839 } |
895 return false; | 840 return false; |
896 } | 841 } |
897 | 842 |
898 CompilationHandleScope handle_scope(info); | 843 CompilationHandleScope handle_scope(info); |
899 if (!Compiler::ParseAndAnalyze(info)) return false; | 844 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
900 info->SaveHandles(); // Copy handles to the compilation handle scope. | 845 |
| 846 // Reopen handles in the new CompilationHandleScope. |
| 847 info->ReopenHandlesInNewHandleScope(); |
| 848 info->parse_info()->ReopenHandlesInNewHandleScope(); |
901 | 849 |
902 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); | 850 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
903 | 851 |
904 OptimizedCompileJob* job = new (info->zone()) OptimizedCompileJob(info); | 852 OptimizedCompileJob* job = new (info->zone()) OptimizedCompileJob(info); |
905 OptimizedCompileJob::Status status = job->CreateGraph(); | 853 OptimizedCompileJob::Status status = job->CreateGraph(); |
906 if (status != OptimizedCompileJob::SUCCEEDED) return false; | 854 if (status != OptimizedCompileJob::SUCCEEDED) return false; |
907 isolate->optimizing_compiler_thread()->QueueForOptimization(job); | 855 isolate->optimizing_compiler_thread()->QueueForOptimization(job); |
908 | 856 |
909 if (FLAG_trace_concurrent_recompilation) { | 857 if (FLAG_trace_concurrent_recompilation) { |
910 PrintF(" ** Queued "); | 858 PrintF(" ** Queued "); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 return true; | 957 return true; |
1010 } | 958 } |
1011 | 959 |
1012 | 960 |
1013 // TODO(turbofan): In the future, unoptimized code with deopt support could | 961 // TODO(turbofan): In the future, unoptimized code with deopt support could |
1014 // be generated lazily once deopt is triggered. | 962 // be generated lazily once deopt is triggered. |
1015 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 963 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
1016 DCHECK(info->function() != NULL); | 964 DCHECK(info->function() != NULL); |
1017 DCHECK(info->scope() != NULL); | 965 DCHECK(info->scope() != NULL); |
1018 if (!info->shared_info()->has_deoptimization_support()) { | 966 if (!info->shared_info()->has_deoptimization_support()) { |
| 967 // TODO(titzer): just reuse the ParseInfo for the unoptimized compile. |
1019 Handle<SharedFunctionInfo> shared = info->shared_info(); | 968 Handle<SharedFunctionInfo> shared = info->shared_info(); |
1020 CompilationInfoWithZone unoptimized(shared); | 969 CompilationInfoWithZone unoptimized(shared); |
1021 // Note that we use the same AST that we will use for generating the | 970 // Note that we use the same AST that we will use for generating the |
1022 // optimized code. | 971 // optimized code. |
1023 unoptimized.SetFunction(info->function()); | 972 ParseInfo* parse_info = unoptimized.parse_info(); |
1024 unoptimized.PrepareForCompilation(info->scope()); | 973 parse_info->set_literal(info->function()); |
1025 unoptimized.SetContext(info->context()); | 974 parse_info->set_scope(info->scope()); |
| 975 parse_info->set_context(info->context()); |
1026 unoptimized.EnableDeoptimizationSupport(); | 976 unoptimized.EnableDeoptimizationSupport(); |
1027 // If the current code has reloc info for serialization, also include | 977 // If the current code has reloc info for serialization, also include |
1028 // reloc info for serialization for the new code, so that deopt support | 978 // reloc info for serialization for the new code, so that deopt support |
1029 // can be added without losing IC state. | 979 // can be added without losing IC state. |
1030 if (shared->code()->kind() == Code::FUNCTION && | 980 if (shared->code()->kind() == Code::FUNCTION && |
1031 shared->code()->has_reloc_info_for_serialization()) { | 981 shared->code()->has_reloc_info_for_serialization()) { |
1032 unoptimized.PrepareForSerializing(); | 982 unoptimized.PrepareForSerializing(); |
1033 } | 983 } |
1034 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; | 984 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; |
1035 | 985 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1089 return maybe_new_code; | 1039 return maybe_new_code; |
1090 } | 1040 } |
1091 | 1041 |
1092 | 1042 |
1093 void Compiler::CompileForLiveEdit(Handle<Script> script) { | 1043 void Compiler::CompileForLiveEdit(Handle<Script> script) { |
1094 // TODO(635): support extensions. | 1044 // TODO(635): support extensions. |
1095 CompilationInfoWithZone info(script); | 1045 CompilationInfoWithZone info(script); |
1096 PostponeInterruptsScope postpone(info.isolate()); | 1046 PostponeInterruptsScope postpone(info.isolate()); |
1097 VMState<COMPILER> state(info.isolate()); | 1047 VMState<COMPILER> state(info.isolate()); |
1098 | 1048 |
1099 info.MarkAsGlobal(); | 1049 info.parse_info()->set_global(); |
1100 if (!Parser::ParseStatic(&info)) return; | 1050 if (!Parser::ParseStatic(info.parse_info())) return; |
1101 | 1051 |
1102 LiveEditFunctionTracker tracker(info.isolate(), info.function()); | 1052 LiveEditFunctionTracker tracker(info.isolate(), info.function()); |
1103 if (!CompileUnoptimizedCode(&info)) return; | 1053 if (!CompileUnoptimizedCode(&info)) return; |
1104 if (!info.shared_info().is_null()) { | 1054 if (info.has_shared_info()) { |
1105 Handle<ScopeInfo> scope_info = | 1055 Handle<ScopeInfo> scope_info = |
1106 ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); | 1056 ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
1107 info.shared_info()->set_scope_info(*scope_info); | 1057 info.shared_info()->set_scope_info(*scope_info); |
1108 } | 1058 } |
1109 tracker.RecordRootFunctionInfo(info.code()); | 1059 tracker.RecordRootFunctionInfo(info.code()); |
1110 } | 1060 } |
1111 | 1061 |
1112 | 1062 |
1113 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { | 1063 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { |
1114 Isolate* isolate = info->isolate(); | 1064 Isolate* isolate = info->isolate(); |
1115 PostponeInterruptsScope postpone(isolate); | 1065 PostponeInterruptsScope postpone(isolate); |
1116 DCHECK(!isolate->native_context().is_null()); | 1066 DCHECK(!isolate->native_context().is_null()); |
1117 Handle<Script> script = info->script(); | 1067 ParseInfo* parse_info = info->parse_info(); |
| 1068 Handle<Script> script = parse_info->script(); |
1118 | 1069 |
1119 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? | 1070 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? |
1120 FixedArray* array = isolate->native_context()->embedder_data(); | 1071 FixedArray* array = isolate->native_context()->embedder_data(); |
1121 script->set_context_data(array->get(0)); | 1072 script->set_context_data(array->get(0)); |
1122 | 1073 |
1123 isolate->debug()->OnBeforeCompile(script); | 1074 isolate->debug()->OnBeforeCompile(script); |
1124 | 1075 |
1125 DCHECK(info->is_eval() || info->is_global() || info->is_module()); | 1076 DCHECK(parse_info->is_eval() || parse_info->is_global() || |
| 1077 parse_info->is_module()); |
1126 | 1078 |
1127 info->MarkAsToplevel(); | 1079 parse_info->set_toplevel(); |
1128 | 1080 |
1129 Handle<SharedFunctionInfo> result; | 1081 Handle<SharedFunctionInfo> result; |
1130 | 1082 |
1131 { VMState<COMPILER> state(info->isolate()); | 1083 { VMState<COMPILER> state(info->isolate()); |
1132 if (info->function() == NULL) { | 1084 if (parse_info->literal() == NULL) { |
1133 // Parse the script if needed (if it's already parsed, function() is | 1085 // Parse the script if needed (if it's already parsed, function() is |
1134 // non-NULL). | 1086 // non-NULL). |
1135 bool parse_allow_lazy = | 1087 ScriptCompiler::CompileOptions options = parse_info->compile_options(); |
1136 (info->compile_options() == ScriptCompiler::kConsumeParserCache || | 1088 bool parse_allow_lazy = (options == ScriptCompiler::kConsumeParserCache || |
1137 String::cast(script->source())->length() > | 1089 String::cast(script->source())->length() > |
1138 FLAG_min_preparse_length) && | 1090 FLAG_min_preparse_length) && |
1139 !Compiler::DebuggerWantsEagerCompilation(info); | 1091 !Compiler::DebuggerWantsEagerCompilation(isolate); |
1140 | 1092 |
| 1093 parse_info->set_allow_lazy_parsing(parse_allow_lazy); |
1141 if (!parse_allow_lazy && | 1094 if (!parse_allow_lazy && |
1142 (info->compile_options() == ScriptCompiler::kProduceParserCache || | 1095 (options == ScriptCompiler::kProduceParserCache || |
1143 info->compile_options() == ScriptCompiler::kConsumeParserCache)) { | 1096 options == ScriptCompiler::kConsumeParserCache)) { |
1144 // We are going to parse eagerly, but we either 1) have cached data | 1097 // We are going to parse eagerly, but we either 1) have cached data |
1145 // produced by lazy parsing or 2) are asked to generate cached data. | 1098 // produced by lazy parsing or 2) are asked to generate cached data. |
1146 // Eager parsing cannot benefit from cached data, and producing cached | 1099 // Eager parsing cannot benefit from cached data, and producing cached |
1147 // data while parsing eagerly is not implemented. | 1100 // data while parsing eagerly is not implemented. |
1148 info->SetCachedData(NULL, ScriptCompiler::kNoCompileOptions); | 1101 parse_info->set_cached_data(nullptr); |
| 1102 parse_info->set_compile_options(ScriptCompiler::kNoCompileOptions); |
1149 } | 1103 } |
1150 if (!Parser::ParseStatic(info, parse_allow_lazy)) { | 1104 if (!Parser::ParseStatic(parse_info)) { |
1151 return Handle<SharedFunctionInfo>::null(); | 1105 return Handle<SharedFunctionInfo>::null(); |
1152 } | 1106 } |
1153 } | 1107 } |
1154 | 1108 |
1155 FunctionLiteral* lit = info->function(); | 1109 FunctionLiteral* lit = info->function(); |
1156 LiveEditFunctionTracker live_edit_tracker(isolate, lit); | 1110 LiveEditFunctionTracker live_edit_tracker(isolate, lit); |
1157 | 1111 |
1158 // Measure how long it takes to do the compilation; only take the | 1112 // Measure how long it takes to do the compilation; only take the |
1159 // rest of the function into account to avoid overlap with the | 1113 // rest of the function into account to avoid overlap with the |
1160 // parsing statistics. | 1114 // parsing statistics. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 | 1174 |
1221 CompilationCache* compilation_cache = isolate->compilation_cache(); | 1175 CompilationCache* compilation_cache = isolate->compilation_cache(); |
1222 MaybeHandle<SharedFunctionInfo> maybe_shared_info = | 1176 MaybeHandle<SharedFunctionInfo> maybe_shared_info = |
1223 compilation_cache->LookupEval(source, outer_info, context, language_mode, | 1177 compilation_cache->LookupEval(source, outer_info, context, language_mode, |
1224 scope_position); | 1178 scope_position); |
1225 Handle<SharedFunctionInfo> shared_info; | 1179 Handle<SharedFunctionInfo> shared_info; |
1226 | 1180 |
1227 if (!maybe_shared_info.ToHandle(&shared_info)) { | 1181 if (!maybe_shared_info.ToHandle(&shared_info)) { |
1228 Handle<Script> script = isolate->factory()->NewScript(source); | 1182 Handle<Script> script = isolate->factory()->NewScript(source); |
1229 CompilationInfoWithZone info(script); | 1183 CompilationInfoWithZone info(script); |
1230 info.MarkAsEval(); | 1184 ParseInfo* parse_info = info.parse_info(); |
1231 if (context->IsNativeContext()) info.MarkAsGlobal(); | 1185 parse_info->set_eval(); |
1232 info.SetLanguageMode(language_mode); | 1186 if (context->IsNativeContext()) parse_info->set_global(); |
1233 info.SetParseRestriction(restriction); | 1187 parse_info->set_language_mode(language_mode); |
1234 info.SetContext(context); | 1188 parse_info->set_parse_restriction(restriction); |
| 1189 parse_info->set_context(context); |
1235 | 1190 |
1236 Debug::RecordEvalCaller(script); | 1191 Debug::RecordEvalCaller(script); |
1237 | 1192 |
1238 shared_info = CompileToplevel(&info); | 1193 shared_info = CompileToplevel(&info); |
1239 | 1194 |
1240 if (shared_info.is_null()) { | 1195 if (shared_info.is_null()) { |
1241 return MaybeHandle<JSFunction>(); | 1196 return MaybeHandle<JSFunction>(); |
1242 } else { | 1197 } else { |
1243 // Explicitly disable optimization for eval code. We're not yet prepared | 1198 // Explicitly disable optimization for eval code. We're not yet prepared |
1244 // to handle eval-code in the optimizing compiler. | 1199 // to handle eval-code in the optimizing compiler. |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 script->set_column_offset(Smi::FromInt(column_offset)); | 1292 script->set_column_offset(Smi::FromInt(column_offset)); |
1338 } | 1293 } |
1339 script->set_is_shared_cross_origin(is_shared_cross_origin); | 1294 script->set_is_shared_cross_origin(is_shared_cross_origin); |
1340 script->set_is_embedder_debug_script(is_embedder_debug_script); | 1295 script->set_is_embedder_debug_script(is_embedder_debug_script); |
1341 if (!source_map_url.is_null()) { | 1296 if (!source_map_url.is_null()) { |
1342 script->set_source_mapping_url(*source_map_url); | 1297 script->set_source_mapping_url(*source_map_url); |
1343 } | 1298 } |
1344 | 1299 |
1345 // Compile the function and add it to the cache. | 1300 // Compile the function and add it to the cache. |
1346 CompilationInfoWithZone info(script); | 1301 CompilationInfoWithZone info(script); |
| 1302 ParseInfo* parse_info = info.parse_info(); |
1347 if (FLAG_harmony_modules && is_module) { | 1303 if (FLAG_harmony_modules && is_module) { |
1348 info.MarkAsModule(); | 1304 parse_info->set_module(); |
1349 } else { | 1305 } else { |
1350 info.MarkAsGlobal(); | 1306 parse_info->set_global(); |
1351 } | 1307 } |
1352 info.SetCachedData(cached_data, compile_options); | 1308 if (compile_options != ScriptCompiler::kNoCompileOptions) { |
1353 info.SetExtension(extension); | 1309 parse_info->set_cached_data(cached_data); |
1354 info.SetContext(context); | 1310 } |
| 1311 parse_info->set_compile_options(compile_options); |
| 1312 parse_info->set_extension(extension); |
| 1313 parse_info->set_context(context); |
1355 if (FLAG_serialize_toplevel && | 1314 if (FLAG_serialize_toplevel && |
1356 compile_options == ScriptCompiler::kProduceCodeCache) { | 1315 compile_options == ScriptCompiler::kProduceCodeCache) { |
1357 info.PrepareForSerializing(); | 1316 info.PrepareForSerializing(); |
1358 } | 1317 } |
1359 | 1318 |
1360 info.SetLanguageMode( | 1319 parse_info->set_language_mode( |
1361 static_cast<LanguageMode>(info.language_mode() | language_mode)); | 1320 static_cast<LanguageMode>(info.language_mode() | language_mode)); |
1362 result = CompileToplevel(&info); | 1321 result = CompileToplevel(&info); |
1363 if (extension == NULL && !result.is_null() && !result->dont_cache()) { | 1322 if (extension == NULL && !result.is_null() && !result->dont_cache()) { |
1364 compilation_cache->PutScript(source, context, language_mode, result); | 1323 compilation_cache->PutScript(source, context, language_mode, result); |
1365 if (FLAG_serialize_toplevel && | 1324 if (FLAG_serialize_toplevel && |
1366 compile_options == ScriptCompiler::kProduceCodeCache) { | 1325 compile_options == ScriptCompiler::kProduceCodeCache) { |
1367 HistogramTimerScope histogram_timer( | 1326 HistogramTimerScope histogram_timer( |
1368 isolate->counters()->compile_serialize()); | 1327 isolate->counters()->compile_serialize()); |
1369 *cached_data = CodeSerializer::Serialize(isolate, result, source); | 1328 *cached_data = CodeSerializer::Serialize(isolate, result, source); |
1370 if (FLAG_profile_deserialization) { | 1329 if (FLAG_profile_deserialization) { |
1371 PrintF("[Compiling and serializing took %0.3f ms]\n", | 1330 PrintF("[Compiling and serializing took %0.3f ms]\n", |
1372 timer.Elapsed().InMillisecondsF()); | 1331 timer.Elapsed().InMillisecondsF()); |
1373 } | 1332 } |
1374 } | 1333 } |
1375 } | 1334 } |
1376 | 1335 |
1377 if (result.is_null()) isolate->ReportPendingMessages(); | 1336 if (result.is_null()) isolate->ReportPendingMessages(); |
1378 } else if (result->ic_age() != isolate->heap()->global_ic_age()) { | 1337 } else if (result->ic_age() != isolate->heap()->global_ic_age()) { |
1379 result->ResetForNewContext(isolate->heap()->global_ic_age()); | 1338 result->ResetForNewContext(isolate->heap()->global_ic_age()); |
1380 } | 1339 } |
1381 return result; | 1340 return result; |
1382 } | 1341 } |
1383 | 1342 |
1384 | 1343 |
1385 Handle<SharedFunctionInfo> Compiler::CompileStreamedScript( | 1344 Handle<SharedFunctionInfo> Compiler::CompileStreamedScript( |
1386 CompilationInfo* info, int source_length) { | 1345 Handle<Script> script, ParseInfo* parse_info, int source_length) { |
1387 Isolate* isolate = info->isolate(); | 1346 Isolate* isolate = script->GetIsolate(); |
| 1347 // TODO(titzer): increment the counters in caller. |
1388 isolate->counters()->total_load_size()->Increment(source_length); | 1348 isolate->counters()->total_load_size()->Increment(source_length); |
1389 isolate->counters()->total_compile_size()->Increment(source_length); | 1349 isolate->counters()->total_compile_size()->Increment(source_length); |
1390 | 1350 |
1391 LanguageMode language_mode = | 1351 LanguageMode language_mode = |
1392 construct_language_mode(FLAG_use_strict, FLAG_use_strong); | 1352 construct_language_mode(FLAG_use_strict, FLAG_use_strong); |
1393 info->SetLanguageMode( | 1353 parse_info->set_language_mode( |
1394 static_cast<LanguageMode>(info->language_mode() | language_mode)); | 1354 static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); |
1395 | 1355 |
| 1356 CompilationInfo compile_info(parse_info); |
1396 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the | 1357 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the |
1397 // real code caching lands, streaming needs to be adapted to use it. | 1358 // real code caching lands, streaming needs to be adapted to use it. |
1398 return CompileToplevel(info); | 1359 return CompileToplevel(&compile_info); |
1399 } | 1360 } |
1400 | 1361 |
1401 | 1362 |
1402 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( | 1363 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( |
1403 FunctionLiteral* literal, Handle<Script> script, | 1364 FunctionLiteral* literal, Handle<Script> script, |
1404 CompilationInfo* outer_info) { | 1365 CompilationInfo* outer_info) { |
1405 // Precondition: code has been parsed and scopes have been analyzed. | 1366 // Precondition: code has been parsed and scopes have been analyzed. |
1406 CompilationInfoWithZone info(script); | 1367 CompilationInfoWithZone info(script); |
1407 info.SetFunction(literal); | 1368 ParseInfo* parse_info = info.parse_info(); |
1408 info.PrepareForCompilation(literal->scope()); | 1369 parse_info->set_literal(literal); |
1409 info.SetLanguageMode(literal->scope()->language_mode()); | 1370 parse_info->set_scope(literal->scope()); |
| 1371 parse_info->set_language_mode(literal->scope()->language_mode()); |
1410 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 1372 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
1411 | 1373 |
1412 Isolate* isolate = info.isolate(); | 1374 Isolate* isolate = info.isolate(); |
1413 Factory* factory = isolate->factory(); | 1375 Factory* factory = isolate->factory(); |
1414 LiveEditFunctionTracker live_edit_tracker(isolate, literal); | 1376 LiveEditFunctionTracker live_edit_tracker(isolate, literal); |
1415 // Determine if the function can be lazily compiled. This is necessary to | 1377 // Determine if the function can be lazily compiled. This is necessary to |
1416 // allow some of our builtin JS files to be lazily compiled. These | 1378 // allow some of our builtin JS files to be lazily compiled. These |
1417 // builtins cannot be handled lazily by the parser, since we have to know | 1379 // builtins cannot be handled lazily by the parser, since we have to know |
1418 // if a function uses the special natives syntax, which is something the | 1380 // if a function uses the special natives syntax, which is something the |
1419 // parser records. | 1381 // parser records. |
1420 // If the debugger requests compilation for break points, we cannot be | 1382 // If the debugger requests compilation for break points, we cannot be |
1421 // aggressive about lazy compilation, because it might trigger compilation | 1383 // aggressive about lazy compilation, because it might trigger compilation |
1422 // of functions without an outer context when setting a breakpoint through | 1384 // of functions without an outer context when setting a breakpoint through |
1423 // Debug::FindSharedFunctionInfoInScript. | 1385 // Debug::FindSharedFunctionInfoInScript. |
1424 bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext(); | 1386 bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext(); |
1425 bool allow_lazy = literal->AllowsLazyCompilation() && | 1387 bool allow_lazy = |
1426 !DebuggerWantsEagerCompilation(&info, allow_lazy_without_ctx); | 1388 literal->AllowsLazyCompilation() && |
| 1389 !DebuggerWantsEagerCompilation(isolate, allow_lazy_without_ctx); |
1427 | 1390 |
1428 if (outer_info->is_toplevel() && outer_info->will_serialize()) { | 1391 if (outer_info->parse_info()->is_toplevel() && outer_info->will_serialize()) { |
1429 // Make sure that if the toplevel code (possibly to be serialized), | 1392 // Make sure that if the toplevel code (possibly to be serialized), |
1430 // the inner function must be allowed to be compiled lazily. | 1393 // the inner function must be allowed to be compiled lazily. |
1431 // This is necessary to serialize toplevel code without inner functions. | 1394 // This is necessary to serialize toplevel code without inner functions. |
1432 DCHECK(allow_lazy); | 1395 DCHECK(allow_lazy); |
1433 } | 1396 } |
1434 | 1397 |
1435 // Generate code | 1398 // Generate code |
1436 Handle<ScopeInfo> scope_info; | 1399 Handle<ScopeInfo> scope_info; |
1437 if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) { | 1400 if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) { |
1438 Handle<Code> code = isolate->builtins()->CompileLazy(); | 1401 Handle<Code> code = isolate->builtins()->CompileLazy(); |
1439 info.SetCode(code); | 1402 info.SetCode(code); |
1440 // There's no need in theory for a lazy-compiled function to have a type | 1403 // There's no need in theory for a lazy-compiled function to have a type |
1441 // feedback vector, but some parts of the system expect all | 1404 // feedback vector, but some parts of the system expect all |
1442 // SharedFunctionInfo instances to have one. The size of the vector depends | 1405 // SharedFunctionInfo instances to have one. The size of the vector depends |
1443 // on how many feedback-needing nodes are in the tree, and when lazily | 1406 // on how many feedback-needing nodes are in the tree, and when lazily |
1444 // parsing we might not know that, if this function was never parsed before. | 1407 // parsing we might not know that, if this function was never parsed before. |
1445 // In that case the vector will be replaced the next time MakeCode is | 1408 // In that case the vector will be replaced the next time MakeCode is |
1446 // called. | 1409 // called. |
1447 info.EnsureFeedbackVector(); | 1410 info.EnsureFeedbackVector(); |
1448 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); | 1411 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); |
1449 } else if (Renumber(&info) && FullCodeGenerator::MakeCode(&info)) { | 1412 } else if (Renumber(info.parse_info()) && |
| 1413 FullCodeGenerator::MakeCode(&info)) { |
1450 // MakeCode will ensure that the feedback vector is present and | 1414 // MakeCode will ensure that the feedback vector is present and |
1451 // appropriately sized. | 1415 // appropriately sized. |
1452 DCHECK(!info.code().is_null()); | 1416 DCHECK(!info.code().is_null()); |
1453 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); | 1417 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
1454 } else { | 1418 } else { |
1455 return Handle<SharedFunctionInfo>::null(); | 1419 return Handle<SharedFunctionInfo>::null(); |
1456 } | 1420 } |
1457 | 1421 |
1458 // Create a shared function info object. | 1422 // Create a shared function info object. |
1459 Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo( | 1423 Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo( |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1567 DCHECK(job->last_status() != OptimizedCompileJob::SUCCEEDED); | 1531 DCHECK(job->last_status() != OptimizedCompileJob::SUCCEEDED); |
1568 if (FLAG_trace_opt) { | 1532 if (FLAG_trace_opt) { |
1569 PrintF("[aborted optimizing "); | 1533 PrintF("[aborted optimizing "); |
1570 info->closure()->ShortPrint(); | 1534 info->closure()->ShortPrint(); |
1571 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); | 1535 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
1572 } | 1536 } |
1573 return Handle<Code>::null(); | 1537 return Handle<Code>::null(); |
1574 } | 1538 } |
1575 | 1539 |
1576 | 1540 |
1577 bool Compiler::DebuggerWantsEagerCompilation(CompilationInfo* info, | 1541 bool Compiler::DebuggerWantsEagerCompilation(Isolate* isolate, |
1578 bool allow_lazy_without_ctx) { | 1542 bool allow_lazy_without_ctx) { |
1579 if (LiveEditFunctionTracker::IsActive(info->isolate())) return true; | 1543 if (LiveEditFunctionTracker::IsActive(isolate)) return true; |
1580 Debug* debug = info->isolate()->debug(); | 1544 Debug* debug = isolate->debug(); |
1581 bool debugging = debug->is_active() || debug->has_break_points(); | 1545 bool debugging = debug->is_active() || debug->has_break_points(); |
1582 return debugging && !allow_lazy_without_ctx; | 1546 return debugging && !allow_lazy_without_ctx; |
1583 } | 1547 } |
1584 | 1548 |
1585 | 1549 |
1586 CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info) | 1550 CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info) |
1587 : name_(name), info_(info) { | 1551 : name_(name), info_(info) { |
1588 if (FLAG_hydrogen_stats) { | 1552 if (FLAG_hydrogen_stats) { |
1589 info_zone_start_allocation_size_ = info->zone()->allocation_size(); | 1553 info_zone_start_allocation_size_ = info->zone()->allocation_size(); |
1590 timer_.Start(); | 1554 timer_.Start(); |
(...skipping 16 matching lines...) Expand all Loading... |
1607 AllowHandleDereference allow_deref; | 1571 AllowHandleDereference allow_deref; |
1608 bool tracing_on = info()->IsStub() | 1572 bool tracing_on = info()->IsStub() |
1609 ? FLAG_trace_hydrogen_stubs | 1573 ? FLAG_trace_hydrogen_stubs |
1610 : (FLAG_trace_hydrogen && | 1574 : (FLAG_trace_hydrogen && |
1611 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); | 1575 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); |
1612 return (tracing_on && | 1576 return (tracing_on && |
1613 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); | 1577 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); |
1614 } | 1578 } |
1615 | 1579 |
1616 | 1580 |
| 1581 CompilationInfoWithZone::CompilationInfoWithZone(Handle<Script> script) |
| 1582 : CompilationInfo((new ParseInfo(&zone_))->InitializeFromScript(script)) {} |
| 1583 |
| 1584 |
| 1585 CompilationInfoWithZone::CompilationInfoWithZone(Handle<JSFunction> function) |
| 1586 : CompilationInfo( |
| 1587 (new ParseInfo(&zone_))->InitializeFromJSFunction(function)) {} |
| 1588 |
| 1589 |
| 1590 CompilationInfoWithZone::CompilationInfoWithZone( |
| 1591 Handle<SharedFunctionInfo> shared_info) |
| 1592 : CompilationInfo((new ParseInfo(&zone_)) |
| 1593 ->InitializeFromSharedFunctionInfo(shared_info)) {} |
| 1594 |
| 1595 |
| 1596 CompilationInfoWithZone::~CompilationInfoWithZone() { |
| 1597 DisableFutureOptimization(); |
| 1598 RollbackDependencies(); |
| 1599 delete parse_info_; |
| 1600 parse_info_ = nullptr; |
| 1601 } |
| 1602 |
1617 #if DEBUG | 1603 #if DEBUG |
1618 void CompilationInfo::PrintAstForTesting() { | 1604 void CompilationInfo::PrintAstForTesting() { |
1619 PrintF("--- Source from AST ---\n%s\n", | 1605 PrintF("--- Source from AST ---\n%s\n", |
1620 PrettyPrinter(isolate(), zone()).PrintProgram(function())); | 1606 PrettyPrinter(isolate(), zone()).PrintProgram(function())); |
1621 } | 1607 } |
1622 #endif | 1608 #endif |
1623 } } // namespace v8::internal | 1609 } } // namespace v8::internal |
OLD | NEW |