Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Commit of the MicroJIT Project #9578

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
27da600
This is a sqashed commit of the development commit log from the Micro…
Scott-Young-6746 Feb 3, 2020
2d204d5
Added documentation for the MicroJIT feature
Scott-Young-6746 Mar 17, 2022
ed205cb
Fixed unordered lists in documentation for the MicroJIT feature
Scott-Young-6746 Mar 17, 2022
278b069
Fixed tables in documentation for the MicroJIT feature
Scott-Young-6746 Mar 17, 2022
e3f886c
Changed vISA documentation to a table
Scott-Young-6746 Mar 17, 2022
932eb49
Moved MJIT exception table into MJIT namespace
Scott-Young-6746 Mar 22, 2022
0d0872c
MicroJIT: Fixing indentation and line endings
harpreetbamrah Mar 25, 2022
83e34fb
Changedmulti-line MJIT C macros to functions
Scott-Young-6746 Mar 28, 2022
c0cf8de
Renamed former MJIT macros and pushed overhead closer to tests
Scott-Young-6746 Mar 31, 2022
9497cbf
MicroJIT: Formatting and alignment
harpreetbamrah Mar 29, 2022
9b98413
MicroJIT: Moving relevant functions and classes inside MJIT namespace…
harpreetbamrah Mar 30, 2022
e5d829e
MicroJIT: Adding list of supported and unsupported bytecodes
harpreetbamrah Mar 31, 2022
2f7d758
Moving MJIT compilation thread to a new file
harpreetbamrah Mar 31, 2022
fc7e697
Preserving count for AOT loads from being overwritten by MJIT count
harpreetbamrah Apr 5, 2022
1433d55
Modify encoding for setting value, formatting and some suggested changes
harpreetbamrah Apr 14, 2022
5327dcf
Using query for checking if the method is interpreted and for MJIT ex…
harpreetbamrah Apr 25, 2022
ba9cdd7
Removing underscore in non-members of the CFG class and other formatt…
harpreetbamrah Apr 25, 2022
70a9123
Moving methods to TR_J9ByteCodeIterator class
harpreetbamrah Apr 28, 2022
312a503
Passing reason to failCompilation and using reference to TR_J9VMBase
harpreetbamrah Apr 28, 2022
c9dc6e5
Labelling MicroJIT TODOs as TODO: MicroJIT
harpreetbamrah May 2, 2022
5585576
Removing the ClassTableCriticalSection aquisition
harpreetbamrah May 4, 2022
a81b851
Moving logCompilationSuccess to appropriate place
harpreetbamrah May 5, 2022
6e2c58a
Resolving failing copyright check
harpreetbamrah May 9, 2022
035a427
Code de-duplication
harpreetbamrah May 12, 2022
0de87ac
Rebase changes
harpreetbamrah May 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions buildspecs/core.feature
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-excepti
<flag id="opt_jitserver" value="false"/>
<flag id="opt_methodHandle" value="true"/>
<flag id="opt_methodHandleCommon" value="true"/>
<flag id="opt_microjit" value="false"/>
<flag id="opt_module" value="true"/>
<flag id="opt_newObjectHash" value="true"/>
<flag id="opt_newRomClassBuilder" value="true"/>
Expand Down
4 changes: 4 additions & 0 deletions buildspecs/j9.flags
Original file line number Diff line number Diff line change
Expand Up @@ -1784,6 +1784,10 @@ Only available on zOS</description>
<description>Enables common dependencies between OpenJ9 and OpenJDK MethodHandles.</description>
<ifRemoved>Disables common dependencies between OpenJ9 and OpenJDK MethodHandles.</ifRemoved>
</flag>
<flag id="opt_microjit">
<description>Enables MicroJIT support.</description>
<ifRemoved></ifRemoved>
</flag>
<flag id="opt_module">
<description>Turns on module support</description>
<ifRemoved></ifRemoved>
Expand Down
60 changes: 60 additions & 0 deletions doc/compiler/MicroJIT/DSL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!--
Copyright (c) 2022, 2022 IBM Corp. and others

This program and the accompanying materials are made available under
the terms of the Eclipse Public License 2.0 which accompanies this
distribution and is available at https://www.eclipse.org/legal/epl-2.0/
or the Apache License, Version 2.0 which accompanies this distribution and
is available at https://www.apache.org/licenses/LICENSE-2.0.

This Source Code may also be made available under the following
Secondary Licenses when the conditions for such availability set
forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
General Public License, version 2 with the GNU Classpath
Exception [1] and GNU General Public License, version 2 with the
OpenJDK Assembly Exception [2].

[1] https://www.gnu.org/software/classpath/license.html
[2] http://openjdk.java.net/legal/assembly-exception.html

SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
-->

# Overview

MicroJIT's DSL helps new contributors to avoid making common mistakes
when writing new, or editing existing, templates. It helps developers keep
sizes of data types and number of slots separate from each other conceptually
while also keeping their own footprint small.

# Current Macros

The current existing DSL macros are:
- pop_single_slot
- Add the size of 1 stack slot to the computation stack pointer
- pop_dual_slot
- Add the size of 2 stack slots to the computation stack pointer
- push_single_slot
- Subtract the size of 1 stack slot from the computation stack pointer
- push_dual_slot
- Subtract the size of 2 stack slots from the computation stack pointer
- _32bit_local_to_rXX_PATCH
- Move a 32-bit value to an r11d-r15d register from a local array slot
- _64bit_local_to_rXX_PATCH
- Move a 64-bit value to a 64-bit register from a local array slot
- _32bit_local_from_rXX_PATCH
- Move a 32-bit value from an r11d-r15d register to a local array slot
- _64bit_local_from_rXX_PATCH
- Move a 64-bit value from a 64-bit register to a local array slot
- _32bit_slot_stack_to_rXX
- Move a 64-bit value to an r11-r15 register from the computation stack
- _32bit_slot_stack_to_eXX
- Move a 32-bit value to an eax-edx register from the computation stack
- _64bit_slot_stack_to_rXX
- Move a 64-bit value to a 64-bit register from the computation stack
- _32bit_slot_stack_from_rXX
- Move a 64-bit value from an r11d-r15d register to the computation stack
- _32bit_slot_stack_from_eXX
- Move a 32-bit value from an eax-edx register to the computation stack
- _64bit_slot_stack_from_rXX
- Move a 64-bit value from a 64-bit register to the computation stack
30 changes: 30 additions & 0 deletions doc/compiler/MicroJIT/Platforms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!--
Copyright (c) 2022, 2022 IBM Corp. and others

This program and the accompanying materials are made available under
the terms of the Eclipse Public License 2.0 which accompanies this
distribution and is available at https://www.eclipse.org/legal/epl-2.0/
or the Apache License, Version 2.0 which accompanies this distribution and
is available at https://www.apache.org/licenses/LICENSE-2.0.

This Source Code may also be made available under the following
Secondary Licenses when the conditions for such availability set
forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
General Public License, version 2 with the GNU Classpath
Exception [1] and GNU General Public License, version 2 with the
OpenJDK Assembly Exception [2].

[1] https://www.gnu.org/software/classpath/license.html
[2] http://openjdk.java.net/legal/assembly-exception.html

SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
-->

# List of currently supported platforms

- AMD64 (a.k.a. x86-64)

# List of expected future platforms

- RISC-V
- AArch64
74 changes: 74 additions & 0 deletions doc/compiler/MicroJIT/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<!--
Copyright (c) 2022, 2022 IBM Corp. and others

This program and the accompanying materials are made available under
the terms of the Eclipse Public License 2.0 which accompanies this
distribution and is available at https://www.eclipse.org/legal/epl-2.0/
or the Apache License, Version 2.0 which accompanies this distribution and
is available at https://www.apache.org/licenses/LICENSE-2.0.

This Source Code may also be made available under the following
Secondary Licenses when the conditions for such availability set
forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
General Public License, version 2 with the GNU Classpath
Exception [1] and GNU General Public License, version 2 with the
OpenJDK Assembly Exception [2].

[1] https://www.gnu.org/software/classpath/license.html
[2] http://openjdk.java.net/legal/assembly-exception.html

SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
-->

# Overview

MicroJIT is a lightweight template-based Just-In-Time (JIT) compiler that integrates
seamlessly with TR. MicroJIT is designed to be used either in-place-of TR
(where CPU resources are scarce) or to reduce the time between start-up and
TR's first compile (where CPU resources are not a constraint).

MicroJIT's entry point is at the `wrapped compile` stage of TR's compile process.
When building with a `--enable-microjit` configuration, the VM checks whether
a method should be compiled with MicroJIT or TR before handing off the method to
code generation ([MicroJIT Compile Stages](Stages.md)).

Being template-based, MicroJIT does not build an intermediate language (IL) the
way that TR does. It instead performs a tight loop over the bytecodes and generates
the patchable assembly for each instance of a JVM Bytecode. This means that porting
MicroJIT to a new platform requires rewriting much of the code generator in that
target platform. The current list of available platforms is available [here](Platforms.md).

MicroJIT uses a stack-based [vISA](vISA.md) for its internal model of how to execute bytecodes.
This maps cleanly onto the JVM Bytecode, so MicroJIT uses the number of stack slots
for JVM data types that the JVM specification requires wherever the target architecture allows.

To keep track of the location of parameters and locals, as well as for creating the
required GCStackAtlas, MicroJIT makes use of [side tables](SideTables.md). These
tables are arrays of structures which represent a row in their table. Using these
tables, and some upper bounding, MicroJIT can allocate the required number of rows
in these tables on the stack rather than the heap, helping MicroJIT compile faster.

The templates MicroJIT uses for its code generation are written in a mix of the
target architecture's assembly (for the NASM assembler) and assembler macros used to
abstract some of the vISA operations away into a domain-specific language ([DSL](DSL.md)).

To try MicroJIT, first build your JVM with a configuration using the `--enable-microjit`
option (see the openj9-openjdk-jdk8 project). Then, once built, use the
`-Xjit:mjitEnabled=1,mjitCount=20` options. You can use other values for `mjitCount` than
20, but peer-reviewed research shows that this value is a good estimation of the best
count for similar template-based JITs on JVM benchmarks.

MicroJIT is an experimental feature. It currently does not compile all methods, and will
fail to compile methods with unsupported bytecodes or calling conventions. For details
on supported bytecodes and calling conventions, see our [supported compilations](support.md)
documentation.

# Topics

- [MicroJIT Compile Stages](Stages.md)
- [Supported Platforms](Platforms.md)
- [vISA](vISA.md)
- [Supporting Side Tables](SideTables.md)
- [Domain-Specific Language](DSL.md)
- [Supported Compilations](support.md)
<hr/>
67 changes: 67 additions & 0 deletions doc/compiler/MicroJIT/SideTables.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!--
Copyright (c) 2022, 2022 IBM Corp. and others

This program and the accompanying materials are made available under
the terms of the Eclipse Public License 2.0 which accompanies this
distribution and is available at https://www.eclipse.org/legal/epl-2.0/
or the Apache License, Version 2.0 which accompanies this distribution and
is available at https://www.apache.org/licenses/LICENSE-2.0.

This Source Code may also be made available under the following
Secondary Licenses when the conditions for such availability set
forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
General Public License, version 2 with the GNU Classpath
Exception [1] and GNU General Public License, version 2 with the
OpenJDK Assembly Exception [2].

[1] https://www.gnu.org/software/classpath/license.html
[2] http://openjdk.java.net/legal/assembly-exception.html

SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
-->

# Overview

This document contains descriptions of all the side tables used by MicroJIT to
generate code while limiting heap allocations.

# Register Stack

The register stack contains the number of stack slots contained
in each register used by TR's linkage. This allows for MicroJIT
to quickly calculate stack offsets for interpreter arguments
on the fly.

RegisterStack:
- useRAX
- useRSI
- useRDX
- useRCX
- useXMM0
- useXMM1
- useXMM2
- useXMM3
- useXMM4
- useXMM5
- useXMM6
- useXMM7
- stackSlotsUsed

# ParamTableEntry and LocalTableEntry

This entry is used for both tables, and contains information used
to copy parameters from their linkage locations to their local
array slots, map their locations into GCMaps, and get the size of
their data without storing their data types.

ParamTableEntry:
| Field | Description |
|:--------------:|:-----------------------------------------------------------------:|
| offset | Offset into stack for loading from stack |
| regNo | Register containing parameter when called by interpreter |
| gcMapOffset | Offset used for lookup by GCMap |
| slots | Number of slots used by this variable when storing in local array |
| size | Number of bytes used by this variable when stored on the stack |
| isReference | Is this variable an object reference |
| onStack | Is this variable currently on the stack |
| notInitialized | Is this entry uninitialized by MicroJIT |
74 changes: 74 additions & 0 deletions doc/compiler/MicroJIT/Stages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<!--
Copyright (c) 2022, 2022 IBM Corp. and others

This program and the accompanying materials are made available under
the terms of the Eclipse Public License 2.0 which accompanies this
distribution and is available at https://www.eclipse.org/legal/epl-2.0/
or the Apache License, Version 2.0 which accompanies this distribution and
is available at https://www.apache.org/licenses/LICENSE-2.0.

This Source Code may also be made available under the following
Secondary Licenses when the conditions for such availability set
forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
General Public License, version 2 with the GNU Classpath
Exception [1] and GNU General Public License, version 2 with the
OpenJDK Assembly Exception [2].

[1] https://www.gnu.org/software/classpath/license.html
[2] http://openjdk.java.net/legal/assembly-exception.html

SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
-->

# Overview

This document contains information on the compilation stages of MicroJIT
from where it diverges from TR.

# MetaData

At the entry point to MicroJIT (the `mjit` method of `TR::CompilationInfoPerThreadBase`),
MicroJIT enters the first stage of compilation, building MetaData. It parses the
method signature to learn the types of its parameters, and bytecodes to learn the
number and type of its locals. It then estimates an upperbound for how much space
the compiled method will need and requests it from the allocator.

During this stage, it also learns the amount of space to save on the stack for calling
child methods, and will eventually also create a control flow graph here to perform
profiling code generation later. The code generator object is constructed and the next
steps begin.

# Pre-prologue

The pre-prologue is generated first. This contains many useful code snippets, jump points,
and small bits of meta-data used throughout the JVM that are relative to an individual
compilation of a method.

# Prologue

The prologue is then generated, copying parameters into appropriate places and updating
tables as needed. Once these tables are created, the structures used by the JVM are created,
namely the `GCStackAtlas` and its initial GC Maps. At this point, the required sizes of the
stack and local array are known. Hence, the code generator can
generate the code for allocating the stack space needed, moving the parameters into their
local array slots, and setting the Computation Stack and Local Array pointers (See [vISA](vISA.md)).

# Body

The code generator then iterates in a tight loop over the bytecode instruction stream,
generating the required template for each bytecode, one at a time, and patching them as
needed. During this phase, if a bytecode that is unsupported (See [supported](support.md))
is reached, the code generator bubbles the error up to the top level and compilation
is marked as a failure. The method is set not to be attempted with MicroJIT again, and
its compilation threshold is set to the default TR threshold.

# Cold Area

The snippets required by MicroJIT are generated last. These snippets can serve a
variety of purposes, but are usually cold code not expected to be executed on every
execution of the method.

# Clean up

The remaining meta-data structures are created, MicroJIT updates the internal counts
for compilations, and the unused space allocated for compilation in the start is reclaimed.
Loading