已开启
fix: add LLT case for finalizer object liveness under O2 #2050
duan创建于 8月21日
fix: add LLT case for finalizer object liveness under O2 #2050
已开启
共 1 个文件变更+48-0
| @@ -0,0 +1,48 @@ | |||
| 1 | +// Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved. | ||
| 2 | +// This source file is part of the Cangjie project, licensed under Apache-2.0 | ||
| 3 | +// with Runtime Library Exception. | ||
| 4 | +// | ||
| 5 | +// See https://cangjie-lang.cn/pages/LICENSE for license information. | ||
| 6 | + | ||
| 7 | +// test1.cj 清洗版回归用例(issue 1089):finalizer 对象的字段读若被 LICM | ||
| 8 | +// 提升出循环,GC 活性分析会误判对象已死,GC 中途回收对象并执行 ~init() | ||
| 9 | +// 置空 m.s,后续 s.getOrThrow() 抛 NoneValueException。 | ||
| 10 | +// 注意不能使用显式 gc() 驱动:gc() 是完整内存屏障会阻止 LICM 提升字段读, | ||
| 11 | +// 用例将无法抓住回归。这里用每轮字符串插值 "${i}" 的分配驱动 GC,分配不会 | ||
| 12 | +// 阻止提升;checksum 累计防止循环被整体优化掉。 | ||
| 13 | +// | ||
| 14 | +// EXEC: %compiler %cmp_opt %enableO2 %f -o %output | ||
| 15 | +// RUN-EXEC: %run %run_opt %output %run_args | ||
| 16 | + | ||
| 17 | +class M { | ||
| 18 | + var s: ?String = "x" | ||
| 19 | + | ||
| 20 | + func g(): Int64 { | ||
| 21 | + // 若 T 被提前 finalize,s 变 None,这里抛 NoneValueException。 | ||
| 22 | + s.getOrThrow() | ||
| 23 | + return 1 | ||
| 24 | + } | ||
| 25 | +} | ||
| 26 | + | ||
| 27 | +public class T { | ||
| 28 | + var m = M() | ||
| 29 | + | ||
| 30 | + ~init() { | ||
| 31 | + m.s = None | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public func f(): Int64 { | ||
| 35 | + return m.g() | ||
| 36 | + } | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +main(): Int64 { | ||
| 40 | + let t = T() | ||
| 41 | + var checksum: Int64 = 0 | ||
| 42 | + for (i in 0..1000000) { | ||
| 43 | + checksum += t.f() | ||
| 44 | + checksum += "${i}".size | ||
| 45 | + } | ||
| 46 | + println("finalizer object liveness ok ${checksum}") | ||
| 47 | + return 0 | ||
| 48 | +} | ||