From 0ad771c4a79dbad72e960eab474a7e1fbd9c524b Mon Sep 17 00:00:00 2001 From: Irwin D'Souza Date: Fri, 4 Aug 2023 12:06:27 -0400 Subject: [PATCH] Document the variable length section of the J9JITExceptionTable Signed-off-by: Irwin D'Souza --- doc/compiler/README.md | 1 + doc/compiler/runtime/J9JITExceptionTable.md | 437 ++++++++++++++++++++ runtime/compiler/runtime/MetaData.cpp | 7 +- 3 files changed, 443 insertions(+), 2 deletions(-) create mode 100644 doc/compiler/runtime/J9JITExceptionTable.md diff --git a/doc/compiler/README.md b/doc/compiler/README.md index 186798b3834..3b49aee299b 100644 --- a/doc/compiler/README.md +++ b/doc/compiler/README.md @@ -165,6 +165,7 @@ In the end code generators perform binary encoding to write the appropriate bits * [ELF Generator (OMR)](https://github.com/eclipse/omr/blob/master/doc/compiler/runtime/ELFGenerator.md#elfgenerator) * [Dynamic Loop Transfer (DLT) (OpenJ9)](https://github.com/eclipse-openj9/openj9/issues/12505) * Stack Walker + * [J9JITExceptionTable (OpenJ9)](runtime/J9JITExceptionTable.md) *
8. Memory diff --git a/doc/compiler/runtime/J9JITExceptionTable.md b/doc/compiler/runtime/J9JITExceptionTable.md new file mode 100644 index 00000000000..e854ff204d3 --- /dev/null +++ b/doc/compiler/runtime/J9JITExceptionTable.md @@ -0,0 +1,437 @@ + + +# Background + +The `J9JITExceptionTable` (also `typedef`'d to `TR_MethodMetaData`) +is generally referred to as "the metadata". It contains most of the +metadata associated with a compiled body[^1]. Most of this metadata +is stored in the variable length section of the `J9JITExceptionTable` +structure. This document outlines this variable length section. It does +not describe fields that are described by a data structure (e.g., the +`J9JITExceptionTable`, `TR_InlinedCallSite`, etc.). + +# Structure + +## High Level Overview +The following diagram provides the high level overview. The +`J9JITExceptionTable` is allocated and populated in +[`createMethodMetaData`](https://github.com/eclipse-openj9/openj9/blob/v0.41.0-release/runtime/compiler/runtime/MetaData.cpp#L1315). + +``` + +-----------------------------------------------------+ + | struct J9JITExceptionTable | + |-----------------------------------------------------| +(1) | Exception Info | + |-----------------------------------------------------| +(2) | Inline Info | + |-----------------------------------------------------| +(3) | Stack Atlas | + |-----------------------------------------------------| +(4) | Stack Alloc Map | // If Local Objects + |-----------------------------------------------------| +(5) | Internal Pointer Map in J9 Format | + |-----------------------------------------------------| +(6) | OSR Info | // If OSR + |-----------------------------------------------------| +(7) | GPU Info | // If GPU + |-----------------------------------------------------| +(8) | Bytecode PC to Instruction Address Map | // If Hardware Profiling + +-----------------------------------------------------+ +``` + +## (1) Exception Info +The Exception Info section starts immediately after the +`J9JITExceptionTable` struct, and so accessing it involves adding +`sizeof(J9JITExceptionTable)` bytes to a pointer pointing to the start +of the metadata. This section consists of the following set of data +for exceptions in the method body. For some entries, the size is 4 bytes +if wide offsets are required, and 2 bytes otherwise; wide offsets are +required when an offset cannot be represented in just 2 bytes. The +decision to use wide offsets or not is global (with respect to this +`J9JITExceptionTable`); i.e., if a single offset cannot be represented +in 2 bytes, then all offsets are represented in 4 bytes. +``` + +-----------------------------------------------------+ + | Instruction Start PC Offset | + | Size: 2 or 4 bytes | + |-----------------------------------------------------| + | Instruction End PC Offset | + | Size: 2 or 4 bytes | + |-----------------------------------------------------| + | Instruction Handler PC Offset | + | Size: 2 or 4 bytes | + |-----------------------------------------------------| + | Catch Type | + | Size: 2 or 4 bytes | + |-----------------------------------------------------| + | BC Caller Index | // If wide offsets, and AOT or Remote Compilation + | Size: pointer | + |-----------------------------------------------------| + | J9Method | // If wide offsets, and local JIT Compilation + | Size: pointer | + |-----------------------------------------------------| + | BC Index | // If FSD + | Size: 4 bytes | + +-----------------------------------------------------+ +``` + +## (2) Inline Info +The Inline Info section can be accessed via the `inlinedCalls` field of +the `J9JITExceptionTable` struct. This section consists of the following +set of data for each inlined site +``` + +-----------------------------------------------------+ + | struct TR_InlinedCallSite | + | Size: sizeof(TR_InlinedCallSite) | + |-----------------------------------------------------| + | Monitor Autos Map | + | Size: Bytes needed to represent | + | cg->getStackAtlas()->getNumberOfSlotsMapped() | + | + 1 (for the live monitor map) | + +-----------------------------------------------------+ +``` + +## (3) Stack Atlas +The Stack Atlas section can be accessed via the `gcStackAtlas` field +of the `J9JITExceptionTable struct`. This section consists of the +following set of data +``` + +-----------------------------------------------------+ + | struct J9JITStackAtlas | + | Size: sizeof(J9JITStackAtlas) | + |-----------------------------------------------------| + | Monitor Autos Map | + | Size: Bytes needed to represent | + | cg->getStackAtlas()->getNumberOfSlotsMapped() | + | + 1 (for the live monitor map) | + |-----------------------------------------------------| + | Stack Maps | + +-----------------------------------------------------+ +``` + +The `Stack Map`s are written in the reverse order in which they exist +in the list in the Compilation. It consists of the following set of +data for each Stack Map. +``` + +-----------------------------------------------------+ + | Lowest code offset | + | Size: 2 or 4 bytes | // 4 bytes if wide offsets, 2 bytes otherwise. + |-----------------------------------------------------| + | Alignment | // If comp->isAlignStackMaps() && !fourByteOffsets + | Size: 2 bytes | + |-----------------------------------------------------| + | TR_BytecodeInfo | + | Size: 4 bytes | + |-----------------------------------------------------| + | Register Save Description | // If the current map is different from the previous + | Size: 4 bytes | + |-----------------------------------------------------| + | Register Map | // If the current map is different from the previous + | Size: 4 bytes | + |-----------------------------------------------------| + | Internal Pointer Map | // If it exists and if the current map is different from the previous + |-----------------------------------------------------| + | Map Bits | + | Size: Bytes needed to represent | + | map->getNumberOfSlotsMapped() | + |-----------------------------------------------------| + | Live Monitor Bits | // If Live Monitor Bits + | Size: Bytes needed to represent | + | map->getNumberOfSlotsMapped() | + +-----------------------------------------------------+ +``` + +where the `Internal Pointer Map` is +``` + +-----------------------------------------------------+ + | Map Size | + | Size: 1 byte | + |-----------------------------------------------------| + | Number of Distinct Pinning Arrays | + | Size: 1 byte | + |-----------------------------------------------------| + | Distinct Pinning Array Info | + +-----------------------------------------------------+ +``` + +where `Distinct Pinning Array Info` contains the following set of data +for each Distinct Pinning Array +``` + +-----------------------------------------------------+ + | Index for this Pinning Array Temp | + | Size: 1 byte | + |-----------------------------------------------------| + | Number of Derived Register Pointers | + | Size: 1 byte | + |-----------------------------------------------------| + | Internal Pointer Register Number | + | Size: 1 byte | + |-----------------------------------------------------| + | Derived Register Number | // One entry for each Derived Register + | Size: 1 byte | + +-----------------------------------------------------+ +``` + +## (4) Stack Alloc Map +The Stack Alloc Map section can be accessed via the `stackAllocMap` +field of the `J9JITStackAtlas` struct that is embedded in the +[(3) Stack Atlas](#3-stack-atlas) section. It consists of the +following set of data +``` + +-----------------------------------------------------+ + | Pointer to first stack map | + | Size: pointer | + |-----------------------------------------------------| + | Stack Map Alloc Map Bits | + | Size: Bytes needed to represent | + | cg->getStackAtlas() ->getStackAllocMap() | + +-----------------------------------------------------+ +``` + +## (5) Internal Pointer Map in J9 Format +The Internal Pointer Map in J9 Format section can be accessed via +the `internalPointerMap` field of the `J9JITStackAtlas` struct that +is embedded in the [(3) Stack Atlas](#3-stack-atlas) section. It +consists of the following set of data +``` + +-----------------------------------------------------+ + | Pointer to first stack map | + | Size: pointer | + |-----------------------------------------------------| + | Map Size | + | Size: 1 byte | + |-----------------------------------------------------| + | Alignment | // If comp->isAlignStackMaps() + | Size: 1 byte | + |-----------------------------------------------------| + | Index of First Internal Pointer | + | Size: 2 bytes | + |-----------------------------------------------------| + | Offset of First Internal Pointer | + | Size: 2 bytes | + |-----------------------------------------------------| + | Number of Distinct Pinning Array Temps | + | + Pinning Arrays for Internal Pointer | + | Registers | + | Size: 1 byte | + |-----------------------------------------------------| + | Distinct Pinning Array Temp Info | + |-----------------------------------------------------| + | Pinning Array for Internal Pointer Registers Info | + +-----------------------------------------------------+ +``` + +Where `Distinct Pinning Array Temp Info` contains the following +set of data for each Distinct Pinning Array Temp +``` + +-----------------------------------------------------+ + | Index of Base Array Temp | + | Size: 1 byte | + |-----------------------------------------------------| + | Number of Derived Internal Pointers | + | Size: 1 byte | + |-----------------------------------------------------| + | Index of this Internal Pointer Temp | + | Size: 1 byte | + |-----------------------------------------------------| + | Index of Remaining Internal Pointer Temp | // One entry for each Remaining Internal Pointer Temp + | Size: 1 byte | // derived from this Base Pinning Array Temp + +-----------------------------------------------------+ +``` + +and `Pinning Arrays for Internal Pointer Registers Info` contains +the following set of data for each Pinning Array for Internal Pointer +Registers +``` + +-----------------------------------------------------+ + | Index | + | Size: 1 byte | + |-----------------------------------------------------| + | 0 | + | Size: 1 byte | + +-----------------------------------------------------+ +``` + +## (6) OSR Info +The OSR Info section can be accessed via the `osrInfo` field +of the `J9JITExceptionTable` struct. This section consists of the +following set of data +``` + +-----------------------------------------------------+ + | Section 0: | + | Mapping from instruction PC offsets to a list | + | of shared slots that are live at that offset | + |-----------------------------------------------------| + | Section 1: | + | Mapping from the call site index to OSR catch | + | block | + +-----------------------------------------------------+ +``` + +### Section 0 +``` + +-----------------------------------------------------+ + | Section Size | + | Size: 4 bytes | + |-----------------------------------------------------| + | Max Scratch Buffer Size | + | Size: 4 bytes | + |-----------------------------------------------------| + | Number of Mappings | + | Size: 4 bytes | + |-----------------------------------------------------| + | Instruction to Shared Slot Map | + +-----------------------------------------------------+ +``` +where `Instruction to Shared Slot Map` contains the following +set of data for each mapping +``` + +-----------------------------------------------------+ + | Instruction PC offset | + | Size: 4 bytes | + |-----------------------------------------------------| + | Number of Scratch Buffer Infos | + | Size: 4 bytes | + |-----------------------------------------------------| + | Scratch Buffer Info | + +-----------------------------------------------------+ +``` +where `Scratch Buffer Info` contains the following set of +data for each Scatch Buffer Info +``` + +-----------------------------------------------------+ + | Inlined Site Index | + | Size: 4 bytes | + |-----------------------------------------------------| + | OSR Buffer Offset | + | Size: 4 bytes | + |-----------------------------------------------------| + | Scratch Buffer Offset | + | Size: 4 bytes | + |-----------------------------------------------------| + | Sym Size | + | Size: 4 Bytes | + +-----------------------------------------------------+ +``` + +### Section 1 +``` + +-----------------------------------------------------+ + | Section Size | + | Size: 4 bytes | + |-----------------------------------------------------| + | Number of Mappings | + | Size: 4 bytes | + |-----------------------------------------------------| + | Start PC Offset or NULL | // For each mapping + | Size: 4 bytes | + +-----------------------------------------------------+ +``` + +## (7) GPU Info +The GPU Info section can be accessed via the `gpuCode` field +of the `J9JITExceptionTable` struct. This section consists of the +following set of data +``` + +-----------------------------------------------------+ + | struct GpuMetaData | + | Size: sizeof(GpuMetaData) | + |-----------------------------------------------------| + | Method Signature Offset | + | Size: strlen(comp->signature())+1 | + |-----------------------------------------------------| + | Line Number Array | + |-----------------------------------------------------| + | Ptx Array | + |-----------------------------------------------------| + | Ptx Array Entry | + |-----------------------------------------------------| + | CU Module Array; initialized to 0 | + | Size: sizeof(CUmodule) | + | * comp->getGPUPtxCount() | + | * maxNumCachedDevices | + +-----------------------------------------------------+ +``` +`Line Number Array Offset` contains the following +set of data for each GPU Ptx +``` + +-----------------------------------------------------+ + | Line Number | + | Size: sizeof(int) | + +-----------------------------------------------------+ +``` +`Ptx Array` contains the following set of data +for each GPU Ptx +``` + +-----------------------------------------------------+ + | GPU Ptx Array Entry Location | + | (Pointer into the | + | `Ptx Array Entry` section) | + | Size: pointer | + +-----------------------------------------------------+ +``` +`Ptx Array Entry` contains the following set +of data for each GPU Ptx +``` + +-----------------------------------------------------+ + | Ptx Array Entry | + | (pointed to by the associated | + | entry in the `Ptx Array` section) | + | Size: strlen of the string at this location | + | + 1 | + +-----------------------------------------------------+ +``` + +## (8) Bytecode PC to Instruction Address Map +The Bytecode PC to Instruction Address Map section can be accessed +via the `riData` field of the `J9JITExceptionTable` struct. This +section consists of the following set of data +``` + +-----------------------------------------------------+ + | METADATA_MAPPING_EYECATCHER | + | Size: pointer | + |-----------------------------------------------------| + | Map Size | + | Size: pointer | + |-----------------------------------------------------| + | Bytecode PC to IA Map | + +-----------------------------------------------------+ +``` +where `Bytecode PC to IA Map` is the following +set of data for each mapping +``` + +-----------------------------------------------------+ + | Bytecode PC | + | Size: pointer | + |-----------------------------------------------------| + | Instruction Address | + | Size: pointer | + +-----------------------------------------------------+ +``` + +[^1]: The rest of the metadata is stored in the +`TR_PersistentJittedBodyInfo` structure, which can be accessed +via the `bodyInfo` field of the `J9JITExceptionTable` struct. This +structure contains data such as flags used to describe the body, +as well as data used to implement features such as +Guarded Counting Recompilation (GCR). \ No newline at end of file diff --git a/runtime/compiler/runtime/MetaData.cpp b/runtime/compiler/runtime/MetaData.cpp index 3e04155741b..453b3889c5c 100644 --- a/runtime/compiler/runtime/MetaData.cpp +++ b/runtime/compiler/runtime/MetaData.cpp @@ -1308,9 +1308,12 @@ static void populateInlineCalls( } + +// The routine that sequences the creation of the meta-data for the method // -//the routine that sequences the creation of the meta-data for the method -// +// The layout, specifically the variable length section, is described in +// J9JITExceptionTable.md; this doc should be updated when changes are +// made to the layout. TR_MethodMetaData * createMethodMetaData( TR_J9VMBase & vmArg,