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

Side by Side Diff: runtime/vm/intermediate_language.h

Issue 2856543002: Use off-heap data for class check instructions (Closed)
Patch Set: Created 3 years, 7 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
OLDNEW
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698