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

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

Issue 968183003: Emit stackmaps even in unoptimized code if slow path pushes untagged values. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/globals.h" // Needed here to get TARGET_ARCH_XXX. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX.
6 6
7 #include "vm/flow_graph_compiler.h" 7 #include "vm/flow_graph_compiler.h"
8 8
9 #include "vm/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/cha.h" 10 #include "vm/cha.h"
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 const GrowableArray<const Function*>& inline_id_to_function, 96 const GrowableArray<const Function*>& inline_id_to_function,
97 const GrowableArray<intptr_t>& caller_inline_id) 97 const GrowableArray<intptr_t>& caller_inline_id)
98 : isolate_(Isolate::Current()), 98 : isolate_(Isolate::Current()),
99 assembler_(assembler), 99 assembler_(assembler),
100 parsed_function_(parsed_function), 100 parsed_function_(parsed_function),
101 flow_graph_(*flow_graph), 101 flow_graph_(*flow_graph),
102 block_order_(*flow_graph->CodegenBlockOrder(is_optimizing)), 102 block_order_(*flow_graph->CodegenBlockOrder(is_optimizing)),
103 current_block_(NULL), 103 current_block_(NULL),
104 exception_handlers_list_(NULL), 104 exception_handlers_list_(NULL),
105 pc_descriptors_list_(NULL), 105 pc_descriptors_list_(NULL),
106 stackmap_table_builder_( 106 stackmap_table_builder_(NULL),
107 is_optimizing ? new StackmapTableBuilder() : NULL),
108 block_info_(block_order_.length()), 107 block_info_(block_order_.length()),
109 deopt_infos_(), 108 deopt_infos_(),
110 static_calls_target_table_(GrowableObjectArray::ZoneHandle( 109 static_calls_target_table_(GrowableObjectArray::ZoneHandle(
111 GrowableObjectArray::New())), 110 GrowableObjectArray::New())),
112 is_optimizing_(is_optimizing), 111 is_optimizing_(is_optimizing),
113 may_reoptimize_(false), 112 may_reoptimize_(false),
114 intrinsic_mode_(false), 113 intrinsic_mode_(false),
115 double_class_(Class::ZoneHandle( 114 double_class_(Class::ZoneHandle(
116 isolate_->object_store()->double_class())), 115 isolate_->object_store()->double_class())),
117 mint_class_(Class::ZoneHandle( 116 mint_class_(Class::ZoneHandle(
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 ICData::kDeoptAtCall, 660 ICData::kDeoptAtCall,
662 0, // No flags. 661 0, // No flags.
663 pending_deoptimization_env_); 662 pending_deoptimization_env_);
664 info->set_pc_offset(assembler()->CodeSize()); 663 info->set_pc_offset(assembler()->CodeSize());
665 deopt_infos_.Add(info); 664 deopt_infos_.Add(info);
666 } 665 }
667 666
668 667
669 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters 668 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters
670 // and FlowGraphCompiler::SlowPathEnvironmentFor. 669 // and FlowGraphCompiler::SlowPathEnvironmentFor.
670 // See StackFrame::VisitObjectPointers for the details of how stack map is
671 // interpreted.
671 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) { 672 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) {
672 if (is_optimizing()) { 673 if (is_optimizing() || locs->live_registers()->HasUntaggedValues()) {
674 const intptr_t spill_area_size = is_optimizing() ?
675 flow_graph_.graph_entry()->spill_slot_count() : 0;
676
673 RegisterSet* registers = locs->live_registers(); 677 RegisterSet* registers = locs->live_registers();
674 ASSERT(registers != NULL); 678 ASSERT(registers != NULL);
675 const intptr_t kFpuRegisterSpillFactor = 679 const intptr_t kFpuRegisterSpillFactor =
676 kFpuRegisterSize / kWordSize; 680 kFpuRegisterSize / kWordSize;
677 const intptr_t live_registers_size = registers->CpuRegisterCount() + 681 const intptr_t live_registers_size = registers->CpuRegisterCount() +
678 (registers->FpuRegisterCount() * kFpuRegisterSpillFactor); 682 (registers->FpuRegisterCount() * kFpuRegisterSpillFactor);
683
679 BitmapBuilder* bitmap = locs->stack_bitmap(); 684 BitmapBuilder* bitmap = locs->stack_bitmap();
680 ASSERT(bitmap != NULL); 685
681 // An instruction may have two safepoints in deferred code. The 686 // An instruction may have two safepoints in deferred code. The
682 // call to RecordSafepoint has the side-effect of appending the live 687 // call to RecordSafepoint has the side-effect of appending the live
683 // registers to the bitmap. This is why the second call to RecordSafepoint 688 // registers to the bitmap. This is why the second call to RecordSafepoint
684 // with the same instruction (and same location summary) sees a bitmap that 689 // with the same instruction (and same location summary) sees a bitmap that
685 // is larger that StackSize(). It will never be larger than StackSize() + 690 // is larger that StackSize(). It will never be larger than StackSize() +
686 // live_registers_size. 691 // live_registers_size.
687 ASSERT(bitmap->Length() <= (StackSize() + live_registers_size)); 692 ASSERT(bitmap->Length() <= (spill_area_size + live_registers_size));
688 // The first safepoint will grow the bitmap to be the size of StackSize() 693 // The first safepoint will grow the bitmap to be the size of
689 // but the second safepoint will truncate the bitmap and append the 694 // spill_area_size but the second safepoint will truncate the bitmap and
690 // live registers to it again. The bitmap produced by both calls will 695 // append the live registers to it again. The bitmap produced by both calls
691 // be the same. 696 // will be the same.
692 bitmap->SetLength(StackSize()); 697 bitmap->SetLength(spill_area_size);
693 698
694 // Mark the bits in the stack map in the same order we push registers in 699 // Mark the bits in the stack map in the same order we push registers in
695 // slow path code (see FlowGraphCompiler::SaveLiveRegisters). 700 // slow path code (see FlowGraphCompiler::SaveLiveRegisters).
696 // 701 //
697 // Slow path code can have registers at the safepoint. 702 // Slow path code can have registers at the safepoint.
698 if (!locs->always_calls()) { 703 if (!locs->always_calls()) {
699 RegisterSet* regs = locs->live_registers(); 704 RegisterSet* regs = locs->live_registers();
700 if (regs->FpuRegisterCount() > 0) { 705 if (regs->FpuRegisterCount() > 0) {
701 // Denote FPU registers with 0 bits in the stackmap. Based on the 706 // Denote FPU registers with 0 bits in the stackmap. Based on the
702 // assumption that there are normally few live FPU registers, this 707 // assumption that there are normally few live FPU registers, this
(...skipping 14 matching lines...) Expand all
717 // General purpose registers have the lowest register number at the 722 // General purpose registers have the lowest register number at the
718 // highest address (i.e., first in the stackmap). 723 // highest address (i.e., first in the stackmap).
719 for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) { 724 for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
720 Register reg = static_cast<Register>(i); 725 Register reg = static_cast<Register>(i);
721 if (locs->live_registers()->ContainsRegister(reg)) { 726 if (locs->live_registers()->ContainsRegister(reg)) {
722 bitmap->Set(bitmap->Length(), locs->live_registers()->IsTagged(reg)); 727 bitmap->Set(bitmap->Length(), locs->live_registers()->IsTagged(reg));
723 } 728 }
724 } 729 }
725 } 730 }
726 731
727 intptr_t register_bit_count = bitmap->Length() - StackSize(); 732 intptr_t register_bit_count = bitmap->Length() - spill_area_size;
728 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), 733 stackmap_table_builder()->AddEntry(assembler()->CodeSize(),
729 bitmap, 734 bitmap,
730 register_bit_count); 735 register_bit_count);
731 } 736 }
732 } 737 }
733 738
734 739
735 // This function must be kept in sync with: 740 // This function must be kept in sync with:
736 // 741 //
737 // FlowGraphCompiler::RecordSafepoint 742 // FlowGraphCompiler::RecordSafepoint
738 // FlowGraphCompiler::SaveLiveRegisters 743 // FlowGraphCompiler::SaveLiveRegisters
739 // MaterializeObjectInstr::RemapRegisters 744 // MaterializeObjectInstr::RemapRegisters
740 // 745 //
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 const Array& object_array = 862 const Array& object_array =
858 Array::Handle(Array::MakeArray(builder.object_table())); 863 Array::Handle(Array::MakeArray(builder.object_table()));
859 ASSERT(code.object_table() == Array::null()); 864 ASSERT(code.object_table() == Array::null());
860 code.set_object_table(object_array); 865 code.set_object_table(object_array);
861 } 866 }
862 } 867 }
863 868
864 869
865 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) { 870 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) {
866 if (stackmap_table_builder_ == NULL) { 871 if (stackmap_table_builder_ == NULL) {
867 // The unoptimizing compiler has no stack maps. 872 // The unoptimizing compiler has no stack maps.
koda 2015/03/03 17:57:48 Update comment.
Vyacheslav Egorov (Google) 2015/03/03 18:01:06 Acknowledged.
868 code.set_stackmaps(Object::null_array()); 873 code.set_stackmaps(Object::null_array());
869 } else { 874 } else {
870 // Finalize the stack map array and add it to the code object. 875 // Finalize the stack map array and add it to the code object.
871 ASSERT(is_optimizing());
872 code.set_stackmaps( 876 code.set_stackmaps(
873 Array::Handle(stackmap_table_builder_->FinalizeStackmaps(code))); 877 Array::Handle(stackmap_table_builder_->FinalizeStackmaps(code)));
874 } 878 }
875 } 879 }
876 880
877 881
878 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) { 882 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) {
879 LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle(); 883 LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle();
880 if (parsed_function().node_sequence() == NULL) { 884 if (parsed_function().node_sequence() == NULL) {
881 ASSERT(flow_graph().IsIrregexpFunction()); 885 ASSERT(flow_graph().IsIrregexpFunction());
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 const Array& res = Array::Handle( 1592 const Array& res = Array::Handle(
1589 Array::New(inline_id_to_function_.length(), Heap::kOld)); 1593 Array::New(inline_id_to_function_.length(), Heap::kOld));
1590 for (intptr_t i = 0; i < inline_id_to_function_.length(); i++) { 1594 for (intptr_t i = 0; i < inline_id_to_function_.length(); i++) {
1591 res.SetAt(i, *inline_id_to_function_[i]); 1595 res.SetAt(i, *inline_id_to_function_[i]);
1592 } 1596 }
1593 return res.raw(); 1597 return res.raw();
1594 } 1598 }
1595 1599
1596 1600
1597 } // namespace dart 1601 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698