OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 class _GrowableList<T> extends ListBase<T> { | 5 class _GrowableList<T> extends ListBase<T> { |
6 void insert(int index, T element) { | 6 void insert(int index, T element) { |
7 if ((index < 0) || (index > length)) { | 7 if ((index < 0) || (index > length)) { |
8 throw new RangeError.range(index, 0, length); | 8 throw new RangeError.range(index, 0, length); |
9 } | 9 } |
10 if (index == this.length) { | 10 if (index == this.length) { |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 // Round up size to the next odd number, since this is free | 227 // Round up size to the next odd number, since this is free |
228 // because of alignment requirements of the GC. | 228 // because of alignment requirements of the GC. |
229 return new _List(capacity | 1); | 229 return new _List(capacity | 1); |
230 } | 230 } |
231 | 231 |
232 // Grow from 0 to 3, and then double + 1. | 232 // Grow from 0 to 3, and then double + 1. |
233 int _nextCapacity(int old_capacity) => (old_capacity * 2) | 3; | 233 int _nextCapacity(int old_capacity) => (old_capacity * 2) | 3; |
234 | 234 |
235 void _grow(int new_capacity) { | 235 void _grow(int new_capacity) { |
236 var newData = _allocateData(new_capacity); | 236 var newData = _allocateData(new_capacity); |
237 for (int i = 0; i < length; i++) { | 237 // This is a work-around for dartbug.com/30090: array-bound-check |
238 newData[i] = this[i]; | 238 // generalization causes excessive deoptimizations because it |
| 239 // hoists CheckArrayBound(i, ...) out of the loop below and turns it |
| 240 // into CheckArrayBound(length - 1, ...). Which deoptimizes |
| 241 // if length == 0. However the loop itself does not execute |
| 242 // if length == 0. |
| 243 if (length > 0) { |
| 244 for (int i = 0; i < length; i++) { |
| 245 newData[i] = this[i]; |
| 246 } |
239 } | 247 } |
240 _setData(newData); | 248 _setData(newData); |
241 } | 249 } |
242 | 250 |
243 void _shrink(int new_capacity, int new_length) { | 251 void _shrink(int new_capacity, int new_length) { |
244 var newData = _allocateData(new_capacity); | 252 var newData = _allocateData(new_capacity); |
245 for (int i = 0; i < new_length; i++) { | 253 // This is a work-around for dartbug.com/30090. See the comment in _grow. |
246 newData[i] = this[i]; | 254 if (new_length > 0) { |
| 255 for (int i = 0; i < new_length; i++) { |
| 256 newData[i] = this[i]; |
| 257 } |
247 } | 258 } |
248 _setData(newData); | 259 _setData(newData); |
249 } | 260 } |
250 | 261 |
251 // Iterable interface. | 262 // Iterable interface. |
252 | 263 |
253 void forEach(f(T element)) { | 264 void forEach(f(T element)) { |
254 int initialLength = length; | 265 int initialLength = length; |
255 for (int i = 0; i < length; i++) { | 266 for (int i = 0; i < length; i++) { |
256 f(this[i]); | 267 f(this[i]); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 result._setLength(length); | 369 result._setLength(length); |
359 return result; | 370 return result; |
360 } | 371 } |
361 return growable ? <T>[] : new List<T>(0); | 372 return growable ? <T>[] : new List<T>(0); |
362 } | 373 } |
363 | 374 |
364 Set<T> toSet() { | 375 Set<T> toSet() { |
365 return new Set<T>.from(this); | 376 return new Set<T>.from(this); |
366 } | 377 } |
367 } | 378 } |
OLD | NEW |