| Index: lib/compiler/implementation/ssa/bailout.dart
|
| diff --git a/lib/compiler/implementation/ssa/bailout.dart b/lib/compiler/implementation/ssa/bailout.dart
|
| index 6cc69c59f8939a44d60830a62f54c98dec369b69..5c0b7a94559c742767354c1190a89fa1a22fceba 100644
|
| --- a/lib/compiler/implementation/ssa/bailout.dart
|
| +++ b/lib/compiler/implementation/ssa/bailout.dart
|
| @@ -107,6 +107,8 @@ class SsaTypeGuardInserter extends HGraphVisitor implements OptimizationPhase {
|
| return type.isPrimitive() && !type.isNull();
|
| }
|
|
|
| + bool get hasTypeGuards() => work.guards.length != 0;
|
| +
|
| bool typeGuardWouldBeValuable(HInstruction instruction,
|
| HType speculativeType) {
|
| // If the type itself is not valuable, do not generate a guard for it.
|
| @@ -145,6 +147,20 @@ class SsaTypeGuardInserter extends HGraphVisitor implements OptimizationPhase {
|
| if (isNested(userLoopHeader, currentLoopHeader)) return true;
|
| }
|
|
|
| + // To speed up computations on values loaded from arrays, we
|
| + // insert type guards for builtin array indexing operations in
|
| + // nested loops. Since this can blow up code size quite
|
| + // significantly, we only do it if type guards have already been
|
| + // inserted for this method. The code size price for an additional
|
| + // type guard is much smaller than the first one that causes the
|
| + // generation of a bailout method.
|
| + if (instruction is HIndex && instruction.builtin && hasTypeGuards) {
|
| + HBasicBlock loopHeader = instruction.block.enclosingLoopHeader;
|
| + if (loopHeader != null && loopHeader.parentLoopHeader != null) {
|
| + return true;
|
| + }
|
| + }
|
| +
|
| // Insert type guards if the method is likely to be called in a
|
| // loop.
|
| return calledInLoop || highTypeLikelyhood;
|
|
|