| 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 #ifndef RUNTIME_VM_FLOW_GRAPH_COMPILER_H_ | 5 #ifndef RUNTIME_VM_FLOW_GRAPH_COMPILER_H_ |
| 6 #define RUNTIME_VM_FLOW_GRAPH_COMPILER_H_ | 6 #define RUNTIME_VM_FLOW_GRAPH_COMPILER_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/code_descriptors.h" | 10 #include "vm/code_descriptors.h" |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 private: | 226 private: |
| 227 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; | 227 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; |
| 228 | 228 |
| 229 Label entry_label_; | 229 Label entry_label_; |
| 230 Label exit_label_; | 230 Label exit_label_; |
| 231 | 231 |
| 232 DISALLOW_COPY_AND_ASSIGN(SlowPathCode); | 232 DISALLOW_COPY_AND_ASSIGN(SlowPathCode); |
| 233 }; | 233 }; |
| 234 | 234 |
| 235 | 235 |
| 236 struct CidRangeTarget { | |
| 237 intptr_t cid_start; | |
| 238 intptr_t cid_end; | |
| 239 Function* target; | |
| 240 intptr_t count; | |
| 241 CidRangeTarget(intptr_t cid_start_arg, | |
| 242 intptr_t cid_end_arg, | |
| 243 Function* target_arg, | |
| 244 intptr_t count_arg) | |
| 245 : cid_start(cid_start_arg), | |
| 246 cid_end(cid_end_arg), | |
| 247 target(target_arg), | |
| 248 count(count_arg) {} | |
| 249 }; | |
| 250 | |
| 251 | |
| 252 class FlowGraphCompiler : public ValueObject { | 236 class FlowGraphCompiler : public ValueObject { |
| 253 private: | 237 private: |
| 254 class BlockInfo : public ZoneAllocated { | 238 class BlockInfo : public ZoneAllocated { |
| 255 public: | 239 public: |
| 256 BlockInfo() | 240 BlockInfo() |
| 257 : block_label_(), | 241 : block_label_(), |
| 258 jump_label_(&block_label_), | 242 jump_label_(&block_label_), |
| 259 next_nonempty_label_(NULL), | 243 next_nonempty_label_(NULL), |
| 260 is_marked_(false) {} | 244 is_marked_(false) {} |
| 261 | 245 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 TokenPosition token_pos, | 411 TokenPosition token_pos, |
| 428 LocationSummary* locs); | 412 LocationSummary* locs); |
| 429 | 413 |
| 430 void EmitInstanceCall(const StubEntry& stub_entry, | 414 void EmitInstanceCall(const StubEntry& stub_entry, |
| 431 const ICData& ic_data, | 415 const ICData& ic_data, |
| 432 intptr_t argument_count, | 416 intptr_t argument_count, |
| 433 intptr_t deopt_id, | 417 intptr_t deopt_id, |
| 434 TokenPosition token_pos, | 418 TokenPosition token_pos, |
| 435 LocationSummary* locs); | 419 LocationSummary* locs); |
| 436 | 420 |
| 437 void EmitPolymorphicInstanceCall(const ICData& ic_data, | 421 void EmitPolymorphicInstanceCall( |
| 438 intptr_t argument_count, | 422 const CallTargets& targets, |
| 439 const Array& argument_names, | 423 const InstanceCallInstr& original_instruction, |
| 440 intptr_t deopt_id, | 424 intptr_t argument_count, |
| 441 TokenPosition token_pos, | 425 const Array& argument_names, |
| 442 LocationSummary* locs, | 426 intptr_t deopt_id, |
| 443 bool complete, | 427 TokenPosition token_pos, |
| 444 intptr_t total_call_count); | 428 LocationSummary* locs, |
| 429 bool complete, |
| 430 intptr_t total_call_count); |
| 445 | 431 |
| 446 // Pass a value for try-index where block is not available (e.g. slow path). | 432 // Pass a value for try-index where block is not available (e.g. slow path). |
| 447 void EmitMegamorphicInstanceCall(const ICData& ic_data, | 433 void EmitMegamorphicInstanceCall(const String& function_name, |
| 434 const Array& arguments_descriptor, |
| 448 intptr_t argument_count, | 435 intptr_t argument_count, |
| 449 intptr_t deopt_id, | 436 intptr_t deopt_id, |
| 450 TokenPosition token_pos, | 437 TokenPosition token_pos, |
| 451 LocationSummary* locs, | 438 LocationSummary* locs, |
| 452 intptr_t try_index, | 439 intptr_t try_index, |
| 453 intptr_t slow_path_argument_count = 0); | 440 intptr_t slow_path_argument_count = 0); |
| 454 | 441 |
| 455 void EmitSwitchableInstanceCall(const ICData& ic_data, | 442 void EmitSwitchableInstanceCall(const ICData& ic_data, |
| 456 intptr_t argument_count, | 443 intptr_t argument_count, |
| 457 intptr_t deopt_id, | 444 intptr_t deopt_id, |
| 458 TokenPosition token_pos, | 445 TokenPosition token_pos, |
| 459 LocationSummary* locs); | 446 LocationSummary* locs); |
| 460 | 447 |
| 461 void EmitTestAndCall(const ICData& ic_data, | 448 void EmitTestAndCall(const CallTargets& targets, |
| 449 const String& function_name, |
| 462 intptr_t arg_count, | 450 intptr_t arg_count, |
| 463 const Array& arg_names, | 451 const Array& arg_names, |
| 464 Label* failed, | 452 Label* failed, |
| 465 Label* match_found, | 453 Label* match_found, |
| 466 intptr_t deopt_id, | 454 intptr_t deopt_id, |
| 467 TokenPosition token_index, | 455 TokenPosition token_index, |
| 468 LocationSummary* locs, | 456 LocationSummary* locs, |
| 469 bool complete, | 457 bool complete, |
| 470 intptr_t total_ic_calls); | 458 intptr_t total_ic_calls); |
| 471 | 459 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 const ICData* GetOrAddInstanceCallICData(intptr_t deopt_id, | 582 const ICData* GetOrAddInstanceCallICData(intptr_t deopt_id, |
| 595 const String& target_name, | 583 const String& target_name, |
| 596 const Array& arguments_descriptor, | 584 const Array& arguments_descriptor, |
| 597 intptr_t num_args_tested); | 585 intptr_t num_args_tested); |
| 598 | 586 |
| 599 const ICData* GetOrAddStaticCallICData(intptr_t deopt_id, | 587 const ICData* GetOrAddStaticCallICData(intptr_t deopt_id, |
| 600 const Function& target, | 588 const Function& target, |
| 601 const Array& arguments_descriptor, | 589 const Array& arguments_descriptor, |
| 602 intptr_t num_args_tested); | 590 intptr_t num_args_tested); |
| 603 | 591 |
| 604 static const ICData& TrySpecializeICDataByReceiverCid(const ICData& ic_data, | 592 static const CallTargets* ResolveCallTargetsForReceiverCid( |
| 605 intptr_t cid); | 593 intptr_t cid, |
| 594 const String& selector, |
| 595 const Array& args_desc_array); |
| 606 | 596 |
| 607 const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data() const { | 597 const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data() const { |
| 608 return *deopt_id_to_ic_data_; | 598 return *deopt_id_to_ic_data_; |
| 609 } | 599 } |
| 610 | 600 |
| 611 Thread* thread() const { return thread_; } | 601 Thread* thread() const { return thread_; } |
| 612 Isolate* isolate() const { return thread_->isolate(); } | 602 Isolate* isolate() const { return thread_->isolate(); } |
| 613 Zone* zone() const { return zone_; } | 603 Zone* zone() const { return zone_; } |
| 614 | 604 |
| 615 void AddStubCallTarget(const Code& code); | 605 void AddStubCallTarget(const Code& code); |
| 616 | 606 |
| 617 RawArray* edge_counters_array() const { return edge_counters_array_.raw(); } | 607 RawArray* edge_counters_array() const { return edge_counters_array_.raw(); } |
| 618 | 608 |
| 619 RawArray* InliningIdToFunction() const; | 609 RawArray* InliningIdToFunction() const; |
| 620 | 610 |
| 621 void BeginCodeSourceRange(); | 611 void BeginCodeSourceRange(); |
| 622 void EndCodeSourceRange(TokenPosition token_pos); | 612 void EndCodeSourceRange(TokenPosition token_pos); |
| 623 | 613 |
| 614 static bool LookupMethodFor(int class_id, |
| 615 const String& name, |
| 616 const ArgumentsDescriptor& args_desc, |
| 617 Function* fn_return); |
| 618 |
| 624 #if defined(TARGET_ARCH_DBC) | 619 #if defined(TARGET_ARCH_DBC) |
| 625 enum CallResult { | 620 enum CallResult { |
| 626 kHasResult, | 621 kHasResult, |
| 627 kNoResult, | 622 kNoResult, |
| 628 }; | 623 }; |
| 629 void RecordAfterCallHelper(TokenPosition token_pos, | 624 void RecordAfterCallHelper(TokenPosition token_pos, |
| 630 intptr_t deopt_id, | 625 intptr_t deopt_id, |
| 631 intptr_t argument_count, | 626 intptr_t argument_count, |
| 632 CallResult result, | 627 CallResult result, |
| 633 LocationSummary* locs); | 628 LocationSummary* locs); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 659 LocationSummary* locs); | 654 LocationSummary* locs); |
| 660 | 655 |
| 661 void EmitUnoptimizedStaticCall(intptr_t argument_count, | 656 void EmitUnoptimizedStaticCall(intptr_t argument_count, |
| 662 intptr_t deopt_id, | 657 intptr_t deopt_id, |
| 663 TokenPosition token_pos, | 658 TokenPosition token_pos, |
| 664 LocationSummary* locs, | 659 LocationSummary* locs, |
| 665 const ICData& ic_data); | 660 const ICData& ic_data); |
| 666 | 661 |
| 667 // Helper for TestAndCall that calculates a good bias that | 662 // Helper for TestAndCall that calculates a good bias that |
| 668 // allows more compact instructions to be emitted. | 663 // allows more compact instructions to be emitted. |
| 669 intptr_t ComputeGoodBiasForCidComparison( | 664 intptr_t ComputeGoodBiasForCidComparison(const CallTargets& sorted, |
| 670 const GrowableArray<CidRangeTarget>& sorted, | 665 intptr_t max_immediate); |
| 671 intptr_t max_immediate); | 666 |
| 667 // More helpers for EmitTestAndCall. |
| 668 void EmitTestAndCallLoadReceiver(intptr_t argument_count, |
| 669 const Array& arguments_descriptor); |
| 670 |
| 671 void EmitTestAndCallSmiBranch(Label* label, bool if_smi); |
| 672 |
| 673 void EmitTestAndCallLoadCid(); |
| 674 |
| 675 // Returns new class-id bias. |
| 676 int EmitTestAndCallCheckCid(Label* next_label, |
| 677 const CidRangeTarget& target, |
| 678 int bias); |
| 672 | 679 |
| 673 // DBC handles type tests differently from all other architectures due | 680 // DBC handles type tests differently from all other architectures due |
| 674 // to its interpreted nature. | 681 // to its interpreted nature. |
| 675 #if !defined(TARGET_ARCH_DBC) | 682 #if !defined(TARGET_ARCH_DBC) |
| 676 // Type checking helper methods. | 683 // Type checking helper methods. |
| 677 void CheckClassIds(Register class_id_reg, | 684 void CheckClassIds(Register class_id_reg, |
| 678 const GrowableArray<intptr_t>& class_ids, | 685 const GrowableArray<intptr_t>& class_ids, |
| 679 Label* is_instance_lbl, | 686 Label* is_instance_lbl, |
| 680 Label* is_not_instance_lbl); | 687 Label* is_not_instance_lbl); |
| 681 | 688 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data_; | 844 ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data_; |
| 838 | 845 |
| 839 Array& edge_counters_array_; | 846 Array& edge_counters_array_; |
| 840 | 847 |
| 841 DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler); | 848 DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler); |
| 842 }; | 849 }; |
| 843 | 850 |
| 844 } // namespace dart | 851 } // namespace dart |
| 845 | 852 |
| 846 #endif // RUNTIME_VM_FLOW_GRAPH_COMPILER_H_ | 853 #endif // RUNTIME_VM_FLOW_GRAPH_COMPILER_H_ |
| OLD | NEW |