[vm/bytecode] Enable OSR for unoptimized code compiled from bytecode

In order to enable OSR, CheckStackOverflow IL instructions are attributed
with a non-zero loop depth. The original loop depth is passed as operand
of CheckStack bytecode instruction.

Change-Id: I771f59ba9f8d071680a3b7156be380e0f606b7b2
Reviewed-on: https://dart-review.googlesource.com/c/84081
Reviewed-by: RĂ©gis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index efaae5f..3309d43 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -371,8 +371,8 @@
     emitWord(_encodeA(Opcode.kAssertBoolean, ra));
   }
 
-  void emitCheckStack() {
-    emitWord(_encode0(Opcode.kCheckStack));
+  void emitCheckStack(int ra) {
+    emitWord(_encodeA(Opcode.kCheckStack, ra));
   }
 
   void emitCheckFunctionTypeArgs(int ra, int rd) {
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 3a45d13..e5045c1 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -165,7 +165,7 @@
   Opcode.kCheckFunctionTypeArgs: const Format(
       Encoding.kAD, const [Operand.imm, Operand.reg, Operand.none]),
   Opcode.kCheckStack: const Format(
-      Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+      Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
   Opcode.kAllocate: const Format(
       Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
   Opcode.kAllocateT: const Format(
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index b9e9dcf..12c4793f 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -103,6 +103,7 @@
   BytecodeAssembler asm;
   List<BytecodeAssembler> savedAssemblers;
   bool hasErrors;
+  int currentLoopDepth;
 
   BytecodeGenerator(
       this.component,
@@ -798,6 +799,7 @@
     constantEmitter = new ConstantEmitter(cp);
     asm = new BytecodeAssembler();
     savedAssemblers = <BytecodeAssembler>[];
+    currentLoopDepth = 0;
 
     locals.enterScope(node);
     assert(!locals.isSyncYieldingFrame);
@@ -899,7 +901,7 @@
     } else {
       asm.emitEntry(locals.frameSize);
     }
-    asm.emitCheckStack();
+    asm.emitCheckStack(0);
 
     if (isClosure) {
       asm.emitPush(locals.closureVarIndexInFrame);
@@ -1231,6 +1233,8 @@
     final savedIsClosure = isClosure;
     isClosure = true;
     enclosingFunction = function;
+    final savedLoopDepth = currentLoopDepth;
+    currentLoopDepth = 0;
 
     if (function.typeParameters.isNotEmpty) {
       functionTypeParameters ??= new List<TypeParameter>();
@@ -1287,6 +1291,7 @@
     enclosingFunction = parentFunction;
     parentFunction = savedParentFunction;
     isClosure = savedIsClosure;
+    currentLoopDepth = savedLoopDepth;
 
     locals.leaveScope();
 
@@ -2307,11 +2312,13 @@
     final Label join = new Label(allowsBackwardJumps: true);
     asm.bind(join);
 
-    asm.emitCheckStack();
+    asm.emitCheckStack(++currentLoopDepth);
 
     node.body.accept(this);
 
     _genConditionAndJumpIf(node.condition, true, join);
+
+    --currentLoopDepth;
   }
 
   @override
@@ -2361,7 +2368,7 @@
     final Label join = new Label(allowsBackwardJumps: true);
 
     asm.bind(join);
-    asm.emitCheckStack();
+    asm.emitCheckStack(++currentLoopDepth);
 
     if (capturedIteratorVar != null) {
       _genLoadVar(capturedIteratorVar);
@@ -2394,6 +2401,7 @@
     asm.emitJump(join);
 
     asm.bind(done);
+    --currentLoopDepth;
   }
 
   @override
@@ -2412,7 +2420,7 @@
       final Label join = new Label(allowsBackwardJumps: true);
       asm.bind(join);
 
-      asm.emitCheckStack();
+      asm.emitCheckStack(++currentLoopDepth);
 
       if (node.condition != null) {
         _genConditionAndJumpIf(node.condition, false, done);
@@ -2434,6 +2442,7 @@
       asm.emitJump(join);
 
       asm.bind(done);
+      --currentLoopDepth;
     } finally {
       _leaveScope();
     }
@@ -2824,13 +2833,14 @@
     final Label join = new Label(allowsBackwardJumps: true);
     asm.bind(join);
 
-    asm.emitCheckStack();
+    asm.emitCheckStack(++currentLoopDepth);
 
     _genConditionAndJumpIf(node.condition, false, done);
 
     node.body.accept(this);
 
     asm.emitJump(join);
+    --currentLoopDepth;
 
     asm.bind(done);
   }
diff --git a/pkg/vm/testcases/bytecode/asserts.dart.expect b/pkg/vm/testcases/bytecode/asserts.dart.expect
index 8c9b60b..e61e22a 100644
--- a/pkg/vm/testcases/bytecode/asserts.dart.expect
+++ b/pkg/vm/testcases/bytecode/asserts.dart.expect
@@ -5,7 +5,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   JumpIfNoAsserts      L1
   Push                 FP[-5]
   AssertBoolean        0
@@ -30,7 +30,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   JumpIfNoAsserts      L1
   Push                 FP[-6]
   InstanceCall         1, CP#1
@@ -60,7 +60,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index a306282..7b539ab 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -6,7 +6,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                3
-  CheckStack
+  CheckStack           0
   Allocate             CP#19
   StoreLocal           r2
   Push                 r2
@@ -70,7 +70,7 @@
   LoadConstant         r2, CP#10
   LoadConstant         r3, CP#10
   Frame                6
-  CheckStack
+  CheckStack           0
   Push                 r0
   LoadFieldTOS         CP#1
   PopLocal             r4
@@ -155,7 +155,7 @@
 
 Closure CP#0 {
   EntryFixed           2, 4
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   LoadFieldTOS         CP#1
   PopLocal             r0
@@ -275,7 +275,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                7
-  CheckStack
+  CheckStack           0
   AllocateContext      4
   PopLocal             r0
   Push                 r0
@@ -375,7 +375,7 @@
   LoadConstant         r2, CP#4
   LoadConstant         r3, CP#4
   Frame                6
-  CheckStack
+  CheckStack           0
   Push                 r0
   LoadFieldTOS         CP#5
   PopLocal             r4
@@ -456,7 +456,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                4
-  CheckStack
+  CheckStack           0
   AllocateContext      11
   PopLocal             r0
   Push                 r0
@@ -581,7 +581,7 @@
   LoadConstant         r2, CP#4
   LoadConstant         r3, CP#4
   Frame                6
-  CheckStack
+  CheckStack           0
   Push                 r0
   LoadFieldTOS         CP#5
   PopLocal             r4
@@ -736,7 +736,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                4
-  CheckStack
+  CheckStack           0
   AllocateContext      11
   PopLocal             r0
   Push                 r0
@@ -866,7 +866,7 @@
   LoadConstant         r2, CP#4
   LoadConstant         r3, CP#4
   Frame                7
-  CheckStack
+  CheckStack           0
   Push                 r0
   LoadFieldTOS         CP#5
   PopLocal             r4
@@ -898,7 +898,7 @@
   PushInt              0
   StoreContextVar      0
 L6:
-  CheckStack
+  CheckStack           1
   Push                 r4
   LoadContextVar       0
   PushInt              10
@@ -915,7 +915,7 @@
   Push                 r8
   StoreContextVar      1
 L5:
-  CheckStack
+  CheckStack           2
   Push                 r4
   LoadContextVar       1
   StoreLocal           r8
@@ -1034,7 +1034,7 @@
   PushInt              0
   PopLocal             r8
 L8:
-  CheckStack
+  CheckStack           1
   Push                 r8
   PushInt              10
   CompareIntLt
@@ -1149,7 +1149,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                4
-  CheckStack
+  CheckStack           0
   AllocateContext      16
   PopLocal             r0
   Push                 r0
@@ -1302,7 +1302,7 @@
   LoadConstant         r2, CP#4
   LoadConstant         r3, CP#4
   Frame                10
-  CheckStack
+  CheckStack           0
   Push                 r0
   LoadFieldTOS         CP#5
   PopLocal             r4
@@ -1783,7 +1783,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                4
-  CheckStack
+  CheckStack           0
   AllocateContext      2
   PopLocal             r0
   Push                 r0
@@ -1857,7 +1857,7 @@
   LoadConstant         r2, CP#7
   LoadConstant         r3, CP#7
   Frame                8
-  CheckStack
+  CheckStack           0
   Push                 r0
   LoadFieldTOS         CP#1
   PopLocal             r4
@@ -2014,7 +2014,7 @@
 
 Closure CP#0 {
   EntryFixed           1, 4
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#1
   PopLocal             r0
@@ -2145,7 +2145,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                4
-  CheckStack
+  CheckStack           0
   AllocateContext      9
   PopLocal             r0
   Push                 r0
@@ -2264,7 +2264,7 @@
   LoadConstant         r2, CP#4
   LoadConstant         r3, CP#4
   Frame                6
-  CheckStack
+  CheckStack           0
   Push                 r0
   LoadFieldTOS         CP#5
   PopLocal             r4
@@ -2398,7 +2398,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
diff --git a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
index c47aadf..a0c9405 100644
--- a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
+++ b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
@@ -9,7 +9,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -30,7 +30,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -48,7 +48,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   Push                 FP[-5]
   NativeCall           CP#0
@@ -62,7 +62,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   NativeCall           CP#0
   ReturnTOS
@@ -75,7 +75,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   NativeCall           CP#0
   ReturnTOS
 }
@@ -87,7 +87,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   Allocate             CP#0
   StoreLocal           r1
   Push                 r1
@@ -115,7 +115,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   PushStatic           CP#0
   EqualsNull
@@ -156,7 +156,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#1
   IndirectStaticCall   0, CP#0
   PushConstant         CP#3
@@ -176,7 +176,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -194,7 +194,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -212,7 +212,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#1
   IndirectStaticCall   0, CP#0
   ReturnTOS
@@ -226,7 +226,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#1
   IndirectStaticCall   0, CP#0
   ReturnTOS
@@ -253,7 +253,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -271,7 +271,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   StoreStaticTOS       CP#0
   PushNull
@@ -290,7 +290,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   PushStatic           CP#0
   EqualsNull
@@ -339,7 +339,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   NativeCall           CP#0
   ReturnTOS
@@ -352,7 +352,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   InstanceCall         1, CP#1
   PushConstant         CP#2
@@ -372,7 +372,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   ReturnTOS
 }
@@ -384,7 +384,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   StoreStaticTOS       CP#0
   PushNull
@@ -399,7 +399,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                3
-  CheckStack
+  CheckStack           0
   Push                 FP[-7]
   StoreStaticTOS       CP#0
   Push                 FP[-6]
@@ -422,7 +422,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   PushStatic           CP#0
   PushConstant         CP#1
@@ -500,7 +500,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   PushConstant         CP#2
   IndirectStaticCall   1, CP#1
@@ -519,7 +519,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect
index c468b72..9bef3f8 100644
--- a/pkg/vm/testcases/bytecode/closures.dart.expect
+++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -7,7 +7,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -27,7 +27,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -47,7 +47,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -67,7 +67,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -87,7 +87,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -107,7 +107,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -127,7 +127,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -147,7 +147,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -167,7 +167,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -185,7 +185,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                5
-  CheckStack
+  CheckStack           0
   CheckFunctionTypeArgs 2, r0
   AllocateContext      1
   PopLocal             r1
@@ -274,7 +274,7 @@
 }
 Closure CP#12 {
   EntryFixed           1, 4
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#1
   PopLocal             r1
@@ -359,7 +359,7 @@
 
 Closure CP#10 {
   EntryFixed           1, 5
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#1
   PopLocal             r1
@@ -411,7 +411,7 @@
 
 Closure CP#0 {
   EntryFixed           1, 5
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#1
   PopLocal             r1
@@ -486,7 +486,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -505,7 +505,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                5
-  CheckStack
+  CheckStack           0
   AllocateContext      4
   PopLocal             r0
   Push                 r0
@@ -623,7 +623,7 @@
 }
 Closure CP#6 {
   EntryFixed           1, 3
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#1
   PopLocal             r0
@@ -651,7 +651,7 @@
 
 Closure CP#0 {
   EntryFixed           2, 4
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   LoadFieldTOS         CP#1
   PopLocal             r0
@@ -722,7 +722,7 @@
 
 Closure CP#29 {
   EntryFixed           1, 3
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#1
   PopLocal             r0
@@ -774,7 +774,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -792,7 +792,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                5
-  CheckStack
+  CheckStack           0
   AllocateContext      1
   PopLocal             r0
   Push                 r0
@@ -826,7 +826,7 @@
   PushInt              0
   StoreContextVar      0
 L2:
-  CheckStack
+  CheckStack           1
   Push                 r0
   LoadContextVar       0
   PushInt              10
@@ -925,7 +925,7 @@
 }
 Closure CP#4 {
   EntryFixed           1, 2
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#5
   PopLocal             r0
@@ -941,7 +941,7 @@
 
 Closure CP#19 {
   EntryFixed           2, 3
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   LoadFieldTOS         CP#5
   PopLocal             r0
@@ -977,12 +977,12 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                5
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   InstanceCall         1, CP#1
   PopLocal             r2
 L2:
-  CheckStack
+  CheckStack           1
   Push                 r2
   InstanceCall         1, CP#2
   JumpIfFalse          L1
@@ -1050,7 +1050,7 @@
 }
 Closure CP#4 {
   EntryFixed           1, 3
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#5
   PopLocal             r0
@@ -1078,7 +1078,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -1096,7 +1096,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                3
-  CheckStack
+  CheckStack           0
   AllocateContext      1
   PopLocal             r0
   Push                 r0
@@ -1152,7 +1152,7 @@
 }
 Closure CP#4 {
   EntryFixed           1, 2
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#5
   PopLocal             r0
@@ -1168,7 +1168,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                4
-  CheckStack
+  CheckStack           0
   AllocateContext      1
   PopLocal             r0
   Push                 r0
@@ -1223,7 +1223,7 @@
 }
 Closure CP#0 {
   EntryFixed           2, 3
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   LoadFieldTOS         CP#1
   PopLocal             r0
@@ -1255,7 +1255,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   CheckFunctionTypeArgs 8, r0
   PushConstant         CP#0
   StoreLocal           r1
@@ -1340,7 +1340,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   PushConstant         CP#2
   PushConstant         CP#1
@@ -1400,7 +1400,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                7
-  CheckStack
+  CheckStack           0
   Allocate             CP#14
   StoreLocal           r3
   Push                 r3
@@ -1477,7 +1477,7 @@
 }
 Closure CP#0 {
   EntryFixed           2, 3
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   LoadFieldTOS         CP#1
   PopLocal             r1
@@ -1518,7 +1518,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
diff --git a/pkg/vm/testcases/bytecode/deferred_lib.dart.expect b/pkg/vm/testcases/bytecode/deferred_lib.dart.expect
index 67139cb..9004858 100644
--- a/pkg/vm/testcases/bytecode/deferred_lib.dart.expect
+++ b/pkg/vm/testcases/bytecode/deferred_lib.dart.expect
@@ -5,7 +5,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   PushNull
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -25,7 +25,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -40,7 +40,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
diff --git a/pkg/vm/testcases/bytecode/field_initializers.dart.expect b/pkg/vm/testcases/bytecode/field_initializers.dart.expect
index d28770d..a375935 100644
--- a/pkg/vm/testcases/bytecode/field_initializers.dart.expect
+++ b/pkg/vm/testcases/bytecode/field_initializers.dart.expect
@@ -11,7 +11,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   PushInt              42
   StoreFieldTOS        CP#0
@@ -48,7 +48,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-7]
   PushInt              42
   StoreFieldTOS        CP#0
@@ -87,7 +87,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushInt              45
   PushConstant         CP#1
@@ -106,7 +106,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-8]
   Push                 FP[-7]
   Push                 FP[-6]
@@ -133,7 +133,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushInt              46
   StoreFieldTOS        CP#0
@@ -157,7 +157,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-7]
   PushInt              46
   StoreFieldTOS        CP#0
@@ -187,7 +187,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
diff --git a/pkg/vm/testcases/bytecode/hello.dart.expect b/pkg/vm/testcases/bytecode/hello.dart.expect
index db4aaaf..1bc42dd 100644
--- a/pkg/vm/testcases/bytecode/hello.dart.expect
+++ b/pkg/vm/testcases/bytecode/hello.dart.expect
@@ -5,7 +5,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   PushConstant         CP#2
   IndirectStaticCall   1, CP#1
diff --git a/pkg/vm/testcases/bytecode/instance_creation.dart.expect b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
index db64c59..8f84e7e 100644
--- a/pkg/vm/testcases/bytecode/instance_creation.dart.expect
+++ b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
@@ -9,7 +9,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -69,7 +69,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -89,7 +89,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -135,7 +135,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -176,7 +176,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -194,7 +194,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadTypeArgumentsField CP#0
   PushConstant         CP#2
@@ -213,7 +213,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -231,7 +231,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadTypeArgumentsField CP#0
   PushConstant         CP#2
@@ -250,7 +250,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -268,7 +268,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushNull
   InstantiateTypeArgumentsTOS 0, CP#1
@@ -294,7 +294,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -314,7 +314,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -335,7 +335,7 @@
   LoadConstant         r1, CP#0
   LoadConstant         r1, CP#1
   Frame                1
-  CheckStack
+  CheckStack           0
   Allocate             CP#2
   StoreLocal           r2
   Push                 r2
@@ -359,7 +359,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   NativeCall           CP#0
   ReturnTOS
@@ -374,7 +374,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#0
   AllocateT
@@ -397,7 +397,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -416,7 +416,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Allocate             CP#0
   StoreLocal           r0
   Push                 r0
@@ -437,7 +437,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   PushConstant         CP#1
   PushConstant         CP#0
   AllocateT
@@ -478,7 +478,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   CheckFunctionTypeArgs 1, r0
   PushNull
   Push                 r0
@@ -506,7 +506,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   PushConstant         CP#2
   IndirectStaticCall   1, CP#1
@@ -525,7 +525,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -551,7 +551,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   PushInt              0
   PushConstant         CP#2
@@ -568,7 +568,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   Push                 FP[-5]
   PushConstant         CP#2
@@ -585,7 +585,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#1
   IndirectStaticCall   0, CP#0
   Drop1
diff --git a/pkg/vm/testcases/bytecode/literals.dart.expect b/pkg/vm/testcases/bytecode/literals.dart.expect
index a818156..f3fe8f4 100644
--- a/pkg/vm/testcases/bytecode/literals.dart.expect
+++ b/pkg/vm/testcases/bytecode/literals.dart.expect
@@ -9,7 +9,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#13
   ReturnTOS
 }
@@ -33,7 +33,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#3
   ReturnTOS
 }
@@ -47,7 +47,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#3
   ReturnTOS
 }
@@ -61,7 +61,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#3
   ReturnTOS
 }
@@ -75,7 +75,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#3
   ReturnTOS
 }
@@ -89,7 +89,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-7]
   Push                 FP[-6]
   StoreFieldTOS        CP#0
@@ -117,7 +117,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -135,7 +135,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   Push                 FP[-5]
   StoreFieldTOS        CP#0
@@ -161,7 +161,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-8]
   Push                 FP[-7]
   Push                 FP[-6]
@@ -195,7 +195,7 @@
   EntryOptional        2, 1, 0
   LoadConstant         r2, CP#0
   Frame                0
-  CheckStack
+  CheckStack           0
   Push                 r0
   Push                 r1
   StoreFieldTOS        CP#1
@@ -226,7 +226,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -246,7 +246,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -265,7 +265,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#3
   ReturnTOS
 }
@@ -280,7 +280,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushInt              6
   ReturnTOS
 }
@@ -290,7 +290,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#3
   ReturnTOS
 }
@@ -304,7 +304,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#3
   ReturnTOS
 }
@@ -319,7 +319,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#3
   PushConstant         CP#5
   IndirectStaticCall   1, CP#4
@@ -372,7 +372,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushInt              42
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -446,7 +446,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   StoreLocal           r0
   Push                 r0
@@ -517,7 +517,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   CheckFunctionTypeArgs 1, r0
   PushConstant         CP#0
   PushConstant         CP#1
@@ -633,7 +633,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   PushConstant         CP#2
   IndirectStaticCall   1, CP#1
@@ -659,7 +659,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   CheckFunctionTypeArgs 1, r0
   PushConstant         CP#0
   PushConstant         CP#2
@@ -688,7 +688,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#1
   ReturnTOS
 }
@@ -701,7 +701,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   ReturnTOS
 }
@@ -713,7 +713,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   PushStatic           CP#0
   ReturnTOS
@@ -726,7 +726,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
diff --git a/pkg/vm/testcases/bytecode/loops.dart.expect b/pkg/vm/testcases/bytecode/loops.dart.expect
index 3c0804e..3d0fc28 100644
--- a/pkg/vm/testcases/bytecode/loops.dart.expect
+++ b/pkg/vm/testcases/bytecode/loops.dart.expect
@@ -5,13 +5,13 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   PushInt              0
   PopLocal             r0
   PushInt              0
   PopLocal             r1
 L2:
-  CheckStack
+  CheckStack           1
   Push                 r1
   Push                 FP[-5]
   InstanceCall         1, CP#1
@@ -50,13 +50,13 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   PushInt              0
   PopLocal             r0
   PushInt              0
   PopLocal             r1
 L3:
-  CheckStack
+  CheckStack           1
   Push                 r1
   PushInt              0
   CompareIntGe
@@ -106,14 +106,14 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   PushInt              0
   PopLocal             r0
   PushInt              100
   NegateInt
   PopLocal             r1
 L4:
-  CheckStack
+  CheckStack           1
   Push                 r1
   Push                 FP[-5]
   InstanceCall         1, CP#1
@@ -165,13 +165,13 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                4
-  CheckStack
+  CheckStack           0
   PushInt              0
   PopLocal             r0
   PushInt              0
   PopLocal             r1
 L2:
-  CheckStack
+  CheckStack           1
   Push                 r1
   Push                 FP[-5]
   InstanceCall         1, CP#1
@@ -213,13 +213,13 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   PushInt              0
   PopLocal             r0
   PushInt              0
   PopLocal             r1
 L1:
-  CheckStack
+  CheckStack           1
   Push                 r0
   Push                 FP[-5]
   Push                 r1
@@ -258,14 +258,14 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                3
-  CheckStack
+  CheckStack           0
   PushInt              0
   PopLocal             r0
   Push                 FP[-5]
   InstanceCall         1, CP#1
   PopLocal             r1
 L2:
-  CheckStack
+  CheckStack           1
   Push                 r1
   InstanceCall         1, CP#2
   JumpIfFalse          L1
@@ -297,7 +297,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                4
-  CheckStack
+  CheckStack           0
   PushInt              0
   PopLocal             r0
   PushInt              42
@@ -306,7 +306,7 @@
   InstanceCall         1, CP#1
   PopLocal             r2
 L2:
-  CheckStack
+  CheckStack           1
   Push                 r2
   InstanceCall         1, CP#2
   JumpIfFalse          L1
@@ -342,7 +342,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
diff --git a/pkg/vm/testcases/bytecode/optional_params.dart.expect b/pkg/vm/testcases/bytecode/optional_params.dart.expect
index e599a14..8fa1589 100644
--- a/pkg/vm/testcases/bytecode/optional_params.dart.expect
+++ b/pkg/vm/testcases/bytecode/optional_params.dart.expect
@@ -8,7 +8,7 @@
   LoadConstant         r1, CP#0
   LoadConstant         r2, CP#1
   Frame                1
-  CheckStack
+  CheckStack           0
   PushNull
   PushInt              2
   CreateArrayTOS
@@ -92,7 +92,7 @@
   LoadConstant         r4, CP#5
   LoadConstant         r4, CP#6
   Frame                1
-  CheckStack
+  CheckStack           0
   PushNull
   PushInt              2
   CreateArrayTOS
@@ -221,7 +221,7 @@
   LoadConstant         r3, CP#2
   LoadConstant         r3, CP#3
   Frame                1
-  CheckStack
+  CheckStack           0
   CheckFunctionTypeArgs 2, r4
   PushNull
   Push                 r4
@@ -259,7 +259,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   PushConstant         CP#1
   PushConstant         CP#3
diff --git a/pkg/vm/testcases/bytecode/super_calls.dart.expect b/pkg/vm/testcases/bytecode/super_calls.dart.expect
index cc3d474..7966de3 100644
--- a/pkg/vm/testcases/bytecode/super_calls.dart.expect
+++ b/pkg/vm/testcases/bytecode/super_calls.dart.expect
@@ -6,7 +6,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -24,7 +24,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   CheckFunctionTypeArgs 1, r0
   PushNull
   ReturnTOS
@@ -35,7 +35,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushInt              42
   ReturnTOS
 }
@@ -46,7 +46,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
@@ -58,7 +58,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -76,7 +76,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   Push                 FP[-6]
   PushConstant         CP#1
@@ -96,7 +96,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -111,7 +111,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -126,7 +126,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   Push                 FP[-5]
   PushConstant         CP#2
@@ -148,7 +148,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushInt              3
   PushConstant         CP#1
@@ -169,7 +169,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -192,7 +192,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -210,7 +210,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   PushConstant         CP#0
   PushConstant         CP#1
@@ -262,7 +262,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#0
   PushConstant         CP#1
@@ -295,7 +295,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#0
   PushConstant         CP#1
@@ -328,7 +328,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   PushConstant         CP#0
   Push                 FP[-5]
   PushConstant         CP#1
@@ -368,7 +368,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#0
   PushConstant         CP#1
@@ -408,7 +408,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
diff --git a/pkg/vm/testcases/bytecode/switch.dart.expect b/pkg/vm/testcases/bytecode/switch.dart.expect
index bb4fbbb..3ed2d95 100644
--- a/pkg/vm/testcases/bytecode/switch.dart.expect
+++ b/pkg/vm/testcases/bytecode/switch.dart.expect
@@ -5,7 +5,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   PushNull
   PopLocal             r0
   Push                 FP[-5]
@@ -73,7 +73,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   PushNull
   PopLocal             r0
   Push                 FP[-5]
@@ -158,7 +158,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   PushNull
   PopLocal             r0
   Push                 FP[-5]
@@ -242,7 +242,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart.expect b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
index ed14054..2bee951 100644
--- a/pkg/vm/testcases/bytecode/try_blocks.dart.expect
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
@@ -5,7 +5,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                4
-  CheckStack
+  CheckStack           0
 Try #0 start:
   PushConstant         CP#0
   PushConstant         CP#2
@@ -64,7 +64,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                5
-  CheckStack
+  CheckStack           0
 Try #0 start:
   PushConstant         CP#0
   PushConstant         CP#2
@@ -228,7 +228,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                7
-  CheckStack
+  CheckStack           0
   AllocateContext      3
   PopLocal             r0
   Push                 r0
@@ -375,7 +375,7 @@
 }
 Closure CP#0 {
   EntryFixed           1, 6
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#1
   PopLocal             r0
@@ -413,7 +413,7 @@
 
 Closure CP#25 {
   EntryFixed           1, 6
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#1
   PopLocal             r0
@@ -506,7 +506,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                8
-  CheckStack
+  CheckStack           0
 Try #0 start:
 Try #1 start:
   PushConstant         CP#0
@@ -615,11 +615,11 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                3
-  CheckStack
+  CheckStack           0
   PushInt              0
   PopLocal             r0
 L5:
-  CheckStack
+  CheckStack           1
   Push                 r0
   PushInt              10
   CompareIntLt
@@ -693,7 +693,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                9
-  CheckStack
+  CheckStack           0
   AllocateContext      2
   PopLocal             r0
   Push                 r0
@@ -849,7 +849,7 @@
 }
 Closure CP#8 {
   EntryFixed           1, 2
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#9
   PopLocal             r0
@@ -906,7 +906,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                6
-  CheckStack
+  CheckStack           0
   AllocateContext      1
   PopLocal             r0
   Push                 r0
@@ -1008,7 +1008,7 @@
 }
 Closure CP#0 {
   EntryFixed           1, 6
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   LoadFieldTOS         CP#1
   PopLocal             r0
@@ -1132,7 +1132,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                5
-  CheckStack
+  CheckStack           0
 Try #0 start:
 Try #1 start:
   PushConstant         CP#0
@@ -1204,7 +1204,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
index 66d2906..6a04383 100644
--- a/pkg/vm/testcases/bytecode/type_ops.dart.expect
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -6,7 +6,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -26,7 +26,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -46,7 +46,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#1
   IndirectStaticCall   1, CP#0
@@ -67,7 +67,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   Push                 FP[-5]
   PushConstant         CP#0
@@ -100,7 +100,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
@@ -170,7 +170,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   CheckFunctionTypeArgs 2, r0
   Push                 FP[-5]
   PushNull
@@ -236,7 +236,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                2
-  CheckStack
+  CheckStack           0
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
   PushNull
@@ -287,7 +287,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
@@ -298,7 +298,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   CheckFunctionTypeArgs 2, r0
   JumpIfNotZeroTypeArgs L1
   Push                 FP[-6]
@@ -330,7 +330,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#0
   InstanceCall         2, CP#2
@@ -389,7 +389,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                1
-  CheckStack
+  CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#0
   PushNull
@@ -412,7 +412,7 @@
 [@vm.bytecode=
 Bytecode (version: stable) {
   Entry                0
-  CheckStack
+  CheckStack           0
   PushNull
   ReturnTOS
 }
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index 2d01855..e78cc28 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -187,9 +187,10 @@
   return instructions.closed();
 }
 
-Fragment BaseFlowGraphBuilder::CheckStackOverflow(TokenPosition position) {
+Fragment BaseFlowGraphBuilder::CheckStackOverflow(TokenPosition position,
+                                                  intptr_t loop_depth) {
   return Fragment(
-      new (Z) CheckStackOverflowInstr(position, loop_depth_, GetNextDeoptId()));
+      new (Z) CheckStackOverflowInstr(position, loop_depth, GetNextDeoptId()));
 }
 
 Fragment BaseFlowGraphBuilder::Constant(const Object& value) {
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index 1491e87..feaaa71 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -129,7 +129,6 @@
         next_used_try_index_(0),
         stack_(NULL),
         pending_argument_count_(0),
-        loop_depth_(0),
         exit_collector_(exit_collector),
         inlining_unchecked_entry_(inlining_unchecked_entry) {}
 
@@ -220,7 +219,7 @@
   Fragment BranchIfStrictEqual(TargetEntryInstr** then_entry,
                                TargetEntryInstr** otherwise_entry);
   Fragment Return(TokenPosition position);
-  Fragment CheckStackOverflow(TokenPosition position);
+  Fragment CheckStackOverflow(TokenPosition position, intptr_t loop_depth);
   Fragment ThrowException(TokenPosition position);
   Fragment TailCall(const Code& code);
 
@@ -290,7 +289,6 @@
 
   Value* stack_;
   intptr_t pending_argument_count_;
-  intptr_t loop_depth_;
   InlineExitCollector* exit_collector_;
 
   const bool inlining_unchecked_entry_;
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index af0e35ee..c4202de 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -624,8 +624,10 @@
 }
 
 void BytecodeFlowGraphBuilder::BuildCheckStack() {
-  // TODO(alexmarkov): update B->loop_depth_
-  code_ += B->CheckStackOverflow(position_);
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+  code_ += B->CheckStackOverflow(position_, DecodeOperandA().value());
   ASSERT(B->stack_ == nullptr);
 }
 
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index aec0853..6b56dcc 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -2606,7 +2606,8 @@
 }
 
 Fragment StreamingFlowGraphBuilder::CheckStackOverflow(TokenPosition position) {
-  return flow_graph_builder_->CheckStackOverflow(position);
+  return flow_graph_builder_->CheckStackOverflow(
+      position, flow_graph_builder_->loop_depth_);
 }
 
 Fragment StreamingFlowGraphBuilder::CloneContext(
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 9e474ba..b8b5bff 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -50,6 +50,7 @@
       optimizing_(optimizing),
       ic_data_array_(*ic_data_array),
       next_function_id_(0),
+      loop_depth_(0),
       try_depth_(0),
       catch_depth_(0),
       for_in_depth_(0),
@@ -325,10 +326,10 @@
   if (IsInlining()) {
     // If we are inlining don't actually attach the stack check.  We must still
     // create the stack check in order to allocate a deopt id.
-    CheckStackOverflow(position);
+    CheckStackOverflow(position, loop_depth_);
     return Fragment();
   }
-  return CheckStackOverflow(position);
+  return CheckStackOverflow(position, loop_depth_);
 }
 
 Fragment FlowGraphBuilder::CloneContext(intptr_t num_context_variables) {
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 6254d1c..2d26d18 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -181,6 +181,7 @@
   intptr_t next_function_id_;
   intptr_t AllocateFunctionId() { return next_function_id_++; }
 
+  intptr_t loop_depth_;
   intptr_t try_depth_;
   intptr_t catch_depth_;
   intptr_t for_in_depth_;
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index 00c39f9..2bec12a 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -137,10 +137,11 @@
 //    Check for a passed-in type argument vector of length A and
 //    store it at FP[D].
 //
-//  - CheckStack
+//  - CheckStack A
 //
 //    Compare SP against isolate stack limit and call StackOverflow handler if
-//    necessary.
+//    necessary. Should be used in prologue (A = 0), or at the beginning of
+//    a loop with depth A.
 //
 //  - Allocate D
 //
@@ -397,7 +398,7 @@
   V(LoadConstant,                        A_D, reg, lit, ___)                   \
   V(Frame,                                 D, num, ___, ___)                   \
   V(CheckFunctionTypeArgs,               A_D, num, reg, ___)                   \
-  V(CheckStack,                            0, ___, ___, ___)                   \
+  V(CheckStack,                            A, num, ___, ___)                   \
   V(Allocate,                              D, lit, ___, ___)                   \
   V(AllocateT,                             0, ___, ___, ___)                   \
   V(CreateArrayTOS,                        0, ___, ___, ___)                   \