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