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_eval() const; |
| 137 bool is_native() const; |
| 138 bool is_module() const; |
| 139 bool this_has_uses() const; |
| 140 LanguageMode language_mode() const; |
| 141 Handle<JSFunction> closure() const; |
| 142 FunctionLiteral* function() const; |
| 143 Scope* scope() const; |
| 144 Handle<Context> context() const; |
| 145 Handle<SharedFunctionInfo> shared_info() const; |
| 146 bool has_shared_info() const; |
| 147 // ----------------------------------------------------------- |
| 148 |
178 Isolate* isolate() const { | 149 Isolate* isolate() const { |
179 return isolate_; | 150 return isolate_; |
180 } | 151 } |
181 Zone* zone() { return zone_; } | 152 Zone* zone() { return zone_; } |
182 bool is_osr() const { return !osr_ast_id_.IsNone(); } | 153 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_; } | 154 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_; } | 155 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_; } | 156 BailoutId osr_ast_id() const { return osr_ast_id_; } |
213 Handle<Code> unoptimized_code() const { return unoptimized_code_; } | 157 Handle<Code> unoptimized_code() const { return unoptimized_code_; } |
214 int opt_count() const { return opt_count_; } | 158 int opt_count() const { return opt_count_; } |
215 int num_parameters() const; | 159 int num_parameters() const; |
216 int num_heap_slots() const; | 160 int num_heap_slots() const; |
217 Code::Flags flags() const; | 161 Code::Flags flags() const; |
218 | 162 |
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) { | 163 void set_parameter_count(int parameter_count) { |
235 DCHECK(IsStub()); | 164 DCHECK(IsStub()); |
236 parameter_count_ = parameter_count; | 165 parameter_count_ = parameter_count; |
237 } | 166 } |
238 | 167 |
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 { | 168 bool is_calling() const { |
256 return GetFlag(kDeferredCalling) || GetFlag(kNonDeferredCalling); | 169 return GetFlag(kDeferredCalling) || GetFlag(kNonDeferredCalling); |
257 } | 170 } |
258 | 171 |
259 void MarkAsDeferredCalling() { SetFlag(kDeferredCalling); } | 172 void MarkAsDeferredCalling() { SetFlag(kDeferredCalling); } |
260 | 173 |
261 bool is_deferred_calling() const { return GetFlag(kDeferredCalling); } | 174 bool is_deferred_calling() const { return GetFlag(kDeferredCalling); } |
262 | 175 |
263 void MarkAsNonDeferredCalling() { SetFlag(kNonDeferredCalling); } | 176 void MarkAsNonDeferredCalling() { SetFlag(kNonDeferredCalling); } |
264 | 177 |
(...skipping 26 matching lines...) Expand all Loading... |
291 bool is_context_specializing() const { return GetFlag(kContextSpecializing); } | 204 bool is_context_specializing() const { return GetFlag(kContextSpecializing); } |
292 | 205 |
293 void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); } | 206 void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); } |
294 | 207 |
295 bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); } | 208 bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); } |
296 | 209 |
297 void MarkAsTypingEnabled() { SetFlag(kTypingEnabled); } | 210 void MarkAsTypingEnabled() { SetFlag(kTypingEnabled); } |
298 | 211 |
299 bool is_typing_enabled() const { return GetFlag(kTypingEnabled); } | 212 bool is_typing_enabled() const { return GetFlag(kTypingEnabled); } |
300 | 213 |
301 void MarkAsToplevel() { SetFlag(kToplevel); } | |
302 | |
303 bool is_toplevel() const { return GetFlag(kToplevel); } | |
304 | |
305 void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); } | 214 void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); } |
306 | 215 |
307 bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); } | 216 bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); } |
308 | 217 |
309 bool IsCodePreAgingActive() const { | 218 bool IsCodePreAgingActive() const { |
310 return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() && | 219 return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() && |
311 !is_debug(); | 220 !is_debug(); |
312 } | 221 } |
313 | 222 |
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(); | 223 void EnsureFeedbackVector(); |
333 Handle<TypeFeedbackVector> feedback_vector() const { | 224 Handle<TypeFeedbackVector> feedback_vector() const { |
334 return feedback_vector_; | 225 return feedback_vector_; |
335 } | 226 } |
336 void SetCode(Handle<Code> code) { code_ = code; } | 227 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 | 228 |
355 void MarkCompilingForDebugging() { SetFlag(kCompilingForDebugging); } | 229 void MarkCompilingForDebugging() { SetFlag(kCompilingForDebugging); } |
356 bool IsCompilingForDebugging() { return GetFlag(kCompilingForDebugging); } | 230 bool IsCompilingForDebugging() { return GetFlag(kCompilingForDebugging); } |
357 void MarkNonOptimizable() { | 231 void MarkNonOptimizable() { |
358 SetMode(CompilationInfo::NONOPT); | 232 SetMode(CompilationInfo::NONOPT); |
359 } | 233 } |
360 | 234 |
361 bool ShouldTrapOnDeopt() const { | 235 bool ShouldTrapOnDeopt() const { |
362 return (FLAG_trap_on_deopt && IsOptimizing()) || | 236 return (FLAG_trap_on_deopt && IsOptimizing()) || |
363 (FLAG_trap_on_stub_deopt && IsStub()); | 237 (FLAG_trap_on_stub_deopt && IsStub()); |
364 } | 238 } |
365 | 239 |
366 bool has_global_object() const { | 240 bool has_global_object() const { |
367 return !closure().is_null() && | 241 return !closure().is_null() && |
368 (closure()->context()->global_object() != NULL); | 242 (closure()->context()->global_object() != NULL); |
369 } | 243 } |
370 | 244 |
371 GlobalObject* global_object() const { | 245 GlobalObject* global_object() const { |
372 return has_global_object() ? closure()->context()->global_object() : NULL; | 246 return has_global_object() ? closure()->context()->global_object() : NULL; |
373 } | 247 } |
374 | 248 |
375 // Accessors for the different compilation modes. | 249 // Accessors for the different compilation modes. |
376 bool IsOptimizing() const { return mode_ == OPTIMIZE; } | 250 bool IsOptimizing() const { return mode_ == OPTIMIZE; } |
377 bool IsOptimizable() const { return mode_ == BASE; } | 251 bool IsOptimizable() const { return mode_ == BASE; } |
378 bool IsStub() const { return mode_ == STUB; } | 252 bool IsStub() const { return mode_ == STUB; } |
379 void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) { | 253 void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) { |
380 DCHECK(!shared_info_.is_null()); | 254 DCHECK(!shared_info().is_null()); |
381 SetMode(OPTIMIZE); | 255 SetMode(OPTIMIZE); |
382 osr_ast_id_ = osr_ast_id; | 256 osr_ast_id_ = osr_ast_id; |
383 unoptimized_code_ = unoptimized; | 257 unoptimized_code_ = unoptimized; |
384 optimization_id_ = isolate()->NextOptimizationId(); | 258 optimization_id_ = isolate()->NextOptimizationId(); |
385 } | 259 } |
386 | 260 |
387 // Deoptimization support. | 261 // Deoptimization support. |
388 bool HasDeoptimizationSupport() const { | 262 bool HasDeoptimizationSupport() const { |
389 return GetFlag(kDeoptimizationSupport); | 263 return GetFlag(kDeoptimizationSupport); |
390 } | 264 } |
(...skipping 15 matching lines...) Expand all Loading... |
406 if (dependencies_[group] == NULL) { | 280 if (dependencies_[group] == NULL) { |
407 dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_); | 281 dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_); |
408 } | 282 } |
409 return dependencies_[group]; | 283 return dependencies_[group]; |
410 } | 284 } |
411 | 285 |
412 void CommitDependencies(Handle<Code> code); | 286 void CommitDependencies(Handle<Code> code); |
413 | 287 |
414 void RollbackDependencies(); | 288 void RollbackDependencies(); |
415 | 289 |
416 void SaveHandles() { | 290 void ReopenHandlesInNewHandleScope() { |
417 SaveHandle(&closure_); | 291 unoptimized_code_ = Handle<Code>(*unoptimized_code_); |
418 SaveHandle(&shared_info_); | |
419 SaveHandle(&context_); | |
420 SaveHandle(&script_); | |
421 SaveHandle(&unoptimized_code_); | |
422 } | 292 } |
423 | 293 |
424 void AbortOptimization(BailoutReason reason) { | 294 void AbortOptimization(BailoutReason reason) { |
425 DCHECK(reason != kNoReason); | 295 DCHECK(reason != kNoReason); |
426 if (bailout_reason_ == kNoReason) bailout_reason_ = reason; | 296 if (bailout_reason_ == kNoReason) bailout_reason_ = reason; |
427 SetFlag(kDisableFutureOptimization); | 297 SetFlag(kDisableFutureOptimization); |
428 } | 298 } |
429 | 299 |
430 void RetryOptimization(BailoutReason reason) { | 300 void RetryOptimization(BailoutReason reason) { |
431 DCHECK(reason != kNoReason); | 301 DCHECK(reason != kNoReason); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); | 349 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); |
480 aborted_due_to_dependency_change_ = true; | 350 aborted_due_to_dependency_change_ = true; |
481 } | 351 } |
482 | 352 |
483 bool HasAbortedDueToDependencyChange() const { | 353 bool HasAbortedDueToDependencyChange() const { |
484 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); | 354 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); |
485 return aborted_due_to_dependency_change_; | 355 return aborted_due_to_dependency_change_; |
486 } | 356 } |
487 | 357 |
488 bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) { | 358 bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) { |
489 return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure_); | 359 return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure()); |
490 } | 360 } |
491 | 361 |
492 int optimization_id() const { return optimization_id_; } | 362 int optimization_id() const { return optimization_id_; } |
493 | 363 |
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_; } | 364 int osr_expr_stack_height() { return osr_expr_stack_height_; } |
502 void set_osr_expr_stack_height(int height) { | 365 void set_osr_expr_stack_height(int height) { |
503 DCHECK(height >= 0); | 366 DCHECK(height >= 0); |
504 osr_expr_stack_height_ = height; | 367 osr_expr_stack_height_ = height; |
505 } | 368 } |
506 | 369 |
507 #if DEBUG | 370 #if DEBUG |
508 void PrintAstForTesting(); | 371 void PrintAstForTesting(); |
509 #endif | 372 #endif |
510 | 373 |
511 bool is_simple_parameter_list(); | 374 bool is_simple_parameter_list(); |
512 | 375 |
513 protected: | 376 protected: |
514 CompilationInfo(Handle<SharedFunctionInfo> shared_info, | 377 ParseInfo* parse_info_; |
515 Zone* zone); | |
516 CompilationInfo(ScriptCompiler::ExternalSourceStream* source_stream, | |
517 ScriptCompiler::StreamedSource::Encoding encoding, | |
518 Isolate* isolate, Zone* zone); | |
519 | 378 |
| 379 void DisableFutureOptimization() { |
| 380 if (GetFlag(kDisableFutureOptimization) && has_shared_info()) { |
| 381 shared_info()->DisableOptimization(bailout_reason()); |
| 382 } |
| 383 } |
520 | 384 |
521 private: | 385 private: |
522 Isolate* isolate_; | 386 Isolate* isolate_; |
523 | 387 |
524 // Compilation mode. | 388 // Compilation mode. |
525 // BASE is generated by the full codegen, optionally prepared for bailouts. | 389 // BASE is generated by the full codegen, optionally prepared for bailouts. |
526 // OPTIMIZE is optimized code generated by the Hydrogen-based backend. | 390 // OPTIMIZE is optimized code generated by the Hydrogen-based backend. |
527 // NONOPT is generated by the full codegen and is not prepared for | 391 // NONOPT is generated by the full codegen and is not prepared for |
528 // recompilation/bailouts. These functions are never recompiled. | 392 // recompilation/bailouts. These functions are never recompiled. |
529 enum Mode { | 393 enum Mode { |
(...skipping 12 matching lines...) Expand all Loading... |
542 void SetFlag(Flag flag) { flags_ |= flag; } | 406 void SetFlag(Flag flag) { flags_ |= flag; } |
543 | 407 |
544 void SetFlag(Flag flag, bool value) { | 408 void SetFlag(Flag flag, bool value) { |
545 flags_ = value ? flags_ | flag : flags_ & ~flag; | 409 flags_ = value ? flags_ | flag : flags_ & ~flag; |
546 } | 410 } |
547 | 411 |
548 bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; } | 412 bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; } |
549 | 413 |
550 unsigned flags_; | 414 unsigned flags_; |
551 | 415 |
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 | 416 // For compiled stubs, the stub object |
561 CodeStub* code_stub_; | 417 CodeStub* code_stub_; |
562 // The compiled code. | 418 // The compiled code. |
563 Handle<Code> code_; | 419 Handle<Code> code_; |
564 | 420 |
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. | 421 // Used by codegen, ultimately kept rooted by the SharedFunctionInfo. |
582 Handle<TypeFeedbackVector> feedback_vector_; | 422 Handle<TypeFeedbackVector> feedback_vector_; |
583 | 423 |
584 // Compilation mode flag and whether deoptimization is allowed. | 424 // Compilation mode flag and whether deoptimization is allowed. |
585 Mode mode_; | 425 Mode mode_; |
586 BailoutId osr_ast_id_; | 426 BailoutId osr_ast_id_; |
587 // The unoptimized code we patched for OSR may not be the shared code | 427 // 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 | 428 // afterwards, since we may need to compile it again to include deoptimization |
589 // data. Keep track which code we patched. | 429 // data. Keep track which code we patched. |
590 Handle<Code> unoptimized_code_; | 430 Handle<Code> unoptimized_code_; |
591 | 431 |
592 // The zone from which the compilation pipeline working on this | 432 // The zone from which the compilation pipeline working on this |
593 // CompilationInfo allocates. | 433 // CompilationInfo allocates. |
594 Zone* zone_; | 434 Zone* zone_; |
595 | 435 |
596 DeferredHandles* deferred_handles_; | 436 DeferredHandles* deferred_handles_; |
597 | 437 |
598 ZoneList<Handle<HeapObject> >* dependencies_[DependentCode::kGroupCount]; | 438 ZoneList<Handle<HeapObject> >* dependencies_[DependentCode::kGroupCount]; |
599 | 439 |
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_; | 440 BailoutReason bailout_reason_; |
609 | 441 |
610 int prologue_offset_; | 442 int prologue_offset_; |
611 | 443 |
612 List<OffsetRange>* no_frame_ranges_; | 444 List<OffsetRange>* no_frame_ranges_; |
613 List<InlinedFunctionInfo>* inlined_function_infos_; | 445 List<InlinedFunctionInfo>* inlined_function_infos_; |
614 List<int>* inlining_id_to_function_id_; | 446 List<int>* inlining_id_to_function_id_; |
615 | 447 |
616 // A copy of shared_info()->opt_count() to avoid handle deref | 448 // A copy of shared_info()->opt_count() to avoid handle deref |
617 // during graph optimization. | 449 // during graph optimization. |
618 int opt_count_; | 450 int opt_count_; |
619 | 451 |
620 // Number of parameters used for compilation of stubs that require arguments. | 452 // Number of parameters used for compilation of stubs that require arguments. |
621 int parameter_count_; | 453 int parameter_count_; |
622 | 454 |
623 Handle<Foreign> object_wrapper_; | 455 Handle<Foreign> object_wrapper_; |
624 | 456 |
625 int optimization_id_; | 457 int optimization_id_; |
626 | 458 |
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 | 459 // This flag is used by the main thread to track whether this compilation |
631 // should be abandoned due to dependency change. | 460 // should be abandoned due to dependency change. |
632 bool aborted_due_to_dependency_change_; | 461 bool aborted_due_to_dependency_change_; |
633 | 462 |
634 int osr_expr_stack_height_; | 463 int osr_expr_stack_height_; |
635 | 464 |
636 DISALLOW_COPY_AND_ASSIGN(CompilationInfo); | 465 DISALLOW_COPY_AND_ASSIGN(CompilationInfo); |
637 }; | 466 }; |
638 | 467 |
639 | 468 |
640 // Exactly like a CompilationInfo, except also creates and enters a | 469 // Exactly like a CompilationInfo, except also creates and enters a |
641 // Zone on construction and deallocates it on exit. | 470 // Zone on construction and deallocates it on exit. |
642 class CompilationInfoWithZone: public CompilationInfo { | 471 class CompilationInfoWithZone: public CompilationInfo { |
643 public: | 472 public: |
644 explicit CompilationInfoWithZone(Handle<Script> script) | 473 explicit CompilationInfoWithZone(Handle<Script> script); |
645 : CompilationInfo(script, &zone_) {} | 474 explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info); |
646 explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info) | 475 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) | 476 CompilationInfoWithZone(CodeStub* stub, Isolate* isolate) |
651 : CompilationInfo(stub, isolate, &zone_) {} | 477 : CompilationInfo(stub, isolate, &zone_) {} |
652 CompilationInfoWithZone(ScriptCompiler::ExternalSourceStream* stream, | |
653 ScriptCompiler::StreamedSource::Encoding encoding, | |
654 Isolate* isolate) | |
655 : CompilationInfo(stream, encoding, isolate, &zone_) {} | |
656 | 478 |
657 // Virtual destructor because a CompilationInfoWithZone has to exit the | 479 // Virtual destructor because a CompilationInfoWithZone has to exit the |
658 // zone scope and get rid of dependent maps even when the destructor is | 480 // zone scope and get rid of dependent maps even when the destructor is |
659 // called when cast as a CompilationInfo. | 481 // called when cast as a CompilationInfo. |
660 virtual ~CompilationInfoWithZone() { | 482 virtual ~CompilationInfoWithZone(); |
661 RollbackDependencies(); | |
662 } | |
663 | 483 |
664 private: | 484 private: |
665 Zone zone_; | 485 Zone zone_; |
666 }; | 486 }; |
667 | 487 |
668 | |
669 // A wrapper around a CompilationInfo that detaches the Handles from | 488 // A wrapper around a CompilationInfo that detaches the Handles from |
670 // the underlying DeferredHandleScope and stores them in info_ on | 489 // the underlying DeferredHandleScope and stores them in info_ on |
671 // destruction. | 490 // destruction. |
672 class CompilationHandleScope BASE_EMBEDDED { | 491 class CompilationHandleScope BASE_EMBEDDED { |
673 public: | 492 public: |
674 explicit CompilationHandleScope(CompilationInfo* info) | 493 explicit CompilationHandleScope(CompilationInfo* info) |
675 : deferred_(info->isolate()), info_(info) {} | 494 : deferred_(info->isolate()), info_(info) {} |
676 ~CompilationHandleScope() { | 495 ~CompilationHandleScope() { |
677 info_->set_deferred_handles(deferred_.Detach()); | 496 info_->set_deferred_handles(deferred_.Detach()); |
678 } | 497 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode( | 602 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode( |
784 Handle<JSFunction> function); | 603 Handle<JSFunction> function); |
785 MUST_USE_RESULT static MaybeHandle<Code> GetLazyCode( | 604 MUST_USE_RESULT static MaybeHandle<Code> GetLazyCode( |
786 Handle<JSFunction> function); | 605 Handle<JSFunction> function); |
787 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode( | 606 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode( |
788 Handle<SharedFunctionInfo> shared); | 607 Handle<SharedFunctionInfo> shared); |
789 MUST_USE_RESULT static MaybeHandle<Code> GetDebugCode( | 608 MUST_USE_RESULT static MaybeHandle<Code> GetDebugCode( |
790 Handle<JSFunction> function); | 609 Handle<JSFunction> function); |
791 | 610 |
792 // Parser::Parse, then Compiler::Analyze. | 611 // Parser::Parse, then Compiler::Analyze. |
793 static bool ParseAndAnalyze(CompilationInfo* info); | 612 static bool ParseAndAnalyze(ParseInfo* info); |
794 // Rewrite, analyze scopes, and renumber. | 613 // Rewrite, analyze scopes, and renumber. |
795 static bool Analyze(CompilationInfo* info); | 614 static bool Analyze(ParseInfo* info); |
796 // Adds deoptimization support, requires ParseAndAnalyze. | 615 // Adds deoptimization support, requires ParseAndAnalyze. |
797 static bool EnsureDeoptimizationSupport(CompilationInfo* info); | 616 static bool EnsureDeoptimizationSupport(CompilationInfo* info); |
798 | 617 |
799 static bool EnsureCompiled(Handle<JSFunction> function, | 618 static bool EnsureCompiled(Handle<JSFunction> function, |
800 ClearExceptionFlag flag); | 619 ClearExceptionFlag flag); |
801 | 620 |
802 static void CompileForLiveEdit(Handle<Script> script); | 621 static void CompileForLiveEdit(Handle<Script> script); |
803 | 622 |
804 // Compile a String source within a context for eval. | 623 // Compile a String source within a context for eval. |
805 MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval( | 624 MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval( |
806 Handle<String> source, Handle<SharedFunctionInfo> outer_info, | 625 Handle<String> source, Handle<SharedFunctionInfo> outer_info, |
807 Handle<Context> context, LanguageMode language_mode, | 626 Handle<Context> context, LanguageMode language_mode, |
808 ParseRestriction restriction, int scope_position); | 627 ParseRestriction restriction, int scope_position); |
809 | 628 |
810 // Compile a String source within a context. | 629 // Compile a String source within a context. |
811 static Handle<SharedFunctionInfo> CompileScript( | 630 static Handle<SharedFunctionInfo> CompileScript( |
812 Handle<String> source, Handle<Object> script_name, int line_offset, | 631 Handle<String> source, Handle<Object> script_name, int line_offset, |
813 int column_offset, bool is_debugger_script, bool is_shared_cross_origin, | 632 int column_offset, bool is_debugger_script, bool is_shared_cross_origin, |
814 Handle<Context> context, v8::Extension* extension, | 633 Handle<Context> context, v8::Extension* extension, |
815 ScriptData** cached_data, ScriptCompiler::CompileOptions compile_options, | 634 ScriptData** cached_data, ScriptCompiler::CompileOptions compile_options, |
816 NativesFlag is_natives_code, bool is_module); | 635 NativesFlag is_natives_code, bool is_module); |
817 | 636 |
818 static Handle<SharedFunctionInfo> CompileStreamedScript(CompilationInfo* info, | 637 static Handle<SharedFunctionInfo> CompileStreamedScript(Handle<Script> script, |
| 638 ParseInfo* info, |
819 int source_length); | 639 int source_length); |
820 | 640 |
821 // Create a shared function info object (the code may be lazily compiled). | 641 // Create a shared function info object (the code may be lazily compiled). |
822 static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node, | 642 static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node, |
823 Handle<Script> script, | 643 Handle<Script> script, |
824 CompilationInfo* outer); | 644 CompilationInfo* outer); |
825 | 645 |
826 enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT }; | 646 enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT }; |
827 | 647 |
828 // Generate and return optimized code or start a concurrent optimization job. | 648 // Generate and return optimized code or start a concurrent optimization job. |
829 // In the latter case, return the InOptimizationQueue builtin. On failure, | 649 // In the latter case, return the InOptimizationQueue builtin. On failure, |
830 // return the empty handle. | 650 // return the empty handle. |
831 MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCode( | 651 MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCode( |
832 Handle<JSFunction> function, | 652 Handle<JSFunction> function, |
833 Handle<Code> current_code, | 653 Handle<Code> current_code, |
834 ConcurrencyMode mode, | 654 ConcurrencyMode mode, |
835 BailoutId osr_ast_id = BailoutId::None()); | 655 BailoutId osr_ast_id = BailoutId::None()); |
836 | 656 |
837 // Generate and return code from previously queued optimization job. | 657 // Generate and return code from previously queued optimization job. |
838 // On failure, return the empty handle. | 658 // On failure, return the empty handle. |
839 static Handle<Code> GetConcurrentlyOptimizedCode(OptimizedCompileJob* job); | 659 static Handle<Code> GetConcurrentlyOptimizedCode(OptimizedCompileJob* job); |
840 | 660 |
| 661 // TODO(titzer): move this method out of the compiler. |
841 static bool DebuggerWantsEagerCompilation( | 662 static bool DebuggerWantsEagerCompilation( |
842 CompilationInfo* info, bool allow_lazy_without_ctx = false); | 663 Isolate* isolate, bool allow_lazy_without_ctx = false); |
843 }; | 664 }; |
844 | 665 |
845 | 666 |
846 class CompilationPhase BASE_EMBEDDED { | 667 class CompilationPhase BASE_EMBEDDED { |
847 public: | 668 public: |
848 CompilationPhase(const char* name, CompilationInfo* info); | 669 CompilationPhase(const char* name, CompilationInfo* info); |
849 ~CompilationPhase(); | 670 ~CompilationPhase(); |
850 | 671 |
851 protected: | 672 protected: |
852 bool ShouldProduceTraceOutput() const; | 673 bool ShouldProduceTraceOutput() const; |
853 | 674 |
854 const char* name() const { return name_; } | 675 const char* name() const { return name_; } |
855 CompilationInfo* info() const { return info_; } | 676 CompilationInfo* info() const { return info_; } |
856 Isolate* isolate() const { return info()->isolate(); } | 677 Isolate* isolate() const { return info()->isolate(); } |
857 Zone* zone() { return &zone_; } | 678 Zone* zone() { return &zone_; } |
858 | 679 |
859 private: | 680 private: |
860 const char* name_; | 681 const char* name_; |
861 CompilationInfo* info_; | 682 CompilationInfo* info_; |
862 Zone zone_; | 683 Zone zone_; |
863 size_t info_zone_start_allocation_size_; | 684 size_t info_zone_start_allocation_size_; |
864 base::ElapsedTimer timer_; | 685 base::ElapsedTimer timer_; |
865 | 686 |
866 DISALLOW_COPY_AND_ASSIGN(CompilationPhase); | 687 DISALLOW_COPY_AND_ASSIGN(CompilationPhase); |
867 }; | 688 }; |
868 | 689 |
869 } } // namespace v8::internal | 690 } } // namespace v8::internal |
870 | 691 |
871 #endif // V8_COMPILER_H_ | 692 #endif // V8_COMPILER_H_ |
OLD | NEW |