| OLD | NEW |
| 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 12 matching lines...) Expand all Loading... |
| 23 | 23 |
| 24 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); | 24 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); |
| 25 DEFINE_FLAG(bool, trace_functions, false, "Trace entry of each function."); | 25 DEFINE_FLAG(bool, trace_functions, false, "Trace entry of each function."); |
| 26 DECLARE_FLAG(bool, code_comments); | 26 DECLARE_FLAG(bool, code_comments); |
| 27 DECLARE_FLAG(bool, enable_type_checks); | 27 DECLARE_FLAG(bool, enable_type_checks); |
| 28 DECLARE_FLAG(bool, intrinsify); | 28 DECLARE_FLAG(bool, intrinsify); |
| 29 DECLARE_FLAG(bool, report_usage_count); | 29 DECLARE_FLAG(bool, report_usage_count); |
| 30 DECLARE_FLAG(bool, trace_functions); | 30 DECLARE_FLAG(bool, trace_functions); |
| 31 DECLARE_FLAG(int, optimization_counter_threshold); | 31 DECLARE_FLAG(int, optimization_counter_threshold); |
| 32 | 32 |
| 33 RawDeoptInfo* DeoptimizationStub::CreateDeoptInfo(FlowGraphCompiler* compiler) { | 33 |
| 34 void CompilerDeoptInfo::BuildReturnAddress(DeoptInfoBuilder* builder, |
| 35 const Function& function, |
| 36 intptr_t slot_ix) { |
| 37 builder->AddReturnAddressAfter(function, deopt_id(), slot_ix); |
| 38 } |
| 39 |
| 40 |
| 41 void CompilerDeoptInfoWithStub::BuildReturnAddress(DeoptInfoBuilder* builder, |
| 42 const Function& function, |
| 43 intptr_t slot_ix) { |
| 44 builder->AddReturnAddressBefore(function, deopt_id(), slot_ix); |
| 45 } |
| 46 |
| 47 |
| 48 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler) { |
| 34 if (deoptimization_env_ == NULL) return DeoptInfo::null(); | 49 if (deoptimization_env_ == NULL) return DeoptInfo::null(); |
| 35 const Function& function = compiler->parsed_function().function(); | 50 const Function& function = compiler->parsed_function().function(); |
| 36 // For functions with optional arguments, all incoming are copied to local | 51 // For functions with optional arguments, all incoming are copied to local |
| 37 // area below FP, deoptimization environment does not track them. | 52 // area below FP, deoptimization environment does not track them. |
| 38 const intptr_t num_args = (function.num_optional_parameters() > 0) ? | 53 const intptr_t num_args = (function.num_optional_parameters() > 0) ? |
| 39 0 : function.num_fixed_parameters(); | 54 0 : function.num_fixed_parameters(); |
| 40 const intptr_t fixed_parameter_count = | 55 const intptr_t fixed_parameter_count = |
| 41 deoptimization_env_->fixed_parameter_count(); | 56 deoptimization_env_->fixed_parameter_count(); |
| 42 DeoptInfoBuilder builder(compiler->object_table(), num_args); | 57 DeoptInfoBuilder builder(compiler->object_table(), num_args); |
| 43 | 58 |
| 44 intptr_t slot_ix = 0; | 59 intptr_t slot_ix = 0; |
| 45 builder.AddReturnAddress(function, deopt_id_, slot_ix++); | 60 BuildReturnAddress(&builder, function, slot_ix++); |
| 46 | 61 |
| 47 // All locals between TOS and PC-marker. | 62 // All locals between TOS and PC-marker. |
| 48 const GrowableArray<Value*>& values = deoptimization_env_->values(); | 63 const GrowableArray<Value*>& values = deoptimization_env_->values(); |
| 49 | 64 |
| 50 // Assign locations to values pushed above spill slots with PushArgument. | 65 // Assign locations to values pushed above spill slots with PushArgument. |
| 51 intptr_t height = compiler->StackSize(); | 66 intptr_t height = compiler->StackSize(); |
| 52 for (intptr_t i = 0; i < values.length(); i++) { | 67 for (intptr_t i = 0; i < values.length(); i++) { |
| 53 if (deoptimization_env_->LocationAt(i).IsInvalid()) { | 68 if (deoptimization_env_->LocationAt(i).IsInvalid()) { |
| 54 ASSERT(values[i]->definition()->IsPushArgument()); | 69 ASSERT(values[i]->definition()->IsPushArgument()); |
| 55 *deoptimization_env_->LocationSlotAt(i) = Location::StackSlot(height++); | 70 *deoptimization_env_->LocationSlotAt(i) = Location::StackSlot(height++); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 80 bool is_leaf) | 95 bool is_leaf) |
| 81 : assembler_(assembler), | 96 : assembler_(assembler), |
| 82 parsed_function_(flow_graph.parsed_function()), | 97 parsed_function_(flow_graph.parsed_function()), |
| 83 block_order_(flow_graph.reverse_postorder()), | 98 block_order_(flow_graph.reverse_postorder()), |
| 84 current_block_(NULL), | 99 current_block_(NULL), |
| 85 exception_handlers_list_(NULL), | 100 exception_handlers_list_(NULL), |
| 86 pc_descriptors_list_(NULL), | 101 pc_descriptors_list_(NULL), |
| 87 stackmap_table_builder_( | 102 stackmap_table_builder_( |
| 88 is_optimizing ? new StackmapTableBuilder() : NULL), | 103 is_optimizing ? new StackmapTableBuilder() : NULL), |
| 89 block_info_(block_order_.length()), | 104 block_info_(block_order_.length()), |
| 90 deopt_stubs_(), | 105 deopt_infos_(), |
| 91 object_table_(GrowableObjectArray::Handle(GrowableObjectArray::New())), | 106 object_table_(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| 92 is_optimizing_(is_optimizing), | 107 is_optimizing_(is_optimizing), |
| 93 is_dart_leaf_(is_leaf), | 108 is_dart_leaf_(is_leaf), |
| 94 bool_true_(Bool::ZoneHandle(Bool::True())), | 109 bool_true_(Bool::ZoneHandle(Bool::True())), |
| 95 bool_false_(Bool::ZoneHandle(Bool::False())), | 110 bool_false_(Bool::ZoneHandle(Bool::False())), |
| 96 double_class_(Class::ZoneHandle( | 111 double_class_(Class::ZoneHandle( |
| 97 Isolate::Current()->object_store()->double_class())), | 112 Isolate::Current()->object_store()->double_class())), |
| 98 parallel_move_resolver_(this) { | 113 parallel_move_resolver_(this) { |
| 99 ASSERT(assembler != NULL); | 114 ASSERT(assembler != NULL); |
| 100 } | 115 } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 | 217 |
| 203 void FlowGraphCompiler::AddSlowPathCode(SlowPathCode* code) { | 218 void FlowGraphCompiler::AddSlowPathCode(SlowPathCode* code) { |
| 204 slow_path_code_.Add(code); | 219 slow_path_code_.Add(code); |
| 205 } | 220 } |
| 206 | 221 |
| 207 | 222 |
| 208 void FlowGraphCompiler::GenerateDeferredCode() { | 223 void FlowGraphCompiler::GenerateDeferredCode() { |
| 209 for (intptr_t i = 0; i < slow_path_code_.length(); i++) { | 224 for (intptr_t i = 0; i < slow_path_code_.length(); i++) { |
| 210 slow_path_code_[i]->EmitNativeCode(this); | 225 slow_path_code_[i]->EmitNativeCode(this); |
| 211 } | 226 } |
| 212 for (intptr_t i = 0; i < deopt_stubs_.length(); i++) { | 227 for (intptr_t i = 0; i < deopt_infos_.length(); i++) { |
| 213 deopt_stubs_[i]->GenerateCode(this, i); | 228 deopt_infos_[i]->GenerateCode(this, i); |
| 214 } | 229 } |
| 215 } | 230 } |
| 216 | 231 |
| 217 | 232 |
| 218 void FlowGraphCompiler::AddExceptionHandler(intptr_t try_index, | 233 void FlowGraphCompiler::AddExceptionHandler(intptr_t try_index, |
| 219 intptr_t pc_offset) { | 234 intptr_t pc_offset) { |
| 220 exception_handlers_list_->AddHandler(try_index, pc_offset); | 235 exception_handlers_list_->AddHandler(try_index, pc_offset); |
| 221 } | 236 } |
| 222 | 237 |
| 223 | 238 |
| 224 // Uses current pc position and try-index. | 239 // Uses current pc position and try-index. |
| 225 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, | 240 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, |
| 226 intptr_t deopt_id, | 241 intptr_t deopt_id, |
| 227 intptr_t token_pos) { | 242 intptr_t token_pos) { |
| 228 pc_descriptors_list()->AddDescriptor(kind, | 243 pc_descriptors_list()->AddDescriptor(kind, |
| 229 assembler()->CodeSize(), | 244 assembler()->CodeSize(), |
| 230 deopt_id, | 245 deopt_id, |
| 231 token_pos, | 246 token_pos, |
| 232 CurrentTryIndex()); | 247 CurrentTryIndex()); |
| 233 } | 248 } |
| 234 | 249 |
| 235 | 250 |
| 236 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, | 251 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, |
| 237 intptr_t token_pos) { | 252 intptr_t token_pos) { |
| 238 // TODO(srdjan): Temporary use deopt stubs to maintain deopt-indexes. | |
| 239 // kDeoptAtCall will not emit code, but will only generate deoptimization | |
| 240 // information. | |
| 241 ASSERT(is_optimizing()); | 253 ASSERT(is_optimizing()); |
| 242 const intptr_t deopt_index = deopt_stubs_.length(); | 254 const intptr_t deopt_index = deopt_infos_.length(); |
| 243 AddDeoptStub(deopt_id, kDeoptAtCall); | 255 CompilerDeoptInfo* info = new CompilerDeoptInfo(deopt_id, kDeoptAtCall); |
| 256 ASSERT(pending_deoptimization_env_ != NULL); |
| 257 info->set_deoptimization_env(pending_deoptimization_env_); |
| 258 deopt_infos_.Add(info); |
| 244 pc_descriptors_list()->AddDeoptIndex(assembler()->CodeSize(), | 259 pc_descriptors_list()->AddDeoptIndex(assembler()->CodeSize(), |
| 245 deopt_id, | 260 deopt_id, |
| 246 kDeoptAtCall, | 261 kDeoptAtCall, |
| 247 deopt_index); | 262 deopt_index); |
| 248 } | 263 } |
| 249 | 264 |
| 250 | 265 |
| 251 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) { | 266 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) { |
| 252 if (is_optimizing()) { | 267 if (is_optimizing()) { |
| 253 BitmapBuilder* bitmap = locs->stack_bitmap(); | 268 BitmapBuilder* bitmap = locs->stack_bitmap(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 intptr_t register_bit_count = bitmap->Length() - StackSize(); | 309 intptr_t register_bit_count = bitmap->Length() - StackSize(); |
| 295 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), | 310 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), |
| 296 bitmap, | 311 bitmap, |
| 297 register_bit_count); | 312 register_bit_count); |
| 298 } | 313 } |
| 299 } | 314 } |
| 300 | 315 |
| 301 | 316 |
| 302 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, | 317 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, |
| 303 DeoptReasonId reason) { | 318 DeoptReasonId reason) { |
| 304 DeoptimizationStub* stub = new DeoptimizationStub(deopt_id, reason); | 319 CompilerDeoptInfoWithStub* stub = |
| 320 new CompilerDeoptInfoWithStub(deopt_id, reason); |
| 305 ASSERT(is_optimizing_); | 321 ASSERT(is_optimizing_); |
| 306 ASSERT(pending_deoptimization_env_ != NULL); | 322 ASSERT(pending_deoptimization_env_ != NULL); |
| 307 stub->set_deoptimization_env(pending_deoptimization_env_); | 323 stub->set_deoptimization_env(pending_deoptimization_env_); |
| 308 deopt_stubs_.Add(stub); | 324 deopt_infos_.Add(stub); |
| 309 return stub->entry_label(); | 325 return stub->entry_label(); |
| 310 } | 326 } |
| 311 | 327 |
| 312 | 328 |
| 313 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { | 329 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { |
| 314 ASSERT(exception_handlers_list_ != NULL); | 330 ASSERT(exception_handlers_list_ != NULL); |
| 315 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( | 331 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( |
| 316 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); | 332 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); |
| 317 code.set_exception_handlers(handlers); | 333 code.set_exception_handlers(handlers); |
| 318 } | 334 } |
| 319 | 335 |
| 320 | 336 |
| 321 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) { | 337 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) { |
| 322 ASSERT(pc_descriptors_list_ != NULL); | 338 ASSERT(pc_descriptors_list_ != NULL); |
| 323 const PcDescriptors& descriptors = PcDescriptors::Handle( | 339 const PcDescriptors& descriptors = PcDescriptors::Handle( |
| 324 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); | 340 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); |
| 325 descriptors.Verify(parsed_function_.function().is_optimizable()); | 341 descriptors.Verify(parsed_function_.function().is_optimizable()); |
| 326 code.set_pc_descriptors(descriptors); | 342 code.set_pc_descriptors(descriptors); |
| 327 } | 343 } |
| 328 | 344 |
| 329 | 345 |
| 330 void FlowGraphCompiler::FinalizeDeoptInfo(const Code& code) { | 346 void FlowGraphCompiler::FinalizeDeoptInfo(const Code& code) { |
| 331 const Array& array = | 347 const Array& array = |
| 332 Array::Handle(Array::New(deopt_stubs_.length(), Heap::kOld)); | 348 Array::Handle(Array::New(deopt_infos_.length(), Heap::kOld)); |
| 333 DeoptInfo& info = DeoptInfo::Handle(); | 349 DeoptInfo& info = DeoptInfo::Handle(); |
| 334 for (intptr_t i = 0; i < deopt_stubs_.length(); i++) { | 350 for (intptr_t i = 0; i < deopt_infos_.length(); i++) { |
| 335 info = deopt_stubs_[i]->CreateDeoptInfo(this); | 351 info = deopt_infos_[i]->CreateDeoptInfo(this); |
| 336 array.SetAt(i, info); | 352 array.SetAt(i, info); |
| 337 } | 353 } |
| 338 code.set_deopt_info_array(array); | 354 code.set_deopt_info_array(array); |
| 339 const Array& object_array = Array::Handle(Array::MakeArray(object_table_)); | 355 const Array& object_array = Array::Handle(Array::MakeArray(object_table_)); |
| 340 code.set_object_table(object_array); | 356 code.set_object_table(object_array); |
| 341 } | 357 } |
| 342 | 358 |
| 343 | 359 |
| 344 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) { | 360 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) { |
| 345 if (stackmap_table_builder_ == NULL) { | 361 if (stackmap_table_builder_ == NULL) { |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 return; | 800 return; |
| 785 } | 801 } |
| 786 } | 802 } |
| 787 | 803 |
| 788 // This move is not blocked. | 804 // This move is not blocked. |
| 789 EmitMove(index); | 805 EmitMove(index); |
| 790 } | 806 } |
| 791 | 807 |
| 792 | 808 |
| 793 } // namespace dart | 809 } // namespace dart |
| OLD | NEW |