| Index: runtime/vm/object.cc
|
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
|
| index bbcb076cd129b99209ae0698eb5c3cde27ec67ba..515dc86ad4195e4e50ad0f82f516cf7b1cc44d62 100644
|
| --- a/runtime/vm/object.cc
|
| +++ b/runtime/vm/object.cc
|
| @@ -11472,6 +11472,11 @@ bool ICData::MayCheckForJSWarning() const {
|
| }
|
|
|
|
|
| +void ICData::set_range_feedback(uint32_t feedback) {
|
| + StoreNonPointer(&raw_ptr()->range_feedback_, feedback);
|
| +}
|
| +
|
| +
|
| void ICData::set_state_bits(uint32_t bits) const {
|
| StoreNonPointer(&raw_ptr()->state_bits_, bits);
|
| }
|
| @@ -11927,6 +11932,7 @@ RawICData* ICData::New(const Function& owner,
|
| result.set_arguments_descriptor(arguments_descriptor);
|
| result.set_deopt_id(deopt_id);
|
| result.set_state_bits(0);
|
| + result.set_range_feedback(0);
|
| result.SetNumArgsTested(num_args_tested);
|
| // Number of array elements in one test entry.
|
| intptr_t len = result.TestEntryLength();
|
| @@ -11943,6 +11949,94 @@ void ICData::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
| }
|
|
|
|
|
| +static Token::Kind RecognizeArithmeticOp(const String& name) {
|
| + ASSERT(name.IsSymbol());
|
| + if (name.raw() == Symbols::Plus().raw()) {
|
| + return Token::kADD;
|
| + } else if (name.raw() == Symbols::Minus().raw()) {
|
| + return Token::kSUB;
|
| + } else if (name.raw() == Symbols::Star().raw()) {
|
| + return Token::kMUL;
|
| + } else if (name.raw() == Symbols::Slash().raw()) {
|
| + return Token::kDIV;
|
| + } else if (name.raw() == Symbols::TruncDivOperator().raw()) {
|
| + return Token::kTRUNCDIV;
|
| + } else if (name.raw() == Symbols::Percent().raw()) {
|
| + return Token::kMOD;
|
| + } else if (name.raw() == Symbols::BitOr().raw()) {
|
| + return Token::kBIT_OR;
|
| + } else if (name.raw() == Symbols::Ampersand().raw()) {
|
| + return Token::kBIT_AND;
|
| + } else if (name.raw() == Symbols::Caret().raw()) {
|
| + return Token::kBIT_XOR;
|
| + } else if (name.raw() == Symbols::LeftShiftOperator().raw()) {
|
| + return Token::kSHL;
|
| + } else if (name.raw() == Symbols::RightShiftOperator().raw()) {
|
| + return Token::kSHR;
|
| + } else if (name.raw() == Symbols::Tilde().raw()) {
|
| + return Token::kBIT_NOT;
|
| + } else if (name.raw() == Symbols::UnaryMinus().raw()) {
|
| + return Token::kNEGATE;
|
| + }
|
| + return Token::kILLEGAL;
|
| +}
|
| +
|
| +
|
| +bool ICData::HasRangeFeedback() const {
|
| + const String& target = String::Handle(target_name());
|
| + const Token::Kind token_kind = RecognizeArithmeticOp(target);
|
| + if (!Token::IsBinaryArithmeticOperator(token_kind) &&
|
| + !Token::IsUnaryArithmeticOperator(token_kind)) {
|
| + return false;
|
| + }
|
| +
|
| + bool initialized = false;
|
| + Function& t = Function::Handle();
|
| + const intptr_t len = NumberOfChecks();
|
| + GrowableArray<intptr_t> class_ids;
|
| + for (intptr_t i = 0; i < len; i++) {
|
| + if (IsUsedAt(i)) {
|
| + initialized = true;
|
| + GetCheckAt(i, &class_ids, &t);
|
| + for (intptr_t j = 0; j < class_ids.length(); j++) {
|
| + const intptr_t cid = class_ids[j];
|
| + if ((cid != kSmiCid) && (cid != kMintCid)) {
|
| + return false;
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| + return initialized;
|
| +}
|
| +
|
| +
|
| +ICData::RangeFeedback ICData::DecodeRangeFeedbackAt(intptr_t idx) const {
|
| + ASSERT((0 <= idx) && (idx < 3));
|
| + const uint32_t feedback =
|
| + (range_feedback() >> (idx * kBitsPerRangeFeedback)) & kRangeFeedbackMask;
|
| + if ((feedback & kInt64RangeBit) != 0) {
|
| + return kInt64Range;
|
| + }
|
| +
|
| + if ((feedback & kUint32RangeBit) != 0) {
|
| + if ((feedback & kSignedRangeBit) == 0) {
|
| + return kUint32Range;
|
| + }
|
| +
|
| + // Check if Smi is large enough to accomodate Int33: a mixture of Uint32
|
| + // and negative Int32 values.
|
| + return (kSmiBits < 33) ? kInt64Range : kSmiRange;
|
| + }
|
| +
|
| + if ((feedback & kInt32RangeBit) != 0) {
|
| + return kInt32Range;
|
| + }
|
| +
|
| + return kSmiRange;
|
| +}
|
| +
|
| +
|
| Code::Comments& Code::Comments::New(intptr_t count) {
|
| Comments* comments;
|
| if (count < 0 || count > (kIntptrMax / kNumberOfEntries)) {
|
|
|