| Index: runtime/vm/object.h
|
| ===================================================================
|
| --- runtime/vm/object.h (revision 35455)
|
| +++ runtime/vm/object.h (working copy)
|
| @@ -3180,6 +3180,219 @@
|
| };
|
|
|
|
|
| +// Object holding information about an IC: test classes and their
|
| +// corresponding targets.
|
| +class ICData : public Object {
|
| + public:
|
| + RawFunction* owner() const {
|
| + return raw_ptr()->owner_;
|
| + }
|
| +
|
| + RawString* target_name() const {
|
| + return raw_ptr()->target_name_;
|
| + }
|
| +
|
| + RawArray* arguments_descriptor() const {
|
| + return raw_ptr()->args_descriptor_;
|
| + }
|
| +
|
| + intptr_t NumArgsTested() const;
|
| +
|
| + intptr_t deopt_id() const {
|
| + return raw_ptr()->deopt_id_;
|
| + }
|
| +
|
| + #define DEOPT_REASONS(V) \
|
| + V(Unknown) \
|
| + V(InstanceGetter) \
|
| + V(PolymorphicInstanceCallTestFail) \
|
| + V(InstanceCallNoICData) \
|
| + V(IntegerToDouble) \
|
| + V(BinarySmiOp) \
|
| + V(BinaryMintOp) \
|
| + V(UnaryMintOp) \
|
| + V(ShiftMintOp) \
|
| + V(BinaryDoubleOp) \
|
| + V(InstanceSetter) \
|
| + V(Equality) \
|
| + V(RelationalOp) \
|
| + V(EqualityClassCheck) \
|
| + V(NoTypeFeedback) \
|
| + V(UnaryOp) \
|
| + V(UnboxInteger) \
|
| + V(CheckClass) \
|
| + V(HoistedCheckClass) \
|
| + V(CheckSmi) \
|
| + V(CheckArrayBound) \
|
| + V(AtCall) \
|
| + V(DoubleToSmi) \
|
| + V(Int32Load) \
|
| + V(Uint32Load) \
|
| + V(GuardField) \
|
| + V(TestCids) \
|
| + V(NumReasons) \
|
| +
|
| + enum DeoptReasonId {
|
| + #define DEFINE_ENUM_LIST(name) kDeopt##name,
|
| + DEOPT_REASONS(DEFINE_ENUM_LIST)
|
| + #undef DEFINE_ENUM_LIST
|
| + };
|
| +
|
| + bool HasDeoptReasons() const { return DeoptReasons() != 0; }
|
| + uint32_t DeoptReasons() const;
|
| + void SetDeoptReasons(uint32_t reasons) const;
|
| +
|
| + bool HasDeoptReason(ICData::DeoptReasonId reason) const;
|
| + void AddDeoptReason(ICData::DeoptReasonId reason) const;
|
| +
|
| + bool IssuedJSWarning() const;
|
| + void SetIssuedJSWarning() const;
|
| +
|
| + bool IsClosureCall() const;
|
| + void SetIsClosureCall() const;
|
| +
|
| + intptr_t NumberOfChecks() const;
|
| +
|
| + static intptr_t InstanceSize() {
|
| + return RoundedAllocationSize(sizeof(RawICData));
|
| + }
|
| +
|
| + static intptr_t target_name_offset() {
|
| + return OFFSET_OF(RawICData, target_name_);
|
| + }
|
| +
|
| + static intptr_t state_bits_offset() {
|
| + return OFFSET_OF(RawICData, state_bits_);
|
| + }
|
| +
|
| + static intptr_t NumArgsTestedShift() {
|
| + return kNumArgsTestedPos;
|
| + }
|
| +
|
| + static intptr_t NumArgsTestedMask() {
|
| + return ((1 << kNumArgsTestedSize) - 1) << kNumArgsTestedPos;
|
| + }
|
| +
|
| + static intptr_t arguments_descriptor_offset() {
|
| + return OFFSET_OF(RawICData, args_descriptor_);
|
| + }
|
| +
|
| + static intptr_t ic_data_offset() {
|
| + return OFFSET_OF(RawICData, ic_data_);
|
| + }
|
| +
|
| + static intptr_t owner_offset() {
|
| + return OFFSET_OF(RawICData, owner_);
|
| + }
|
| +
|
| + // Used for unoptimized static calls when no class-ids are checked.
|
| + void AddTarget(const Function& target) const;
|
| +
|
| + // Adding checks.
|
| +
|
| + // Adds one more class test to ICData. Length of 'classes' must be equal to
|
| + // the number of arguments tested. Use only for num_args_tested > 1.
|
| + void AddCheck(const GrowableArray<intptr_t>& class_ids,
|
| + const Function& target) const;
|
| + // Adds sorted so that Smi is the first class-id. Use only for
|
| + // num_args_tested == 1.
|
| + void AddReceiverCheck(intptr_t receiver_class_id,
|
| + const Function& target,
|
| + intptr_t count = 1) const;
|
| +
|
| + // Retrieving checks.
|
| +
|
| + void GetCheckAt(intptr_t index,
|
| + GrowableArray<intptr_t>* class_ids,
|
| + Function* target) const;
|
| + // Only for 'num_args_checked == 1'.
|
| + void GetOneClassCheckAt(intptr_t index,
|
| + intptr_t* class_id,
|
| + Function* target) const;
|
| + // Only for 'num_args_checked == 1'.
|
| + intptr_t GetCidAt(intptr_t index) const;
|
| +
|
| + intptr_t GetReceiverClassIdAt(intptr_t index) const;
|
| + intptr_t GetClassIdAt(intptr_t index, intptr_t arg_nr) const;
|
| +
|
| + RawFunction* GetTargetAt(intptr_t index) const;
|
| + RawFunction* GetTargetForReceiverClassId(intptr_t class_id) const;
|
| +
|
| + void IncrementCountAt(intptr_t index, intptr_t value) const;
|
| + void SetCountAt(intptr_t index, intptr_t value) const;
|
| + intptr_t GetCountAt(intptr_t index) const;
|
| + intptr_t AggregateCount() const;
|
| +
|
| + // Returns this->raw() if num_args_tested == 1 and arg_nr == 1, otherwise
|
| + // returns a new ICData object containing only unique arg_nr checks.
|
| + RawICData* AsUnaryClassChecksForArgNr(intptr_t arg_nr) const;
|
| + RawICData* AsUnaryClassChecks() const {
|
| + return AsUnaryClassChecksForArgNr(0);
|
| + }
|
| +
|
| + bool AllTargetsHaveSameOwner(intptr_t owner_cid) const;
|
| + bool AllReceiversAreNumbers() const;
|
| + bool HasOneTarget() const;
|
| + bool HasReceiverClassId(intptr_t class_id) const;
|
| +
|
| + static RawICData* New(const Function& owner,
|
| + const String& target_name,
|
| + const Array& arguments_descriptor,
|
| + intptr_t deopt_id,
|
| + intptr_t num_args_tested);
|
| +
|
| + static intptr_t TestEntryLengthFor(intptr_t num_args);
|
| +
|
| + static intptr_t TargetIndexFor(intptr_t num_args) {
|
| + return num_args;
|
| + }
|
| +
|
| + static intptr_t CountIndexFor(intptr_t num_args) {
|
| + return (num_args + 1);
|
| + }
|
| +
|
| + private:
|
| + RawArray* ic_data() const {
|
| + return raw_ptr()->ic_data_;
|
| + }
|
| +
|
| + void set_owner(const Function& value) const;
|
| + void set_target_name(const String& value) const;
|
| + void set_arguments_descriptor(const Array& value) const;
|
| + void set_deopt_id(intptr_t value) const;
|
| + void SetNumArgsTested(intptr_t value) const;
|
| + void set_ic_data(const Array& value) const;
|
| + void set_state_bits(uint32_t bits) const;
|
| +
|
| + enum {
|
| + kNumArgsTestedPos = 0,
|
| + kNumArgsTestedSize = 2,
|
| + kDeoptReasonPos = kNumArgsTestedPos + kNumArgsTestedSize,
|
| + kDeoptReasonSize = kDeoptNumReasons,
|
| + kIssuedJSWarningBit = kDeoptReasonPos + kDeoptReasonSize,
|
| + kIsClosureCallBit = kIssuedJSWarningBit + 1,
|
| + };
|
| +
|
| + class NumArgsTestedBits : public BitField<uint32_t,
|
| + kNumArgsTestedPos, kNumArgsTestedSize> {}; // NOLINT
|
| + class DeoptReasonBits : public BitField<uint32_t,
|
| + ICData::kDeoptReasonPos, ICData::kDeoptReasonSize> {}; // NOLINT
|
| + class IssuedJSWarningBit : public BitField<bool, kIssuedJSWarningBit, 1> {};
|
| + class IsClosureCallBit : public BitField<bool, kIsClosureCallBit, 1> {};
|
| +
|
| +#if defined(DEBUG)
|
| + // Used in asserts to verify that a check is not added twice.
|
| + bool HasCheck(const GrowableArray<intptr_t>& cids) const;
|
| +#endif // DEBUG
|
| +
|
| + intptr_t TestEntryLength() const;
|
| + void WriteSentinel(const Array& data) const;
|
| +
|
| + FINAL_HEAP_OBJECT_IMPLEMENTATION(ICData, Object);
|
| + friend class Class;
|
| +};
|
| +
|
| +
|
| class Code : public Object {
|
| public:
|
| RawInstructions* instructions() const { return raw_ptr()->instructions_; }
|
| @@ -3257,7 +3470,8 @@
|
| return raw_ptr()->static_calls_target_table_;
|
| }
|
|
|
| - RawDeoptInfo* GetDeoptInfoAtPc(uword pc, intptr_t* deopt_reason) const;
|
| + RawDeoptInfo* GetDeoptInfoAtPc(
|
| + uword pc, ICData::ICData::DeoptReasonId* deopt_reason) const;
|
|
|
| // Returns null if there is no static call at 'pc'.
|
| RawFunction* GetStaticCallTargetFunctionAt(uword pc) const;
|
| @@ -3604,163 +3818,6 @@
|
| };
|
|
|
|
|
| -// Object holding information about an IC: test classes and their
|
| -// corresponding targets.
|
| -class ICData : public Object {
|
| - public:
|
| - RawFunction* function() const {
|
| - return raw_ptr()->function_;
|
| - }
|
| -
|
| - RawString* target_name() const {
|
| - return raw_ptr()->target_name_;
|
| - }
|
| -
|
| - RawArray* arguments_descriptor() const {
|
| - return raw_ptr()->args_descriptor_;
|
| - }
|
| -
|
| - intptr_t num_args_tested() const {
|
| - return raw_ptr()->num_args_tested_;
|
| - }
|
| -
|
| - intptr_t deopt_id() const {
|
| - return raw_ptr()->deopt_id_;
|
| - }
|
| -
|
| - intptr_t deopt_reason() const {
|
| - return raw_ptr()->deopt_reason_;
|
| - }
|
| -
|
| - void set_deopt_reason(intptr_t reason) const;
|
| -
|
| - bool is_closure_call() const {
|
| - return raw_ptr()->is_closure_call_ == 1;
|
| - }
|
| -
|
| - void set_is_closure_call(bool value) const;
|
| -
|
| - intptr_t NumberOfChecks() const;
|
| -
|
| - static intptr_t InstanceSize() {
|
| - return RoundedAllocationSize(sizeof(RawICData));
|
| - }
|
| -
|
| - static intptr_t target_name_offset() {
|
| - return OFFSET_OF(RawICData, target_name_);
|
| - }
|
| -
|
| - static intptr_t num_args_tested_offset() {
|
| - return OFFSET_OF(RawICData, num_args_tested_);
|
| - }
|
| -
|
| - static intptr_t arguments_descriptor_offset() {
|
| - return OFFSET_OF(RawICData, args_descriptor_);
|
| - }
|
| -
|
| - static intptr_t ic_data_offset() {
|
| - return OFFSET_OF(RawICData, ic_data_);
|
| - }
|
| -
|
| - static intptr_t function_offset() {
|
| - return OFFSET_OF(RawICData, function_);
|
| - }
|
| -
|
| - static intptr_t is_closure_call_offset() {
|
| - return OFFSET_OF(RawICData, is_closure_call_);
|
| - }
|
| -
|
| - // Used for unoptimized static calls when no class-ids are checked.
|
| - void AddTarget(const Function& target) const;
|
| -
|
| - // Adding checks.
|
| -
|
| - // Adds one more class test to ICData. Length of 'classes' must be equal to
|
| - // the number of arguments tested. Use only for num_args_tested > 1.
|
| - void AddCheck(const GrowableArray<intptr_t>& class_ids,
|
| - const Function& target) const;
|
| - // Adds sorted so that Smi is the first class-id. Use only for
|
| - // num_args_tested == 1.
|
| - void AddReceiverCheck(intptr_t receiver_class_id,
|
| - const Function& target,
|
| - intptr_t count = 1) const;
|
| -
|
| - // Retrieving checks.
|
| -
|
| - void GetCheckAt(intptr_t index,
|
| - GrowableArray<intptr_t>* class_ids,
|
| - Function* target) const;
|
| - // Only for 'num_args_checked == 1'.
|
| - void GetOneClassCheckAt(intptr_t index,
|
| - intptr_t* class_id,
|
| - Function* target) const;
|
| - // Only for 'num_args_checked == 1'.
|
| - intptr_t GetCidAt(intptr_t index) const;
|
| -
|
| - intptr_t GetReceiverClassIdAt(intptr_t index) const;
|
| - intptr_t GetClassIdAt(intptr_t index, intptr_t arg_nr) const;
|
| -
|
| - RawFunction* GetTargetAt(intptr_t index) const;
|
| - RawFunction* GetTargetForReceiverClassId(intptr_t class_id) const;
|
| -
|
| - void IncrementCountAt(intptr_t index, intptr_t value) const;
|
| - void SetCountAt(intptr_t index, intptr_t value) const;
|
| - intptr_t GetCountAt(intptr_t index) const;
|
| - intptr_t AggregateCount() const;
|
| -
|
| - // Returns this->raw() if num_args_tested == 1 and arg_nr == 1, otherwise
|
| - // returns a new ICData object containing only unique arg_nr checks.
|
| - RawICData* AsUnaryClassChecksForArgNr(intptr_t arg_nr) const;
|
| - RawICData* AsUnaryClassChecks() const {
|
| - return AsUnaryClassChecksForArgNr(0);
|
| - }
|
| -
|
| - bool AllTargetsHaveSameOwner(intptr_t owner_cid) const;
|
| - bool AllReceiversAreNumbers() const;
|
| - bool HasOneTarget() const;
|
| - bool HasReceiverClassId(intptr_t class_id) const;
|
| -
|
| - static RawICData* New(const Function& caller_function,
|
| - const String& target_name,
|
| - const Array& arguments_descriptor,
|
| - intptr_t deopt_id,
|
| - intptr_t num_args_tested);
|
| -
|
| - static intptr_t TestEntryLengthFor(intptr_t num_args);
|
| -
|
| - static intptr_t TargetIndexFor(intptr_t num_args) {
|
| - return num_args;
|
| - }
|
| -
|
| - static intptr_t CountIndexFor(intptr_t num_args) {
|
| - return (num_args + 1);
|
| - }
|
| -
|
| - private:
|
| - RawArray* ic_data() const {
|
| - return raw_ptr()->ic_data_;
|
| - }
|
| -
|
| - void set_function(const Function& value) const;
|
| - void set_target_name(const String& value) const;
|
| - void set_arguments_descriptor(const Array& value) const;
|
| - void set_deopt_id(intptr_t value) const;
|
| - void set_num_args_tested(intptr_t value) const;
|
| - void set_ic_data(const Array& value) const;
|
| -
|
| -#if defined(DEBUG)
|
| - // Used in asserts to verify that a check is not added twice.
|
| - bool HasCheck(const GrowableArray<intptr_t>& cids) const;
|
| -#endif // DEBUG
|
| -
|
| - intptr_t TestEntryLength() const;
|
| - void WriteSentinel(const Array& data) const;
|
| -
|
| - FINAL_HEAP_OBJECT_IMPLEMENTATION(ICData, Object);
|
| - friend class Class;
|
| -};
|
| -
|
| -
|
| class MegamorphicCache : public Object {
|
| public:
|
| static const int kInitialCapacity = 16;
|
|
|