JEP 233: 自动生成运行时编译器测试
概述
开发一个工具,通过自动生成测试用例来测试运行时编译器。
目标
-
生成的测试应兼容
jtreg
-
该工具应在最终结果的语言(Java 源代码、Java 字节码)、语言结构的使用、控制流和表达式的复杂性等方面具备可配置性。
-
测试应随机生成,但需可重现。
动机
随着我们添加新的平台、利用新的 CPU 指令、引入新的优化措施,并对运行时编译器进行其他改进,使用直接的、有针对性的测试来有效测试编译器变得越来越不可行。
描述
该工具将随机生成语法和语义上正确的 Java 源代码或字节码,必要时进行编译,并在解释模式(-Xint
)和编译模式(-Xcomp
)下运行,然后验证结果。
该工具将自动运行,无需人工干预。生成的测试将尽可能在合理的时间内覆盖尽可能多的组合。
Java 源代码编译器 javac
并未使用 Java 的所有字节码,因此仅生成 Java 源代码将会导致一些字节码未被覆盖。为所有类型的测试仅生成字节码将是一项复杂得多的任务,因此我们将采用一种混合方法,同时生成 Java 源代码和字节码。
在测试执行期间编译源代码对于嵌入式平台来说是有问题的,因为在这些平台上可能没有完整的 JDK,所以该工具将提供一种预编译源代码测试的方法。
生成的测试用例将包括复杂的表达式和控制流图,并会利用内联函数、浮点运算、try-catch-finally
结构等。还将提供一种调整工具配置的方法。
该工具将随机生成测试,但为了可重复性,它将报告其随机化种子,并接受这样的种子以重新播放完全相同的生成测试序列。
该工具的源代码将放置在 hotspot/test/testlibrary/jit-tester
目录中。测试可以通过工具 makefile 中提供的目标生成。测试生成的结果是一个完整的 jtreg
测试套件,可以通过同一个 makefile 运行,或者直接通过 jtreg
运行。该工具的 makefile 不会被集成到 HotSpot/JDK 的构建基础设施中。
鉴于测试生成过程需要耗费大量时间,因此生成并运行这些测试并不被视为预集成测试的一部分。然而,定期运行预先生成的测试以进行可靠性测试,以及运行新生成的测试以获得更好的代码覆盖率,是很有意义的。那些发现漏洞的生成测试应作为常规回归测试整合到适当的测试套件中,并以与其他回归测试相同的方式运行。
替代方案
在编译模式下运行现有的测试可以被视为该工具的一种可行替代方案。但这种方法存在几个缺点:
-
它并不保证覆盖所有的语言结构和不同优化的组合
-
测试失败并不总是意味着运行时编译器存在缺陷,需要工程师额外花费时间进行调查/重现
-
由于某些测试可能是特定于运行时编译器的测试,它们可能会强制自行进行运行时编译和/或需要特定的运行时编译器状态。因此,显式的编译模式可以改变测试行为并导致假阳性结果
-
为测试失败创建回归测试相对较难
由于这些缺点,这种方法不能完全取代所提出的工具。