Chromium Code Reviews| Index: lib/compiler/implementation/ssa/bailout.dart |
| diff --git a/lib/compiler/implementation/ssa/bailout.dart b/lib/compiler/implementation/ssa/bailout.dart |
| index 548de769ef6c99637e8bc850336a9dab2af00009..facc95cba1b3e7ec1a057f95b0aca2ed4f541e42 100644 |
| --- a/lib/compiler/implementation/ssa/bailout.dart |
| +++ b/lib/compiler/implementation/ssa/bailout.dart |
| @@ -152,7 +152,9 @@ class SsaTypeGuardInserter extends HGraphVisitor implements OptimizationPhase { |
| // 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) { |
| + if (instruction is HIndex && |
| + (instruction as HIndex).builtin && |
| + hasTypeGuards) { |
| HBasicBlock loopHeader = instruction.block.enclosingLoopHeader; |
| if (loopHeader != null && loopHeader.parentLoopHeader != null) { |
| return true; |
| @@ -189,7 +191,6 @@ class SsaTypeGuardInserter extends HGraphVisitor implements OptimizationPhase { |
| void visitInstruction(HInstruction instruction) { |
| HType speculativeType = instruction.propagatedType; |
| if (shouldInsertTypeGuard(instruction)) { |
| - List<HInstruction> inputs = <HInstruction>[instruction]; |
| HInstruction insertionPoint; |
| if (instruction is HPhi) { |
| insertionPoint = instruction.block.first; |
| @@ -206,14 +207,17 @@ class SsaTypeGuardInserter extends HGraphVisitor implements OptimizationPhase { |
| // If the previous instruction is also a type guard, then both |
| // guards have the same environment, and can therefore share the |
| // same state id. |
| + HBailoutTarget target; |
| int state; |
| if (insertionPoint.previous is HTypeGuard) { |
| HTypeGuard other = insertionPoint.previous; |
| - state = other.state; |
| + target = other.bailoutTarget; |
| } else { |
| state = stateId++; |
| + target = new HBailoutTarget(state); |
| + insertionPoint.block.addBefore(insertionPoint, target); |
| } |
| - HTypeGuard guard = new HTypeGuard(speculativeType, state, inputs); |
| + HTypeGuard guard = new HTypeGuard(speculativeType, instruction, target); |
| guard.propagatedType = speculativeType; |
| work.guards.add(guard); |
| instruction.block.rewrite(instruction, guard); |
| @@ -234,12 +238,12 @@ class SsaEnvironmentBuilder extends HBaseVisitor implements OptimizationPhase { |
| final Compiler compiler; |
| final String name = 'SsaEnvironmentBuilder'; |
| - final Map<HInstruction, Environment> capturedEnvironments; |
| + final Map<HBailoutTarget, Environment> capturedEnvironments; |
| final Map<HBasicBlock, Environment> liveInstructions; |
| Environment environment; |
| SsaEnvironmentBuilder(Compiler this.compiler) |
| - : capturedEnvironments = new Map<HInstruction, Environment>(), |
| + : capturedEnvironments = new Map<HBailoutTarget, Environment>(), |
| liveInstructions = new Map<HBasicBlock, Environment>(); |
| @@ -323,9 +327,9 @@ class SsaEnvironmentBuilder extends HBaseVisitor implements OptimizationPhase { |
| liveInstructions[block] = environment; |
| } |
| - void visitTypeGuard(HTypeGuard guard) { |
| - visitInstruction(guard); |
| - capturedEnvironments[guard] = new Environment.from(environment); |
| + void visitBailoutTarget(HBailoutTarget target) { |
| + visitInstruction(target); |
| + capturedEnvironments[target] = new Environment.from(environment); |
| } |
| void visitInstruction(HInstruction instruction) { |
| @@ -335,44 +339,26 @@ class SsaEnvironmentBuilder extends HBaseVisitor implements OptimizationPhase { |
| } |
| } |
| - void insertCapturedEnvironments() { |
| - Map<int, HTypeGuard> seenGuardStates = new Map<int, HTypeGuard>(); |
| - capturedEnvironments.forEach((HTypeGuard guard, Environment env) { |
| - storeInGuard(guard, env.lives, seenGuardStates); |
| - }); |
| - } |
| - |
| /** |
| - * Stores all live variables in the guard. |
| + * Stores all live variables in the bailout target and the guards. |
| */ |
| - void storeInGuard(HTypeGuard guard, |
| - Set<HInstruction> lives, |
| - Map<int, HTypeGuard> seenGuardStates) { |
| - HInstruction guarded = guard.guarded; |
| - List<HInstruction> inputs = guard.inputs; |
| - assert(inputs.length == 1); |
| - inputs.clear(); |
| - HTypeGuard other = seenGuardStates[guard.state]; |
| - if (other !== null) { |
| - // The guards are sharing the same state. Also share the same |
| - // environment, in the same order. |
| - inputs.addAll(other.inputs); |
| - assert(inputs.length == lives.length); |
| - } else { |
| - seenGuardStates[guard.state] = guard; |
| - inputs.addAll(lives); |
| - } |
| - |
| - for (int i = 0; i < inputs.length; i++) { |
| - HInstruction input = inputs[i]; |
| - if (input == guarded) { |
| - guard.checkedInputIndex = i; |
| - // No need to update [input.usedBy], the guard is already |
| - // there. |
| - } else { |
| - input.usedBy.add(guard); |
| + void insertCapturedEnvironments() { |
| + capturedEnvironments.forEach((HBailoutTarget target, Environment env) { |
| + assert(target.inputs.length == 0); |
| + target.inputs.addAll(env.lives); |
| + // TODO(floitsch): we should add the bailout-target's input variables |
| + // as input to the guards only in the optimized version. The |
| + // non-optimized version does not use the bailout guards and it is |
| + // unnecessary to keep the variables alive until the check. |
| + for (HTypeGuard guard in target.usedBy) { |
| + assert(guard.inputs.length == 2); |
|
ricow1
2012/07/23 12:52:26
Why is the length of the inputs always 2
floitsch
2012/07/23 13:27:48
Added comment:
// A type-guard initially only has
|
| + guard.inputs.addAll(env.lives); |
| } |
| - } |
| + for (HInstruction live in env.lives) { |
| + live.usedBy.add(target); |
| + live.usedBy.addAll(target.usedBy); |
| + } |
| + }); |
| } |
| } |
| @@ -394,12 +380,12 @@ class SsaBailoutPropagator extends HBaseVisitor { |
| * different places, or a bailout inside an if or a loop. For such a |
| * graph, the code generator will emit a generic switch. |
| */ |
| - bool hasComplexTypeGuards = false; |
| + bool hasComplexBailoutTargets = false; |
| /** |
| * The first type guard in the graph. |
| */ |
| - HTypeGuard firstTypeGuard; |
| + HBailoutTarget firstBailoutTarget; |
| /** |
| * If set, it is the first block in the graph where we generate |
| @@ -522,21 +508,21 @@ class SsaBailoutPropagator extends HBaseVisitor { |
| } |
| } |
| - visitTypeGuard(HTypeGuard guard) { |
| - int inputLength = guard.inputs.length; |
| + visitBailoutTarget(HBailoutTarget target) { |
| + int inputLength = target.inputs.length; |
| if (inputLength > maxBailoutParameters) { |
| maxBailoutParameters = inputLength; |
| } |
| if (blocks.isEmpty()) { |
| - if (firstTypeGuard === null || firstTypeGuard.state === guard.state) { |
| - firstTypeGuard = guard; |
| + if (firstBailoutTarget === null) { |
| + firstBailoutTarget = target; |
| } else { |
| - hasComplexTypeGuards = true; |
| + hasComplexBailoutTargets = true; |
| } |
| } else { |
| - hasComplexTypeGuards = true; |
| + hasComplexBailoutTargets = true; |
| blocks.forEach((HBasicBlock block) { |
| - block.guards.add(guard); |
| + block.bailoutTargets.add(target); |
| }); |
| } |
| } |