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

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

Issue 2856543002: Use off-heap data for class check instructions (Closed)
Patch Set: Feedback from Slava: rejig inheritance of CallTargets 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"
11 #include "vm/locations.h" 11 #include "vm/locations.h"
12 #include "vm/method_recognizer.h" 12 #include "vm/method_recognizer.h"
13 #include "vm/object.h" 13 #include "vm/object.h"
14 #include "vm/parser.h" 14 #include "vm/parser.h"
15 #include "vm/token_position.h" 15 #include "vm/token_position.h"
16 16
17 namespace dart { 17 namespace dart {
18 18
19 class BitVector; 19 class BitVector;
20 class BlockEntryInstr; 20 class BlockEntryInstr;
21 class BoxIntegerInstr; 21 class BoxIntegerInstr;
22 class BufferFormatter; 22 class BufferFormatter;
23 class CallTargets;
23 class CatchBlockEntryInstr; 24 class CatchBlockEntryInstr;
24 class ComparisonInstr; 25 class ComparisonInstr;
25 class Definition; 26 class Definition;
26 class Environment; 27 class Environment;
27 class FlowGraph; 28 class FlowGraph;
28 class FlowGraphBuilder; 29 class FlowGraphBuilder;
29 class FlowGraphCompiler; 30 class FlowGraphCompiler;
30 class FlowGraphVisitor; 31 class FlowGraphVisitor;
31 class Instruction; 32 class Instruction;
32 class LocalVariable; 33 class LocalVariable;
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 #endif // !PRODUCT 543 #endif // !PRODUCT
543 544
544 #ifndef PRODUCT 545 #ifndef PRODUCT
545 #define PRINT_OPERANDS_TO_SUPPORT \ 546 #define PRINT_OPERANDS_TO_SUPPORT \
546 virtual void PrintOperandsTo(BufferFormatter* f) const; 547 virtual void PrintOperandsTo(BufferFormatter* f) const;
547 #else 548 #else
548 #define PRINT_OPERANDS_TO_SUPPORT 549 #define PRINT_OPERANDS_TO_SUPPORT
549 #endif // !PRODUCT 550 #endif // !PRODUCT
550 551
551 552
552 // Represents a mapping from a range of class-ids to a method for a given 553 // Represents a range of class-ids for use in class checks and polymorphic
553 // selector (method name). Also can contain an indication of how frequently a 554 // dispatches.
554 // given method has been called at a call site. This information can be 555 struct CidRange : public ZoneAllocated {
555 // harvested from the inline caches (ICs).
556 struct CidRangeTarget {
557 intptr_t cid_start; 556 intptr_t cid_start;
558 intptr_t cid_end; 557 intptr_t cid_end;
559 Function* target; 558 CidRange(const CidRange& o)
Vyacheslav Egorov (Google) 2017/05/09 21:07:27 Please order constructors before fields.
erikcorry 2017/05/10 08:47:43 Done.
560 intptr_t count; 559 : ZoneAllocated(), cid_start(o.cid_start), cid_end(o.cid_end) {}
561 CidRangeTarget(intptr_t cid_start_arg, 560 CidRange(intptr_t cid_start_arg, intptr_t cid_end_arg)
562 intptr_t cid_end_arg, 561 : cid_start(cid_start_arg), cid_end(cid_end_arg) {}
563 Function* target_arg, 562 CidRange(intptr_t cid_start_arg,
Vyacheslav Egorov (Google) 2017/05/09 21:07:27 I don't think this constructor is used.
erikcorry 2017/05/10 08:47:43 Gone
564 intptr_t count_arg) 563 intptr_t cid_end_arg,
565 : cid_start(cid_start_arg), 564 const Function* target_arg,
566 cid_end(cid_end_arg), 565 intptr_t count_arg)
566 : cid_start(cid_start_arg), cid_end(cid_end_arg) {}
567 };
568
569
570 // Together with CidRange, this represents a mapping from a range of class-ids
571 // to a method for a given selector (method name). Also can contain an
572 // indication of how frequently a given method has been called at a call site.
573 // This information can be harvested from the inline caches (ICs).
574 struct TargetInfo : public CidRange {
575 TargetInfo(intptr_t cid_start_arg,
576 intptr_t cid_end_arg,
577 const Function* target_arg,
578 intptr_t count_arg)
579 : CidRange(cid_start_arg, cid_end_arg),
567 target(target_arg), 580 target(target_arg),
568 count(count_arg) { 581 count(count_arg) {
569 ASSERT(target->IsZoneHandle()); 582 ASSERT(target->IsZoneHandle());
570 } 583 }
584 const Function* target;
585 intptr_t count;
571 }; 586 };
572 587
573 588
574 class CallTargets : public ZoneAllocated { 589 // A set of class-ids, arranged in ranges. Used for the CheckClass
590 // and PolymorphicInstanceCall instructions.
591 class Cids : public ZoneAllocated {
575 public: 592 public:
576 // Creates the off-heap CallTargets object that reflects the contents 593 explicit Cids(Zone* zone) : zone_(zone) {}
577 // of the on-VM-heap IC data. Also expands the class-ids to neighbouring 594 // Creates the off-heap Cids object that reflects the contents
578 // classes that inherit the same method. 595 // of the on-VM-heap IC data.
579 static CallTargets* Create(Zone* zone, const ICData& ic_data); 596 static Cids* Create(Zone* zone, const ICData& ic_data, int argument_number);
597 static Cids* CreateMonomorphic(Zone* zone, intptr_t cid);
580 598
581 void Add(const CidRangeTarget& target) { cid_ranges_.Add(target); } 599 bool Equals(const Cids& other) const;
582 600
583 CidRangeTarget& operator[](intptr_t index) const { 601 bool HasClassId(intptr_t cid) const;
584 return cid_ranges_[index];
585 }
586 602
587 CidRangeTarget At(int index) { return cid_ranges_.At(index); } 603 void Add(CidRange* target) { cid_ranges_.Add(target); }
604
605 CidRange& operator[](intptr_t index) const { return *cid_ranges_[index]; }
606
607 CidRange* At(int index) const { return cid_ranges_[index]; }
588 608
589 intptr_t length() const { return cid_ranges_.length(); } 609 intptr_t length() const { return cid_ranges_.length(); }
590 610
591 void SetLength(intptr_t len) { cid_ranges_.SetLength(len); } 611 void SetLength(intptr_t len) { cid_ranges_.SetLength(len); }
592 612
593 bool is_empty() const { return cid_ranges_.is_empty(); } 613 bool is_empty() const { return cid_ranges_.is_empty(); }
594 614
595 void Sort(int compare(const CidRangeTarget* a, const CidRangeTarget* b)) { 615 void Sort(int compare(CidRange* const* a, CidRange* const* b)) {
596 cid_ranges_.Sort(compare); 616 cid_ranges_.Sort(compare);
597 } 617 }
598 618
619 bool IsMonomorphic() const;
620 intptr_t MonomorphicReceiverCid() const;
621 bool ContainsExternalizableCids() const;
622 intptr_t ComputeLowestCid() const;
623 intptr_t ComputeHighestCid() const;
624
625 protected:
626 void CreateHelper(Zone* zone,
627 const ICData& ic_data,
628 int argument_number,
629 bool include_targets);
630 GrowableArray<CidRange*> cid_ranges_;
631 Zone* zone_;
632
633 private:
634 DISALLOW_IMPLICIT_CONSTRUCTORS(Cids);
635 };
636
637
638 class CallTargets : public Cids {
639 public:
640 explicit CallTargets(Zone* zone) : Cids(zone) {}
641 // Creates the off-heap CallTargets object that reflects the contents
642 // of the on-VM-heap IC data.
643 static CallTargets* Create(Zone* zone, const ICData& ic_data);
644
645 // This variant also expands the class-ids to neighbouring classes that
646 // inherit the same method.
647 static CallTargets* CreateAndExpand(Zone* zone, const ICData& ic_data);
648
649 TargetInfo* TargetAt(int i) const {
650 return reinterpret_cast<TargetInfo*>(At(i));
Vyacheslav Egorov (Google) 2017/05/09 21:07:27 static_cast<TargetInfo*>(...)
erikcorry 2017/05/10 08:47:43 Done.
651 }
652
599 intptr_t AggregateCallCount() const; 653 intptr_t AggregateCallCount() const;
600 654
601 bool HasSingleTarget() const; 655 bool HasSingleTarget() const;
602 bool HasSingleRecognizedTarget() const; 656 bool HasSingleRecognizedTarget() const;
603 Function& FirstTarget() const; 657 const Function& FirstTarget() const;
604 Function& MostPopularTarget() const; 658 const Function& MostPopularTarget() const;
605 bool IsMonomorphic() const;
606 intptr_t MonomorphicReceiverCid() const;
607 659
608 private: 660 private:
609 GrowableArray<CidRangeTarget> cid_ranges_; 661 void MergeIntoRanges();
610 }; 662 };
611 663
612 664
613 class Instruction : public ZoneAllocated { 665 class Instruction : public ZoneAllocated {
614 public: 666 public:
615 #define DECLARE_TAG(type) k##type, 667 #define DECLARE_TAG(type) k##type,
616 enum Tag { FOR_EACH_INSTRUCTION(DECLARE_TAG) }; 668 enum Tag { FOR_EACH_INSTRUCTION(DECLARE_TAG) };
617 #undef DECLARE_TAG 669 #undef DECLARE_TAG
618 670
619 explicit Instruction(intptr_t deopt_id = Thread::kNoDeoptId) 671 explicit Instruction(intptr_t deopt_id = Thread::kNoDeoptId)
(...skipping 6964 matching lines...) Expand 10 before | Expand all | Expand 10 after
7584 ZoneGrowableArray<Value*>* inputs_; 7636 ZoneGrowableArray<Value*>* inputs_;
7585 MergedMathInstr::Kind kind_; 7637 MergedMathInstr::Kind kind_;
7586 DISALLOW_COPY_AND_ASSIGN(MergedMathInstr); 7638 DISALLOW_COPY_AND_ASSIGN(MergedMathInstr);
7587 }; 7639 };
7588 7640
7589 7641
7590 class CheckClassInstr : public TemplateInstruction<1, NoThrow> { 7642 class CheckClassInstr : public TemplateInstruction<1, NoThrow> {
7591 public: 7643 public:
7592 CheckClassInstr(Value* value, 7644 CheckClassInstr(Value* value,
7593 intptr_t deopt_id, 7645 intptr_t deopt_id,
7594 const ICData& unary_checks, 7646 const Cids& cids,
7595 TokenPosition token_pos); 7647 TokenPosition token_pos);
7596 7648
7597 DECLARE_INSTRUCTION(CheckClass) 7649 DECLARE_INSTRUCTION(CheckClass)
7598 7650
7599 virtual bool ComputeCanDeoptimize() const { return true; } 7651 virtual bool ComputeCanDeoptimize() const { return true; }
7600 7652
7601 virtual TokenPosition token_pos() const { return token_pos_; } 7653 virtual TokenPosition token_pos() const { return token_pos_; }
7602 7654
7603 Value* value() const { return inputs_[0]; } 7655 Value* value() const { return inputs_[0]; }
7604 7656
7605 const ICData& unary_checks() const { return unary_checks_; } 7657 const Cids& cids() const { return cids_; }
7606
7607 const GrowableArray<intptr_t>& cids() const { return cids_; }
7608 7658
7609 virtual Instruction* Canonicalize(FlowGraph* flow_graph); 7659 virtual Instruction* Canonicalize(FlowGraph* flow_graph);
7610 7660
7611 bool IsNullCheck() const { return DeoptIfNull() || DeoptIfNotNull(); } 7661 bool IsNullCheck() const { return IsDeoptIfNull() || IsDeoptIfNotNull(); }
7612 7662
7613 bool DeoptIfNull() const; 7663 bool IsDeoptIfNull() const;
7614 bool DeoptIfNotNull() const; 7664 bool IsDeoptIfNotNull() const;
7615 7665
7616 bool IsDenseSwitch() const; 7666 bool IsBitTest() const;
7617 static bool IsDenseCidRange(const ICData& unary_checks); 7667 static bool IsCompactCidRange(const Cids& cids);
7618 intptr_t ComputeCidMask() const; 7668 intptr_t ComputeCidMask() const;
7619 static bool IsDenseMask(intptr_t mask);
7620 7669
7621 virtual bool AllowsCSE() const { return true; } 7670 virtual bool AllowsCSE() const { return true; }
7622 virtual EffectSet Dependencies() const; 7671 virtual EffectSet Dependencies() const;
7623 virtual EffectSet Effects() const { return EffectSet::None(); } 7672 virtual EffectSet Effects() const { return EffectSet::None(); }
7624 virtual bool AttributesEqual(Instruction* other) const; 7673 virtual bool AttributesEqual(Instruction* other) const;
7625 7674
7626 bool licm_hoisted() const { return licm_hoisted_; } 7675 bool licm_hoisted() const { return licm_hoisted_; }
7627 void set_licm_hoisted(bool value) { licm_hoisted_ = value; } 7676 void set_licm_hoisted(bool value) { licm_hoisted_ = value; }
7628 7677
7629 PRINT_OPERANDS_TO_SUPPORT 7678 PRINT_OPERANDS_TO_SUPPORT
7630 7679
7631 private: 7680 private:
7632 const ICData& unary_checks_; 7681 const Cids& cids_;
7633 GrowableArray<intptr_t> cids_; // Sorted, lowest first.
7634 bool licm_hoisted_; 7682 bool licm_hoisted_;
7635 bool is_dense_switch_; 7683 bool is_bit_test_;
7636 const TokenPosition token_pos_; 7684 const TokenPosition token_pos_;
7637 7685
7686 int EmitCheckCid(FlowGraphCompiler* compiler,
7687 int bias,
7688 intptr_t cid_start,
7689 intptr_t cid_end,
7690 bool is_last,
7691 Label* is_ok,
7692 Label* deopt,
7693 bool use_near_jump);
7694 void EmitBitTest(FlowGraphCompiler* compiler,
7695 intptr_t min,
7696 intptr_t max,
7697 intptr_t mask,
7698 Label* deopt);
7699 void EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt);
7700
7638 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); 7701 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr);
7639 }; 7702 };
7640 7703
7641 7704
7642 class CheckSmiInstr : public TemplateInstruction<1, NoThrow, Pure> { 7705 class CheckSmiInstr : public TemplateInstruction<1, NoThrow, Pure> {
7643 public: 7706 public:
7644 CheckSmiInstr(Value* value, intptr_t deopt_id, TokenPosition token_pos) 7707 CheckSmiInstr(Value* value, intptr_t deopt_id, TokenPosition token_pos)
7645 : TemplateInstruction(deopt_id), 7708 : TemplateInstruction(deopt_id),
7646 token_pos_(token_pos), 7709 token_pos_(token_pos),
7647 licm_hoisted_(false) { 7710 licm_hoisted_(false) {
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
8114 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ 8177 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \
8115 UNIMPLEMENTED(); \ 8178 UNIMPLEMENTED(); \
8116 return NULL; \ 8179 return NULL; \
8117 } \ 8180 } \
8118 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } 8181 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
8119 8182
8120 8183
8121 } // namespace dart 8184 } // namespace dart
8122 8185
8123 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ 8186 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698