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 #ifndef V8_COMPILER_H_ | 5 #ifndef V8_COMPILER_H_ |
6 #define V8_COMPILER_H_ | 6 #define V8_COMPILER_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/ast.h" | 9 #include "src/ast.h" |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
11 #include "src/zone.h" | 11 #include "src/zone.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 class AstValueFactory; | 16 class AstValueFactory; |
17 class HydrogenCodeStub; | 17 class HydrogenCodeStub; |
18 | 18 class ParseInfo; |
19 // ParseRestriction is used to restrict the set of valid statements in a | 19 class ScriptData; |
20 // unit of compilation. Restriction violations cause a syntax error. | |
21 enum ParseRestriction { | |
22 NO_PARSE_RESTRICTION, // All expressions are allowed. | |
23 ONLY_SINGLE_FUNCTION_LITERAL // Only a single FunctionLiteral expression. | |
24 }; | |
25 | 20 |
26 struct OffsetRange { | 21 struct OffsetRange { |
27 OffsetRange(int from, int to) : from(from), to(to) {} | 22 OffsetRange(int from, int to) : from(from), to(to) {} |
28 int from; | 23 int from; |
29 int to; | 24 int to; |
30 }; | 25 }; |
31 | 26 |
32 | 27 |
33 // This class encapsulates encoding and decoding of sources positions from | 28 // This class encapsulates encoding and decoding of sources positions from |
34 // which hydrogen values originated. | 29 // which hydrogen values originated. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
98 | 93 |
99 Handle<SharedFunctionInfo> shared() const { return shared_; } | 94 Handle<SharedFunctionInfo> shared() const { return shared_; } |
100 int start_position() const { return start_position_; } | 95 int start_position() const { return start_position_; } |
101 | 96 |
102 private: | 97 private: |
103 Handle<SharedFunctionInfo> shared_; | 98 Handle<SharedFunctionInfo> shared_; |
104 int start_position_; | 99 int start_position_; |
105 }; | 100 }; |
106 | 101 |
107 | 102 |
108 class ScriptData { | |
109 public: | |
110 ScriptData(const byte* data, int length); | |
111 ~ScriptData() { | |
112 if (owns_data_) DeleteArray(data_); | |
113 } | |
114 | |
115 const byte* data() const { return data_; } | |
116 int length() const { return length_; } | |
117 bool rejected() const { return rejected_; } | |
118 | |
119 void Reject() { rejected_ = true; } | |
120 | |
121 void AcquireDataOwnership() { | |
122 DCHECK(!owns_data_); | |
123 owns_data_ = true; | |
124 } | |
125 | |
126 void ReleaseDataOwnership() { | |
127 DCHECK(owns_data_); | |
128 owns_data_ = false; | |
129 } | |
130 | |
131 private: | |
132 bool owns_data_ : 1; | |
133 bool rejected_ : 1; | |
134 const byte* data_; | |
135 int length_; | |
136 | |
137 DISALLOW_COPY_AND_ASSIGN(ScriptData); | |
138 }; | |
139 | |
140 // CompilationInfo encapsulates some information known at compile time. It | 103 // CompilationInfo encapsulates some information known at compile time. It |
141 // is constructed based on the resources available at compile-time. | 104 // is constructed based on the resources available at compile-time. |
142 class CompilationInfo { | 105 class CompilationInfo { |
143 public: | 106 public: |
144 // Various configuration flags for a compilation, as well as some properties | 107 // Various configuration flags for a compilation, as well as some properties |
145 // of the compiled code produced by a compilation. | 108 // of the compiled code produced by a compilation. |
146 enum Flag { | 109 enum Flag { |
147 kLazy = 1 << 0, | |
148 kEval = 1 << 1, | |
149 kGlobal = 1 << 2, | |
150 kStrictMode = 1 << 3, | |
151 kStrongMode = 1 << 4, | |
152 kThisHasUses = 1 << 5, | |
153 kNative = 1 << 6, | |
154 kDeferredCalling = 1 << 7, | 110 kDeferredCalling = 1 << 7, |
155 kNonDeferredCalling = 1 << 8, | 111 kNonDeferredCalling = 1 << 8, |
156 kSavesCallerDoubles = 1 << 9, | 112 kSavesCallerDoubles = 1 << 9, |
157 kRequiresFrame = 1 << 10, | 113 kRequiresFrame = 1 << 10, |
158 kMustNotHaveEagerFrame = 1 << 11, | 114 kMustNotHaveEagerFrame = 1 << 11, |
159 kDeoptimizationSupport = 1 << 12, | 115 kDeoptimizationSupport = 1 << 12, |
160 kDebug = 1 << 13, | 116 kDebug = 1 << 13, |
161 kCompilingForDebugging = 1 << 14, | 117 kCompilingForDebugging = 1 << 14, |
162 kParseRestriction = 1 << 15, | |
163 kSerializing = 1 << 16, | 118 kSerializing = 1 << 16, |
164 kContextSpecializing = 1 << 17, | 119 kContextSpecializing = 1 << 17, |
165 kInliningEnabled = 1 << 18, | 120 kInliningEnabled = 1 << 18, |
166 kTypingEnabled = 1 << 19, | 121 kTypingEnabled = 1 << 19, |
167 kDisableFutureOptimization = 1 << 20, | 122 kDisableFutureOptimization = 1 << 20, |
168 kModule = 1 << 21, | |
169 kToplevel = 1 << 22, | |
170 kSplittingEnabled = 1 << 23 | 123 kSplittingEnabled = 1 << 23 |
171 }; | 124 }; |
172 | 125 |
173 CompilationInfo(Handle<JSFunction> closure, Zone* zone); | 126 explicit CompilationInfo(ParseInfo* parse_info); |
174 CompilationInfo(Handle<Script> script, Zone* zone); | |
175 CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone); | 127 CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone); |
176 virtual ~CompilationInfo(); | 128 virtual ~CompilationInfo(); |
177 | 129 |
130 ParseInfo* parse_info() const { return parse_info_; } | |
131 | |
132 // ----------------------------------------------------------- | |
133 // TODO(titzer): inline and delete accessors of ParseInfo | |
134 // ----------------------------------------------------------- | |
135 Handle<Script> script() const; | |
136 bool is_toplevel() const; | |
137 bool is_lazy() const; | |
138 bool is_eval() const; | |
139 bool is_global() const; | |
140 bool is_native() const; | |
141 bool is_module() const; | |
142 bool this_has_uses() const; | |
143 LanguageMode language_mode() const; | |
144 Handle<JSFunction> closure() const; | |
145 FunctionLiteral* function() const; | |
146 Scope* scope() const; | |
147 Scope* script_scope() const; | |
148 Handle<Context> context() const; | |
149 Handle<SharedFunctionInfo> shared_info() const; | |
150 bool has_shared_info() const; | |
151 // ----------------------------------------------------------- | |
152 | |
178 Isolate* isolate() const { | 153 Isolate* isolate() const { |
179 return isolate_; | 154 return isolate_; |
180 } | 155 } |
181 Zone* zone() { return zone_; } | 156 Zone* zone() { return zone_; } |
182 bool is_osr() const { return !osr_ast_id_.IsNone(); } | 157 bool is_osr() const { return !osr_ast_id_.IsNone(); } |
183 bool is_lazy() const { return GetFlag(kLazy); } | |
184 bool is_eval() const { return GetFlag(kEval); } | |
185 bool is_global() const { return GetFlag(kGlobal); } | |
186 bool is_module() const { return GetFlag(kModule); } | |
187 LanguageMode language_mode() const { | |
188 STATIC_ASSERT(LANGUAGE_END == 3); | |
189 return construct_language_mode(GetFlag(kStrictMode), GetFlag(kStrongMode)); | |
190 } | |
191 FunctionLiteral* function() const { return function_; } | |
192 Scope* scope() const { return scope_; } | |
193 Scope* script_scope() const { return script_scope_; } | |
194 Handle<Code> code() const { return code_; } | 158 Handle<Code> code() const { return code_; } |
195 Handle<JSFunction> closure() const { return closure_; } | |
196 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } | |
197 Handle<Script> script() const { return script_; } | |
198 void set_script(Handle<Script> script) { script_ = script; } | |
199 CodeStub* code_stub() const { return code_stub_; } | 159 CodeStub* code_stub() const { return code_stub_; } |
200 v8::Extension* extension() const { return extension_; } | |
201 ScriptData** cached_data() const { return cached_data_; } | |
202 ScriptCompiler::CompileOptions compile_options() const { | |
203 return compile_options_; | |
204 } | |
205 ScriptCompiler::ExternalSourceStream* source_stream() const { | |
206 return source_stream_; | |
207 } | |
208 ScriptCompiler::StreamedSource::Encoding source_stream_encoding() const { | |
209 return source_stream_encoding_; | |
210 } | |
211 Handle<Context> context() const { return context_; } | |
212 BailoutId osr_ast_id() const { return osr_ast_id_; } | 160 BailoutId osr_ast_id() const { return osr_ast_id_; } |
213 Handle<Code> unoptimized_code() const { return unoptimized_code_; } | 161 Handle<Code> unoptimized_code() const { return unoptimized_code_; } |
214 int opt_count() const { return opt_count_; } | 162 int opt_count() const { return opt_count_; } |
215 int num_parameters() const; | 163 int num_parameters() const; |
216 int num_heap_slots() const; | 164 int num_heap_slots() const; |
217 Code::Flags flags() const; | 165 Code::Flags flags() const; |
218 | 166 |
219 void MarkAsEval() { | |
220 DCHECK(!is_lazy()); | |
221 SetFlag(kEval); | |
222 } | |
223 | |
224 void MarkAsGlobal() { | |
225 DCHECK(!is_lazy()); | |
226 SetFlag(kGlobal); | |
227 } | |
228 | |
229 void MarkAsModule() { | |
230 DCHECK(!is_lazy()); | |
231 SetFlag(kModule); | |
232 } | |
233 | |
234 void set_parameter_count(int parameter_count) { | 167 void set_parameter_count(int parameter_count) { |
235 DCHECK(IsStub()); | 168 DCHECK(IsStub()); |
236 parameter_count_ = parameter_count; | 169 parameter_count_ = parameter_count; |
237 } | 170 } |
238 | 171 |
239 void set_this_has_uses(bool has_no_uses) { | |
240 SetFlag(kThisHasUses, has_no_uses); | |
241 } | |
242 | |
243 bool this_has_uses() { return GetFlag(kThisHasUses); } | |
244 | |
245 void SetLanguageMode(LanguageMode language_mode) { | |
246 STATIC_ASSERT(LANGUAGE_END == 3); | |
247 SetFlag(kStrictMode, language_mode & STRICT_BIT); | |
248 SetFlag(kStrongMode, language_mode & STRONG_BIT); | |
249 } | |
250 | |
251 void MarkAsNative() { SetFlag(kNative); } | |
252 | |
253 bool is_native() const { return GetFlag(kNative); } | |
254 | |
255 bool is_calling() const { | 172 bool is_calling() const { |
256 return GetFlag(kDeferredCalling) || GetFlag(kNonDeferredCalling); | 173 return GetFlag(kDeferredCalling) || GetFlag(kNonDeferredCalling); |
257 } | 174 } |
258 | 175 |
259 void MarkAsDeferredCalling() { SetFlag(kDeferredCalling); } | 176 void MarkAsDeferredCalling() { SetFlag(kDeferredCalling); } |
260 | 177 |
261 bool is_deferred_calling() const { return GetFlag(kDeferredCalling); } | 178 bool is_deferred_calling() const { return GetFlag(kDeferredCalling); } |
262 | 179 |
263 void MarkAsNonDeferredCalling() { SetFlag(kNonDeferredCalling); } | 180 void MarkAsNonDeferredCalling() { SetFlag(kNonDeferredCalling); } |
264 | 181 |
(...skipping 26 matching lines...) Expand all Loading... | |
291 bool is_context_specializing() const { return GetFlag(kContextSpecializing); } | 208 bool is_context_specializing() const { return GetFlag(kContextSpecializing); } |
292 | 209 |
293 void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); } | 210 void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); } |
294 | 211 |
295 bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); } | 212 bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); } |
296 | 213 |
297 void MarkAsTypingEnabled() { SetFlag(kTypingEnabled); } | 214 void MarkAsTypingEnabled() { SetFlag(kTypingEnabled); } |
298 | 215 |
299 bool is_typing_enabled() const { return GetFlag(kTypingEnabled); } | 216 bool is_typing_enabled() const { return GetFlag(kTypingEnabled); } |
300 | 217 |
301 void MarkAsToplevel() { SetFlag(kToplevel); } | |
302 | |
303 bool is_toplevel() const { return GetFlag(kToplevel); } | |
304 | |
305 void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); } | 218 void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); } |
306 | 219 |
307 bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); } | 220 bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); } |
308 | 221 |
309 bool IsCodePreAgingActive() const { | 222 bool IsCodePreAgingActive() const { |
310 return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() && | 223 return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() && |
311 !is_debug(); | 224 !is_debug(); |
312 } | 225 } |
313 | 226 |
314 void SetParseRestriction(ParseRestriction restriction) { | |
315 SetFlag(kParseRestriction, restriction != NO_PARSE_RESTRICTION); | |
316 } | |
317 | |
318 ParseRestriction parse_restriction() const { | |
319 return GetFlag(kParseRestriction) ? ONLY_SINGLE_FUNCTION_LITERAL | |
320 : NO_PARSE_RESTRICTION; | |
321 } | |
322 | |
323 void SetFunction(FunctionLiteral* literal) { | |
324 DCHECK(function_ == NULL); | |
325 function_ = literal; | |
326 } | |
327 void PrepareForCompilation(Scope* scope); | |
328 void SetScriptScope(Scope* script_scope) { | |
329 DCHECK(script_scope_ == NULL); | |
330 script_scope_ = script_scope; | |
331 } | |
332 void EnsureFeedbackVector(); | 227 void EnsureFeedbackVector(); |
333 Handle<TypeFeedbackVector> feedback_vector() const { | 228 Handle<TypeFeedbackVector> feedback_vector() const { |
334 return feedback_vector_; | 229 return feedback_vector_; |
335 } | 230 } |
336 void SetCode(Handle<Code> code) { code_ = code; } | 231 void SetCode(Handle<Code> code) { code_ = code; } |
337 void SetExtension(v8::Extension* extension) { | |
338 DCHECK(!is_lazy()); | |
339 extension_ = extension; | |
340 } | |
341 void SetCachedData(ScriptData** cached_data, | |
342 ScriptCompiler::CompileOptions compile_options) { | |
343 compile_options_ = compile_options; | |
344 if (compile_options == ScriptCompiler::kNoCompileOptions) { | |
345 cached_data_ = NULL; | |
346 } else { | |
347 DCHECK(!is_lazy()); | |
348 cached_data_ = cached_data; | |
349 } | |
350 } | |
351 void SetContext(Handle<Context> context) { | |
352 context_ = context; | |
353 } | |
354 | 232 |
355 void MarkCompilingForDebugging() { SetFlag(kCompilingForDebugging); } | 233 void MarkCompilingForDebugging() { SetFlag(kCompilingForDebugging); } |
356 bool IsCompilingForDebugging() { return GetFlag(kCompilingForDebugging); } | 234 bool IsCompilingForDebugging() { return GetFlag(kCompilingForDebugging); } |
357 void MarkNonOptimizable() { | 235 void MarkNonOptimizable() { |
358 SetMode(CompilationInfo::NONOPT); | 236 SetMode(CompilationInfo::NONOPT); |
359 } | 237 } |
360 | 238 |
361 bool ShouldTrapOnDeopt() const { | 239 bool ShouldTrapOnDeopt() const { |
362 return (FLAG_trap_on_deopt && IsOptimizing()) || | 240 return (FLAG_trap_on_deopt && IsOptimizing()) || |
363 (FLAG_trap_on_stub_deopt && IsStub()); | 241 (FLAG_trap_on_stub_deopt && IsStub()); |
364 } | 242 } |
365 | 243 |
366 bool has_global_object() const { | 244 bool has_global_object() const { |
367 return !closure().is_null() && | 245 return !closure().is_null() && |
368 (closure()->context()->global_object() != NULL); | 246 (closure()->context()->global_object() != NULL); |
369 } | 247 } |
370 | 248 |
371 GlobalObject* global_object() const { | 249 GlobalObject* global_object() const { |
372 return has_global_object() ? closure()->context()->global_object() : NULL; | 250 return has_global_object() ? closure()->context()->global_object() : NULL; |
373 } | 251 } |
374 | 252 |
375 // Accessors for the different compilation modes. | 253 // Accessors for the different compilation modes. |
376 bool IsOptimizing() const { return mode_ == OPTIMIZE; } | 254 bool IsOptimizing() const { return mode_ == OPTIMIZE; } |
377 bool IsOptimizable() const { return mode_ == BASE; } | 255 bool IsOptimizable() const { return mode_ == BASE; } |
378 bool IsStub() const { return mode_ == STUB; } | 256 bool IsStub() const { return mode_ == STUB; } |
379 void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) { | 257 void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) { |
380 DCHECK(!shared_info_.is_null()); | 258 DCHECK(!shared_info().is_null()); |
381 SetMode(OPTIMIZE); | 259 SetMode(OPTIMIZE); |
382 osr_ast_id_ = osr_ast_id; | 260 osr_ast_id_ = osr_ast_id; |
383 unoptimized_code_ = unoptimized; | 261 unoptimized_code_ = unoptimized; |
384 optimization_id_ = isolate()->NextOptimizationId(); | 262 optimization_id_ = isolate()->NextOptimizationId(); |
385 } | 263 } |
386 | 264 |
387 // Deoptimization support. | 265 // Deoptimization support. |
388 bool HasDeoptimizationSupport() const { | 266 bool HasDeoptimizationSupport() const { |
389 return GetFlag(kDeoptimizationSupport); | 267 return GetFlag(kDeoptimizationSupport); |
390 } | 268 } |
(...skipping 15 matching lines...) Expand all Loading... | |
406 if (dependencies_[group] == NULL) { | 284 if (dependencies_[group] == NULL) { |
407 dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_); | 285 dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_); |
408 } | 286 } |
409 return dependencies_[group]; | 287 return dependencies_[group]; |
410 } | 288 } |
411 | 289 |
412 void CommitDependencies(Handle<Code> code); | 290 void CommitDependencies(Handle<Code> code); |
413 | 291 |
414 void RollbackDependencies(); | 292 void RollbackDependencies(); |
415 | 293 |
416 void SaveHandles() { | 294 void ReopenHandlesInNewHandleScope() { |
417 SaveHandle(&closure_); | 295 unoptimized_code_ = Handle<Code>(*unoptimized_code_); |
418 SaveHandle(&shared_info_); | |
419 SaveHandle(&context_); | |
420 SaveHandle(&script_); | |
421 SaveHandle(&unoptimized_code_); | |
422 } | 296 } |
423 | 297 |
424 void AbortOptimization(BailoutReason reason) { | 298 void AbortOptimization(BailoutReason reason) { |
425 DCHECK(reason != kNoReason); | 299 DCHECK(reason != kNoReason); |
426 if (bailout_reason_ == kNoReason) bailout_reason_ = reason; | 300 if (bailout_reason_ == kNoReason) bailout_reason_ = reason; |
427 SetFlag(kDisableFutureOptimization); | 301 SetFlag(kDisableFutureOptimization); |
428 } | 302 } |
429 | 303 |
430 void RetryOptimization(BailoutReason reason) { | 304 void RetryOptimization(BailoutReason reason) { |
431 DCHECK(reason != kNoReason); | 305 DCHECK(reason != kNoReason); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
479 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); | 353 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); |
480 aborted_due_to_dependency_change_ = true; | 354 aborted_due_to_dependency_change_ = true; |
481 } | 355 } |
482 | 356 |
483 bool HasAbortedDueToDependencyChange() const { | 357 bool HasAbortedDueToDependencyChange() const { |
484 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); | 358 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); |
485 return aborted_due_to_dependency_change_; | 359 return aborted_due_to_dependency_change_; |
486 } | 360 } |
487 | 361 |
488 bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) { | 362 bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) { |
489 return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure_); | 363 return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure()); |
490 } | 364 } |
491 | 365 |
492 int optimization_id() const { return optimization_id_; } | 366 int optimization_id() const { return optimization_id_; } |
493 | 367 |
494 AstValueFactory* ast_value_factory() const { return ast_value_factory_; } | |
495 void SetAstValueFactory(AstValueFactory* ast_value_factory, | |
496 bool owned = true) { | |
497 ast_value_factory_ = ast_value_factory; | |
498 ast_value_factory_owned_ = owned; | |
499 } | |
500 | |
501 int osr_expr_stack_height() { return osr_expr_stack_height_; } | 368 int osr_expr_stack_height() { return osr_expr_stack_height_; } |
502 void set_osr_expr_stack_height(int height) { | 369 void set_osr_expr_stack_height(int height) { |
503 DCHECK(height >= 0); | 370 DCHECK(height >= 0); |
504 osr_expr_stack_height_ = height; | 371 osr_expr_stack_height_ = height; |
505 } | 372 } |
506 | 373 |
507 #if DEBUG | 374 #if DEBUG |
508 void PrintAstForTesting(); | 375 void PrintAstForTesting(); |
509 #endif | 376 #endif |
510 | 377 |
511 bool is_simple_parameter_list(); | 378 bool is_simple_parameter_list(); |
512 | 379 |
513 protected: | |
514 CompilationInfo(Handle<SharedFunctionInfo> shared_info, | |
515 Zone* zone); | |
516 CompilationInfo(ScriptCompiler::ExternalSourceStream* source_stream, | |
517 ScriptCompiler::StreamedSource::Encoding encoding, | |
518 Isolate* isolate, Zone* zone); | |
519 | |
520 | |
521 private: | 380 private: |
381 ParseInfo* parse_info_; | |
marja
2015/03/04 09:24:40
Owned? Not owned? Who owns it?
| |
522 Isolate* isolate_; | 382 Isolate* isolate_; |
523 | 383 |
524 // Compilation mode. | 384 // Compilation mode. |
525 // BASE is generated by the full codegen, optionally prepared for bailouts. | 385 // BASE is generated by the full codegen, optionally prepared for bailouts. |
526 // OPTIMIZE is optimized code generated by the Hydrogen-based backend. | 386 // OPTIMIZE is optimized code generated by the Hydrogen-based backend. |
527 // NONOPT is generated by the full codegen and is not prepared for | 387 // NONOPT is generated by the full codegen and is not prepared for |
528 // recompilation/bailouts. These functions are never recompiled. | 388 // recompilation/bailouts. These functions are never recompiled. |
529 enum Mode { | 389 enum Mode { |
530 BASE, | 390 BASE, |
531 OPTIMIZE, | 391 OPTIMIZE, |
(...skipping 10 matching lines...) Expand all Loading... | |
542 void SetFlag(Flag flag) { flags_ |= flag; } | 402 void SetFlag(Flag flag) { flags_ |= flag; } |
543 | 403 |
544 void SetFlag(Flag flag, bool value) { | 404 void SetFlag(Flag flag, bool value) { |
545 flags_ = value ? flags_ | flag : flags_ & ~flag; | 405 flags_ = value ? flags_ | flag : flags_ & ~flag; |
546 } | 406 } |
547 | 407 |
548 bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; } | 408 bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; } |
549 | 409 |
550 unsigned flags_; | 410 unsigned flags_; |
551 | 411 |
552 // Fields filled in by the compilation pipeline. | |
553 // AST filled in by the parser. | |
554 FunctionLiteral* function_; | |
555 // The scope of the function literal as a convenience. Set to indicate | |
556 // that scopes have been analyzed. | |
557 Scope* scope_; | |
558 // The script scope provided as a convenience. | |
559 Scope* script_scope_; | |
560 // For compiled stubs, the stub object | 412 // For compiled stubs, the stub object |
561 CodeStub* code_stub_; | 413 CodeStub* code_stub_; |
562 // The compiled code. | 414 // The compiled code. |
563 Handle<Code> code_; | 415 Handle<Code> code_; |
564 | 416 |
565 // Possible initial inputs to the compilation process. | |
566 Handle<JSFunction> closure_; | |
567 Handle<SharedFunctionInfo> shared_info_; | |
568 Handle<Script> script_; | |
569 ScriptCompiler::ExternalSourceStream* source_stream_; // Not owned. | |
570 ScriptCompiler::StreamedSource::Encoding source_stream_encoding_; | |
571 | |
572 // Fields possibly needed for eager compilation, NULL by default. | |
573 v8::Extension* extension_; | |
574 ScriptData** cached_data_; | |
575 ScriptCompiler::CompileOptions compile_options_; | |
576 | |
577 // The context of the caller for eval code, and the script context for a | |
578 // global script. Will be a null handle otherwise. | |
579 Handle<Context> context_; | |
580 | |
581 // Used by codegen, ultimately kept rooted by the SharedFunctionInfo. | 417 // Used by codegen, ultimately kept rooted by the SharedFunctionInfo. |
582 Handle<TypeFeedbackVector> feedback_vector_; | 418 Handle<TypeFeedbackVector> feedback_vector_; |
583 | 419 |
584 // Compilation mode flag and whether deoptimization is allowed. | 420 // Compilation mode flag and whether deoptimization is allowed. |
585 Mode mode_; | 421 Mode mode_; |
586 BailoutId osr_ast_id_; | 422 BailoutId osr_ast_id_; |
587 // The unoptimized code we patched for OSR may not be the shared code | 423 // The unoptimized code we patched for OSR may not be the shared code |
588 // afterwards, since we may need to compile it again to include deoptimization | 424 // afterwards, since we may need to compile it again to include deoptimization |
589 // data. Keep track which code we patched. | 425 // data. Keep track which code we patched. |
590 Handle<Code> unoptimized_code_; | 426 Handle<Code> unoptimized_code_; |
591 | 427 |
592 // The zone from which the compilation pipeline working on this | 428 // The zone from which the compilation pipeline working on this |
593 // CompilationInfo allocates. | 429 // CompilationInfo allocates. |
594 Zone* zone_; | 430 Zone* zone_; |
595 | 431 |
596 DeferredHandles* deferred_handles_; | 432 DeferredHandles* deferred_handles_; |
597 | 433 |
598 ZoneList<Handle<HeapObject> >* dependencies_[DependentCode::kGroupCount]; | 434 ZoneList<Handle<HeapObject> >* dependencies_[DependentCode::kGroupCount]; |
599 | 435 |
600 template<typename T> | |
601 void SaveHandle(Handle<T> *object) { | |
602 if (!object->is_null()) { | |
603 Handle<T> handle(*(*object)); | |
604 *object = handle; | |
605 } | |
606 } | |
607 | |
608 BailoutReason bailout_reason_; | 436 BailoutReason bailout_reason_; |
609 | 437 |
610 int prologue_offset_; | 438 int prologue_offset_; |
611 | 439 |
612 List<OffsetRange>* no_frame_ranges_; | 440 List<OffsetRange>* no_frame_ranges_; |
613 List<InlinedFunctionInfo>* inlined_function_infos_; | 441 List<InlinedFunctionInfo>* inlined_function_infos_; |
614 List<int>* inlining_id_to_function_id_; | 442 List<int>* inlining_id_to_function_id_; |
615 | 443 |
616 // A copy of shared_info()->opt_count() to avoid handle deref | 444 // A copy of shared_info()->opt_count() to avoid handle deref |
617 // during graph optimization. | 445 // during graph optimization. |
618 int opt_count_; | 446 int opt_count_; |
619 | 447 |
620 // Number of parameters used for compilation of stubs that require arguments. | 448 // Number of parameters used for compilation of stubs that require arguments. |
621 int parameter_count_; | 449 int parameter_count_; |
622 | 450 |
623 Handle<Foreign> object_wrapper_; | 451 Handle<Foreign> object_wrapper_; |
624 | 452 |
625 int optimization_id_; | 453 int optimization_id_; |
626 | 454 |
627 AstValueFactory* ast_value_factory_; | |
628 bool ast_value_factory_owned_; | |
629 | |
630 // This flag is used by the main thread to track whether this compilation | 455 // This flag is used by the main thread to track whether this compilation |
631 // should be abandoned due to dependency change. | 456 // should be abandoned due to dependency change. |
632 bool aborted_due_to_dependency_change_; | 457 bool aborted_due_to_dependency_change_; |
633 | 458 |
634 int osr_expr_stack_height_; | 459 int osr_expr_stack_height_; |
635 | 460 |
636 DISALLOW_COPY_AND_ASSIGN(CompilationInfo); | 461 DISALLOW_COPY_AND_ASSIGN(CompilationInfo); |
637 }; | 462 }; |
638 | 463 |
639 | 464 |
640 // Exactly like a CompilationInfo, except also creates and enters a | 465 // Exactly like a CompilationInfo, except also creates and enters a |
641 // Zone on construction and deallocates it on exit. | 466 // Zone on construction and deallocates it on exit. |
642 class CompilationInfoWithZone: public CompilationInfo { | 467 class CompilationInfoWithZone: public CompilationInfo { |
643 public: | 468 public: |
644 explicit CompilationInfoWithZone(Handle<Script> script) | 469 explicit CompilationInfoWithZone(Handle<Script> script); |
645 : CompilationInfo(script, &zone_) {} | 470 explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info); |
646 explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info) | 471 explicit CompilationInfoWithZone(Handle<JSFunction> closure); |
647 : CompilationInfo(shared_info, &zone_) {} | |
648 explicit CompilationInfoWithZone(Handle<JSFunction> closure) | |
649 : CompilationInfo(closure, &zone_) {} | |
650 CompilationInfoWithZone(CodeStub* stub, Isolate* isolate) | 472 CompilationInfoWithZone(CodeStub* stub, Isolate* isolate) |
651 : CompilationInfo(stub, isolate, &zone_) {} | 473 : CompilationInfo(stub, isolate, &zone_) {} |
652 CompilationInfoWithZone(ScriptCompiler::ExternalSourceStream* stream, | |
653 ScriptCompiler::StreamedSource::Encoding encoding, | |
654 Isolate* isolate) | |
655 : CompilationInfo(stream, encoding, isolate, &zone_) {} | |
656 | 474 |
657 // Virtual destructor because a CompilationInfoWithZone has to exit the | 475 // Virtual destructor because a CompilationInfoWithZone has to exit the |
658 // zone scope and get rid of dependent maps even when the destructor is | 476 // zone scope and get rid of dependent maps even when the destructor is |
659 // called when cast as a CompilationInfo. | 477 // called when cast as a CompilationInfo. |
660 virtual ~CompilationInfoWithZone() { | 478 virtual ~CompilationInfoWithZone(); |
661 RollbackDependencies(); | |
662 } | |
663 | 479 |
664 private: | 480 private: |
665 Zone zone_; | 481 Zone zone_; |
666 }; | 482 }; |
667 | 483 |
668 | |
669 // A wrapper around a CompilationInfo that detaches the Handles from | 484 // A wrapper around a CompilationInfo that detaches the Handles from |
670 // the underlying DeferredHandleScope and stores them in info_ on | 485 // the underlying DeferredHandleScope and stores them in info_ on |
671 // destruction. | 486 // destruction. |
672 class CompilationHandleScope BASE_EMBEDDED { | 487 class CompilationHandleScope BASE_EMBEDDED { |
673 public: | 488 public: |
674 explicit CompilationHandleScope(CompilationInfo* info) | 489 explicit CompilationHandleScope(CompilationInfo* info) |
675 : deferred_(info->isolate()), info_(info) {} | 490 : deferred_(info->isolate()), info_(info) {} |
676 ~CompilationHandleScope() { | 491 ~CompilationHandleScope() { |
677 info_->set_deferred_handles(deferred_.Detach()); | 492 info_->set_deferred_handles(deferred_.Detach()); |
678 } | 493 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
783 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode( | 598 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode( |
784 Handle<JSFunction> function); | 599 Handle<JSFunction> function); |
785 MUST_USE_RESULT static MaybeHandle<Code> GetLazyCode( | 600 MUST_USE_RESULT static MaybeHandle<Code> GetLazyCode( |
786 Handle<JSFunction> function); | 601 Handle<JSFunction> function); |
787 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode( | 602 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode( |
788 Handle<SharedFunctionInfo> shared); | 603 Handle<SharedFunctionInfo> shared); |
789 MUST_USE_RESULT static MaybeHandle<Code> GetDebugCode( | 604 MUST_USE_RESULT static MaybeHandle<Code> GetDebugCode( |
790 Handle<JSFunction> function); | 605 Handle<JSFunction> function); |
791 | 606 |
792 // Parser::Parse, then Compiler::Analyze. | 607 // Parser::Parse, then Compiler::Analyze. |
793 static bool ParseAndAnalyze(CompilationInfo* info); | 608 static bool ParseAndAnalyze(ParseInfo* info); |
794 // Rewrite, analyze scopes, and renumber. | 609 // Rewrite, analyze scopes, and renumber. |
795 static bool Analyze(CompilationInfo* info); | 610 static bool Analyze(ParseInfo* info); |
796 // Adds deoptimization support, requires ParseAndAnalyze. | 611 // Adds deoptimization support, requires ParseAndAnalyze. |
797 static bool EnsureDeoptimizationSupport(CompilationInfo* info); | 612 static bool EnsureDeoptimizationSupport(CompilationInfo* info); |
798 | 613 |
799 static bool EnsureCompiled(Handle<JSFunction> function, | 614 static bool EnsureCompiled(Handle<JSFunction> function, |
800 ClearExceptionFlag flag); | 615 ClearExceptionFlag flag); |
801 | 616 |
802 static void CompileForLiveEdit(Handle<Script> script); | 617 static void CompileForLiveEdit(Handle<Script> script); |
803 | 618 |
804 // Compile a String source within a context for eval. | 619 // Compile a String source within a context for eval. |
805 MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval( | 620 MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval( |
806 Handle<String> source, Handle<SharedFunctionInfo> outer_info, | 621 Handle<String> source, Handle<SharedFunctionInfo> outer_info, |
807 Handle<Context> context, LanguageMode language_mode, | 622 Handle<Context> context, LanguageMode language_mode, |
808 ParseRestriction restriction, int scope_position); | 623 ParseRestriction restriction, int scope_position); |
809 | 624 |
810 // Compile a String source within a context. | 625 // Compile a String source within a context. |
811 static Handle<SharedFunctionInfo> CompileScript( | 626 static Handle<SharedFunctionInfo> CompileScript( |
812 Handle<String> source, Handle<Object> script_name, int line_offset, | 627 Handle<String> source, Handle<Object> script_name, int line_offset, |
813 int column_offset, bool is_debugger_script, bool is_shared_cross_origin, | 628 int column_offset, bool is_debugger_script, bool is_shared_cross_origin, |
814 Handle<Context> context, v8::Extension* extension, | 629 Handle<Context> context, v8::Extension* extension, |
815 ScriptData** cached_data, ScriptCompiler::CompileOptions compile_options, | 630 ScriptData** cached_data, ScriptCompiler::CompileOptions compile_options, |
816 NativesFlag is_natives_code, bool is_module); | 631 NativesFlag is_natives_code, bool is_module); |
817 | 632 |
818 static Handle<SharedFunctionInfo> CompileStreamedScript(CompilationInfo* info, | 633 static Handle<SharedFunctionInfo> CompileStreamedScript(Handle<Script> script, |
634 ParseInfo* info, | |
819 int source_length); | 635 int source_length); |
820 | 636 |
821 // Create a shared function info object (the code may be lazily compiled). | 637 // Create a shared function info object (the code may be lazily compiled). |
822 static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node, | 638 static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node, |
823 Handle<Script> script, | 639 Handle<Script> script, |
824 CompilationInfo* outer); | 640 CompilationInfo* outer); |
825 | 641 |
826 enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT }; | 642 enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT }; |
827 | 643 |
828 // Generate and return optimized code or start a concurrent optimization job. | 644 // Generate and return optimized code or start a concurrent optimization job. |
829 // In the latter case, return the InOptimizationQueue builtin. On failure, | 645 // In the latter case, return the InOptimizationQueue builtin. On failure, |
830 // return the empty handle. | 646 // return the empty handle. |
831 MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCode( | 647 MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCode( |
832 Handle<JSFunction> function, | 648 Handle<JSFunction> function, |
833 Handle<Code> current_code, | 649 Handle<Code> current_code, |
834 ConcurrencyMode mode, | 650 ConcurrencyMode mode, |
835 BailoutId osr_ast_id = BailoutId::None()); | 651 BailoutId osr_ast_id = BailoutId::None()); |
836 | 652 |
837 // Generate and return code from previously queued optimization job. | 653 // Generate and return code from previously queued optimization job. |
838 // On failure, return the empty handle. | 654 // On failure, return the empty handle. |
839 static Handle<Code> GetConcurrentlyOptimizedCode(OptimizedCompileJob* job); | 655 static Handle<Code> GetConcurrentlyOptimizedCode(OptimizedCompileJob* job); |
840 | 656 |
657 // TODO(titzer): move this method out of the compiler. | |
841 static bool DebuggerWantsEagerCompilation( | 658 static bool DebuggerWantsEagerCompilation( |
842 CompilationInfo* info, bool allow_lazy_without_ctx = false); | 659 Isolate* isolate, bool allow_lazy_without_ctx = false); |
843 }; | 660 }; |
844 | 661 |
845 | 662 |
846 class CompilationPhase BASE_EMBEDDED { | 663 class CompilationPhase BASE_EMBEDDED { |
847 public: | 664 public: |
848 CompilationPhase(const char* name, CompilationInfo* info); | 665 CompilationPhase(const char* name, CompilationInfo* info); |
849 ~CompilationPhase(); | 666 ~CompilationPhase(); |
850 | 667 |
851 protected: | 668 protected: |
852 bool ShouldProduceTraceOutput() const; | 669 bool ShouldProduceTraceOutput() const; |
853 | 670 |
854 const char* name() const { return name_; } | 671 const char* name() const { return name_; } |
855 CompilationInfo* info() const { return info_; } | 672 CompilationInfo* info() const { return info_; } |
856 Isolate* isolate() const { return info()->isolate(); } | 673 Isolate* isolate() const { return info()->isolate(); } |
857 Zone* zone() { return &zone_; } | 674 Zone* zone() { return &zone_; } |
858 | 675 |
859 private: | 676 private: |
860 const char* name_; | 677 const char* name_; |
861 CompilationInfo* info_; | 678 CompilationInfo* info_; |
862 Zone zone_; | 679 Zone zone_; |
863 size_t info_zone_start_allocation_size_; | 680 size_t info_zone_start_allocation_size_; |
864 base::ElapsedTimer timer_; | 681 base::ElapsedTimer timer_; |
865 | 682 |
866 DISALLOW_COPY_AND_ASSIGN(CompilationPhase); | 683 DISALLOW_COPY_AND_ASSIGN(CompilationPhase); |
867 }; | 684 }; |
868 | 685 |
869 } } // namespace v8::internal | 686 } } // namespace v8::internal |
870 | 687 |
871 #endif // V8_COMPILER_H_ | 688 #endif // V8_COMPILER_H_ |
OLD | NEW |