blob: ad4a120ad88c7ce4373aaf4d6e6179490fc9eb83 [file] [log] [blame]
// Copyright (c) 2025, 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.
// VMOptions=--gc_at_throw --verify_before_gc --verify_after_gc --verify_store_buffer
// Regression test for https://github.com/dart-lang/sdk/issues/60836.
// Write barrier elimination applies when there is no potential Dart call
// between a StoreFieldInstr and an AllocateObjectInstr. But the control flow
// between all potentially throwing instructions in a try block and the
// corresponding catch block is not explicitly repreresented in the flow graph,
// so the writer barrier elimination pass needs to handle catch entries
// specially.
class Context {
var error;
var stack;
}
@pragma("vm:never-inline")
indirectThrow() => indirectThrow2();
@pragma("vm:never-inline")
indirectThrow2() => throw "Exception!";
@pragma("vm:never-inline")
Context foo() {
final context = new Context();
try {
context.error = 1; // Write barrier elimination okay.
indirectThrow();
context.error = 2; // Write barrier elimination not okay.
} catch (e, st) {
context.error = e; // Write barrier elimination not okay.
context.stack = st; // Write barrier elimination not okay.
}
return context;
}
main() {
for (int i = 0; i < 3; i++) {
final context = foo();
print(context.error);
print(context.stack);
}
print("Okay");
}