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

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

Issue 12529008: Collect type feedback for fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 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 | Annotate | Revision Log
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 VM_INTERMEDIATE_LANGUAGE_H_ 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_
6 #define VM_INTERMEDIATE_LANGUAGE_H_ 6 #define 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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 cid_(other.cid_), 135 cid_(other.cid_),
136 type_(other.type_) { } 136 type_(other.type_) { }
137 137
138 CompileType& operator=(const CompileType& other) { 138 CompileType& operator=(const CompileType& other) {
139 is_nullable_ = other.is_nullable_; 139 is_nullable_ = other.is_nullable_;
140 cid_ = other.cid_; 140 cid_ = other.cid_;
141 type_ = other.type_; 141 type_ = other.type_;
142 return *this; 142 return *this;
143 } 143 }
144 144
145 bool is_nullable() const { return is_nullable_; }
146
145 // Return type such that concrete value's type in runtime is guaranteed to 147 // Return type such that concrete value's type in runtime is guaranteed to
146 // be subtype of it. 148 // be subtype of it.
147 const AbstractType* ToAbstractType(); 149 const AbstractType* ToAbstractType();
148 150
149 // Return class id such that it is either kDynamicCid or in runtime 151 // Return class id such that it is either kDynamicCid or in runtime
150 // value is guaranteed to have an equal class id. 152 // value is guaranteed to have an equal class id.
151 intptr_t ToCid(); 153 intptr_t ToCid();
152 154
153 // Return class id such that it is either kDynamicCid or in runtime 155 // Return class id such that it is either kDynamicCid or in runtime
154 // value is guaranteed to be either null or have an equal class id. 156 // value is guaranteed to be either null or have an equal class id.
(...skipping 14 matching lines...) Expand all
169 bool IsAssignableTo(const AbstractType& type) { 171 bool IsAssignableTo(const AbstractType& type) {
170 bool is_instance; 172 bool is_instance;
171 return CanComputeIsInstanceOf(type, kNullable, &is_instance) && 173 return CanComputeIsInstanceOf(type, kNullable, &is_instance) &&
172 is_instance; 174 is_instance;
173 } 175 }
174 176
175 // Create a new CompileType representing given combination of class id and 177 // Create a new CompileType representing given combination of class id and
176 // abstract type. The pair is assumed to be coherent. 178 // abstract type. The pair is assumed to be coherent.
177 static CompileType Create(intptr_t cid, const AbstractType& type); 179 static CompileType Create(intptr_t cid, const AbstractType& type);
178 180
181 CompileType CopyNonNullable() const {
182 return CompileType(kNonNullable, cid_, type_);
183 }
184
185 static CompileType CreateNullable(bool is_nullable, intptr_t cid) {
186 return CompileType(is_nullable, cid, NULL);
187 }
188
179 // Create a new CompileType representing given abstract type. By default 189 // Create a new CompileType representing given abstract type. By default
180 // values as assumed to be nullable. 190 // values as assumed to be nullable.
181 static CompileType FromAbstractType(const AbstractType& type, 191 static CompileType FromAbstractType(const AbstractType& type,
182 bool is_nullable = kNullable); 192 bool is_nullable = kNullable);
183 193
184 // Create a new CompileType representing an value with the given class id. 194 // Create a new CompileType representing an value with the given class id.
185 // Resulting CompileType is nullable only if cid is kDynamicCid or kNullCid. 195 // Resulting CompileType is nullable only if cid is kDynamicCid or kNullCid.
186 static CompileType FromCid(intptr_t cid); 196 static CompileType FromCid(intptr_t cid);
187 197
188 // Create None CompileType. It is the bottom of the lattice and is used to 198 // Create None CompileType. It is the bottom of the lattice and is used to
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 M(BoxDouble) \ 484 M(BoxDouble) \
475 M(UnboxInteger) \ 485 M(UnboxInteger) \
476 M(BoxInteger) \ 486 M(BoxInteger) \
477 M(BinaryMintOp) \ 487 M(BinaryMintOp) \
478 M(ShiftMintOp) \ 488 M(ShiftMintOp) \
479 M(UnaryMintOp) \ 489 M(UnaryMintOp) \
480 M(CheckArrayBound) \ 490 M(CheckArrayBound) \
481 M(Constraint) \ 491 M(Constraint) \
482 M(StringFromCharCode) \ 492 M(StringFromCharCode) \
483 M(InvokeMathCFunction) \ 493 M(InvokeMathCFunction) \
494 M(GuardField) \
484 495
485 496
486 #define FORWARD_DECLARATION(type) class type##Instr; 497 #define FORWARD_DECLARATION(type) class type##Instr;
487 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) 498 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
488 #undef FORWARD_DECLARATION 499 #undef FORWARD_DECLARATION
489 500
490 501
491 // Functions required in all concrete instruction classes. 502 // Functions required in all concrete instruction classes.
492 #define DECLARE_INSTRUCTION(type) \ 503 #define DECLARE_INSTRUCTION(type) \
493 virtual Tag tag() const { return k##type; } \ 504 virtual Tag tag() const { return k##type; } \
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 friend class UnboxIntegerInstr; 734 friend class UnboxIntegerInstr;
724 friend class UnboxDoubleInstr; 735 friend class UnboxDoubleInstr;
725 friend class BinaryDoubleOpInstr; 736 friend class BinaryDoubleOpInstr;
726 friend class BinaryMintOpInstr; 737 friend class BinaryMintOpInstr;
727 friend class BinarySmiOpInstr; 738 friend class BinarySmiOpInstr;
728 friend class UnarySmiOpInstr; 739 friend class UnarySmiOpInstr;
729 friend class ShiftMintOpInstr; 740 friend class ShiftMintOpInstr;
730 friend class UnaryMintOpInstr; 741 friend class UnaryMintOpInstr;
731 friend class MathSqrtInstr; 742 friend class MathSqrtInstr;
732 friend class CheckClassInstr; 743 friend class CheckClassInstr;
744 friend class GuardFieldInstr;
733 friend class CheckSmiInstr; 745 friend class CheckSmiInstr;
734 friend class CheckArrayBoundInstr; 746 friend class CheckArrayBoundInstr;
735 friend class CheckEitherNonSmiInstr; 747 friend class CheckEitherNonSmiInstr;
736 friend class LICM; 748 friend class LICM;
737 friend class DoubleToSmiInstr; 749 friend class DoubleToSmiInstr;
738 friend class DoubleToDoubleInstr; 750 friend class DoubleToDoubleInstr;
739 friend class InvokeMathCFunctionInstr; 751 friend class InvokeMathCFunctionInstr;
740 friend class FlowGraphOptimizer; 752 friend class FlowGraphOptimizer;
741 friend class LoadIndexedInstr; 753 friend class LoadIndexedInstr;
742 friend class StoreIndexedInstr; 754 friend class StoreIndexedInstr;
755 friend class StoreInstanceFieldInstr;
743 756
744 virtual void RawSetInputAt(intptr_t i, Value* value) = 0; 757 virtual void RawSetInputAt(intptr_t i, Value* value) = 0;
745 758
746 intptr_t deopt_id_; 759 intptr_t deopt_id_;
747 intptr_t lifetime_position_; // Position used by register allocator. 760 intptr_t lifetime_position_; // Position used by register allocator.
748 Instruction* previous_; 761 Instruction* previous_;
749 Instruction* next_; 762 Instruction* next_;
750 Environment* env_; 763 Environment* env_;
751 intptr_t expr_id_; 764 intptr_t expr_id_;
752 765
(...skipping 1995 matching lines...) Expand 10 before | Expand all | Expand 10 after
2748 kNoStoreBarrier, 2761 kNoStoreBarrier,
2749 kEmitStoreBarrier 2762 kEmitStoreBarrier
2750 }; 2763 };
2751 2764
2752 2765
2753 class StoreInstanceFieldInstr : public TemplateDefinition<2> { 2766 class StoreInstanceFieldInstr : public TemplateDefinition<2> {
2754 public: 2767 public:
2755 StoreInstanceFieldInstr(const Field& field, 2768 StoreInstanceFieldInstr(const Field& field,
2756 Value* instance, 2769 Value* instance,
2757 Value* value, 2770 Value* value,
2758 StoreBarrierType emit_store_barrier) 2771 StoreBarrierType emit_store_barrier,
2759 : field_(field), emit_store_barrier_(emit_store_barrier) { 2772 bool emit_field_guard = true)
2773 : field_(field),
2774 emit_store_barrier_(emit_store_barrier),
2775 emit_field_guard_(emit_field_guard) {
2760 SetInputAt(0, instance); 2776 SetInputAt(0, instance);
2761 SetInputAt(1, value); 2777 SetInputAt(1, value);
2762 } 2778 }
2763 2779
2780 void SetDeoptId(intptr_t deopt_id) {
2781 ASSERT(CanDeoptimize());
2782 deopt_id_ = deopt_id;
2783 }
2784
2764 DECLARE_INSTRUCTION(StoreInstanceField) 2785 DECLARE_INSTRUCTION(StoreInstanceField)
2765 virtual CompileType* ComputeInitialType() const; 2786 virtual CompileType* ComputeInitialType() const;
2766 2787
2767 const Field& field() const { return field_; } 2788 const Field& field() const { return field_; }
2768 2789
2769 Value* instance() const { return inputs_[0]; } 2790 Value* instance() const { return inputs_[0]; }
2770 Value* value() const { return inputs_[1]; } 2791 Value* value() const { return inputs_[1]; }
2771 bool ShouldEmitStoreBarrier() const { 2792 bool ShouldEmitStoreBarrier() const {
2772 return value()->NeedsStoreBuffer() 2793 return value()->NeedsStoreBuffer()
2773 && (emit_store_barrier_ == kEmitStoreBarrier); 2794 && (emit_store_barrier_ == kEmitStoreBarrier);
2774 } 2795 }
2775 2796
2776 virtual void PrintOperandsTo(BufferFormatter* f) const; 2797 virtual void PrintOperandsTo(BufferFormatter* f) const;
2777 2798
2778 virtual bool CanDeoptimize() const { return false; } 2799 virtual bool CanDeoptimize() const { return emit_field_guard_; }
2779 2800
2780 virtual bool HasSideEffect() const { return true; } 2801 virtual bool HasSideEffect() const { return true; }
2781 2802
2803 void detach_field_guard() { emit_field_guard_ = false; }
2804
2805 bool should_emit_field_guard() const { return emit_field_guard_; }
2806
2782 private: 2807 private:
2783 const Field& field_; 2808 const Field& field_;
2784 const StoreBarrierType emit_store_barrier_; 2809 const StoreBarrierType emit_store_barrier_;
2810 bool emit_field_guard_;
2785 2811
2786 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr); 2812 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr);
2787 }; 2813 };
2788 2814
2789 2815
2816 class GuardFieldInstr : public TemplateInstruction<1> {
2817 public:
2818 GuardFieldInstr(Value* value,
2819 const Field& field,
2820 intptr_t deopt_id)
2821 : field_(field) {
2822 deopt_id_ = deopt_id;
2823 SetInputAt(0, value);
2824 }
2825
2826 DECLARE_INSTRUCTION(GuardField)
2827
2828 virtual intptr_t ArgumentCount() const { return 0; }
2829
2830 virtual bool CanDeoptimize() const { return env() != NULL; }
2831
2832 virtual bool HasSideEffect() const { return false; }
2833
2834 virtual bool AttributesEqual(Instruction* other) const;
2835
2836 virtual bool AffectedBySideEffect() const;
2837
2838 Value* value() const { return inputs_[0]; }
2839
2840 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer);
2841
2842 virtual void PrintOperandsTo(BufferFormatter* f) const;
2843
2844 const Field& field() const { return field_; }
2845
2846 private:
2847 const Field& field_;
2848
2849 DISALLOW_COPY_AND_ASSIGN(GuardFieldInstr);
2850 };
2851
2852
2790 class LoadStaticFieldInstr : public TemplateDefinition<0> { 2853 class LoadStaticFieldInstr : public TemplateDefinition<0> {
2791 public: 2854 public:
2792 explicit LoadStaticFieldInstr(const Field& field) : field_(field) {} 2855 explicit LoadStaticFieldInstr(const Field& field) : field_(field) {}
2793 2856
2794 DECLARE_INSTRUCTION(LoadStaticField); 2857 DECLARE_INSTRUCTION(LoadStaticField);
2795 virtual CompileType ComputeType() const; 2858 virtual CompileType ComputeType() const;
2796 2859
2797 const Field& field() const { return field_; } 2860 const Field& field() const { return field_; }
2798 2861
2799 virtual void PrintOperandsTo(BufferFormatter* f) const; 2862 virtual void PrintOperandsTo(BufferFormatter* f) const;
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
3173 class LoadFieldInstr : public TemplateDefinition<1> { 3236 class LoadFieldInstr : public TemplateDefinition<1> {
3174 public: 3237 public:
3175 LoadFieldInstr(Value* value, 3238 LoadFieldInstr(Value* value,
3176 intptr_t offset_in_bytes, 3239 intptr_t offset_in_bytes,
3177 const AbstractType& type, 3240 const AbstractType& type,
3178 bool immutable = false) 3241 bool immutable = false)
3179 : offset_in_bytes_(offset_in_bytes), 3242 : offset_in_bytes_(offset_in_bytes),
3180 type_(type), 3243 type_(type),
3181 result_cid_(kDynamicCid), 3244 result_cid_(kDynamicCid),
3182 immutable_(immutable), 3245 immutable_(immutable),
3183 recognized_kind_(MethodRecognizer::kUnknown) { 3246 recognized_kind_(MethodRecognizer::kUnknown),
3247 field_name_(NULL),
3248 field_(NULL) {
3184 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance. 3249 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance.
3185 SetInputAt(0, value); 3250 SetInputAt(0, value);
3186 } 3251 }
3187 3252
3188 DECLARE_INSTRUCTION(LoadField) 3253 DECLARE_INSTRUCTION(LoadField)
3189 virtual CompileType ComputeType() const; 3254 virtual CompileType ComputeType() const;
3190 3255
3191 Value* value() const { return inputs_[0]; } 3256 Value* value() const { return inputs_[0]; }
3192 intptr_t offset_in_bytes() const { return offset_in_bytes_; } 3257 intptr_t offset_in_bytes() const { return offset_in_bytes_; }
3193 const AbstractType& type() const { return type_; } 3258 const AbstractType& type() const { return type_; }
(...skipping 20 matching lines...) Expand all
3214 } 3279 }
3215 3280
3216 bool IsImmutableLengthLoad() const; 3281 bool IsImmutableLengthLoad() const;
3217 3282
3218 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer); 3283 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
3219 3284
3220 static MethodRecognizer::Kind RecognizedKindFromArrayCid(intptr_t cid); 3285 static MethodRecognizer::Kind RecognizedKindFromArrayCid(intptr_t cid);
3221 3286
3222 static bool IsFixedLengthArrayCid(intptr_t cid); 3287 static bool IsFixedLengthArrayCid(intptr_t cid);
3223 3288
3289 void set_field_name(const char* name) { field_name_ = name; }
3290 const char* field_name() const { return field_name_; }
3291
3292 Field* field() const { return field_; }
3293 void set_field(Field* field) { field_ = field; }
3294
3224 private: 3295 private:
3225 const intptr_t offset_in_bytes_; 3296 const intptr_t offset_in_bytes_;
3226 const AbstractType& type_; 3297 const AbstractType& type_;
3227 intptr_t result_cid_; 3298 intptr_t result_cid_;
3228 const bool immutable_; 3299 const bool immutable_;
3229 3300
3230 MethodRecognizer::Kind recognized_kind_; 3301 MethodRecognizer::Kind recognized_kind_;
3231 3302
3303 const char* field_name_;
3304 Field* field_;
3305
3232 DISALLOW_COPY_AND_ASSIGN(LoadFieldInstr); 3306 DISALLOW_COPY_AND_ASSIGN(LoadFieldInstr);
3233 }; 3307 };
3234 3308
3235 3309
3236 class StoreVMFieldInstr : public TemplateDefinition<2> { 3310 class StoreVMFieldInstr : public TemplateDefinition<2> {
3237 public: 3311 public:
3238 StoreVMFieldInstr(Value* dest, 3312 StoreVMFieldInstr(Value* dest,
3239 intptr_t offset_in_bytes, 3313 intptr_t offset_in_bytes,
3240 Value* value, 3314 Value* value,
3241 const AbstractType& type) 3315 const AbstractType& type)
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after
4206 virtual bool AffectedBySideEffect() const; 4280 virtual bool AffectedBySideEffect() const;
4207 4281
4208 Value* value() const { return inputs_[0]; } 4282 Value* value() const { return inputs_[0]; }
4209 4283
4210 const ICData& unary_checks() const { return unary_checks_; } 4284 const ICData& unary_checks() const { return unary_checks_; }
4211 4285
4212 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer); 4286 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer);
4213 4287
4214 virtual void PrintOperandsTo(BufferFormatter* f) const; 4288 virtual void PrintOperandsTo(BufferFormatter* f) const;
4215 4289
4290 void set_null_check(bool flag) { null_check_ = flag; }
4291
4292 bool null_check() const { return null_check_; }
4293
4216 private: 4294 private:
4217 const ICData& unary_checks_; 4295 const ICData& unary_checks_;
4218 4296
4297 bool null_check_;
4298
4219 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); 4299 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr);
4220 }; 4300 };
4221 4301
4222 4302
4223 class CheckSmiInstr : public TemplateInstruction<1> { 4303 class CheckSmiInstr : public TemplateInstruction<1> {
4224 public: 4304 public:
4225 CheckSmiInstr(Value* value, intptr_t original_deopt_id) { 4305 CheckSmiInstr(Value* value, intptr_t original_deopt_id) {
4226 ASSERT(original_deopt_id != Isolate::kNoDeoptId); 4306 ASSERT(original_deopt_id != Isolate::kNoDeoptId);
4227 SetInputAt(0, value); 4307 SetInputAt(0, value);
4228 deopt_id_ = original_deopt_id; 4308 deopt_id_ = original_deopt_id;
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
4514 ForwardInstructionIterator* current_iterator_; 4594 ForwardInstructionIterator* current_iterator_;
4515 4595
4516 private: 4596 private:
4517 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 4597 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
4518 }; 4598 };
4519 4599
4520 4600
4521 } // namespace dart 4601 } // namespace dart
4522 4602
4523 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 4603 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698