[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)) {