Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #ifndef RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
| 6 #define RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
| 10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
| (...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 549 #endif // !PRODUCT | 549 #endif // !PRODUCT |
| 550 | 550 |
| 551 | 551 |
| 552 // Represents a mapping from a range of class-ids to a method for a given | 552 // Represents a mapping from a range of class-ids to a method for a given |
| 553 // selector (method name). Also can contain an indication of how frequently a | 553 // selector (method name). Also can contain an indication of how frequently a |
| 554 // given method has been called at a call site. This information can be | 554 // given method has been called at a call site. This information can be |
| 555 // harvested from the inline caches (ICs). | 555 // harvested from the inline caches (ICs). |
| 556 struct CidRangeTarget { | 556 struct CidRangeTarget { |
| 557 intptr_t cid_start; | 557 intptr_t cid_start; |
| 558 intptr_t cid_end; | 558 intptr_t cid_end; |
| 559 Function* target; | 559 const Function* target; |
| 560 intptr_t count; | 560 intptr_t count; |
| 561 CidRangeTarget(intptr_t cid_start_arg, | 561 CidRangeTarget(intptr_t cid_start_arg, |
| 562 intptr_t cid_end_arg, | 562 intptr_t cid_end_arg, |
| 563 Function* target_arg, | 563 const Function* target_arg, |
| 564 intptr_t count_arg) | 564 intptr_t count_arg) |
| 565 : cid_start(cid_start_arg), | 565 : cid_start(cid_start_arg), |
| 566 cid_end(cid_end_arg), | 566 cid_end(cid_end_arg), |
| 567 target(target_arg), | 567 target(target_arg), |
| 568 count(count_arg) { | 568 count(count_arg) { |
| 569 ASSERT(target->IsZoneHandle()); | 569 ASSERT(target == NULL || target->IsZoneHandle()); |
| 570 } | 570 } |
| 571 }; | 571 }; |
| 572 | 572 |
| 573 | 573 |
| 574 class CallTargets : public ZoneAllocated { | 574 class CallTargets : public ZoneAllocated { |
|
Vyacheslav Egorov (Google)
2017/05/01 12:21:25
It feels a bit strange to use CallTargets as a "ci
erikcorry
2017/05/05 15:15:51
I tried several things here. In the end the one t
| |
| 575 public: | 575 public: |
| 576 // Creates the off-heap CallTargets object that reflects the contents | 576 // Creates the off-heap CallTargets object that reflects the contents |
| 577 // of the on-VM-heap IC data. Also expands the class-ids to neighbouring | 577 // of the on-VM-heap IC data. |
| 578 // classes that inherit the same method. | 578 static CallTargets* Create(Zone* zone, |
| 579 static CallTargets* Create(Zone* zone, const ICData& ic_data); | 579 const ICData& ic_data, |
| 580 int argument_number); | |
| 581 | |
| 582 // This variant always uses the IC data for argument 0 (the receiver) and | |
| 583 // also expands the class-ids to neighbouring classes that inherit the same | |
| 584 // method. | |
| 585 static CallTargets* CreateAndExpand(Zone* zone, const ICData& ic_data); | |
| 580 | 586 |
| 581 void Add(const CidRangeTarget& target) { cid_ranges_.Add(target); } | 587 void Add(const CidRangeTarget& target) { cid_ranges_.Add(target); } |
| 582 | 588 |
| 589 bool Equals(const CallTargets& other) const; | |
| 590 | |
| 591 bool HasClassId(intptr_t cid) const; | |
| 592 | |
| 583 CidRangeTarget& operator[](intptr_t index) const { | 593 CidRangeTarget& operator[](intptr_t index) const { |
| 584 return cid_ranges_[index]; | 594 return cid_ranges_[index]; |
| 585 } | 595 } |
| 586 | 596 |
| 587 CidRangeTarget At(int index) { return cid_ranges_.At(index); } | 597 CidRangeTarget At(int index) { return cid_ranges_.At(index); } |
| 588 | 598 |
| 589 intptr_t length() const { return cid_ranges_.length(); } | 599 intptr_t length() const { return cid_ranges_.length(); } |
| 590 | 600 |
| 591 void SetLength(intptr_t len) { cid_ranges_.SetLength(len); } | 601 void SetLength(intptr_t len) { cid_ranges_.SetLength(len); } |
| 592 | 602 |
| 593 bool is_empty() const { return cid_ranges_.is_empty(); } | 603 bool is_empty() const { return cid_ranges_.is_empty(); } |
| 594 | 604 |
| 595 void Sort(int compare(const CidRangeTarget* a, const CidRangeTarget* b)) { | 605 void Sort(int compare(const CidRangeTarget* a, const CidRangeTarget* b)) { |
| 596 cid_ranges_.Sort(compare); | 606 cid_ranges_.Sort(compare); |
| 597 } | 607 } |
| 598 | 608 |
| 599 intptr_t AggregateCallCount() const; | 609 intptr_t AggregateCallCount() const; |
| 600 | 610 |
| 601 bool HasSingleTarget() const; | 611 bool HasSingleTarget() const; |
| 602 bool HasSingleRecognizedTarget() const; | 612 bool HasSingleRecognizedTarget() const; |
| 603 Function& FirstTarget() const; | 613 const Function& FirstTarget() const; |
| 604 Function& MostPopularTarget() const; | 614 const Function& MostPopularTarget() const; |
| 605 bool IsMonomorphic() const; | 615 bool IsMonomorphic() const; |
| 606 intptr_t MonomorphicReceiverCid() const; | 616 intptr_t MonomorphicReceiverCid() const; |
| 617 bool AreAllChecksImmutable() const; | |
| 618 bool HasReceiverClassId(intptr_t cid) const; | |
| 619 intptr_t ComputeLowestCid() const; | |
| 620 intptr_t ComputeHighestCid() const; | |
| 621 | |
| 607 | 622 |
| 608 private: | 623 private: |
| 624 void MergeIntoRanges(); | |
| 625 static CallTargets* CreateHelper(Zone* zone, | |
| 626 const ICData& ic_data, | |
| 627 int argument_number); | |
| 628 | |
| 609 GrowableArray<CidRangeTarget> cid_ranges_; | 629 GrowableArray<CidRangeTarget> cid_ranges_; |
| 610 }; | 630 }; |
| 611 | 631 |
| 612 | 632 |
| 613 class Instruction : public ZoneAllocated { | 633 class Instruction : public ZoneAllocated { |
| 614 public: | 634 public: |
| 615 #define DECLARE_TAG(type) k##type, | 635 #define DECLARE_TAG(type) k##type, |
| 616 enum Tag { FOR_EACH_INSTRUCTION(DECLARE_TAG) }; | 636 enum Tag { FOR_EACH_INSTRUCTION(DECLARE_TAG) }; |
| 617 #undef DECLARE_TAG | 637 #undef DECLARE_TAG |
| 618 | 638 |
| (...skipping 6965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7584 ZoneGrowableArray<Value*>* inputs_; | 7604 ZoneGrowableArray<Value*>* inputs_; |
| 7585 MergedMathInstr::Kind kind_; | 7605 MergedMathInstr::Kind kind_; |
| 7586 DISALLOW_COPY_AND_ASSIGN(MergedMathInstr); | 7606 DISALLOW_COPY_AND_ASSIGN(MergedMathInstr); |
| 7587 }; | 7607 }; |
| 7588 | 7608 |
| 7589 | 7609 |
| 7590 class CheckClassInstr : public TemplateInstruction<1, NoThrow> { | 7610 class CheckClassInstr : public TemplateInstruction<1, NoThrow> { |
| 7591 public: | 7611 public: |
| 7592 CheckClassInstr(Value* value, | 7612 CheckClassInstr(Value* value, |
| 7593 intptr_t deopt_id, | 7613 intptr_t deopt_id, |
| 7594 const ICData& unary_checks, | 7614 const CallTargets& targets, |
| 7595 TokenPosition token_pos); | 7615 TokenPosition token_pos); |
| 7596 | 7616 |
| 7597 DECLARE_INSTRUCTION(CheckClass) | 7617 DECLARE_INSTRUCTION(CheckClass) |
| 7598 | 7618 |
| 7599 virtual bool ComputeCanDeoptimize() const { return true; } | 7619 virtual bool ComputeCanDeoptimize() const { return true; } |
| 7600 | 7620 |
| 7601 virtual TokenPosition token_pos() const { return token_pos_; } | 7621 virtual TokenPosition token_pos() const { return token_pos_; } |
| 7602 | 7622 |
| 7603 Value* value() const { return inputs_[0]; } | 7623 Value* value() const { return inputs_[0]; } |
| 7604 | 7624 |
| 7605 const ICData& unary_checks() const { return unary_checks_; } | 7625 const CallTargets& targets() const { return targets_; } |
| 7606 | |
| 7607 const GrowableArray<intptr_t>& cids() const { return cids_; } | |
| 7608 | 7626 |
| 7609 virtual Instruction* Canonicalize(FlowGraph* flow_graph); | 7627 virtual Instruction* Canonicalize(FlowGraph* flow_graph); |
| 7610 | 7628 |
| 7611 bool IsNullCheck() const { return DeoptIfNull() || DeoptIfNotNull(); } | 7629 bool IsNullCheck() const { return IsDeoptIfNull() || IsDeoptIfNotNull(); } |
| 7612 | 7630 |
| 7613 bool DeoptIfNull() const; | 7631 bool IsDeoptIfNull() const; |
| 7614 bool DeoptIfNotNull() const; | 7632 bool IsDeoptIfNotNull() const; |
| 7615 | 7633 |
| 7616 bool IsDenseSwitch() const; | 7634 bool IsDenseSwitch() const; |
| 7617 static bool IsDenseCidRange(const ICData& unary_checks); | 7635 static bool IsDenseCidRange(const CallTargets& targets); |
| 7618 intptr_t ComputeCidMask() const; | 7636 intptr_t ComputeCidMask() const; |
| 7619 static bool IsDenseMask(intptr_t mask); | |
| 7620 | 7637 |
| 7621 virtual bool AllowsCSE() const { return true; } | 7638 virtual bool AllowsCSE() const { return true; } |
| 7622 virtual EffectSet Dependencies() const; | 7639 virtual EffectSet Dependencies() const; |
| 7623 virtual EffectSet Effects() const { return EffectSet::None(); } | 7640 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 7624 virtual bool AttributesEqual(Instruction* other) const; | 7641 virtual bool AttributesEqual(Instruction* other) const; |
| 7625 | 7642 |
| 7626 bool licm_hoisted() const { return licm_hoisted_; } | 7643 bool licm_hoisted() const { return licm_hoisted_; } |
| 7627 void set_licm_hoisted(bool value) { licm_hoisted_ = value; } | 7644 void set_licm_hoisted(bool value) { licm_hoisted_ = value; } |
| 7628 | 7645 |
| 7629 PRINT_OPERANDS_TO_SUPPORT | 7646 PRINT_OPERANDS_TO_SUPPORT |
| 7630 | 7647 |
| 7631 private: | 7648 private: |
| 7632 const ICData& unary_checks_; | 7649 const CallTargets& targets_; |
| 7633 GrowableArray<intptr_t> cids_; // Sorted, lowest first. | |
| 7634 bool licm_hoisted_; | 7650 bool licm_hoisted_; |
| 7635 bool is_dense_switch_; | 7651 bool is_dense_switch_; |
| 7636 const TokenPosition token_pos_; | 7652 const TokenPosition token_pos_; |
| 7637 | 7653 |
| 7654 int EmitCheckCid(FlowGraphCompiler* compiler, | |
| 7655 int bias, | |
| 7656 intptr_t cid_start, | |
| 7657 intptr_t cid_end, | |
| 7658 bool is_last, | |
| 7659 Label* is_ok, | |
| 7660 Label* deopt, | |
| 7661 bool use_near_jump); | |
| 7662 void EmitDenseSwitch(FlowGraphCompiler* compiler, | |
| 7663 intptr_t min, | |
| 7664 intptr_t max, | |
| 7665 intptr_t mask, | |
| 7666 Label* deopt); | |
| 7667 void EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt); | |
| 7668 | |
| 7638 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); | 7669 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); |
| 7639 }; | 7670 }; |
| 7640 | 7671 |
| 7641 | 7672 |
| 7642 class CheckSmiInstr : public TemplateInstruction<1, NoThrow, Pure> { | 7673 class CheckSmiInstr : public TemplateInstruction<1, NoThrow, Pure> { |
| 7643 public: | 7674 public: |
| 7644 CheckSmiInstr(Value* value, intptr_t deopt_id, TokenPosition token_pos) | 7675 CheckSmiInstr(Value* value, intptr_t deopt_id, TokenPosition token_pos) |
| 7645 : TemplateInstruction(deopt_id), | 7676 : TemplateInstruction(deopt_id), |
| 7646 token_pos_(token_pos), | 7677 token_pos_(token_pos), |
| 7647 licm_hoisted_(false) { | 7678 licm_hoisted_(false) { |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8114 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ | 8145 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ |
| 8115 UNIMPLEMENTED(); \ | 8146 UNIMPLEMENTED(); \ |
| 8116 return NULL; \ | 8147 return NULL; \ |
| 8117 } \ | 8148 } \ |
| 8118 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } | 8149 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } |
| 8119 | 8150 |
| 8120 | 8151 |
| 8121 } // namespace dart | 8152 } // namespace dart |
| 8122 | 8153 |
| 8123 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 8154 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |