Precise, Efficient and Secure Just-In-Time Analysis of Java Programs
One of the main challenges in JIT compilation arises from the fact that the time spent in compilation, which includes program-analysis time, gets added to the execution-time of the program. Hence, it is important that the time spent in JIT compilation is not prohibitively high. Consequently, typical JIT compilers in popular virtual machines (such as the HotSpot JVM and the Eclipse OpenJ9) perform imprecise analyses and end-up sacrificing precision for efficiency. An alternative to performing imprecise analyses during JIT compilation is to perform expensive whole-program analyses during static compilation, and use the results during JIT compilation. However, the runtime libraries (such as the JDK) on the machine where the program is executed may differ from those available statically on the machine where the program is compiled. As a result, though this alternative does not impact the JIT compilation time much, the static analyses have to handle calls to library methods in a conservative manner, which may again lead to imprecision. Thus, both the practical alternatives – (i) whole-program analysis at compile-time and (ii) fast analysis during JIT compilation – may lead to imprecise results.
In our recent paper (accepted for publication in ACM TOPLAS; preprint available at: http://www.cse.iitm.ac.in/~krishna/preprints/toplas19/toplas19.pdf), we propose a two-stage analysis framework called PYE (Precise-Yet-Efficient) for analyzing programs written in languages with a static+JIT mode of compilation. The PYE framework relies on a novel notion of conditional values, which denote dependencies on the unavailable portions of the program being analyzed (for example, the library while analyzing the application). PYE analyzes an application using two inter-related components: the partial-analyzer (added to the static Java compiler), and the fast-precise-analyzer (added to the C2 compiler of the HotSpot JVM). The partial-analyzer statically generates partial summaries (consisting of conditional values) for the methods of a program, which are then sent to the machine on which the program is to be executed. During JIT compilation, the fast-precise-analyzer reads the application and library partial summaries, resolves the dependencies between the two, and generates final analysis results.
We have instantiated PYE for performing two non-trivial analyses: points-to analysis for null-check elimination and escape analysis for synchronization elimination, and evaluated the instantiations by comparing them with the existing analyzers of C2. The results assert that PYE effectively addresses the three challenges that can be envisaged in such a multi-step analysis framework: (i) It handles the possible imprecision arising out of the unavailable parts of a program while performing precise whole-program analyses. (ii) It makes sure that the generated partial summaries are succinct and do not lead to significant storage overhead. (iii) It loads and resolves the partial summaries efficiently without increasing the time spent during JIT compilation.
There are, however, more challenges to solve, for bringing the proposed approach into practice. Two such important associated requirements are: (i) the results generated by the partial-analyzer be transferred to the target machine along with the class files; and (ii) the results be verified at the target machine before using them to perform optimizations. In this talk, we first describe the PYE framework and its instantiations with brief results of the same. We then discuss some initial directions to explore the solutions to the above challenges. We propose to solve these challenges in a modular manner, in the context of the Eclipse OpenJ9 virtual machine.