| 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, | 77 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, |
| 78 const FlowGraph& flow_graph, | 78 const FlowGraph& flow_graph, |
| 79 bool is_optimizing, | 79 bool is_optimizing, |
| 80 bool is_leaf) | 80 bool is_leaf) |
| 81 : assembler_(assembler), | 81 : assembler_(assembler), |
| 82 parsed_function_(flow_graph.parsed_function()), | 82 parsed_function_(flow_graph.parsed_function()), |
| 83 block_order_(flow_graph.reverse_postorder()), | 83 block_order_(flow_graph.reverse_postorder()), |
| 84 current_block_(NULL), | 84 current_block_(NULL), |
| 85 exception_handlers_list_(NULL), | 85 exception_handlers_list_(NULL), |
| 86 pc_descriptors_list_(NULL), | 86 pc_descriptors_list_(NULL), |
| 87 stackmap_table_builder_(NULL), | 87 stackmap_table_builder_( |
| 88 is_optimizing ? new StackmapTableBuilder() : NULL), |
| 88 block_info_(block_order_.length()), | 89 block_info_(block_order_.length()), |
| 89 deopt_stubs_(), | 90 deopt_stubs_(), |
| 90 object_table_(GrowableObjectArray::Handle(GrowableObjectArray::New())), | 91 object_table_(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| 91 is_optimizing_(is_optimizing), | 92 is_optimizing_(is_optimizing), |
| 92 is_dart_leaf_(is_leaf), | 93 is_dart_leaf_(is_leaf), |
| 93 bool_true_(Bool::ZoneHandle(Bool::True())), | 94 bool_true_(Bool::ZoneHandle(Bool::True())), |
| 94 bool_false_(Bool::ZoneHandle(Bool::False())), | 95 bool_false_(Bool::ZoneHandle(Bool::False())), |
| 95 double_class_(Class::ZoneHandle( | 96 double_class_(Class::ZoneHandle( |
| 96 Isolate::Current()->object_store()->double_class())), | 97 Isolate::Current()->object_store()->double_class())), |
| 97 parallel_move_resolver_(this) { | 98 parallel_move_resolver_(this) { |
| 98 ASSERT(assembler != NULL); | 99 ASSERT(assembler != NULL); |
| 99 if (is_optimizing_) { | |
| 100 stackmap_table_builder_ = new StackmapTableBuilder(StackSize()); | |
| 101 } | |
| 102 } | 100 } |
| 103 | 101 |
| 104 | 102 |
| 105 FlowGraphCompiler::~FlowGraphCompiler() { | 103 FlowGraphCompiler::~FlowGraphCompiler() { |
| 106 // BlockInfos are zone-allocated, so their destructors are not called. | 104 // BlockInfos are zone-allocated, so their destructors are not called. |
| 107 // Verify the labels explicitly here. | 105 // Verify the labels explicitly here. |
| 108 for (int i = 0; i < block_info_.length(); ++i) { | 106 for (int i = 0; i < block_info_.length(); ++i) { |
| 109 ASSERT(!block_info_[i]->label.IsLinked()); | 107 ASSERT(!block_info_[i]->label.IsLinked()); |
| 110 ASSERT(!block_info_[i]->label.HasNear()); | 108 ASSERT(!block_info_[i]->label.HasNear()); |
| 111 } | 109 } |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 intptr_t token_pos, | 247 intptr_t token_pos, |
| 250 intptr_t try_index) { | 248 intptr_t try_index) { |
| 251 pc_descriptors_list()->AddDescriptor(kind, | 249 pc_descriptors_list()->AddDescriptor(kind, |
| 252 assembler()->CodeSize(), | 250 assembler()->CodeSize(), |
| 253 deopt_id, | 251 deopt_id, |
| 254 token_pos, | 252 token_pos, |
| 255 try_index); | 253 try_index); |
| 256 } | 254 } |
| 257 | 255 |
| 258 | 256 |
| 257 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) { |
| 258 if (is_optimizing()) { |
| 259 BitmapBuilder* bitmap = locs->stack_bitmap(); |
| 260 ASSERT(bitmap != NULL); |
| 261 bitmap->SetLength(StackSize()); |
| 262 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), bitmap); |
| 263 } |
| 264 } |
| 265 |
| 266 |
| 259 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, | 267 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, |
| 260 intptr_t try_index, | 268 intptr_t try_index, |
| 261 DeoptReasonId reason) { | 269 DeoptReasonId reason) { |
| 262 DeoptimizationStub* stub = | 270 DeoptimizationStub* stub = |
| 263 new DeoptimizationStub(deopt_id, try_index, reason); | 271 new DeoptimizationStub(deopt_id, try_index, reason); |
| 264 ASSERT(is_optimizing_); | 272 ASSERT(is_optimizing_); |
| 265 ASSERT(pending_deoptimization_env_ != NULL); | 273 ASSERT(pending_deoptimization_env_ != NULL); |
| 266 stub->set_deoptimization_env(pending_deoptimization_env_); | 274 stub->set_deoptimization_env(pending_deoptimization_env_); |
| 267 deopt_stubs_.Add(stub); | 275 deopt_stubs_.Add(stub); |
| 268 return stub->entry_label(); | 276 return stub->entry_label(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 299 code.set_object_table(object_array); | 307 code.set_object_table(object_array); |
| 300 } | 308 } |
| 301 | 309 |
| 302 | 310 |
| 303 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) { | 311 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) { |
| 304 if (stackmap_table_builder_ == NULL) { | 312 if (stackmap_table_builder_ == NULL) { |
| 305 // The unoptimizing compiler has no stack maps. | 313 // The unoptimizing compiler has no stack maps. |
| 306 code.set_stackmaps(Array::Handle()); | 314 code.set_stackmaps(Array::Handle()); |
| 307 } else { | 315 } else { |
| 308 // Finalize the stack map array and add it to the code object. | 316 // Finalize the stack map array and add it to the code object. |
| 317 ASSERT(is_optimizing()); |
| 309 code.set_stackmaps( | 318 code.set_stackmaps( |
| 310 Array::Handle(stackmap_table_builder_->FinalizeStackmaps(code))); | 319 Array::Handle(stackmap_table_builder_->FinalizeStackmaps(code))); |
| 311 ASSERT(is_optimizing()); | |
| 312 } | 320 } |
| 313 } | 321 } |
| 314 | 322 |
| 315 | 323 |
| 316 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) { | 324 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) { |
| 317 const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle( | 325 const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle( |
| 318 parsed_function_.node_sequence()->scope()->GetVarDescriptors( | 326 parsed_function_.node_sequence()->scope()->GetVarDescriptors( |
| 319 parsed_function_.function())); | 327 parsed_function_.function())); |
| 320 code.set_var_descriptors(var_descs); | 328 code.set_var_descriptors(var_descs); |
| 321 } | 329 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 | 376 |
| 369 | 377 |
| 370 void FlowGraphCompiler::GenerateInstanceCall( | 378 void FlowGraphCompiler::GenerateInstanceCall( |
| 371 intptr_t deopt_id, | 379 intptr_t deopt_id, |
| 372 intptr_t token_pos, | 380 intptr_t token_pos, |
| 373 intptr_t try_index, | 381 intptr_t try_index, |
| 374 const String& function_name, | 382 const String& function_name, |
| 375 intptr_t argument_count, | 383 intptr_t argument_count, |
| 376 const Array& argument_names, | 384 const Array& argument_names, |
| 377 intptr_t checked_argument_count, | 385 intptr_t checked_argument_count, |
| 378 BitmapBuilder* stack_bitmap) { | 386 LocationSummary* locs) { |
| 379 ASSERT(!IsLeaf()); | 387 ASSERT(!IsLeaf()); |
| 380 ICData& ic_data = | 388 ICData& ic_data = |
| 381 ICData::ZoneHandle(ICData::New(parsed_function().function(), | 389 ICData::ZoneHandle(ICData::New(parsed_function().function(), |
| 382 function_name, | 390 function_name, |
| 383 deopt_id, | 391 deopt_id, |
| 384 checked_argument_count)); | 392 checked_argument_count)); |
| 385 const Array& arguments_descriptor = | 393 const Array& arguments_descriptor = |
| 386 DartEntry::ArgumentsDescriptor(argument_count, argument_names); | 394 DartEntry::ArgumentsDescriptor(argument_count, argument_names); |
| 387 uword label_address = 0; | 395 uword label_address = 0; |
| 388 switch (checked_argument_count) { | 396 switch (checked_argument_count) { |
| 389 case 1: | 397 case 1: |
| 390 label_address = StubCode::OneArgCheckInlineCacheEntryPoint(); | 398 label_address = StubCode::OneArgCheckInlineCacheEntryPoint(); |
| 391 break; | 399 break; |
| 392 case 2: | 400 case 2: |
| 393 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); | 401 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); |
| 394 break; | 402 break; |
| 395 default: | 403 default: |
| 396 UNIMPLEMENTED(); | 404 UNIMPLEMENTED(); |
| 397 } | 405 } |
| 398 ExternalLabel target_label("InlineCache", label_address); | 406 ExternalLabel target_label("InlineCache", label_address); |
| 399 | 407 |
| 400 const intptr_t descr_offset = EmitInstanceCall(&target_label, | 408 EmitInstanceCall(&target_label, ic_data, arguments_descriptor, argument_count, |
| 401 ic_data, | 409 deopt_id, token_pos, try_index, locs); |
| 402 arguments_descriptor, | |
| 403 argument_count); | |
| 404 if (is_optimizing() && (stack_bitmap != NULL)) { | |
| 405 stackmap_table_builder_->AddEntry(descr_offset, stack_bitmap); | |
| 406 } | |
| 407 pc_descriptors_list()->AddDescriptor(PcDescriptors::kIcCall, | |
| 408 descr_offset, | |
| 409 deopt_id, | |
| 410 token_pos, | |
| 411 try_index); | |
| 412 } | 410 } |
| 413 | 411 |
| 414 | 412 |
| 415 void FlowGraphCompiler::GenerateStaticCall(intptr_t deopt_id, | 413 void FlowGraphCompiler::GenerateStaticCall(intptr_t deopt_id, |
| 416 intptr_t token_pos, | 414 intptr_t token_pos, |
| 417 intptr_t try_index, | 415 intptr_t try_index, |
| 418 const Function& function, | 416 const Function& function, |
| 419 intptr_t argument_count, | 417 intptr_t argument_count, |
| 420 const Array& argument_names, | 418 const Array& argument_names, |
| 421 BitmapBuilder* stack_bitmap) { | 419 LocationSummary* locs) { |
| 422 const Array& arguments_descriptor = | 420 const Array& arguments_descriptor = |
| 423 DartEntry::ArgumentsDescriptor(argument_count, argument_names); | 421 DartEntry::ArgumentsDescriptor(argument_count, argument_names); |
| 424 const intptr_t descr_offset = EmitStaticCall(function, | 422 EmitStaticCall(function, arguments_descriptor, argument_count, |
| 425 arguments_descriptor, | 423 deopt_id, token_pos, try_index, locs); |
| 426 argument_count); | |
| 427 if (is_optimizing() && (stack_bitmap != NULL)) { | |
| 428 stackmap_table_builder_->AddEntry(descr_offset, stack_bitmap); | |
| 429 } | |
| 430 pc_descriptors_list()->AddDescriptor(PcDescriptors::kFuncCall, | |
| 431 descr_offset, | |
| 432 deopt_id, | |
| 433 token_pos, | |
| 434 try_index); | |
| 435 } | 424 } |
| 436 | 425 |
| 437 | 426 |
| 438 void FlowGraphCompiler::GenerateNumberTypeCheck(Register kClassIdReg, | 427 void FlowGraphCompiler::GenerateNumberTypeCheck(Register kClassIdReg, |
| 439 const AbstractType& type, | 428 const AbstractType& type, |
| 440 Label* is_instance_lbl, | 429 Label* is_instance_lbl, |
| 441 Label* is_not_instance_lbl) { | 430 Label* is_not_instance_lbl) { |
| 442 GrowableArray<intptr_t> args; | 431 GrowableArray<intptr_t> args; |
| 443 if (type.IsNumberInterface()) { | 432 if (type.IsNumberInterface()) { |
| 444 args.Add(kDoubleCid); | 433 args.Add(kDoubleCid); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 | 479 |
| 491 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, | 480 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, |
| 492 Register class_id_reg, | 481 Register class_id_reg, |
| 493 intptr_t arg_count, | 482 intptr_t arg_count, |
| 494 const Array& arg_names, | 483 const Array& arg_names, |
| 495 Label* deopt, | 484 Label* deopt, |
| 496 Label* done, | 485 Label* done, |
| 497 intptr_t deopt_id, | 486 intptr_t deopt_id, |
| 498 intptr_t token_index, | 487 intptr_t token_index, |
| 499 intptr_t try_index, | 488 intptr_t try_index, |
| 500 BitmapBuilder* stack_bitmap) { | 489 LocationSummary* locs) { |
| 501 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); | 490 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); |
| 502 Label match_found; | 491 Label match_found; |
| 503 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | 492 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { |
| 504 const bool is_last_check = (i == (ic_data.NumberOfChecks() - 1)); | 493 const bool is_last_check = (i == (ic_data.NumberOfChecks() - 1)); |
| 505 Label next_test; | 494 Label next_test; |
| 506 assembler()->cmpl(class_id_reg, Immediate(ic_data.GetReceiverClassIdAt(i))); | 495 assembler()->cmpl(class_id_reg, Immediate(ic_data.GetReceiverClassIdAt(i))); |
| 507 if (is_last_check) { | 496 if (is_last_check) { |
| 508 assembler()->j(NOT_EQUAL, deopt); | 497 assembler()->j(NOT_EQUAL, deopt); |
| 509 } else { | 498 } else { |
| 510 assembler()->j(NOT_EQUAL, &next_test); | 499 assembler()->j(NOT_EQUAL, &next_test); |
| 511 } | 500 } |
| 512 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); | 501 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); |
| 513 GenerateStaticCall(deopt_id, | 502 GenerateStaticCall(deopt_id, |
| 514 token_index, | 503 token_index, |
| 515 try_index, | 504 try_index, |
| 516 target, | 505 target, |
| 517 arg_count, | 506 arg_count, |
| 518 arg_names, | 507 arg_names, |
| 519 stack_bitmap); | 508 locs); |
| 520 if (!is_last_check) { | 509 if (!is_last_check) { |
| 521 assembler()->jmp(&match_found); | 510 assembler()->jmp(&match_found); |
| 522 } | 511 } |
| 523 assembler()->Bind(&next_test); | 512 assembler()->Bind(&next_test); |
| 524 } | 513 } |
| 525 assembler()->Bind(&match_found); | 514 assembler()->Bind(&match_found); |
| 526 if (done != NULL) { | 515 if (done != NULL) { |
| 527 assembler()->jmp(done); | 516 assembler()->jmp(done); |
| 528 } | 517 } |
| 529 } | 518 } |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 return; | 756 return; |
| 768 } | 757 } |
| 769 } | 758 } |
| 770 | 759 |
| 771 // This move is not blocked. | 760 // This move is not blocked. |
| 772 EmitMove(index); | 761 EmitMove(index); |
| 773 } | 762 } |
| 774 | 763 |
| 775 | 764 |
| 776 } // namespace dart | 765 } // namespace dart |
| OLD | NEW |