[vm/compiler/bytecode] Ensure CheckStackOverflow is in the join block

Fixes https://github.com/dart-lang/sdk/issues/36590

Change-Id: Ie18f0f61a437c58b452bbcde8f4bafe58125328f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99377
Reviewed-by: Aart Bik <ajcbik@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
diff --git a/runtime/tests/vm/dart/regress_36590_test.dart b/runtime/tests/vm/dart/regress_36590_test.dart
new file mode 100644
index 0000000..645c45b
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_36590_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Regression test for https://github.com/dart-lang/sdk/issues/36590.
+//
+// This test verifies that compiler does not crash if OSR occurs at
+// CheckStack bytecode instruction which is not at the beginning of a join
+// block in bytecode (if the end of the "loop" body is unreachable and hence
+// there is no backward jump).
+//
+// VMOptions=--deterministic
+
+var var6 = [1, 2, 3];
+
+void bar() {}
+
+var cond_true = true;
+
+void foo() {
+  for (int i = 0; i < 9995; ++i) {
+    var6[0] += 1;
+  }
+  if (cond_true) {
+    var6[0] += 1;
+    for (var loc1 in var6) {
+      break;
+    }
+  }
+  if (cond_true) {
+    var6[0] += 1;
+    for (var loc1 in var6) {
+      break;
+    }
+  }
+  if (cond_true) {
+    var6[0] += 1;
+    for (var loc1 in var6) {
+      break;
+    }
+  }
+  if (cond_true) {
+    var6[0] += 1;
+    for (var loc1 in var6) {
+      break;
+    }
+  }
+  if (cond_true) {
+    var6[0] += 1;
+    for (var loc1 in var6) {
+      break;
+    }
+  }
+}
+
+main() {
+  foo();
+}
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index a7c5ee0..19b94e1 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -1808,6 +1808,13 @@
     if (KernelBytecode::IsJumpOpcode(instr)) {
       const intptr_t target = pc + KernelBytecode::DecodeT(instr);
       EnsureControlFlowJoin(descriptors, target);
+    } else if ((KernelBytecode::DecodeOpcode(instr) ==
+                KernelBytecode::kCheckStack) &&
+               (KernelBytecode::DecodeA(instr) != 0)) {
+      // (dartbug.com/36590) BlockEntryInstr::FindOsrEntryAndRelink assumes
+      // that CheckStackOverflow instruction is at the beginning of a join
+      // block.
+      EnsureControlFlowJoin(descriptors, pc);
     }
 
     if ((scratch_var_ == nullptr) && RequiresScratchVar(instr)) {