Chromium Code Reviews| Index: runtime/vm/intermediate_language.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language.cc (revision 38118) |
| +++ runtime/vm/intermediate_language.cc (working copy) |
| @@ -95,11 +95,19 @@ |
| } |
| +static int LowestFirst(const intptr_t* a, const intptr_t* b) { |
| + return *a - *b; |
| +} |
| + |
| + |
| CheckClassInstr::CheckClassInstr(Value* value, |
| intptr_t deopt_id, |
| const ICData& unary_checks, |
| intptr_t token_pos) |
| - : unary_checks_(unary_checks), licm_hoisted_(false), token_pos_(token_pos) { |
| + : unary_checks_(unary_checks), |
| + cids_(unary_checks.NumberOfChecks()), |
| + licm_hoisted_(false), |
| + token_pos_(token_pos) { |
| ASSERT(unary_checks.IsZoneHandle()); |
| // Expected useful check data. |
| ASSERT(!unary_checks_.IsNull()); |
| @@ -110,6 +118,10 @@ |
| // Otherwise use CheckSmiInstr. |
| ASSERT((unary_checks_.NumberOfChecks() != 1) || |
| (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid)); |
| + for (intptr_t i = 0; i < unary_checks.NumberOfChecks(); ++i) { |
| + cids_.Add(unary_checks.GetReceiverClassIdAt(i)); |
| + } |
| + cids_.Sort(LowestFirst); |
| } |
| @@ -140,6 +152,17 @@ |
| } |
| +EffectSet CheckClassIdInstr::Dependencies() const { |
| + ASSERT(right()->BindsToConstant()); |
| + ASSERT(right()->BoundConstant().IsSmi()); |
| + // Externalization of strings via the API can change the class-id. |
| + const intptr_t cid = Smi::Cast(right()->BoundConstant()).Value(); |
| + const bool externalizable = |
| + cid == kOneByteStringCid || cid == kTwoByteStringCid; |
| + return externalizable ? EffectSet::Externalization() : EffectSet::None(); |
| +} |
| + |
| + |
| bool CheckClassInstr::IsNullCheck() const { |
| if (unary_checks().NumberOfChecks() != 1) { |
| return false; |
| @@ -152,6 +175,33 @@ |
| } |
| +bool CheckClassInstr::IsDenseSwitch() const { |
| + if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) return false; |
| + if (cids_.length() > 2 && |
| + cids_[cids_.length() - 1] - cids_[0] < kBitsPerWord) { |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| + |
| +intptr_t CheckClassInstr::ComputeCidMask() const { |
| + ASSERT(IsDenseSwitch()); |
| + intptr_t mask = 0; |
| + for (intptr_t i = 0; i < cids_.length(); ++i) { |
| + mask |= 1 << (cids_[i] - cids_[0]); |
| + } |
| + return mask; |
| +} |
| + |
| + |
| +bool CheckClassInstr::IsDenseMask(intptr_t mask) { |
| + // Returns true if the mask is a continuos sequence of ones in its binary |
| + // representation (i.e. no holes) |
| + return mask == -1 || Utils::IsPowerOfTwo(mask + 1); |
| +} |
| + |
| + |
| bool LoadFieldInstr::IsUnboxedLoad() const { |
| return FLAG_unbox_numeric_fields |
| && (field() != NULL) |
| @@ -2485,8 +2535,9 @@ |
| RangeBoundary RangeBoundary::Add(const RangeBoundary& a, |
| const RangeBoundary& b, |
| const RangeBoundary& overflow) { |
| + if (a.IsInfinity() || b.IsInfinity()) return overflow; |
|
Florian Schneider
2014/07/10 15:10:13
Handle infinity here in Add and Sub.
Cutch
2014/07/10 16:04:20
Why is this being added? I removed this from my 64
Vyacheslav Egorov (Google)
2014/07/10 16:34:56
When trying to Add ranges we sometimes pass infini
|
| + |
| ASSERT(a.IsConstant() && b.IsConstant()); |
| - |
| if (Utils::WillAddOverflow(a.ConstantValue(), b.ConstantValue())) { |
| return overflow; |
| } |
| @@ -2500,8 +2551,8 @@ |
| RangeBoundary RangeBoundary::Sub(const RangeBoundary& a, |
| const RangeBoundary& b, |
| const RangeBoundary& overflow) { |
| + if (a.IsInfinity() || b.IsInfinity()) return overflow; |
| ASSERT(a.IsConstant() && b.IsConstant()); |
| - |
| if (Utils::WillSubOverflow(a.ConstantValue(), b.ConstantValue())) { |
| return overflow; |
| } |