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

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

Issue 11040058: Compress deoptimization information by sharing common suffixes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Ditto. Created 8 years, 2 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/flow_graph_compiler.h ('k') | runtime/vm/flow_graph_compiler_ia32.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/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/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/debugger.h" 10 #include "vm/debugger.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 AllocateIncomingParametersRecursive(env->outer(), stack_height); 55 AllocateIncomingParametersRecursive(env->outer(), stack_height);
56 for (Environment::ShallowIterator it(env); !it.Done(); it.Advance()) { 56 for (Environment::ShallowIterator it(env); !it.Done(); it.Advance()) {
57 if (it.CurrentLocation().IsInvalid()) { 57 if (it.CurrentLocation().IsInvalid()) {
58 ASSERT(it.CurrentValue()->definition()->IsPushArgument()); 58 ASSERT(it.CurrentValue()->definition()->IsPushArgument());
59 it.SetCurrentLocation(Location::StackSlot((*stack_height)++)); 59 it.SetCurrentLocation(Location::StackSlot((*stack_height)++));
60 } 60 }
61 } 61 }
62 } 62 }
63 63
64 64
65 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler) { 65 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
66 DeoptInfoBuilder* builder) {
66 if (deoptimization_env_ == NULL) return DeoptInfo::null(); 67 if (deoptimization_env_ == NULL) return DeoptInfo::null();
67 68
68 intptr_t stack_height = compiler->StackSize(); 69 intptr_t stack_height = compiler->StackSize();
69 AllocateIncomingParametersRecursive(deoptimization_env_, &stack_height); 70 AllocateIncomingParametersRecursive(deoptimization_env_, &stack_height);
70 71
71 const Function& function = compiler->parsed_function().function();
72 // For functions with optional arguments, all incoming arguments are copied
73 // to spill slots. The deoptimization environment does not track them.
74 const intptr_t incoming_arg_count =
75 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
76 DeoptInfoBuilder builder(compiler->object_table(), incoming_arg_count);
77
78 intptr_t slot_ix = 0; 72 intptr_t slot_ix = 0;
79 Environment* inner = deoptimization_env_; 73 Environment* current = deoptimization_env_;
80 74
81 // For the innermost environment, call the virtual return builder. 75 // For the innermost environment, call the virtual return builder.
82 BuildReturnAddress(&builder, inner->function(), slot_ix++); 76 BuildReturnAddress(builder, current->function(), slot_ix++);
83 77
84 // For the innermost environment, set outgoing arguments and the locals. 78 // For the innermost environment, set outgoing arguments and the locals.
85 for (intptr_t i = inner->Length() - 1; 79 for (intptr_t i = current->Length() - 1;
86 i >= inner->fixed_parameter_count(); 80 i >= current->fixed_parameter_count();
87 i--) { 81 i--) {
88 builder.AddCopy(inner->LocationAt(i), *inner->ValueAt(i), slot_ix++); 82 builder->AddCopy(current->LocationAt(i), *current->ValueAt(i), slot_ix++);
89 } 83 }
90 84
91 // PC marker and caller FP. 85 // PC marker and caller FP.
92 builder.AddPcMarker(inner->function(), slot_ix++); 86 builder->AddPcMarker(current->function(), slot_ix++);
93 builder.AddCallerFp(slot_ix++); 87 builder->AddCallerFp(slot_ix++);
94 88
95 while (inner->outer() != NULL) { 89 Environment* previous = current;
96 // Write the frame for an outer environment. 90 current = current->outer();
97 const Environment* current = inner->outer(); 91 while (current != NULL) {
98
99 // For any outer environment the deopt id is that of the call instruction 92 // For any outer environment the deopt id is that of the call instruction
100 // which is recorded in the outer environment. 93 // which is recorded in the outer environment.
101 builder.AddReturnAddressAfter(current->function(), 94 builder->AddReturnAddressAfter(current->function(),
102 current->deopt_id(), 95 current->deopt_id(),
103 slot_ix++); 96 slot_ix++);
104 97
105 // The values of outgoing arguments can be changed from the inlined call so 98 // The values of outgoing arguments can be changed from the inlined call so
106 // we must read them from the inner environment. 99 // we must read them from the previous environment.
107 for (intptr_t i = inner->fixed_parameter_count() - 1; i >= 0; i--) { 100 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
108 builder.AddCopy(inner->LocationAt(i), *inner->ValueAt(i), slot_ix++); 101 builder->AddCopy(previous->LocationAt(i), *previous->ValueAt(i),
102 slot_ix++);
109 } 103 }
110 104
111 // Set the locals, note that outgoing arguments are not in the environment. 105 // Set the locals, note that outgoing arguments are not in the environment.
112 for (intptr_t i = current->Length() - 1; 106 for (intptr_t i = current->Length() - 1;
113 i >= current->fixed_parameter_count(); 107 i >= current->fixed_parameter_count();
114 i--) { 108 i--) {
115 builder.AddCopy(current->LocationAt(i), *current->ValueAt(i), slot_ix++); 109 builder->AddCopy(current->LocationAt(i), *current->ValueAt(i), slot_ix++);
116 } 110 }
117 111
118 // PC marker and caller FP. 112 // PC marker and caller FP.
119 builder.AddPcMarker(current->function(), slot_ix++); 113 builder->AddPcMarker(current->function(), slot_ix++);
120 builder.AddCallerFp(slot_ix++); 114 builder->AddCallerFp(slot_ix++);
121 115
122 // Iterate on the outer environment. 116 // Iterate on the outer environment.
123 inner = inner->outer(); 117 previous = current;
118 current = current->outer();
124 } 119 }
125 ASSERT(inner != NULL); // The inner pointer is now the outermost environment. 120 // The previous pointer is now the outermost environment.
121 ASSERT(previous != NULL);
126 122
127 // For the outermost environment, set caller PC. 123 // For the outermost environment, set caller PC.
128 builder.AddCallerPc(slot_ix++); 124 builder->AddCallerPc(slot_ix++);
129 125
130 // For the outermost environment, set the incoming arguments. 126 // For the outermost environment, set the incoming arguments.
131 for (intptr_t i = inner->fixed_parameter_count() - 1; i >= 0; i--) { 127 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
132 builder.AddCopy(inner->LocationAt(i), *inner->ValueAt(i), slot_ix++); 128 builder->AddCopy(previous->LocationAt(i), *previous->ValueAt(i), slot_ix++);
133 } 129 }
134 130
135 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder.CreateDeoptInfo()); 131 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo());
136 return deopt_info.raw(); 132 return deopt_info.raw();
137 } 133 }
138 134
139 135
140 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, 136 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler,
141 const FlowGraph& flow_graph, 137 const FlowGraph& flow_graph,
142 bool is_optimizing, 138 bool is_optimizing,
143 bool is_leaf) 139 bool is_leaf)
144 : assembler_(assembler), 140 : assembler_(assembler),
145 parsed_function_(flow_graph.parsed_function()), 141 parsed_function_(flow_graph.parsed_function()),
146 block_order_(flow_graph.reverse_postorder()), 142 block_order_(flow_graph.reverse_postorder()),
147 current_block_(NULL), 143 current_block_(NULL),
148 exception_handlers_list_(NULL), 144 exception_handlers_list_(NULL),
149 pc_descriptors_list_(NULL), 145 pc_descriptors_list_(NULL),
150 stackmap_table_builder_( 146 stackmap_table_builder_(
151 is_optimizing ? new StackmapTableBuilder() : NULL), 147 is_optimizing ? new StackmapTableBuilder() : NULL),
152 block_info_(block_order_.length()), 148 block_info_(block_order_.length()),
153 deopt_infos_(), 149 deopt_infos_(),
154 object_table_(GrowableObjectArray::Handle(GrowableObjectArray::New())),
155 is_optimizing_(is_optimizing), 150 is_optimizing_(is_optimizing),
156 is_dart_leaf_(is_leaf), 151 is_dart_leaf_(is_leaf),
157 bool_true_(Bool::ZoneHandle(Bool::True())), 152 bool_true_(Bool::ZoneHandle(Bool::True())),
158 bool_false_(Bool::ZoneHandle(Bool::False())), 153 bool_false_(Bool::ZoneHandle(Bool::False())),
159 double_class_(Class::ZoneHandle( 154 double_class_(Class::ZoneHandle(
160 Isolate::Current()->object_store()->double_class())), 155 Isolate::Current()->object_store()->double_class())),
161 parallel_move_resolver_(this) { 156 parallel_move_resolver_(this) {
162 ASSERT(assembler != NULL); 157 ASSERT(assembler != NULL);
163 } 158 }
164 159
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) { 377 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) {
383 ASSERT(pc_descriptors_list_ != NULL); 378 ASSERT(pc_descriptors_list_ != NULL);
384 const PcDescriptors& descriptors = PcDescriptors::Handle( 379 const PcDescriptors& descriptors = PcDescriptors::Handle(
385 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); 380 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint()));
386 if (!is_optimizing_) descriptors.Verify(parsed_function_.function()); 381 if (!is_optimizing_) descriptors.Verify(parsed_function_.function());
387 code.set_pc_descriptors(descriptors); 382 code.set_pc_descriptors(descriptors);
388 } 383 }
389 384
390 385
391 void FlowGraphCompiler::FinalizeDeoptInfo(const Code& code) { 386 void FlowGraphCompiler::FinalizeDeoptInfo(const Code& code) {
387 // For functions with optional arguments, all incoming arguments are copied
388 // to spill slots. The deoptimization environment does not track them.
389 const Function& function = parsed_function().function();
390 const intptr_t incoming_arg_count =
391 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
392 DeoptInfoBuilder builder(incoming_arg_count);
393
392 const Array& array = 394 const Array& array =
393 Array::Handle(Array::New(DeoptTable::SizeFor(deopt_infos_.length()), 395 Array::Handle(Array::New(DeoptTable::SizeFor(deopt_infos_.length()),
394 Heap::kOld)); 396 Heap::kOld));
395 Smi& offset = Smi::Handle(); 397 Smi& offset = Smi::Handle();
396 DeoptInfo& info = DeoptInfo::Handle(); 398 DeoptInfo& info = DeoptInfo::Handle();
397 Smi& reason = Smi::Handle(); 399 Smi& reason = Smi::Handle();
398 for (intptr_t i = 0; i < deopt_infos_.length(); i++) { 400 for (intptr_t i = 0; i < deopt_infos_.length(); i++) {
399 offset = Smi::New(deopt_infos_[i]->pc_offset()); 401 offset = Smi::New(deopt_infos_[i]->pc_offset());
400 info = deopt_infos_[i]->CreateDeoptInfo(this); 402 info = deopt_infos_[i]->CreateDeoptInfo(this, &builder);
401 reason = Smi::New(deopt_infos_[i]->reason()); 403 reason = Smi::New(deopt_infos_[i]->reason());
402 DeoptTable::SetEntry(array, i, offset, info, reason); 404 DeoptTable::SetEntry(array, i, offset, info, reason);
403 } 405 }
404 code.set_deopt_info_array(array); 406 code.set_deopt_info_array(array);
405 const Array& object_array = Array::Handle(Array::MakeArray(object_table_)); 407 const Array& object_array =
408 Array::Handle(Array::MakeArray(builder.object_table()));
406 code.set_object_table(object_array); 409 code.set_object_table(object_array);
407 } 410 }
408 411
409 412
410 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) { 413 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) {
411 if (stackmap_table_builder_ == NULL) { 414 if (stackmap_table_builder_ == NULL) {
412 // The unoptimizing compiler has no stack maps. 415 // The unoptimizing compiler has no stack maps.
413 code.set_stackmaps(Array::Handle()); 416 code.set_stackmaps(Array::Handle());
414 } else { 417 } else {
415 // Finalize the stack map array and add it to the code object. 418 // Finalize the stack map array and add it to the code object.
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 case ABOVE: return unsigned_left > unsigned_right; 903 case ABOVE: return unsigned_left > unsigned_right;
901 case ABOVE_EQUAL: return unsigned_left >= unsigned_right; 904 case ABOVE_EQUAL: return unsigned_left >= unsigned_right;
902 default: 905 default:
903 UNIMPLEMENTED(); 906 UNIMPLEMENTED();
904 return false; 907 return false;
905 } 908 }
906 } 909 }
907 910
908 911
909 } // namespace dart 912 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.h ('k') | runtime/vm/flow_graph_compiler_ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698