Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(365)

Side by Side Diff: src/compiler.h

Issue 110203002: Refactor the compiling pipeline. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: move some code Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 Scope* global_scope() const { return global_scope_; } 77 Scope* global_scope() const { return global_scope_; }
78 Handle<Code> code() const { return code_; } 78 Handle<Code> code() const { return code_; }
79 Handle<JSFunction> closure() const { return closure_; } 79 Handle<JSFunction> closure() const { return closure_; }
80 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } 80 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
81 Handle<Script> script() const { return script_; } 81 Handle<Script> script() const { return script_; }
82 HydrogenCodeStub* code_stub() const {return code_stub_; } 82 HydrogenCodeStub* code_stub() const {return code_stub_; }
83 v8::Extension* extension() const { return extension_; } 83 v8::Extension* extension() const { return extension_; }
84 ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; } 84 ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
85 Handle<Context> context() const { return context_; } 85 Handle<Context> context() const { return context_; }
86 BailoutId osr_ast_id() const { return osr_ast_id_; } 86 BailoutId osr_ast_id() const { return osr_ast_id_; }
87 uint32_t osr_pc_offset() const { return osr_pc_offset_; } 87 Handle<Code> unoptimized_code() const { return unoptimized_code_; }
88 Handle<Code> osr_patched_code() const { return osr_patched_code_; }
89 int opt_count() const { return opt_count_; } 88 int opt_count() const { return opt_count_; }
90 int num_parameters() const; 89 int num_parameters() const;
91 int num_heap_slots() const; 90 int num_heap_slots() const;
92 Code::Flags flags() const; 91 Code::Flags flags() const;
93 92
94 void MarkAsEval() { 93 void MarkAsEval() {
95 ASSERT(!is_lazy()); 94 ASSERT(!is_lazy());
96 flags_ |= IsEval::encode(true); 95 flags_ |= IsEval::encode(true);
97 } 96 }
98 void MarkAsGlobal() { 97 void MarkAsGlobal() {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 ASSERT(!is_lazy()); 181 ASSERT(!is_lazy());
183 extension_ = extension; 182 extension_ = extension;
184 } 183 }
185 void SetPreParseData(ScriptDataImpl* pre_parse_data) { 184 void SetPreParseData(ScriptDataImpl* pre_parse_data) {
186 ASSERT(!is_lazy()); 185 ASSERT(!is_lazy());
187 pre_parse_data_ = pre_parse_data; 186 pre_parse_data_ = pre_parse_data;
188 } 187 }
189 void SetContext(Handle<Context> context) { 188 void SetContext(Handle<Context> context) {
190 context_ = context; 189 context_ = context;
191 } 190 }
192 void MarkCompilingForDebugging(Handle<Code> current_code) { 191
193 ASSERT(mode_ != OPTIMIZE); 192 void MarkCompilingForDebugging() {
194 ASSERT(current_code->kind() == Code::FUNCTION);
195 flags_ |= IsCompilingForDebugging::encode(true); 193 flags_ |= IsCompilingForDebugging::encode(true);
196 if (current_code->is_compiled_optimizable()) {
197 EnableDeoptimizationSupport();
198 } else {
199 mode_ = CompilationInfo::NONOPT;
200 }
201 } 194 }
202 bool IsCompilingForDebugging() { 195 bool IsCompilingForDebugging() {
203 return IsCompilingForDebugging::decode(flags_); 196 return IsCompilingForDebugging::decode(flags_);
204 } 197 }
198 void MarkNonOptimizable() {
199 SetMode(CompilationInfo::NONOPT);
200 }
205 201
206 bool ShouldTrapOnDeopt() const { 202 bool ShouldTrapOnDeopt() const {
207 return (FLAG_trap_on_deopt && IsOptimizing()) || 203 return (FLAG_trap_on_deopt && IsOptimizing()) ||
208 (FLAG_trap_on_stub_deopt && IsStub()); 204 (FLAG_trap_on_stub_deopt && IsStub());
209 } 205 }
210 206
211 bool has_global_object() const { 207 bool has_global_object() const {
212 return !closure().is_null() && 208 return !closure().is_null() &&
213 (closure()->context()->global_object() != NULL); 209 (closure()->context()->global_object() != NULL);
214 } 210 }
215 211
216 GlobalObject* global_object() const { 212 GlobalObject* global_object() const {
217 return has_global_object() ? closure()->context()->global_object() : NULL; 213 return has_global_object() ? closure()->context()->global_object() : NULL;
218 } 214 }
219 215
220 // Accessors for the different compilation modes. 216 // Accessors for the different compilation modes.
221 bool IsOptimizing() const { return mode_ == OPTIMIZE; } 217 bool IsOptimizing() const { return mode_ == OPTIMIZE; }
222 bool IsOptimizable() const { return mode_ == BASE; } 218 bool IsOptimizable() const { return mode_ == BASE; }
223 bool IsStub() const { return mode_ == STUB; } 219 bool IsStub() const { return mode_ == STUB; }
224 void SetOptimizing(BailoutId osr_ast_id) { 220 void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) {
221 ASSERT(!shared_info_.is_null());
225 SetMode(OPTIMIZE); 222 SetMode(OPTIMIZE);
226 osr_ast_id_ = osr_ast_id; 223 osr_ast_id_ = osr_ast_id;
224 unoptimized_code_ = unoptimized;
227 } 225 }
228 void DisableOptimization(); 226 void DisableOptimization();
229 227
230 // Deoptimization support. 228 // Deoptimization support.
231 bool HasDeoptimizationSupport() const { 229 bool HasDeoptimizationSupport() const {
232 return SupportsDeoptimization::decode(flags_); 230 return SupportsDeoptimization::decode(flags_);
233 } 231 }
234 void EnableDeoptimizationSupport() { 232 void EnableDeoptimizationSupport() {
235 ASSERT(IsOptimizable()); 233 ASSERT(IsOptimizable());
236 flags_ |= SupportsDeoptimization::encode(true); 234 flags_ |= SupportsDeoptimization::encode(true);
237 } 235 }
238 236
239 // Determines whether or not to insert a self-optimization header. 237 // Determines whether or not to insert a self-optimization header.
240 bool ShouldSelfOptimize(); 238 bool ShouldSelfOptimize();
241 239
242 // Reset code to the unoptimized version when optimization is aborted.
243 void AbortOptimization() {
244 SetCode(handle(shared_info()->code()));
245 }
246
247 void set_deferred_handles(DeferredHandles* deferred_handles) { 240 void set_deferred_handles(DeferredHandles* deferred_handles) {
248 ASSERT(deferred_handles_ == NULL); 241 ASSERT(deferred_handles_ == NULL);
249 deferred_handles_ = deferred_handles; 242 deferred_handles_ = deferred_handles;
250 } 243 }
251 244
252 ZoneList<Handle<HeapObject> >* dependencies( 245 ZoneList<Handle<HeapObject> >* dependencies(
253 DependentCode::DependencyGroup group) { 246 DependentCode::DependencyGroup group) {
254 if (dependencies_[group] == NULL) { 247 if (dependencies_[group] == NULL) {
255 dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_); 248 dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_);
256 } 249 }
257 return dependencies_[group]; 250 return dependencies_[group];
258 } 251 }
259 252
260 void CommitDependencies(Handle<Code> code); 253 void CommitDependencies(Handle<Code> code);
261 254
262 void RollbackDependencies(); 255 void RollbackDependencies();
263 256
264 void SaveHandles() { 257 void SaveHandles() {
265 SaveHandle(&closure_); 258 SaveHandle(&closure_);
266 SaveHandle(&shared_info_); 259 SaveHandle(&shared_info_);
267 SaveHandle(&context_); 260 SaveHandle(&context_);
268 SaveHandle(&script_); 261 SaveHandle(&script_);
269 SaveHandle(&osr_patched_code_); 262 SaveHandle(&unoptimized_code_);
270 } 263 }
271 264
272 BailoutReason bailout_reason() const { return bailout_reason_; } 265 BailoutReason bailout_reason() const { return bailout_reason_; }
273 void set_bailout_reason(BailoutReason reason) { bailout_reason_ = reason; } 266 void set_bailout_reason(BailoutReason reason) { bailout_reason_ = reason; }
274 267
275 int prologue_offset() const { 268 int prologue_offset() const {
276 ASSERT_NE(Code::kPrologueOffsetNotSet, prologue_offset_); 269 ASSERT_NE(Code::kPrologueOffsetNotSet, prologue_offset_);
277 return prologue_offset_; 270 return prologue_offset_;
278 } 271 }
279 272
(...skipping 26 matching lines...) Expand all
306 void AbortDueToDependencyChange() { 299 void AbortDueToDependencyChange() {
307 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate())); 300 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate()));
308 abort_due_to_dependency_ = true; 301 abort_due_to_dependency_ = true;
309 } 302 }
310 303
311 bool HasAbortedDueToDependencyChange() { 304 bool HasAbortedDueToDependencyChange() {
312 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate())); 305 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate()));
313 return abort_due_to_dependency_; 306 return abort_due_to_dependency_;
314 } 307 }
315 308
316 void SetOsrInfo(Handle<Code> code, uint32_t pc_offset) { 309 bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) {
317 osr_patched_code_ = code; 310 return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure_);
318 osr_pc_offset_ = pc_offset;
319 }
320
321 bool HasSameOsrEntry(Handle<JSFunction> function, uint32_t pc_offset) {
322 return osr_pc_offset_ == pc_offset && function.is_identical_to(closure_);
323 } 311 }
324 312
325 protected: 313 protected:
326 CompilationInfo(Handle<Script> script, 314 CompilationInfo(Handle<Script> script,
327 Zone* zone); 315 Zone* zone);
328 CompilationInfo(Handle<SharedFunctionInfo> shared_info, 316 CompilationInfo(Handle<SharedFunctionInfo> shared_info,
329 Zone* zone); 317 Zone* zone);
330 CompilationInfo(HydrogenCodeStub* stub, 318 CompilationInfo(HydrogenCodeStub* stub,
331 Isolate* isolate, 319 Isolate* isolate,
332 Zone* zone); 320 Zone* zone);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 v8::Extension* extension_; 397 v8::Extension* extension_;
410 ScriptDataImpl* pre_parse_data_; 398 ScriptDataImpl* pre_parse_data_;
411 399
412 // The context of the caller for eval code, and the global context for a 400 // The context of the caller for eval code, and the global context for a
413 // global script. Will be a null handle otherwise. 401 // global script. Will be a null handle otherwise.
414 Handle<Context> context_; 402 Handle<Context> context_;
415 403
416 // Compilation mode flag and whether deoptimization is allowed. 404 // Compilation mode flag and whether deoptimization is allowed.
417 Mode mode_; 405 Mode mode_;
418 BailoutId osr_ast_id_; 406 BailoutId osr_ast_id_;
419 // The pc_offset corresponding to osr_ast_id_ in unoptimized code.
420 // We can look this up in the back edge table, but cache it for quick access.
421 uint32_t osr_pc_offset_;
422 // The unoptimized code we patched for OSR may not be the shared code 407 // The unoptimized code we patched for OSR may not be the shared code
423 // afterwards, since we may need to compile it again to include deoptimization 408 // afterwards, since we may need to compile it again to include deoptimization
424 // data. Keep track which code we patched. 409 // data. Keep track which code we patched.
425 Handle<Code> osr_patched_code_; 410 Handle<Code> unoptimized_code_;
426 411
427 // Flag whether compilation needs to be aborted due to dependency change. 412 // Flag whether compilation needs to be aborted due to dependency change.
428 bool abort_due_to_dependency_; 413 bool abort_due_to_dependency_;
429 414
430 // The zone from which the compilation pipeline working on this 415 // The zone from which the compilation pipeline working on this
431 // CompilationInfo allocates. 416 // CompilationInfo allocates.
432 Zone* zone_; 417 Zone* zone_;
433 418
434 DeferredHandles* deferred_handles_; 419 DeferredHandles* deferred_handles_;
435 420
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 class HGraph; 496 class HGraph;
512 class HOptimizedGraphBuilder; 497 class HOptimizedGraphBuilder;
513 class LChunk; 498 class LChunk;
514 499
515 // A helper class that calls the three compilation phases in 500 // A helper class that calls the three compilation phases in
516 // Crankshaft and keeps track of its state. The three phases 501 // Crankshaft and keeps track of its state. The three phases
517 // CreateGraph, OptimizeGraph and GenerateAndInstallCode can either 502 // CreateGraph, OptimizeGraph and GenerateAndInstallCode can either
518 // fail, bail-out to the full code generator or succeed. Apart from 503 // fail, bail-out to the full code generator or succeed. Apart from
519 // their return value, the status of the phase last run can be checked 504 // their return value, the status of the phase last run can be checked
520 // using last_status(). 505 // using last_status().
521 class RecompileJob: public ZoneObject { 506 class RecompileJob: public ZoneObject {
titzer 2013/12/09 14:49:28 Probably want to rename this class as well. Maybe
Yang 2013/12/10 11:22:04 Done.
522 public: 507 public:
523 explicit RecompileJob(CompilationInfo* info) 508 explicit RecompileJob(CompilationInfo* info)
524 : info_(info), 509 : info_(info),
525 graph_builder_(NULL), 510 graph_builder_(NULL),
526 graph_(NULL), 511 graph_(NULL),
527 chunk_(NULL), 512 chunk_(NULL),
528 last_status_(FAILED), 513 last_status_(FAILED),
529 awaiting_install_(false) { } 514 awaiting_install_(false) { }
530 515
531 enum Status { 516 enum Status {
532 FAILED, BAILED_OUT, SUCCEEDED 517 FAILED, BAILED_OUT, SUCCEEDED
533 }; 518 };
534 519
535 MUST_USE_RESULT Status CreateGraph(); 520 MUST_USE_RESULT Status CreateGraph();
536 MUST_USE_RESULT Status OptimizeGraph(); 521 MUST_USE_RESULT Status OptimizeGraph();
537 MUST_USE_RESULT Status GenerateAndInstallCode(); 522 MUST_USE_RESULT Status GenerateCode();
538 523
539 Status last_status() const { return last_status_; } 524 Status last_status() const { return last_status_; }
540 CompilationInfo* info() const { return info_; } 525 CompilationInfo* info() const { return info_; }
541 Isolate* isolate() const { return info()->isolate(); } 526 Isolate* isolate() const { return info()->isolate(); }
542 527
543 MUST_USE_RESULT Status AbortOptimization() { 528 MUST_USE_RESULT Status AbortOptimization() {
544 info_->AbortOptimization(); 529 return SetLastStatus(BAILED_OUT);
530 }
531
532 MUST_USE_RESULT Status AbortAndDisableOptimization() {
545 info_->shared_info()->DisableOptimization(info_->bailout_reason()); 533 info_->shared_info()->DisableOptimization(info_->bailout_reason());
546 return SetLastStatus(BAILED_OUT); 534 return SetLastStatus(BAILED_OUT);
547 } 535 }
548 536
549 void WaitForInstall() { 537 void WaitForInstall() {
550 ASSERT(info_->is_osr()); 538 ASSERT(info_->is_osr());
551 awaiting_install_ = true; 539 awaiting_install_ = true;
552 } 540 }
553 541
554 bool IsWaitingForInstall() { return awaiting_install_; } 542 bool IsWaitingForInstall() { return awaiting_install_; }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 // parameters which then can be executed. If the source code contains other 582 // parameters which then can be executed. If the source code contains other
595 // functions, they will be compiled and allocated as part of the compilation 583 // functions, they will be compiled and allocated as part of the compilation
596 // of the source code. 584 // of the source code.
597 585
598 // Please note this interface returns shared function infos. This means you 586 // Please note this interface returns shared function infos. This means you
599 // need to call Factory::NewFunctionFromSharedFunctionInfo before you have a 587 // need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
600 // real function with a context. 588 // real function with a context.
601 589
602 class Compiler : public AllStatic { 590 class Compiler : public AllStatic {
603 public: 591 public:
604 // Call count before primitive functions trigger their own optimization. 592 static Handle<Code> GetUnoptimizedCode(Handle<JSFunction> function);
605 static const int kCallsUntilPrimitiveOpt = 200; 593 static Handle<Code> GetUnoptimizedCode(Handle<SharedFunctionInfo> shared);
594 static bool EnsureCompiled(Handle<JSFunction> function,
595 ClearExceptionFlag flag);
596 static Handle<Code> GetCodeForDebugging(Handle<JSFunction> function);
606 597
607 // All routines return a SharedFunctionInfo. 598 #ifdef ENABLE_DEBUGGER_SUPPORT
608 // If an error occurs an exception is raised and the return handle 599 static void CompileForLiveEdit(Handle<Script> script);
609 // contains NULL. 600 #endif
610 601
611 // Compile a String source within a context. 602 // Compile a String source within a context for eval.
612 static Handle<SharedFunctionInfo> Compile(Handle<String> source, 603 static Handle<JSFunction> GetFunctionFromEval(Handle<String> source,
613 Handle<Object> script_name,
614 int line_offset,
615 int column_offset,
616 bool is_shared_cross_origin,
617 Handle<Context> context,
618 v8::Extension* extension,
619 ScriptDataImpl* pre_data,
620 Handle<Object> script_data,
621 NativesFlag is_natives_code);
622
623 // Compile a String source within a context for Eval.
624 static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
625 Handle<Context> context, 604 Handle<Context> context,
626 bool is_global,
627 LanguageMode language_mode, 605 LanguageMode language_mode,
628 ParseRestriction restriction, 606 ParseRestriction restriction,
629 int scope_position); 607 int scope_position);
630 608
631 // Compile from function info (used for lazy compilation). Returns true on 609 // Compile a String source within a context.
632 // success and false if the compilation resulted in a stack overflow. 610 static Handle<SharedFunctionInfo> CompileScript(Handle<String> source,
633 static bool CompileLazy(CompilationInfo* info); 611 Handle<Object> script_name,
612 int line_offset,
613 int column_offset,
614 bool is_shared_cross_origin,
615 Handle<Context> context,
616 v8::Extension* extension,
617 ScriptDataImpl* pre_data,
618 Handle<Object> script_data,
619 NativesFlag is_natives_code);
634 620
635 static bool RecompileConcurrent(Handle<JSFunction> function, 621 // Create a shared function info object (the code may be lazily compiled).
636 Handle<Code> unoptimized,
637 uint32_t osr_pc_offset = 0);
638
639 // Compile a shared function info object (the function is possibly lazily
640 // compiled).
641 static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node, 622 static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
642 Handle<Script> script); 623 Handle<Script> script);
643 624
644 // Set the function info for a newly compiled function. 625 enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT };
645 static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
646 FunctionLiteral* lit,
647 bool is_toplevel,
648 Handle<Script> script);
649 626
650 static Handle<Code> InstallOptimizedCode(RecompileJob* job); 627 static Handle<Code> GetOptimizedCode(
628 Handle<JSFunction> function,
629 Handle<Code> current_code,
630 ConcurrencyMode mode,
631 BailoutId osr_ast_id = BailoutId::None());
651 632
652 #ifdef ENABLE_DEBUGGER_SUPPORT 633 static Handle<Code> GetConcurrentlyOptimizedCode(RecompileJob* job);
653 static bool MakeCodeForLiveEdit(CompilationInfo* info);
654 #endif
655 634
656 static void RecordFunctionCompilation(Logger::LogEventsAndTags tag, 635 static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
657 CompilationInfo* info, 636 CompilationInfo* info,
658 Handle<SharedFunctionInfo> shared); 637 Handle<SharedFunctionInfo> shared);
659 }; 638 };
660 639
661 640
662 class CompilationPhase BASE_EMBEDDED { 641 class CompilationPhase BASE_EMBEDDED {
663 public: 642 public:
664 CompilationPhase(const char* name, CompilationInfo* info); 643 CompilationPhase(const char* name, CompilationInfo* info);
(...skipping 14 matching lines...) Expand all
679 unsigned info_zone_start_allocation_size_; 658 unsigned info_zone_start_allocation_size_;
680 ElapsedTimer timer_; 659 ElapsedTimer timer_;
681 660
682 DISALLOW_COPY_AND_ASSIGN(CompilationPhase); 661 DISALLOW_COPY_AND_ASSIGN(CompilationPhase);
683 }; 662 };
684 663
685 664
686 } } // namespace v8::internal 665 } } // namespace v8::internal
687 666
688 #endif // V8_COMPILER_H_ 667 #endif // V8_COMPILER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698