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

Side by Side Diff: runtime/vm/compiler.cc

Issue 16888013: Revert "Initial implementation of on-stack replacement (OSR)." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 6 months 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
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/flow_graph.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/compiler.h" 5 #include "vm/compiler.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 8
9 #include "vm/ast_printer.h" 9 #include "vm/ast_printer.h"
10 #include "vm/code_generator.h" 10 #include "vm/code_generator.h"
11 #include "vm/code_patcher.h" 11 #include "vm/code_patcher.h"
12 #include "vm/dart_entry.h" 12 #include "vm/dart_entry.h"
13 #include "vm/debugger.h" 13 #include "vm/debugger.h"
14 #include "vm/deopt_instructions.h" 14 #include "vm/deopt_instructions.h"
15 #include "vm/disassembler.h"
15 #include "vm/exceptions.h" 16 #include "vm/exceptions.h"
16 #include "vm/flags.h" 17 #include "vm/flags.h"
17 #include "vm/flow_graph.h" 18 #include "vm/flow_graph.h"
18 #include "vm/flow_graph_allocator.h" 19 #include "vm/flow_graph_allocator.h"
19 #include "vm/flow_graph_builder.h" 20 #include "vm/flow_graph_builder.h"
20 #include "vm/flow_graph_compiler.h" 21 #include "vm/flow_graph_compiler.h"
21 #include "vm/flow_graph_inliner.h" 22 #include "vm/flow_graph_inliner.h"
22 #include "vm/flow_graph_optimizer.h" 23 #include "vm/flow_graph_optimizer.h"
23 #include "vm/flow_graph_type_propagator.h" 24 #include "vm/flow_graph_type_propagator.h"
24 #include "vm/il_printer.h" 25 #include "vm/il_printer.h"
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 function.SwitchToUnoptimizedCode(); 234 function.SwitchToUnoptimizedCode();
234 if (FLAG_trace_compiler) { 235 if (FLAG_trace_compiler) {
235 OS::Print("--> restoring entry at %#"Px"\n", 236 OS::Print("--> restoring entry at %#"Px"\n",
236 Code::Handle(function.unoptimized_code()).EntryPoint()); 237 Code::Handle(function.unoptimized_code()).EntryPoint());
237 } 238 }
238 } 239 }
239 240
240 241
241 // Return false if bailed out. 242 // Return false if bailed out.
242 static bool CompileParsedFunctionHelper(ParsedFunction* parsed_function, 243 static bool CompileParsedFunctionHelper(ParsedFunction* parsed_function,
243 bool optimized, 244 bool optimized) {
244 intptr_t osr_id) {
245 const Function& function = parsed_function->function(); 245 const Function& function = parsed_function->function();
246 if (optimized && !function.is_optimizable()) { 246 if (optimized && !function.is_optimizable()) {
247 return false; 247 return false;
248 } 248 }
249 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); 249 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer);
250 bool is_compiled = false; 250 bool is_compiled = false;
251 Isolate* isolate = Isolate::Current(); 251 Isolate* isolate = Isolate::Current();
252 HANDLESCOPE(isolate); 252 HANDLESCOPE(isolate);
253 const intptr_t prev_deopt_id = isolate->deopt_id(); 253 const intptr_t prev_deopt_id = isolate->deopt_id();
254 isolate->set_deopt_id(0); 254 isolate->set_deopt_id(0);
(...skipping 19 matching lines...) Expand all
274 FLAG_deoptimization_counter_threshold) { 274 FLAG_deoptimization_counter_threshold) {
275 const Code& unoptimized_code = 275 const Code& unoptimized_code =
276 Code::Handle(function.unoptimized_code()); 276 Code::Handle(function.unoptimized_code());
277 ic_data_array = unoptimized_code.ExtractTypeFeedbackArray(); 277 ic_data_array = unoptimized_code.ExtractTypeFeedbackArray();
278 } 278 }
279 } 279 }
280 280
281 // Build the flow graph. 281 // Build the flow graph.
282 FlowGraphBuilder builder(parsed_function, 282 FlowGraphBuilder builder(parsed_function,
283 ic_data_array, 283 ic_data_array,
284 NULL, // NULL = not inlining. 284 NULL); // NULL = not inlining.
285 osr_id);
286 flow_graph = builder.BuildGraph(); 285 flow_graph = builder.BuildGraph();
287 } 286 }
288 287
289 if (FLAG_print_flow_graph || 288 if (FLAG_print_flow_graph ||
290 (optimized && FLAG_print_flow_graph_optimized)) { 289 (optimized && FLAG_print_flow_graph_optimized)) {
291 if (osr_id == Isolate::kNoDeoptId) { 290 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
292 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
293 } else {
294 FlowGraphPrinter::PrintGraph("For OSR", flow_graph);
295 }
296 } 291 }
297 292
298 if (optimized) { 293 if (optimized) {
299 TimerScope timer(FLAG_compiler_stats, 294 TimerScope timer(FLAG_compiler_stats,
300 &CompilerStats::ssa_timer, 295 &CompilerStats::ssa_timer,
301 isolate); 296 isolate);
302 // Transform to SSA (virtual register 0 and no inlining arguments). 297 // Transform to SSA (virtual register 0 and no inlining arguments).
303 flow_graph->ComputeSSA(0, NULL); 298 flow_graph->ComputeSSA(0, NULL);
304 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 299 DEBUG_ASSERT(flow_graph->VerifyUseLists());
305 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { 300 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 code.set_is_optimized(optimized); 501 code.set_is_optimized(optimized);
507 graph_compiler.FinalizePcDescriptors(code); 502 graph_compiler.FinalizePcDescriptors(code);
508 graph_compiler.FinalizeDeoptInfo(code); 503 graph_compiler.FinalizeDeoptInfo(code);
509 graph_compiler.FinalizeStackmaps(code); 504 graph_compiler.FinalizeStackmaps(code);
510 graph_compiler.FinalizeVarDescriptors(code); 505 graph_compiler.FinalizeVarDescriptors(code);
511 graph_compiler.FinalizeExceptionHandlers(code); 506 graph_compiler.FinalizeExceptionHandlers(code);
512 graph_compiler.FinalizeComments(code); 507 graph_compiler.FinalizeComments(code);
513 graph_compiler.FinalizeStaticCallTargetsTable(code); 508 graph_compiler.FinalizeStaticCallTargetsTable(code);
514 509
515 if (optimized) { 510 if (optimized) {
516 if (osr_id == Isolate::kNoDeoptId) { 511 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode()));
517 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); 512 function.SetCode(code);
518 if (FLAG_trace_compiler) { 513 if (FLAG_trace_compiler) {
519 OS::Print("--> patching entry %#"Px"\n", 514 OS::Print("--> patching entry %#"Px"\n",
520 Code::Handle(function.unoptimized_code()).EntryPoint()); 515 Code::Handle(function.unoptimized_code()).EntryPoint());
521 }
522 } 516 }
523 function.SetCode(code);
524 517
525 for (intptr_t i = 0; i < guarded_fields.length(); i++) { 518 for (intptr_t i = 0; i < guarded_fields.length(); i++) {
526 const Field& field = *guarded_fields[i]; 519 const Field& field = *guarded_fields[i];
527 field.RegisterDependentCode(code); 520 field.RegisterDependentCode(code);
528 } 521 }
529 } else { 522 } else {
530 function.set_unoptimized_code(code); 523 function.set_unoptimized_code(code);
531 function.SetCode(code); 524 function.SetCode(code);
532 ASSERT(CodePatcher::CodeIsPatchable(code)); 525 ASSERT(CodePatcher::CodeIsPatchable(code));
533 } 526 }
(...skipping 17 matching lines...) Expand all
551 return is_compiled; 544 return is_compiled;
552 } 545 }
553 546
554 547
555 static void DisassembleCode(const Function& function, bool optimized) { 548 static void DisassembleCode(const Function& function, bool optimized) {
556 const char* function_fullname = function.ToFullyQualifiedCString(); 549 const char* function_fullname = function.ToFullyQualifiedCString();
557 OS::Print("Code for %sfunction '%s' {\n", 550 OS::Print("Code for %sfunction '%s' {\n",
558 optimized ? "optimized " : "", 551 optimized ? "optimized " : "",
559 function_fullname); 552 function_fullname);
560 const Code& code = Code::Handle(function.CurrentCode()); 553 const Code& code = Code::Handle(function.CurrentCode());
561 code.Disassemble(); 554 const Instructions& instructions =
555 Instructions::Handle(code.instructions());
556 uword start = instructions.EntryPoint();
557 Disassembler::Disassemble(start,
558 start + instructions.size(),
559 code.comments());
562 OS::Print("}\n"); 560 OS::Print("}\n");
563 561
564 OS::Print("Pointer offsets for function: {\n"); 562 OS::Print("Pointer offsets for function: {\n");
565 // Pointer offsets are stored in descending order. 563 // Pointer offsets are stored in descending order.
566 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { 564 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) {
567 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); 565 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint();
568 Object& obj = Object::Handle(); 566 Object& obj = Object::Handle();
569 obj = *reinterpret_cast<RawObject**>(addr); 567 obj = *reinterpret_cast<RawObject**>(addr);
570 OS::Print(" %d : %#"Px" '%s'\n", 568 OS::Print(" %d : %#"Px" '%s'\n",
571 code.GetPointerOffsetAt(i), addr, obj.ToCString()); 569 code.GetPointerOffsetAt(i), addr, obj.ToCString());
572 } 570 }
573 OS::Print("}\n"); 571 OS::Print("}\n");
574 572
575 OS::Print("PC Descriptors for function '%s' {\n", function_fullname); 573 OS::Print("PC Descriptors for function '%s' {\n", function_fullname);
576 PcDescriptors::PrintHeaderString(); 574 PcDescriptors::PrintHeaderString();
577 const PcDescriptors& descriptors = 575 const PcDescriptors& descriptors =
578 PcDescriptors::Handle(code.pc_descriptors()); 576 PcDescriptors::Handle(code.pc_descriptors());
579 OS::Print("%s}\n", descriptors.ToCString()); 577 OS::Print("%s}\n", descriptors.ToCString());
580 578
581 uword start = Instructions::Handle(code.instructions()).EntryPoint();
582 const Array& deopt_table = Array::Handle(code.deopt_info_array()); 579 const Array& deopt_table = Array::Handle(code.deopt_info_array());
583 intptr_t deopt_table_length = DeoptTable::GetLength(deopt_table); 580 intptr_t deopt_table_length = DeoptTable::GetLength(deopt_table);
584 if (deopt_table_length > 0) { 581 if (deopt_table_length > 0) {
585 OS::Print("DeoptInfo: {\n"); 582 OS::Print("DeoptInfo: {\n");
586 Smi& offset = Smi::Handle(); 583 Smi& offset = Smi::Handle();
587 DeoptInfo& info = DeoptInfo::Handle(); 584 DeoptInfo& info = DeoptInfo::Handle();
588 Smi& reason = Smi::Handle(); 585 Smi& reason = Smi::Handle();
589 for (intptr_t i = 0; i < deopt_table_length; ++i) { 586 for (intptr_t i = 0; i < deopt_table_length; ++i) {
590 DeoptTable::GetEntry(deopt_table, i, &offset, &info, &reason); 587 DeoptTable::GetEntry(deopt_table, i, &offset, &info, &reason);
591 OS::Print("%4"Pd": 0x%"Px" %s (%s)\n", 588 OS::Print("%4"Pd": 0x%"Px" %s (%s)\n",
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 start + offset.Value(), 668 start + offset.Value(),
672 function.ToFullyQualifiedCString(), 669 function.ToFullyQualifiedCString(),
673 code.raw()); 670 code.raw());
674 } 671 }
675 OS::Print("}\n"); 672 OS::Print("}\n");
676 } 673 }
677 } 674 }
678 675
679 676
680 static RawError* CompileFunctionHelper(const Function& function, 677 static RawError* CompileFunctionHelper(const Function& function,
681 bool optimized, 678 bool optimized) {
682 intptr_t osr_id) {
683 Isolate* isolate = Isolate::Current(); 679 Isolate* isolate = Isolate::Current();
684 StackZone zone(isolate); 680 StackZone zone(isolate);
685 LongJump* base = isolate->long_jump_base(); 681 LongJump* base = isolate->long_jump_base();
686 LongJump jump; 682 LongJump jump;
687 isolate->set_long_jump_base(&jump); 683 isolate->set_long_jump_base(&jump);
688 // Skips parsing if we need to only install unoptimized code. 684 // Skips parsing if we need to only install unoptimized code.
689 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) { 685 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) {
690 InstallUnoptimizedCode(function); 686 InstallUnoptimizedCode(function);
691 isolate->set_long_jump_base(base); 687 isolate->set_long_jump_base(base);
692 return Error::null(); 688 return Error::null();
693 } 689 }
694 if (setjmp(*jump.Set()) == 0) { 690 if (setjmp(*jump.Set()) == 0) {
695 TIMERSCOPE(time_compilation); 691 TIMERSCOPE(time_compilation);
696 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); 692 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time");
697 per_compile_timer.Start(); 693 per_compile_timer.Start();
698 ParsedFunction* parsed_function = new ParsedFunction( 694 ParsedFunction* parsed_function = new ParsedFunction(
699 Function::ZoneHandle(function.raw())); 695 Function::ZoneHandle(function.raw()));
700 if (FLAG_trace_compiler) { 696 if (FLAG_trace_compiler) {
701 OS::Print("Compiling %s%sfunction: '%s' @ token %"Pd", size %"Pd"\n", 697 OS::Print("Compiling %sfunction: '%s' @ token %"Pd", size %"Pd"\n",
702 (osr_id == Isolate::kNoDeoptId ? "" : "osr "),
703 (optimized ? "optimized " : ""), 698 (optimized ? "optimized " : ""),
704 function.ToFullyQualifiedCString(), 699 function.ToFullyQualifiedCString(),
705 function.token_pos(), 700 function.token_pos(),
706 (function.end_token_pos() - function.token_pos())); 701 (function.end_token_pos() - function.token_pos()));
707 } 702 }
708 { 703 {
709 HANDLESCOPE(isolate); 704 HANDLESCOPE(isolate);
710 Parser::ParseFunction(parsed_function); 705 Parser::ParseFunction(parsed_function);
711 parsed_function->AllocateVariables(); 706 parsed_function->AllocateVariables();
712 } 707 }
713 708
714 const bool success = 709 const bool success =
715 CompileParsedFunctionHelper(parsed_function, optimized, osr_id); 710 CompileParsedFunctionHelper(parsed_function, optimized);
716 if (optimized && !success) { 711 if (optimized && !success) {
717 // Optimizer bailed out. Disable optimizations and to never try again. 712 // Optimizer bailed out. Disable optimizations and to never try again.
718 if (FLAG_trace_compiler) { 713 if (FLAG_trace_compiler) {
719 OS::Print("--> disabling optimizations for '%s'\n", 714 OS::Print("--> disabling optimizations for '%s'\n",
720 function.ToFullyQualifiedCString()); 715 function.ToFullyQualifiedCString());
721 } else if (FLAG_trace_failed_optimization_attempts) { 716 } else if (FLAG_trace_failed_optimization_attempts) {
722 OS::Print("Cannot optimize: %s\n", function.ToFullyQualifiedCString()); 717 OS::Print("Cannot optimize: %s\n", function.ToFullyQualifiedCString());
723 } 718 }
724 function.set_is_optimizable(false); 719 function.set_is_optimizable(false);
725 isolate->set_long_jump_base(base); 720 isolate->set_long_jump_base(base);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 isolate->object_store()->clear_sticky_error(); 752 isolate->object_store()->clear_sticky_error();
758 isolate->set_long_jump_base(base); 753 isolate->set_long_jump_base(base);
759 return error.raw(); 754 return error.raw();
760 } 755 }
761 UNREACHABLE(); 756 UNREACHABLE();
762 return Error::null(); 757 return Error::null();
763 } 758 }
764 759
765 760
766 RawError* Compiler::CompileFunction(const Function& function) { 761 RawError* Compiler::CompileFunction(const Function& function) {
767 return CompileFunctionHelper(function, false, Isolate::kNoDeoptId); 762 return CompileFunctionHelper(function, false); // Non-optimized.
768 } 763 }
769 764
770 765
771 RawError* Compiler::CompileOptimizedFunction(const Function& function, 766 RawError* Compiler::CompileOptimizedFunction(const Function& function) {
772 intptr_t osr_id) { 767 return CompileFunctionHelper(function, true); // Optimized.
773 return CompileFunctionHelper(function, true, osr_id);
774 } 768 }
775 769
776 770
777 RawError* Compiler::CompileParsedFunction( 771 RawError* Compiler::CompileParsedFunction(
778 ParsedFunction* parsed_function) { 772 ParsedFunction* parsed_function) {
779 Isolate* isolate = Isolate::Current(); 773 Isolate* isolate = Isolate::Current();
780 LongJump* base = isolate->long_jump_base(); 774 LongJump* base = isolate->long_jump_base();
781 LongJump jump; 775 LongJump jump;
782 isolate->set_long_jump_base(&jump); 776 isolate->set_long_jump_base(&jump);
783 if (setjmp(*jump.Set()) == 0) { 777 if (setjmp(*jump.Set()) == 0) {
784 // Non-optimized code generator. 778 // Non-optimized code generator.
785 CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); 779 CompileParsedFunctionHelper(parsed_function, false);
786 if (FLAG_disassemble) { 780 if (FLAG_disassemble) {
787 DisassembleCode(parsed_function->function(), false); 781 DisassembleCode(parsed_function->function(), false);
788 } 782 }
789 isolate->set_long_jump_base(base); 783 isolate->set_long_jump_base(base);
790 return Error::null(); 784 return Error::null();
791 } else { 785 } else {
792 Error& error = Error::Handle(); 786 Error& error = Error::Handle();
793 // We got an error during compilation. 787 // We got an error during compilation.
794 error = isolate->object_store()->sticky_error(); 788 error = isolate->object_store()->sticky_error();
795 isolate->object_store()->clear_sticky_error(); 789 isolate->object_store()->clear_sticky_error();
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 // would compile func automatically. We are checking fewer invariants 856 // would compile func automatically. We are checking fewer invariants
863 // here. 857 // here.
864 ParsedFunction* parsed_function = new ParsedFunction(func); 858 ParsedFunction* parsed_function = new ParsedFunction(func);
865 parsed_function->SetNodeSequence(fragment); 859 parsed_function->SetNodeSequence(fragment);
866 parsed_function->set_default_parameter_values(Array::ZoneHandle()); 860 parsed_function->set_default_parameter_values(Array::ZoneHandle());
867 parsed_function->EnsureExpressionTemp(); 861 parsed_function->EnsureExpressionTemp();
868 fragment->scope()->AddVariable(parsed_function->expression_temp_var()); 862 fragment->scope()->AddVariable(parsed_function->expression_temp_var());
869 parsed_function->AllocateVariables(); 863 parsed_function->AllocateVariables();
870 864
871 // Non-optimized code generator. 865 // Non-optimized code generator.
872 CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); 866 CompileParsedFunctionHelper(parsed_function, false);
873 867
874 const Object& result = Object::Handle( 868 const Object& result = Object::Handle(
875 DartEntry::InvokeFunction(func, Object::empty_array())); 869 DartEntry::InvokeFunction(func, Object::empty_array()));
876 isolate->set_long_jump_base(base); 870 isolate->set_long_jump_base(base);
877 return result.raw(); 871 return result.raw();
878 } else { 872 } else {
879 const Object& result = 873 const Object& result =
880 Object::Handle(isolate->object_store()->sticky_error()); 874 Object::Handle(isolate->object_store()->sticky_error());
881 isolate->object_store()->clear_sticky_error(); 875 isolate->object_store()->clear_sticky_error();
882 isolate->set_long_jump_base(base); 876 isolate->set_long_jump_base(base);
883 return result.raw(); 877 return result.raw();
884 } 878 }
885 UNREACHABLE(); 879 UNREACHABLE();
886 return Object::null(); 880 return Object::null();
887 } 881 }
888 882
889 } // namespace dart 883 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/flow_graph.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698