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

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: rewritten instruction pattern on ia32 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 1996 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 : field_(field),
2773 emit_store_barrier_(emit_store_barrier) {
2760 SetInputAt(0, instance); 2774 SetInputAt(0, instance);
2761 SetInputAt(1, value); 2775 SetInputAt(1, value);
2762 } 2776 }
2763 2777
2778 void SetDeoptId(intptr_t deopt_id) {
2779 ASSERT(CanDeoptimize());
2780 deopt_id_ = deopt_id;
2781 }
2782
2764 DECLARE_INSTRUCTION(StoreInstanceField) 2783 DECLARE_INSTRUCTION(StoreInstanceField)
2765 virtual CompileType* ComputeInitialType() const; 2784 virtual CompileType* ComputeInitialType() const;
2766 2785
2767 const Field& field() const { return field_; } 2786 const Field& field() const { return field_; }
2768 2787
2769 Value* instance() const { return inputs_[0]; } 2788 Value* instance() const { return inputs_[0]; }
2770 Value* value() const { return inputs_[1]; } 2789 Value* value() const { return inputs_[1]; }
2771 bool ShouldEmitStoreBarrier() const { 2790 bool ShouldEmitStoreBarrier() const {
2772 return value()->NeedsStoreBuffer() 2791 return value()->NeedsStoreBuffer()
2773 && (emit_store_barrier_ == kEmitStoreBarrier); 2792 && (emit_store_barrier_ == kEmitStoreBarrier);
2774 } 2793 }
2775 2794
2776 virtual void PrintOperandsTo(BufferFormatter* f) const; 2795 virtual void PrintOperandsTo(BufferFormatter* f) const;
2777 2796
2778 virtual bool CanDeoptimize() const { return false; } 2797 virtual bool CanDeoptimize() const { return false; }
2779 2798
2780 virtual bool HasSideEffect() const { return true; } 2799 virtual bool HasSideEffect() const { return true; }
2781 2800
2782 private: 2801 private:
2783 const Field& field_; 2802 const Field& field_;
2784 const StoreBarrierType emit_store_barrier_; 2803 const StoreBarrierType emit_store_barrier_;
2785 2804
2786 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr); 2805 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr);
2787 }; 2806 };
2788 2807
2789 2808
2809 class GuardFieldInstr : public TemplateInstruction<1> {
2810 public:
2811 GuardFieldInstr(Value* value,
2812 const Field& field,
2813 intptr_t deopt_id)
2814 : field_(field) {
2815 deopt_id_ = deopt_id;
2816 SetInputAt(0, value);
2817 }
2818
2819 DECLARE_INSTRUCTION(GuardField)
2820
2821 virtual intptr_t ArgumentCount() const { return 0; }
2822
2823 virtual bool CanDeoptimize() const { return true; }
2824
2825 virtual bool HasSideEffect() const { return false; }
2826
2827 virtual bool AttributesEqual(Instruction* other) const;
2828
2829 virtual bool AffectedBySideEffect() const;
2830
2831 Value* value() const { return inputs_[0]; }
2832
2833 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer);
2834
2835 virtual void PrintOperandsTo(BufferFormatter* f) const;
2836
2837 const Field& field() const { return field_; }
2838
2839 private:
2840 const Field& field_;
2841
2842 DISALLOW_COPY_AND_ASSIGN(GuardFieldInstr);
2843 };
2844
2845
2790 class LoadStaticFieldInstr : public TemplateDefinition<0> { 2846 class LoadStaticFieldInstr : public TemplateDefinition<0> {
2791 public: 2847 public:
2792 explicit LoadStaticFieldInstr(const Field& field) : field_(field) {} 2848 explicit LoadStaticFieldInstr(const Field& field) : field_(field) {}
2793 2849
2794 DECLARE_INSTRUCTION(LoadStaticField); 2850 DECLARE_INSTRUCTION(LoadStaticField);
2795 virtual CompileType ComputeType() const; 2851 virtual CompileType ComputeType() const;
2796 2852
2797 const Field& field() const { return field_; } 2853 const Field& field() const { return field_; }
2798 2854
2799 virtual void PrintOperandsTo(BufferFormatter* f) const; 2855 virtual void PrintOperandsTo(BufferFormatter* f) const;
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
3173 class LoadFieldInstr : public TemplateDefinition<1> { 3229 class LoadFieldInstr : public TemplateDefinition<1> {
3174 public: 3230 public:
3175 LoadFieldInstr(Value* value, 3231 LoadFieldInstr(Value* value,
3176 intptr_t offset_in_bytes, 3232 intptr_t offset_in_bytes,
3177 const AbstractType& type, 3233 const AbstractType& type,
3178 bool immutable = false) 3234 bool immutable = false)
3179 : offset_in_bytes_(offset_in_bytes), 3235 : offset_in_bytes_(offset_in_bytes),
3180 type_(type), 3236 type_(type),
3181 result_cid_(kDynamicCid), 3237 result_cid_(kDynamicCid),
3182 immutable_(immutable), 3238 immutable_(immutable),
3183 recognized_kind_(MethodRecognizer::kUnknown) { 3239 recognized_kind_(MethodRecognizer::kUnknown),
3240 field_name_(NULL),
3241 field_(NULL) {
3184 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance. 3242 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance.
3185 SetInputAt(0, value); 3243 SetInputAt(0, value);
3186 } 3244 }
3187 3245
3188 DECLARE_INSTRUCTION(LoadField) 3246 DECLARE_INSTRUCTION(LoadField)
3189 virtual CompileType ComputeType() const; 3247 virtual CompileType ComputeType() const;
3190 3248
3191 Value* value() const { return inputs_[0]; } 3249 Value* value() const { return inputs_[0]; }
3192 intptr_t offset_in_bytes() const { return offset_in_bytes_; } 3250 intptr_t offset_in_bytes() const { return offset_in_bytes_; }
3193 const AbstractType& type() const { return type_; } 3251 const AbstractType& type() const { return type_; }
(...skipping 20 matching lines...) Expand all
3214 } 3272 }
3215 3273
3216 bool IsImmutableLengthLoad() const; 3274 bool IsImmutableLengthLoad() const;
3217 3275
3218 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer); 3276 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
3219 3277
3220 static MethodRecognizer::Kind RecognizedKindFromArrayCid(intptr_t cid); 3278 static MethodRecognizer::Kind RecognizedKindFromArrayCid(intptr_t cid);
3221 3279
3222 static bool IsFixedLengthArrayCid(intptr_t cid); 3280 static bool IsFixedLengthArrayCid(intptr_t cid);
3223 3281
3282 void set_field_name(const char* name) { field_name_ = name; }
3283 const char* field_name() const { return field_name_; }
3284
3285 Field* field() const { return field_; }
3286 void set_field(Field* field) { field_ = field; }
3287
3224 private: 3288 private:
3225 const intptr_t offset_in_bytes_; 3289 const intptr_t offset_in_bytes_;
3226 const AbstractType& type_; 3290 const AbstractType& type_;
3227 intptr_t result_cid_; 3291 intptr_t result_cid_;
3228 const bool immutable_; 3292 const bool immutable_;
3229 3293
3230 MethodRecognizer::Kind recognized_kind_; 3294 MethodRecognizer::Kind recognized_kind_;
3231 3295
3296 const char* field_name_;
3297 Field* field_;
3298
3232 DISALLOW_COPY_AND_ASSIGN(LoadFieldInstr); 3299 DISALLOW_COPY_AND_ASSIGN(LoadFieldInstr);
3233 }; 3300 };
3234 3301
3235 3302
3236 class StoreVMFieldInstr : public TemplateDefinition<2> { 3303 class StoreVMFieldInstr : public TemplateDefinition<2> {
3237 public: 3304 public:
3238 StoreVMFieldInstr(Value* dest, 3305 StoreVMFieldInstr(Value* dest,
3239 intptr_t offset_in_bytes, 3306 intptr_t offset_in_bytes,
3240 Value* value, 3307 Value* value,
3241 const AbstractType& type) 3308 const AbstractType& type)
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after
4206 virtual bool AffectedBySideEffect() const; 4273 virtual bool AffectedBySideEffect() const;
4207 4274
4208 Value* value() const { return inputs_[0]; } 4275 Value* value() const { return inputs_[0]; }
4209 4276
4210 const ICData& unary_checks() const { return unary_checks_; } 4277 const ICData& unary_checks() const { return unary_checks_; }
4211 4278
4212 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer); 4279 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer);
4213 4280
4214 virtual void PrintOperandsTo(BufferFormatter* f) const; 4281 virtual void PrintOperandsTo(BufferFormatter* f) const;
4215 4282
4283 void set_null_check(bool flag) { null_check_ = flag; }
4284
4285 bool null_check() const { return null_check_; }
4286
4216 private: 4287 private:
4217 const ICData& unary_checks_; 4288 const ICData& unary_checks_;
4218 4289
4290 bool null_check_;
4291
4219 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); 4292 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr);
4220 }; 4293 };
4221 4294
4222 4295
4223 class CheckSmiInstr : public TemplateInstruction<1> { 4296 class CheckSmiInstr : public TemplateInstruction<1> {
4224 public: 4297 public:
4225 CheckSmiInstr(Value* value, intptr_t original_deopt_id) { 4298 CheckSmiInstr(Value* value, intptr_t original_deopt_id) {
4226 ASSERT(original_deopt_id != Isolate::kNoDeoptId); 4299 ASSERT(original_deopt_id != Isolate::kNoDeoptId);
4227 SetInputAt(0, value); 4300 SetInputAt(0, value);
4228 deopt_id_ = original_deopt_id; 4301 deopt_id_ = original_deopt_id;
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
4514 ForwardInstructionIterator* current_iterator_; 4587 ForwardInstructionIterator* current_iterator_;
4515 4588
4516 private: 4589 private:
4517 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 4590 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
4518 }; 4591 };
4519 4592
4520 4593
4521 } // namespace dart 4594 } // namespace dart
4522 4595
4523 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 4596 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698