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

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

Issue 254723003: Remember all deopt reasons in ic_data, not just the last one. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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
« no previous file with comments | « runtime/vm/intermediate_language_x64.cc ('k') | runtime/vm/object.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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_OBJECT_H_ 5 #ifndef VM_OBJECT_H_
6 #define VM_OBJECT_H_ 6 #define VM_OBJECT_H_
7 7
8 #include "include/dart_api.h" 8 #include "include/dart_api.h"
9 #include "platform/assert.h" 9 #include "platform/assert.h"
10 #include "platform/utils.h" 10 #include "platform/utils.h"
(...skipping 3162 matching lines...) Expand 10 before | Expand all | Expand 10 after
3173 return &raw_ptr()->data_[data_index]; 3173 return &raw_ptr()->data_[data_index];
3174 } 3174 }
3175 3175
3176 void SetLength(intptr_t value) const; 3176 void SetLength(intptr_t value) const;
3177 3177
3178 FINAL_HEAP_OBJECT_IMPLEMENTATION(DeoptInfo, Object); 3178 FINAL_HEAP_OBJECT_IMPLEMENTATION(DeoptInfo, Object);
3179 friend class Class; 3179 friend class Class;
3180 }; 3180 };
3181 3181
3182 3182
3183 // Object holding information about an IC: test classes and their
3184 // corresponding targets.
3185 class ICData : public Object {
3186 public:
3187 RawFunction* owner() const {
3188 return raw_ptr()->owner_;
3189 }
3190
3191 RawString* target_name() const {
3192 return raw_ptr()->target_name_;
3193 }
3194
3195 RawArray* arguments_descriptor() const {
3196 return raw_ptr()->args_descriptor_;
3197 }
3198
3199 intptr_t NumArgsTested() const;
3200
3201 intptr_t deopt_id() const {
3202 return raw_ptr()->deopt_id_;
3203 }
3204
3205 #define DEOPT_REASONS(V) \
3206 V(Unknown) \
3207 V(InstanceGetter) \
3208 V(PolymorphicInstanceCallTestFail) \
3209 V(InstanceCallNoICData) \
3210 V(IntegerToDouble) \
3211 V(BinarySmiOp) \
3212 V(BinaryMintOp) \
3213 V(UnaryMintOp) \
3214 V(ShiftMintOp) \
3215 V(BinaryDoubleOp) \
3216 V(InstanceSetter) \
3217 V(Equality) \
3218 V(RelationalOp) \
3219 V(EqualityClassCheck) \
3220 V(NoTypeFeedback) \
3221 V(UnaryOp) \
3222 V(UnboxInteger) \
3223 V(CheckClass) \
3224 V(HoistedCheckClass) \
3225 V(CheckSmi) \
3226 V(CheckArrayBound) \
3227 V(AtCall) \
3228 V(DoubleToSmi) \
3229 V(Int32Load) \
3230 V(Uint32Load) \
3231 V(GuardField) \
3232 V(TestCids) \
3233 V(NumReasons) \
3234
3235 enum DeoptReasonId {
3236 #define DEFINE_ENUM_LIST(name) kDeopt##name,
3237 DEOPT_REASONS(DEFINE_ENUM_LIST)
3238 #undef DEFINE_ENUM_LIST
3239 };
3240
3241 bool HasDeoptReasons() const { return DeoptReasons() != 0; }
3242 uint32_t DeoptReasons() const;
3243 void SetDeoptReasons(uint32_t reasons) const;
3244
3245 bool HasDeoptReason(ICData::DeoptReasonId reason) const;
3246 void AddDeoptReason(ICData::DeoptReasonId reason) const;
3247
3248 bool IssuedJSWarning() const;
3249 void SetIssuedJSWarning() const;
3250
3251 bool IsClosureCall() const;
3252 void SetIsClosureCall() const;
3253
3254 intptr_t NumberOfChecks() const;
3255
3256 static intptr_t InstanceSize() {
3257 return RoundedAllocationSize(sizeof(RawICData));
3258 }
3259
3260 static intptr_t target_name_offset() {
3261 return OFFSET_OF(RawICData, target_name_);
3262 }
3263
3264 static intptr_t state_bits_offset() {
3265 return OFFSET_OF(RawICData, state_bits_);
3266 }
3267
3268 static intptr_t NumArgsTestedShift() {
3269 return kNumArgsTestedPos;
3270 }
3271
3272 static intptr_t NumArgsTestedMask() {
3273 return ((1 << kNumArgsTestedSize) - 1) << kNumArgsTestedPos;
3274 }
3275
3276 static intptr_t arguments_descriptor_offset() {
3277 return OFFSET_OF(RawICData, args_descriptor_);
3278 }
3279
3280 static intptr_t ic_data_offset() {
3281 return OFFSET_OF(RawICData, ic_data_);
3282 }
3283
3284 static intptr_t owner_offset() {
3285 return OFFSET_OF(RawICData, owner_);
3286 }
3287
3288 // Used for unoptimized static calls when no class-ids are checked.
3289 void AddTarget(const Function& target) const;
3290
3291 // Adding checks.
3292
3293 // Adds one more class test to ICData. Length of 'classes' must be equal to
3294 // the number of arguments tested. Use only for num_args_tested > 1.
3295 void AddCheck(const GrowableArray<intptr_t>& class_ids,
3296 const Function& target) const;
3297 // Adds sorted so that Smi is the first class-id. Use only for
3298 // num_args_tested == 1.
3299 void AddReceiverCheck(intptr_t receiver_class_id,
3300 const Function& target,
3301 intptr_t count = 1) const;
3302
3303 // Retrieving checks.
3304
3305 void GetCheckAt(intptr_t index,
3306 GrowableArray<intptr_t>* class_ids,
3307 Function* target) const;
3308 // Only for 'num_args_checked == 1'.
3309 void GetOneClassCheckAt(intptr_t index,
3310 intptr_t* class_id,
3311 Function* target) const;
3312 // Only for 'num_args_checked == 1'.
3313 intptr_t GetCidAt(intptr_t index) const;
3314
3315 intptr_t GetReceiverClassIdAt(intptr_t index) const;
3316 intptr_t GetClassIdAt(intptr_t index, intptr_t arg_nr) const;
3317
3318 RawFunction* GetTargetAt(intptr_t index) const;
3319 RawFunction* GetTargetForReceiverClassId(intptr_t class_id) const;
3320
3321 void IncrementCountAt(intptr_t index, intptr_t value) const;
3322 void SetCountAt(intptr_t index, intptr_t value) const;
3323 intptr_t GetCountAt(intptr_t index) const;
3324 intptr_t AggregateCount() const;
3325
3326 // Returns this->raw() if num_args_tested == 1 and arg_nr == 1, otherwise
3327 // returns a new ICData object containing only unique arg_nr checks.
3328 RawICData* AsUnaryClassChecksForArgNr(intptr_t arg_nr) const;
3329 RawICData* AsUnaryClassChecks() const {
3330 return AsUnaryClassChecksForArgNr(0);
3331 }
3332
3333 bool AllTargetsHaveSameOwner(intptr_t owner_cid) const;
3334 bool AllReceiversAreNumbers() const;
3335 bool HasOneTarget() const;
3336 bool HasReceiverClassId(intptr_t class_id) const;
3337
3338 static RawICData* New(const Function& owner,
3339 const String& target_name,
3340 const Array& arguments_descriptor,
3341 intptr_t deopt_id,
3342 intptr_t num_args_tested);
3343
3344 static intptr_t TestEntryLengthFor(intptr_t num_args);
3345
3346 static intptr_t TargetIndexFor(intptr_t num_args) {
3347 return num_args;
3348 }
3349
3350 static intptr_t CountIndexFor(intptr_t num_args) {
3351 return (num_args + 1);
3352 }
3353
3354 private:
3355 RawArray* ic_data() const {
3356 return raw_ptr()->ic_data_;
3357 }
3358
3359 void set_owner(const Function& value) const;
3360 void set_target_name(const String& value) const;
3361 void set_arguments_descriptor(const Array& value) const;
3362 void set_deopt_id(intptr_t value) const;
3363 void SetNumArgsTested(intptr_t value) const;
3364 void set_ic_data(const Array& value) const;
3365 void set_state_bits(uint32_t bits) const;
3366
3367 enum {
3368 kNumArgsTestedPos = 0,
3369 kNumArgsTestedSize = 2,
3370 kDeoptReasonPos = kNumArgsTestedPos + kNumArgsTestedSize,
3371 kDeoptReasonSize = kDeoptNumReasons,
3372 kIssuedJSWarningBit = kDeoptReasonPos + kDeoptReasonSize,
3373 kIsClosureCallBit = kIssuedJSWarningBit + 1,
3374 };
3375
3376 class NumArgsTestedBits : public BitField<uint32_t,
3377 kNumArgsTestedPos, kNumArgsTestedSize> {}; // NOLINT
3378 class DeoptReasonBits : public BitField<uint32_t,
3379 ICData::kDeoptReasonPos, ICData::kDeoptReasonSize> {}; // NOLINT
3380 class IssuedJSWarningBit : public BitField<bool, kIssuedJSWarningBit, 1> {};
3381 class IsClosureCallBit : public BitField<bool, kIsClosureCallBit, 1> {};
3382
3383 #if defined(DEBUG)
3384 // Used in asserts to verify that a check is not added twice.
3385 bool HasCheck(const GrowableArray<intptr_t>& cids) const;
3386 #endif // DEBUG
3387
3388 intptr_t TestEntryLength() const;
3389 void WriteSentinel(const Array& data) const;
3390
3391 FINAL_HEAP_OBJECT_IMPLEMENTATION(ICData, Object);
3392 friend class Class;
3393 };
3394
3395
3183 class Code : public Object { 3396 class Code : public Object {
3184 public: 3397 public:
3185 RawInstructions* instructions() const { return raw_ptr()->instructions_; } 3398 RawInstructions* instructions() const { return raw_ptr()->instructions_; }
3186 static intptr_t instructions_offset() { 3399 static intptr_t instructions_offset() {
3187 return OFFSET_OF(RawCode, instructions_); 3400 return OFFSET_OF(RawCode, instructions_);
3188 } 3401 }
3189 intptr_t pointer_offsets_length() const { 3402 intptr_t pointer_offsets_length() const {
3190 return raw_ptr()->pointer_offsets_length_; 3403 return raw_ptr()->pointer_offsets_length_;
3191 } 3404 }
3192 3405
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3250 kSCallTableFunctionEntry = 1, 3463 kSCallTableFunctionEntry = 1,
3251 kSCallTableCodeEntry = 2, 3464 kSCallTableCodeEntry = 2,
3252 kSCallTableEntryLength = 3, 3465 kSCallTableEntryLength = 3,
3253 }; 3466 };
3254 3467
3255 void set_static_calls_target_table(const Array& value) const; 3468 void set_static_calls_target_table(const Array& value) const;
3256 RawArray* static_calls_target_table() const { 3469 RawArray* static_calls_target_table() const {
3257 return raw_ptr()->static_calls_target_table_; 3470 return raw_ptr()->static_calls_target_table_;
3258 } 3471 }
3259 3472
3260 RawDeoptInfo* GetDeoptInfoAtPc(uword pc, intptr_t* deopt_reason) const; 3473 RawDeoptInfo* GetDeoptInfoAtPc(
3474 uword pc, ICData::ICData::DeoptReasonId* deopt_reason) const;
3261 3475
3262 // Returns null if there is no static call at 'pc'. 3476 // Returns null if there is no static call at 'pc'.
3263 RawFunction* GetStaticCallTargetFunctionAt(uword pc) const; 3477 RawFunction* GetStaticCallTargetFunctionAt(uword pc) const;
3264 // Returns null if there is no static call at 'pc'. 3478 // Returns null if there is no static call at 'pc'.
3265 RawCode* GetStaticCallTargetCodeAt(uword pc) const; 3479 RawCode* GetStaticCallTargetCodeAt(uword pc) const;
3266 // Aborts if there is no static call at 'pc'. 3480 // Aborts if there is no static call at 'pc'.
3267 void SetStaticCallTargetCodeAt(uword pc, const Code& code) const; 3481 void SetStaticCallTargetCodeAt(uword pc, const Code& code) const;
3268 3482
3269 void Disassemble(DisassemblyFormatter* formatter = NULL) const; 3483 void Disassemble(DisassemblyFormatter* formatter = NULL) const;
3270 3484
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
3597 raw_addr += sizeof(RawContextScope) + 3811 raw_addr += sizeof(RawContextScope) +
3598 (index * sizeof(RawContextScope::VariableDesc)); 3812 (index * sizeof(RawContextScope::VariableDesc));
3599 return reinterpret_cast<RawContextScope::VariableDesc*>(raw_addr); 3813 return reinterpret_cast<RawContextScope::VariableDesc*>(raw_addr);
3600 } 3814 }
3601 3815
3602 FINAL_HEAP_OBJECT_IMPLEMENTATION(ContextScope, Object); 3816 FINAL_HEAP_OBJECT_IMPLEMENTATION(ContextScope, Object);
3603 friend class Class; 3817 friend class Class;
3604 }; 3818 };
3605 3819
3606 3820
3607 // Object holding information about an IC: test classes and their
3608 // corresponding targets.
3609 class ICData : public Object {
3610 public:
3611 RawFunction* function() const {
3612 return raw_ptr()->function_;
3613 }
3614
3615 RawString* target_name() const {
3616 return raw_ptr()->target_name_;
3617 }
3618
3619 RawArray* arguments_descriptor() const {
3620 return raw_ptr()->args_descriptor_;
3621 }
3622
3623 intptr_t num_args_tested() const {
3624 return raw_ptr()->num_args_tested_;
3625 }
3626
3627 intptr_t deopt_id() const {
3628 return raw_ptr()->deopt_id_;
3629 }
3630
3631 intptr_t deopt_reason() const {
3632 return raw_ptr()->deopt_reason_;
3633 }
3634
3635 void set_deopt_reason(intptr_t reason) const;
3636
3637 bool is_closure_call() const {
3638 return raw_ptr()->is_closure_call_ == 1;
3639 }
3640
3641 void set_is_closure_call(bool value) const;
3642
3643 intptr_t NumberOfChecks() const;
3644
3645 static intptr_t InstanceSize() {
3646 return RoundedAllocationSize(sizeof(RawICData));
3647 }
3648
3649 static intptr_t target_name_offset() {
3650 return OFFSET_OF(RawICData, target_name_);
3651 }
3652
3653 static intptr_t num_args_tested_offset() {
3654 return OFFSET_OF(RawICData, num_args_tested_);
3655 }
3656
3657 static intptr_t arguments_descriptor_offset() {
3658 return OFFSET_OF(RawICData, args_descriptor_);
3659 }
3660
3661 static intptr_t ic_data_offset() {
3662 return OFFSET_OF(RawICData, ic_data_);
3663 }
3664
3665 static intptr_t function_offset() {
3666 return OFFSET_OF(RawICData, function_);
3667 }
3668
3669 static intptr_t is_closure_call_offset() {
3670 return OFFSET_OF(RawICData, is_closure_call_);
3671 }
3672
3673 // Used for unoptimized static calls when no class-ids are checked.
3674 void AddTarget(const Function& target) const;
3675
3676 // Adding checks.
3677
3678 // Adds one more class test to ICData. Length of 'classes' must be equal to
3679 // the number of arguments tested. Use only for num_args_tested > 1.
3680 void AddCheck(const GrowableArray<intptr_t>& class_ids,
3681 const Function& target) const;
3682 // Adds sorted so that Smi is the first class-id. Use only for
3683 // num_args_tested == 1.
3684 void AddReceiverCheck(intptr_t receiver_class_id,
3685 const Function& target,
3686 intptr_t count = 1) const;
3687
3688 // Retrieving checks.
3689
3690 void GetCheckAt(intptr_t index,
3691 GrowableArray<intptr_t>* class_ids,
3692 Function* target) const;
3693 // Only for 'num_args_checked == 1'.
3694 void GetOneClassCheckAt(intptr_t index,
3695 intptr_t* class_id,
3696 Function* target) const;
3697 // Only for 'num_args_checked == 1'.
3698 intptr_t GetCidAt(intptr_t index) const;
3699
3700 intptr_t GetReceiverClassIdAt(intptr_t index) const;
3701 intptr_t GetClassIdAt(intptr_t index, intptr_t arg_nr) const;
3702
3703 RawFunction* GetTargetAt(intptr_t index) const;
3704 RawFunction* GetTargetForReceiverClassId(intptr_t class_id) const;
3705
3706 void IncrementCountAt(intptr_t index, intptr_t value) const;
3707 void SetCountAt(intptr_t index, intptr_t value) const;
3708 intptr_t GetCountAt(intptr_t index) const;
3709 intptr_t AggregateCount() const;
3710
3711 // Returns this->raw() if num_args_tested == 1 and arg_nr == 1, otherwise
3712 // returns a new ICData object containing only unique arg_nr checks.
3713 RawICData* AsUnaryClassChecksForArgNr(intptr_t arg_nr) const;
3714 RawICData* AsUnaryClassChecks() const {
3715 return AsUnaryClassChecksForArgNr(0);
3716 }
3717
3718 bool AllTargetsHaveSameOwner(intptr_t owner_cid) const;
3719 bool AllReceiversAreNumbers() const;
3720 bool HasOneTarget() const;
3721 bool HasReceiverClassId(intptr_t class_id) const;
3722
3723 static RawICData* New(const Function& caller_function,
3724 const String& target_name,
3725 const Array& arguments_descriptor,
3726 intptr_t deopt_id,
3727 intptr_t num_args_tested);
3728
3729 static intptr_t TestEntryLengthFor(intptr_t num_args);
3730
3731 static intptr_t TargetIndexFor(intptr_t num_args) {
3732 return num_args;
3733 }
3734
3735 static intptr_t CountIndexFor(intptr_t num_args) {
3736 return (num_args + 1);
3737 }
3738
3739 private:
3740 RawArray* ic_data() const {
3741 return raw_ptr()->ic_data_;
3742 }
3743
3744 void set_function(const Function& value) const;
3745 void set_target_name(const String& value) const;
3746 void set_arguments_descriptor(const Array& value) const;
3747 void set_deopt_id(intptr_t value) const;
3748 void set_num_args_tested(intptr_t value) const;
3749 void set_ic_data(const Array& value) const;
3750
3751 #if defined(DEBUG)
3752 // Used in asserts to verify that a check is not added twice.
3753 bool HasCheck(const GrowableArray<intptr_t>& cids) const;
3754 #endif // DEBUG
3755
3756 intptr_t TestEntryLength() const;
3757 void WriteSentinel(const Array& data) const;
3758
3759 FINAL_HEAP_OBJECT_IMPLEMENTATION(ICData, Object);
3760 friend class Class;
3761 };
3762
3763
3764 class MegamorphicCache : public Object { 3821 class MegamorphicCache : public Object {
3765 public: 3822 public:
3766 static const int kInitialCapacity = 16; 3823 static const int kInitialCapacity = 16;
3767 static const double kLoadFactor; 3824 static const double kLoadFactor;
3768 3825
3769 RawArray* buckets() const; 3826 RawArray* buckets() const;
3770 void set_buckets(const Array& buckets) const; 3827 void set_buckets(const Array& buckets) const;
3771 3828
3772 intptr_t mask() const; 3829 intptr_t mask() const;
3773 void set_mask(intptr_t mask) const; 3830 void set_mask(intptr_t mask) const;
(...skipping 3139 matching lines...) Expand 10 before | Expand all | Expand 10 after
6913 6970
6914 6971
6915 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, 6972 RawObject* MegamorphicCache::GetTargetFunction(const Array& array,
6916 intptr_t index) { 6973 intptr_t index) {
6917 return array.At((index * kEntryLength) + kTargetFunctionIndex); 6974 return array.At((index * kEntryLength) + kTargetFunctionIndex);
6918 } 6975 }
6919 6976
6920 } // namespace dart 6977 } // namespace dart
6921 6978
6922 #endif // VM_OBJECT_H_ 6979 #endif // VM_OBJECT_H_
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_x64.cc ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698