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

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

Issue 2734883002: ICData::NumberOfChecks is O(n) so don't call it in loops (Closed)
Patch Set: Add const Created 3 years, 9 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
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm.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) 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/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/bootstrap.h" 8 #include "vm/bootstrap.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/constant_propagator.h" 10 #include "vm/constant_propagator.h"
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 TokenPosition token_pos) 153 TokenPosition token_pos)
154 : TemplateInstruction(deopt_id), 154 : TemplateInstruction(deopt_id),
155 unary_checks_(unary_checks), 155 unary_checks_(unary_checks),
156 cids_(unary_checks.NumberOfChecks()), 156 cids_(unary_checks.NumberOfChecks()),
157 licm_hoisted_(false), 157 licm_hoisted_(false),
158 is_dense_switch_(IsDenseCidRange(unary_checks)), 158 is_dense_switch_(IsDenseCidRange(unary_checks)),
159 token_pos_(token_pos) { 159 token_pos_(token_pos) {
160 ASSERT(unary_checks.IsZoneHandle()); 160 ASSERT(unary_checks.IsZoneHandle());
161 // Expected useful check data. 161 // Expected useful check data.
162 ASSERT(!unary_checks_.IsNull()); 162 ASSERT(!unary_checks_.IsNull());
163 ASSERT(unary_checks_.NumberOfChecks() > 0); 163 const intptr_t number_of_checks = unary_checks_.NumberOfChecks();
164 ASSERT(number_of_checks > 0);
164 ASSERT(unary_checks_.NumArgsTested() == 1); 165 ASSERT(unary_checks_.NumArgsTested() == 1);
165 SetInputAt(0, value); 166 SetInputAt(0, value);
166 // Otherwise use CheckSmiInstr. 167 // Otherwise use CheckSmiInstr.
167 ASSERT((unary_checks_.NumberOfChecks() != 1) || 168 ASSERT(number_of_checks != 1 ||
168 (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid)); 169 (unary_checks_.GetReceiverClassIdAt(0) != kSmiCid));
169 for (intptr_t i = 0; i < unary_checks.NumberOfChecks(); ++i) { 170 for (intptr_t i = 0; i < number_of_checks; ++i) {
170 cids_.Add(unary_checks.GetReceiverClassIdAt(i)); 171 cids_.Add(unary_checks.GetReceiverClassIdAt(i));
171 } 172 }
172 cids_.Sort(LowestFirst); 173 cids_.Sort(LowestFirst);
173 } 174 }
174 175
175 176
176 bool CheckClassInstr::AttributesEqual(Instruction* other) const { 177 bool CheckClassInstr::AttributesEqual(Instruction* other) const {
177 CheckClassInstr* other_check = other->AsCheckClass(); 178 CheckClassInstr* other_check = other->AsCheckClass();
178 ASSERT(other_check != NULL); 179 ASSERT(other_check != NULL);
179 if (unary_checks().NumberOfChecks() != 180 const intptr_t number_of_checks = unary_checks_.NumberOfChecks();
180 other_check->unary_checks().NumberOfChecks()) { 181 if (number_of_checks != other_check->unary_checks().NumberOfChecks()) {
181 return false; 182 return false;
182 } 183 }
183 for (intptr_t i = 0; i < unary_checks().NumberOfChecks(); ++i) { 184 for (intptr_t i = 0; i < number_of_checks; ++i) {
184 // TODO(fschneider): Make sure ic_data are sorted to hit more cases. 185 // TODO(fschneider): Make sure ic_data are sorted to hit more cases.
185 if (unary_checks().GetReceiverClassIdAt(i) != 186 if (unary_checks().GetReceiverClassIdAt(i) !=
186 other_check->unary_checks().GetReceiverClassIdAt(i)) { 187 other_check->unary_checks().GetReceiverClassIdAt(i)) {
187 return false; 188 return false;
188 } 189 }
189 } 190 }
190 return true; 191 return true;
191 } 192 }
192 193
193 194
(...skipping 18 matching lines...) Expand all
212 213
213 214
214 EffectSet CheckClassIdInstr::Dependencies() const { 215 EffectSet CheckClassIdInstr::Dependencies() const {
215 // Externalization of strings via the API can change the class-id. 216 // Externalization of strings via the API can change the class-id.
216 return Field::IsExternalizableCid(cid_) ? EffectSet::Externalization() 217 return Field::IsExternalizableCid(cid_) ? EffectSet::Externalization()
217 : EffectSet::None(); 218 : EffectSet::None();
218 } 219 }
219 220
220 221
221 bool CheckClassInstr::DeoptIfNull() const { 222 bool CheckClassInstr::DeoptIfNull() const {
222 if (unary_checks().NumberOfChecks() != 1) { 223 if (!unary_checks().NumberOfChecksIs(1)) {
223 return false; 224 return false;
224 } 225 }
225 CompileType* in_type = value()->Type(); 226 CompileType* in_type = value()->Type();
226 const intptr_t cid = unary_checks().GetCidAt(0); 227 const intptr_t cid = unary_checks().GetCidAt(0);
227 // Performance check: use CheckSmiInstr instead. 228 // Performance check: use CheckSmiInstr instead.
228 ASSERT(cid != kSmiCid); 229 ASSERT(cid != kSmiCid);
229 return in_type->is_nullable() && (in_type->ToNullableCid() == cid); 230 return in_type->is_nullable() && (in_type->ToNullableCid() == cid);
230 } 231 }
231 232
232 233
233 // Null object is a singleton of null-class (except for some sentinel, 234 // Null object is a singleton of null-class (except for some sentinel,
234 // transitional temporaries). Instead of checking against the null class only 235 // transitional temporaries). Instead of checking against the null class only
235 // we can check against null instance instead. 236 // we can check against null instance instead.
236 bool CheckClassInstr::DeoptIfNotNull() const { 237 bool CheckClassInstr::DeoptIfNotNull() const {
237 if (unary_checks().NumberOfChecks() != 1) { 238 if (!unary_checks().NumberOfChecksIs(1)) {
238 return false; 239 return false;
239 } 240 }
240 const intptr_t cid = unary_checks().GetCidAt(0); 241 const intptr_t cid = unary_checks().GetCidAt(0);
241 return cid == kNullCid; 242 return cid == kNullCid;
242 } 243 }
243 244
244 245
245 bool CheckClassInstr::IsDenseCidRange(const ICData& unary_checks) { 246 bool CheckClassInstr::IsDenseCidRange(const ICData& unary_checks) {
246 ASSERT(unary_checks.NumArgsTested() == 1); 247 ASSERT(unary_checks.NumArgsTested() == 1);
247 // TODO(fschneider): Support smis in dense cid checks. 248 // TODO(fschneider): Support smis in dense cid checks.
248 if (unary_checks.GetReceiverClassIdAt(0) == kSmiCid) return false; 249 if (unary_checks.GetReceiverClassIdAt(0) == kSmiCid) return false;
249 if (unary_checks.NumberOfChecks() <= 2) return false; 250 const intptr_t number_of_checks = unary_checks.NumberOfChecks();
251 if (number_of_checks <= 2) return false;
250 intptr_t max = 0; 252 intptr_t max = 0;
251 intptr_t min = kIntptrMax; 253 intptr_t min = kIntptrMax;
252 for (intptr_t i = 0; i < unary_checks.NumberOfChecks(); ++i) { 254 for (intptr_t i = 0; i < number_of_checks; ++i) {
253 intptr_t cid = unary_checks.GetCidAt(i); 255 intptr_t cid = unary_checks.GetCidAt(i);
254 if (cid < min) min = cid; 256 if (cid < min) min = cid;
255 if (cid > max) max = cid; 257 if (cid > max) max = cid;
256 } 258 }
257 return (max - min) < kBitsPerWord; 259 return (max - min) < kBitsPerWord;
258 } 260 }
259 261
260 262
261 bool CheckClassInstr::IsDenseSwitch() const { 263 bool CheckClassInstr::IsDenseSwitch() const {
262 return is_dense_switch_; 264 return is_dense_switch_;
(...skipping 3695 matching lines...) Expand 10 before | Expand all | Expand 10 after
3958 set_native_c_function(native_function); 3960 set_native_c_function(native_function);
3959 function().SetIsNativeAutoSetupScope(auto_setup_scope); 3961 function().SetIsNativeAutoSetupScope(auto_setup_scope);
3960 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); 3962 Dart_NativeEntryResolver resolver = library.native_entry_resolver();
3961 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); 3963 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver);
3962 set_is_bootstrap_native(is_bootstrap_native); 3964 set_is_bootstrap_native(is_bootstrap_native);
3963 } 3965 }
3964 3966
3965 #undef __ 3967 #undef __
3966 3968
3967 } // namespace dart 3969 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698