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

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 381803005: Reland r38116: Improve receiver class check in polymorphic inlining. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 5 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 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 } 88 }
89 return AttributesEqual(other); 89 return AttributesEqual(other);
90 } 90 }
91 91
92 92
93 bool Value::Equals(Value* other) const { 93 bool Value::Equals(Value* other) const {
94 return definition() == other->definition(); 94 return definition() == other->definition();
95 } 95 }
96 96
97 97
98 static int LowestFirst(const intptr_t* a, const intptr_t* b) {
99 return *a - *b;
100 }
101
102
98 CheckClassInstr::CheckClassInstr(Value* value, 103 CheckClassInstr::CheckClassInstr(Value* value,
99 intptr_t deopt_id, 104 intptr_t deopt_id,
100 const ICData& unary_checks, 105 const ICData& unary_checks,
101 intptr_t token_pos) 106 intptr_t token_pos)
102 : unary_checks_(unary_checks), licm_hoisted_(false), token_pos_(token_pos) { 107 : unary_checks_(unary_checks),
108 cids_(unary_checks.NumberOfChecks()),
109 licm_hoisted_(false),
110 token_pos_(token_pos) {
103 ASSERT(unary_checks.IsZoneHandle()); 111 ASSERT(unary_checks.IsZoneHandle());
104 // Expected useful check data. 112 // Expected useful check data.
105 ASSERT(!unary_checks_.IsNull()); 113 ASSERT(!unary_checks_.IsNull());
106 ASSERT(unary_checks_.NumberOfChecks() > 0); 114 ASSERT(unary_checks_.NumberOfChecks() > 0);
107 ASSERT(unary_checks_.NumArgsTested() == 1); 115 ASSERT(unary_checks_.NumArgsTested() == 1);
108 SetInputAt(0, value); 116 SetInputAt(0, value);
109 deopt_id_ = deopt_id; 117 deopt_id_ = deopt_id;
110 // Otherwise use CheckSmiInstr. 118 // Otherwise use CheckSmiInstr.
111 ASSERT((unary_checks_.NumberOfChecks() != 1) || 119 ASSERT((unary_checks_.NumberOfChecks() != 1) ||
112 (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid)); 120 (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid));
121 for (intptr_t i = 0; i < unary_checks.NumberOfChecks(); ++i) {
122 cids_.Add(unary_checks.GetReceiverClassIdAt(i));
123 }
124 cids_.Sort(LowestFirst);
113 } 125 }
114 126
115 127
116 bool CheckClassInstr::AttributesEqual(Instruction* other) const { 128 bool CheckClassInstr::AttributesEqual(Instruction* other) const {
117 CheckClassInstr* other_check = other->AsCheckClass(); 129 CheckClassInstr* other_check = other->AsCheckClass();
118 ASSERT(other_check != NULL); 130 ASSERT(other_check != NULL);
119 if (unary_checks().NumberOfChecks() != 131 if (unary_checks().NumberOfChecks() !=
120 other_check->unary_checks().NumberOfChecks()) { 132 other_check->unary_checks().NumberOfChecks()) {
121 return false; 133 return false;
122 } 134 }
(...skipping 10 matching lines...) Expand all
133 145
134 EffectSet CheckClassInstr::Dependencies() const { 146 EffectSet CheckClassInstr::Dependencies() const {
135 // Externalization of strings via the API can change the class-id. 147 // Externalization of strings via the API can change the class-id.
136 const bool externalizable = 148 const bool externalizable =
137 unary_checks().HasReceiverClassId(kOneByteStringCid) || 149 unary_checks().HasReceiverClassId(kOneByteStringCid) ||
138 unary_checks().HasReceiverClassId(kTwoByteStringCid); 150 unary_checks().HasReceiverClassId(kTwoByteStringCid);
139 return externalizable ? EffectSet::Externalization() : EffectSet::None(); 151 return externalizable ? EffectSet::Externalization() : EffectSet::None();
140 } 152 }
141 153
142 154
155 EffectSet CheckClassIdInstr::Dependencies() const {
156 ASSERT(right()->BindsToConstant());
157 ASSERT(right()->BoundConstant().IsSmi());
158 // Externalization of strings via the API can change the class-id.
159 const intptr_t cid = Smi::Cast(right()->BoundConstant()).Value();
160 const bool externalizable =
161 cid == kOneByteStringCid || cid == kTwoByteStringCid;
162 return externalizable ? EffectSet::Externalization() : EffectSet::None();
163 }
164
165
143 bool CheckClassInstr::IsNullCheck() const { 166 bool CheckClassInstr::IsNullCheck() const {
144 if (unary_checks().NumberOfChecks() != 1) { 167 if (unary_checks().NumberOfChecks() != 1) {
145 return false; 168 return false;
146 } 169 }
147 CompileType* in_type = value()->Type(); 170 CompileType* in_type = value()->Type();
148 const intptr_t cid = unary_checks().GetCidAt(0); 171 const intptr_t cid = unary_checks().GetCidAt(0);
149 // Performance check: use CheckSmiInstr instead. 172 // Performance check: use CheckSmiInstr instead.
150 ASSERT(cid != kSmiCid); 173 ASSERT(cid != kSmiCid);
151 return in_type->is_nullable() && (in_type->ToNullableCid() == cid); 174 return in_type->is_nullable() && (in_type->ToNullableCid() == cid);
152 } 175 }
153 176
154 177
178 bool CheckClassInstr::IsDenseSwitch() const {
179 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) return false;
180 if (cids_.length() > 2 &&
181 cids_[cids_.length() - 1] - cids_[0] < kBitsPerWord) {
182 return true;
183 }
184 return false;
185 }
186
187
188 intptr_t CheckClassInstr::ComputeCidMask() const {
189 ASSERT(IsDenseSwitch());
190 intptr_t mask = 0;
191 for (intptr_t i = 0; i < cids_.length(); ++i) {
192 mask |= 1 << (cids_[i] - cids_[0]);
193 }
194 return mask;
195 }
196
197
198 bool CheckClassInstr::IsDenseMask(intptr_t mask) {
199 // Returns true if the mask is a continuos sequence of ones in its binary
200 // representation (i.e. no holes)
201 return mask == -1 || Utils::IsPowerOfTwo(mask + 1);
202 }
203
204
155 bool LoadFieldInstr::IsUnboxedLoad() const { 205 bool LoadFieldInstr::IsUnboxedLoad() const {
156 return FLAG_unbox_numeric_fields 206 return FLAG_unbox_numeric_fields
157 && (field() != NULL) 207 && (field() != NULL)
158 && field()->IsUnboxedField(); 208 && field()->IsUnboxedField();
159 } 209 }
160 210
161 211
162 bool LoadFieldInstr::IsPotentialUnboxedLoad() const { 212 bool LoadFieldInstr::IsPotentialUnboxedLoad() const {
163 return FLAG_unbox_numeric_fields 213 return FLAG_unbox_numeric_fields
164 && (field() != NULL) 214 && (field() != NULL)
(...skipping 2313 matching lines...) Expand 10 before | Expand all | Expand 10 after
2478 if (IsConstant()) return *this; 2528 if (IsConstant()) return *this;
2479 return Add(Range::ConstantMax(symbol()->range()), 2529 return Add(Range::ConstantMax(symbol()->range()),
2480 RangeBoundary::FromConstant(offset_), 2530 RangeBoundary::FromConstant(offset_),
2481 PositiveInfinity()); 2531 PositiveInfinity());
2482 } 2532 }
2483 2533
2484 2534
2485 RangeBoundary RangeBoundary::Add(const RangeBoundary& a, 2535 RangeBoundary RangeBoundary::Add(const RangeBoundary& a,
2486 const RangeBoundary& b, 2536 const RangeBoundary& b,
2487 const RangeBoundary& overflow) { 2537 const RangeBoundary& overflow) {
2538 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
2539
2488 ASSERT(a.IsConstant() && b.IsConstant()); 2540 ASSERT(a.IsConstant() && b.IsConstant());
2489
2490 if (Utils::WillAddOverflow(a.ConstantValue(), b.ConstantValue())) { 2541 if (Utils::WillAddOverflow(a.ConstantValue(), b.ConstantValue())) {
2491 return overflow; 2542 return overflow;
2492 } 2543 }
2493 2544
2494 int64_t result = a.ConstantValue() + b.ConstantValue(); 2545 int64_t result = a.ConstantValue() + b.ConstantValue();
2495 2546
2496 return RangeBoundary::FromConstant(result); 2547 return RangeBoundary::FromConstant(result);
2497 } 2548 }
2498 2549
2499 2550
2500 RangeBoundary RangeBoundary::Sub(const RangeBoundary& a, 2551 RangeBoundary RangeBoundary::Sub(const RangeBoundary& a,
2501 const RangeBoundary& b, 2552 const RangeBoundary& b,
2502 const RangeBoundary& overflow) { 2553 const RangeBoundary& overflow) {
2554 if (a.IsInfinity() || b.IsInfinity()) return overflow;
2503 ASSERT(a.IsConstant() && b.IsConstant()); 2555 ASSERT(a.IsConstant() && b.IsConstant());
2504
2505 if (Utils::WillSubOverflow(a.ConstantValue(), b.ConstantValue())) { 2556 if (Utils::WillSubOverflow(a.ConstantValue(), b.ConstantValue())) {
2506 return overflow; 2557 return overflow;
2507 } 2558 }
2508 2559
2509 int64_t result = a.ConstantValue() - b.ConstantValue(); 2560 int64_t result = a.ConstantValue() - b.ConstantValue();
2510 2561
2511 return RangeBoundary::FromConstant(result); 2562 return RangeBoundary::FromConstant(result);
2512 } 2563 }
2513 2564
2514 2565
(...skipping 1460 matching lines...) Expand 10 before | Expand all | Expand 10 after
3975 case Token::kTRUNCDIV: return 0; 4026 case Token::kTRUNCDIV: return 0;
3976 case Token::kMOD: return 1; 4027 case Token::kMOD: return 1;
3977 default: UNIMPLEMENTED(); return -1; 4028 default: UNIMPLEMENTED(); return -1;
3978 } 4029 }
3979 } 4030 }
3980 4031
3981 4032
3982 #undef __ 4033 #undef __
3983 4034
3984 } // namespace dart 4035 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698