Index: runtime/lib/growable_array.dart |
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart |
index 463214700e356ba0810b9d7ba4294226272cf31c..917950aac726a8987eab184e38e4506ee6e857a5 100644 |
--- a/runtime/lib/growable_array.dart |
+++ b/runtime/lib/growable_array.dart |
@@ -234,16 +234,27 @@ class _GrowableList<T> extends ListBase<T> { |
void _grow(int new_capacity) { |
var newData = _allocateData(new_capacity); |
- for (int i = 0; i < length; i++) { |
- newData[i] = this[i]; |
+ // This is a work-around for dartbug.com/30090: array-bound-check |
+ // generalization causes excessive deoptimizations because it |
+ // hoists CheckArrayBound(i, ...) out of the loop below and turns it |
+ // into CheckArrayBound(length - 1, ...). Which deoptimizes |
+ // if length == 0. However the loop itself does not execute |
+ // if length == 0. |
+ if (length > 0) { |
+ for (int i = 0; i < length; i++) { |
+ newData[i] = this[i]; |
+ } |
} |
_setData(newData); |
} |
void _shrink(int new_capacity, int new_length) { |
var newData = _allocateData(new_capacity); |
- for (int i = 0; i < new_length; i++) { |
- newData[i] = this[i]; |
+ // This is a work-around for dartbug.com/30090. See the comment in _grow. |
+ if (new_length > 0) { |
+ for (int i = 0; i < new_length; i++) { |
+ newData[i] = this[i]; |
+ } |
} |
_setData(newData); |
} |