| Index: sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
|
| index cd961728012fa07b1e80e55a294c1623ac551b27..8116646ac79b2fe535e0de28e9b0d28c43a6c1ea 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
|
| @@ -1706,14 +1706,22 @@ class MemorySet {
|
| MemorySet(this.compiler);
|
|
|
| /**
|
| - * Returns whether [first] and [second] may alias to the same
|
| - * object.
|
| + * Returns whether [first] and [second] always alias to the same object.
|
| + */
|
| + bool mustAlias(HInstruction first, HInstruction second) {
|
| + return first == second;
|
| + }
|
| +
|
| + /**
|
| + * Returns whether [first] and [second] may alias to the same object.
|
| */
|
| bool mayAlias(HInstruction first, HInstruction second) {
|
| - if (first == second) return true;
|
| + if (mustAlias(first, second)) return true;
|
| if (isConcrete(first) && isConcrete(second)) return false;
|
| if (nonEscapingReceivers.contains(first)) return false;
|
| if (nonEscapingReceivers.contains(second)) return false;
|
| + // Typed arrays of different types might have a shared buffer.
|
| + if (couldBeTypedArray(first) && couldBeTypedArray(second)) return true;
|
| TypeMask intersection = first.instructionType.intersection(
|
| second.instructionType, compiler);
|
| if (intersection.isEmpty) return false;
|
| @@ -1730,6 +1738,11 @@ class MemorySet {
|
| || instruction is HLiteralList;
|
| }
|
|
|
| + bool couldBeTypedArray(HInstruction receiver) {
|
| + JavaScriptBackend backend = compiler.backend;
|
| + return backend.couldBeTypedArray(receiver.instructionType);
|
| + }
|
| +
|
| /**
|
| * Returns whether [receiver] escapes the current function.
|
| */
|
| @@ -1849,15 +1862,19 @@ class MemorySet {
|
| nonEscapingReceivers.remove(value);
|
| keyedValues.forEach((key, values) {
|
| if (mayAlias(receiver, key)) {
|
| + // Typed arrays that are views of the same buffer may have different
|
| + // offsets or element sizes, unless they are the same typed array.
|
| + bool weakIndex = couldBeTypedArray(key) && !mustAlias(receiver, key);
|
| values.forEach((otherIndex, otherValue) {
|
| - if (mayAlias(index, otherIndex)) values[otherIndex] = null;
|
| + if (weakIndex || mayAlias(index, otherIndex)) {
|
| + values[otherIndex] = null;
|
| + }
|
| });
|
| }
|
| });
|
|
|
| - JavaScriptBackend backend = compiler.backend;
|
| // Typed arrays may narrow incoming values.
|
| - if (backend.couldBeTypedArray(receiver.instructionType)) return;
|
| + if (couldBeTypedArray(receiver)) return;
|
|
|
| Map<HInstruction, HInstruction> map = keyedValues.putIfAbsent(
|
| receiver, () => <HInstruction, HInstruction> {});
|
|
|