Skip to content

Abolish PSPSym from ABI #114630

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

Merged
merged 52 commits into from
Apr 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
e69f16f
Update VM and NativeAOT to use PSPSym-less convention for calling fun…
filipnavara Apr 14, 2025
4319268
Do not emit and use PSPSym in JIT
filipnavara Apr 14, 2025
01986aa
Update documentation
filipnavara Apr 14, 2025
b1987e2
Fix build
filipnavara Apr 14, 2025
d86572f
Fix ARM64 build
filipnavara Apr 14, 2025
d248211
Fix RISC-V and LA64 build
filipnavara Apr 14, 2025
ed12de5
Remove unused fiFunction_CallerSP_to_FP_delta
filipnavara Apr 14, 2025
24f60d7
Remove unused fiFunction_InitialSP_to_FP_delta
filipnavara Apr 14, 2025
a06a6a6
Apply JIT diff
filipnavara Apr 14, 2025
f6ff6e1
Fix typo
filipnavara Apr 14, 2025
951b7eb
Remove unused fiFunctionCallerSPtoFPdelta
filipnavara Apr 14, 2025
9c697df
sp -> rsp
filipnavara Apr 14, 2025
fdee150
Save establisher frame in funclet frame, use it in GetExactGenericsToken
filipnavara Apr 15, 2025
7085e5f
Try to restore the former ABI
filipnavara Apr 15, 2025
8365e15
Fix build
filipnavara Apr 15, 2025
d05eeca
WIP
filipnavara Apr 15, 2025
bb43879
Remove mentions of USE_FUNCLET_CALL_HELPER from documentation
filipnavara Apr 15, 2025
43c8dc8
Build fixes
filipnavara Apr 15, 2025
42815c4
Apply JIT format
filipnavara Apr 15, 2025
4ceea64
WASM build fix
filipnavara Apr 15, 2025
21b9077
Fix linux-x64 CallEHFunclet
filipnavara Apr 15, 2025
41e98a4
WASM build fix
filipnavara Apr 15, 2025
78bc386
WIP
filipnavara Apr 15, 2025
4c843d8
Add comment
filipnavara Apr 15, 2025
6db4625
Cleanup
filipnavara Apr 15, 2025
f429aa6
Reencode generics instance context stack slot as SP/FP based
filipnavara Apr 16, 2025
1679464
Remove establisher frame pointer again
filipnavara Apr 16, 2025
e02b5c1
Use symbolic constants
filipnavara Apr 16, 2025
0e93d0d
Cleanup the code in gcencode.cpp
filipnavara Apr 16, 2025
e3b98b6
Fix NativeAOT x64
filipnavara Apr 16, 2025
c315047
Apply JIT format
filipnavara Apr 16, 2025
792d01d
Fix CallEHFilterFunclet on linux-x64
filipnavara Apr 16, 2025
4317b07
Build fix
filipnavara Apr 16, 2025
b7b6b08
Attempt to fix unwinding info for ARM64
filipnavara Apr 16, 2025
f630b13
Reuse the PROLOG_SAVE_REG_PAIR_NO_FP_INDEXED macro from NativeAOT
filipnavara Apr 16, 2025
7be6fff
Fix RV64 and LA64 CallEHFilterFunclet unwind info
filipnavara Apr 16, 2025
c97c7cf
Light version of CallEH[Filter]Funclet for x64 without restoring CONT…
filipnavara Apr 16, 2025
c78ea88
Remove obsolete docs and comments
filipnavara Apr 16, 2025
67ef94a
Quick test for linux-x64 test failure
filipnavara Apr 16, 2025
2c87f23
Fix hex notation
filipnavara Apr 16, 2025
298b850
Reduce the scope of throw-in-filter workaround on linux-x64
filipnavara Apr 17, 2025
10ffb86
Fix stack trashing on linux-x64
filipnavara Apr 17, 2025
414e311
Update documentation
filipnavara Apr 17, 2025
3bee83b
Prevent peephole optimization in funclet prolog/epilog; it results in…
filipnavara Apr 20, 2025
3340a70
Remove support for encoding the PSPSym in GC info
filipnavara Apr 20, 2025
5d7a4c0
Minor doc update
filipnavara Apr 20, 2025
f41cb02
Revert "Prevent peephole optimization in funclet prolog/epilog; it re…
filipnavara Apr 20, 2025
8d17a6a
don't optimize prologs/epilogues in OptimizePostIndexed
EgorBo Apr 20, 2025
fba3040
R2R / GC info versioning
filipnavara Apr 20, 2025
52b3fcf
Bump R2R version on two more places
filipnavara Apr 20, 2025
d78b7e5
Save R11 in CallEHFilterFunclet on ARM
filipnavara Apr 21, 2025
83efb78
Apply doc suggestions
filipnavara Apr 21, 2025
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
40 changes: 5 additions & 35 deletions docs/design/coreclr/botr/clr-abi.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,33 +322,9 @@ Finally1:

Note that JIT64 does not implement this properly. The C# compiler used to always insert all necessary "step" blocks. The Roslyn C# compiler at one point did not, but then was changed to once again insert them.

## The PSPSym and funclet parameters
## Funclet parameters

The *PSPSym* (which stands for Previous Stack Pointer Symbol) is a pointer-sized local variable used to access locals from the main function body.

NativeAOT does not use PSPSym. For filter funclets the VM sets the frame register to be the same as the parent function. For second pass funclets the VM restores all non-volatile registers. The same convention is used across all platforms.

CoreCLR uses PSPSym for all platforms except x86: the frame pointer on x86 is always preserved when the handlers are invoked.

First, two definitions.

*Caller-SP* is the value of the stack pointer in a function's caller before the call instruction is executed. That is, when function A calls function B, Caller-SP for B is the value of the stack pointer immediately before the call instruction in A (calling B) was executed. Note that this definition holds for both AMD64, which pushes the return value when a call instruction is executed, and for ARM, which doesn't. For AMD64, Caller-SP is the address above the call return address.

*Initial-SP* is the initial value of the stack pointer after the fixed-size portion of the frame has been allocated. That is, before any "alloca"-type allocations.

The value stored in PSPSym is the value of Initial-SP for AMD64 or Caller-SP for other platforms, for the main function. The stack offset of the PSPSym is reported to the VM in the GC information header. The value reported in the GC information is the offset of the PSPSym from Initial-SP for AMD64 or Caller-SP for other platforms. (Note that both the value stored, and the way the value is reported to the VM, differs between architectures. In particular, note that most things in the GC information header are reported as offsets relative to Caller-SP, but PSPSym on AMD64 is one exception, and maybe the only exception.)

The VM uses the PSPSym to find other locals it cares about (such as the generics context in a funclet frame). The JIT uses it to re-establish the frame pointer register, so that the frame pointer is the same value in a funclet as it is in the main function body.

When a funclet is called, it is passed the *Establisher Frame Pointer*. For AMD64 this is true for all funclets and it is passed as the first argument in RCX, but for ARM and ARM64 this is only true for first pass funclets (currently just filters) and it is passed as the second argument in R1. The Establisher Frame Pointer is a stack pointer of an interesting "parent" frame in the exception processing system. For the CLR, it points either to the main function frame or a dynamically enclosing funclet frame from the same function, for the funclet being invoked. The value of the Establisher Frame Pointer is Initial-SP on AMD64, Caller-SP on x86, ARM, and ARM64.

Using the establisher frame, the funclet wants to load the value of the PSPSym. Since we don't know if the Establisher Frame is from the main function or a funclet, we design the main function and funclet frame layouts to place the PSPSym at an identical, small, constant offset from the Establisher Frame in each case. (This is also required because we only report a single offset to the PSPSym in the GC information, and that offset must be valid for the main function and all of its funclets). Then, the funclet uses this known offset to compute the PSPSym address and read its value. From this, it can compute the value of the frame pointer (which is a constant offset from the PSPSym value) and set the frame register to be the same as the parent function. Also, the funclet writes the value of the PSPSym to its own frame's PSPSym. This "copying" of the PSPSym happens for every funclet invocation, in particular, for every nested funclet invocation.

On ARM and ARM64, for all second pass funclets (finally, fault, catch, and filter-handler) the VM restores all non-volatile registers to their values within the parent frame. This includes the frame register (`R11`). Thus, the PSPSym is not used to recompute the frame pointer register in this case, though the PSPSym is copied to the funclet's frame, as for all funclets.

Catch, Filter, and Filter-handlers also get an Exception object (GC ref) as an argument (`REG_EXCEPTION_OBJECT`). On AMD64 it is the second argument and thus passed in RDX. On ARM and ARM64 this is the first argument and passed in R0.

(Note that the JIT64 source code contains a comment that says, "The current CLR doesn't always pass the correct establisher frame to the funclet. Funclet may receive establisher frame of funclet when expecting that of original routine." It indicates this is the reason that a PSPSym is required in all funclets as well as the main function, whereas if the establisher frame was correctly reported, the PSPSym could be omitted in some cases.)
Catch, Filter, and Filter-handlers get an Exception object (GC ref) as an argument (`REG_EXCEPTION_OBJECT`). On AMD64 it is passed in RCX (Windows ABI) or RSI (Unix ABI). On ARM and ARM64 this is the first argument and passed in R0.

## Funclet Return Values

Expand All @@ -374,11 +350,11 @@ Some definitions:

When an exception occurs, the VM is invoked to do some processing. If the exception is within a "try" region, it eventually calls a corresponding handler (which also includes calling filters). The exception location within a function might be where a "throw" instruction executes, the point of a processor exception like null pointer dereference or divide by zero, or the point of a call where the callee threw an exception but did not catch it.

On AMD64, all register values that existed at the exception point in the corresponding "try" region are trashed on entry to the funclet. That is, the only registers that have known values are those of the funclet parameters.
The VM sets the frame register to be the same as the parent function. This allows the funclets to access local variables using frame-relative addresses.

On ARM and ARM64, all registers are restored to their values at the exception point.
For filter funclets and on CoreCLR/AMD64 for all funclets, all other register values that existed at the exception point in the corresponding "try" region are trashed on entry to the funclet. That is, the only registers that have known values are those of the funclet parameters and the frame register.

On x86: TBD.
For other funclets on all platforms except CoreCLR/AMD64, all non-volatile registers are restored to their values at the exception point. The JIT codegen [does not take advantage of it currently](https://github.com/dotnet/runtime/pull/114630#issuecomment-2810210759).

### Registers on return from a funclet

Expand Down Expand Up @@ -696,12 +672,6 @@ x64 currently saves RBP, RSI and RDI while ARM64 saves just FP and LR.

However, EnC remap is not supported inside funclets. The stack layout of funclets does not matter for EnC.

## Considerations with regards to PSPSym

As explained previously in this document, on x64 we have Initial RSP == PSPSym. For EnC methods, as we disallow remappings after localloc (see below), we furthermore have RBP == PSPSym.
For ARM64 we have Caller SP == PSPSym and the FP points to the previously saved FP/LR pair. For EnC the JIT always sets up the stack frame so that the FP/LR pair is at Caller SP - 16 and does not save any additional callee saves.
These invariants allow the VM to compute new value of the frame pointer and PSPSym after the edit without any additional information. Note that the frame pointer and PSPSym do not change values or location on ARM64. However, EH may be added to a function in which case a new PSPSym needs to be materialized, even on ARM64. Location of PSPSym is found via GC info.

## Localloc

Localloc is allowed in EnC code, but remap is disallowed after the method has executed a localloc instruction. VM uses the invariants above (`RSP == RBP` on x64, `FP + 16 == SP + stack size` on ARM64) to detect whether localloc was executed by the method.
Expand Down
6 changes: 2 additions & 4 deletions docs/design/coreclr/botr/guide-for-porting.md
Original file line number Diff line number Diff line change
Expand Up @@ -386,12 +386,10 @@ Here is an annotated list of the stubs implemented for Unix on Arm64.
application

11. `CallEHFunclet` – Used to call catch, finally and fault funclets. Behavior
is specific to exactly how funclets are implemented. Only used if
USE_FUNCLET_CALL_HELPER is set
is specific to exactly how funclets are implemented.

12. `CallEHFilterFunclet` – Used to call filter funclets. Behavior is specific
to exactly how funclets are implemented. Only used if
USE_FUNCLET_CALL_HELPER is set
to exactly how funclets are implemented.

13. `ResolveWorkerChainLookupAsmStub`/ `ResolveWorkerAsmStub` Used for virtual
stub dispatch (virtual call support for interface, and some virtual
Expand Down
2 changes: 0 additions & 2 deletions docs/design/features/OsrDetailsAndDebugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,6 @@ On Arm64 we have epilog unwind codes and the second SP adjust does not appear to

OSR funclets are more or less normal funclets.

On Arm64, to satisfy PSPSym reporting constraints, the funclet frame must be padded to include the Tier0 frame size. This is conceptually similar to the way the funclet frames also pad for homed varargs arguments -- in both cases the padded space is never used, it is just there to ensure the PSPSym ends up at the same caller-SP relative offset for the main function and any funclet.

#### OSR Unwind Info

On x64 the prolog unwind includes a phantom SP adjustment at offset 0 for the Tier0 frame.
Expand Down
26 changes: 2 additions & 24 deletions src/coreclr/gcinfo/gcinfoencoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,6 @@ GcInfoSize& GcInfoSize::operator+=(const GcInfoSize& other)
SecObjSize += other.SecObjSize;
GsCookieSize += other.GsCookieSize;
GenericsCtxSize += other.GenericsCtxSize;
PspSymSize += other.PspSymSize;
StackBaseSize += other.StackBaseSize;
ReversePInvokeFrameSize += other.ReversePInvokeFrameSize;
FixedAreaSize += other.FixedAreaSize;
Expand Down Expand Up @@ -406,7 +405,6 @@ void GcInfoSize::Log(DWORD level, const char * header)
LogSpew(LF_GCINFO, level, "Prolog/Epilog: %zu\n", ProEpilogSize);
LogSpew(LF_GCINFO, level, "SecObj: %zu\n", SecObjSize);
LogSpew(LF_GCINFO, level, "GsCookie: %zu\n", GsCookieSize);
LogSpew(LF_GCINFO, level, "PspSym: %zu\n", PspSymSize);
LogSpew(LF_GCINFO, level, "GenericsCtx: %zu\n", GenericsCtxSize);
LogSpew(LF_GCINFO, level, "StackBase: %zu\n", StackBaseSize);
LogSpew(LF_GCINFO, level, "FixedArea: %zu\n", FixedAreaSize);
Expand Down Expand Up @@ -471,7 +469,6 @@ template <typename GcInfoEncoding> TGcInfoEncoder<GcInfoEncoding>::TGcInfoEncode
m_GSCookieValidRangeStart = 0;
_ASSERTE(sizeof(m_GSCookieValidRangeEnd) == sizeof(UINT32));
m_GSCookieValidRangeEnd = (UINT32) (-1); // == UINT32.MaxValue
m_PSPSymStackSlot = NO_PSP_SYM;
m_GenericsInstContextStackSlot = NO_GENERICS_INST_CONTEXT;
m_contextParamType = GENERIC_CONTEXTPARAM_NONE;

Expand Down Expand Up @@ -702,14 +699,6 @@ template <typename GcInfoEncoding> void TGcInfoEncoder<GcInfoEncoding>::SetGSCoo
m_GSCookieValidRangeEnd = validRangeEnd;
}

template <typename GcInfoEncoding> void TGcInfoEncoder<GcInfoEncoding>::SetPSPSymStackSlot( INT32 spOffsetPSPSym )
{
_ASSERTE( spOffsetPSPSym != NO_PSP_SYM );
_ASSERTE( m_PSPSymStackSlot == NO_PSP_SYM || m_PSPSymStackSlot == spOffsetPSPSym );

m_PSPSymStackSlot = spOffsetPSPSym;
}

template <typename GcInfoEncoding> void TGcInfoEncoder<GcInfoEncoding>::SetGenericsInstContextStackSlot( INT32 spOffsetGenericsContext, GENERIC_CONTEXTPARAM_TYPE type)
{
_ASSERTE( spOffsetGenericsContext != NO_GENERICS_INST_CONTEXT);
Expand Down Expand Up @@ -941,7 +930,7 @@ template <typename GcInfoEncoding> void TGcInfoEncoder<GcInfoEncoding>::Build()
UINT32 hasContextParamType = (m_GenericsInstContextStackSlot != NO_GENERICS_INST_CONTEXT);
UINT32 hasReversePInvokeFrame = (m_ReversePInvokeFrameSlot != NO_REVERSE_PINVOKE_FRAME);

BOOL slimHeader = (!m_IsVarArg && !hasGSCookie && (m_PSPSymStackSlot == NO_PSP_SYM) &&
BOOL slimHeader = (!m_IsVarArg && !hasGSCookie &&
!hasContextParamType && (m_InterruptibleRanges.Count() == 0) && !hasReversePInvokeFrame &&
((m_StackBaseRegister == NO_STACK_BASE_REGISTER) || (GcInfoEncoding::NORMALIZE_STACK_BASE_REGISTER(m_StackBaseRegister) == 0))) &&
#ifdef TARGET_AMD64
Expand Down Expand Up @@ -970,7 +959,7 @@ template <typename GcInfoEncoding> void TGcInfoEncoder<GcInfoEncoding>::Build()
GCINFO_WRITE(m_Info1, (m_IsVarArg ? 1 : 0), 1, FlagsSize);
GCINFO_WRITE(m_Info1, 0 /* unused - was hasSecurityObject */, 1, FlagsSize);
GCINFO_WRITE(m_Info1, (hasGSCookie ? 1 : 0), 1, FlagsSize);
GCINFO_WRITE(m_Info1, ((m_PSPSymStackSlot != NO_PSP_SYM) ? 1 : 0), 1, FlagsSize);
GCINFO_WRITE(m_Info1, 0 /* unused - was hasPSPSymStackSlot */, 1, FlagsSize);
GCINFO_WRITE(m_Info1, m_contextParamType, 2, FlagsSize);
#if defined(TARGET_LOONGARCH64)
assert(m_StackBaseRegister == 22 || 3 == m_StackBaseRegister);
Expand Down Expand Up @@ -1037,17 +1026,6 @@ template <typename GcInfoEncoding> void TGcInfoEncoder<GcInfoEncoding>::Build()

}

// Encode the offset to the PSPSym.
// The PSPSym is relative to the caller SP on IA64 and the initial stack pointer before stack allocations on X64.
if(m_PSPSymStackSlot != NO_PSP_SYM)
{
_ASSERTE(!slimHeader);
#ifdef _DEBUG
LOG((LF_GCINFO, LL_INFO1000, "Parent PSP at " FMT_STK "\n", DBG_STK(m_PSPSymStackSlot)));
#endif
GCINFO_WRITE_VARL_S(m_Info1, GcInfoEncoding::NORMALIZE_STACK_SLOT(m_PSPSymStackSlot), GcInfoEncoding::PSP_SYM_STACK_SLOT_ENCBASE, PspSymSize);
}

// Encode the offset to the generics type context.
if(m_GenericsInstContextStackSlot != NO_GENERICS_INST_CONTEXT)
{
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/inc/eetwain.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,10 +483,10 @@ PTR_VOID GetExactGenericsToken(PREGDISPLAY pContext,
EECodeInfo * pCodeInfo);

static
PTR_VOID GetExactGenericsToken(SIZE_T baseStackSlot,
PTR_VOID GetExactGenericsToken(TADDR sp,
TADDR fp,
EECodeInfo * pCodeInfo);


#endif // FEATURE_EH_FUNCLETS && USE_GC_INFO_DECODER

/*
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/inc/gcinfodecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ enum GcInfoDecoderFlags
DECODE_INTERRUPTIBILITY = 0x08,
DECODE_GC_LIFETIMES = 0x10,
DECODE_NO_VALIDATION = 0x20,
DECODE_PSP_SYM = 0x40,
DECODE_PSP_SYM = 0x40, // Unused starting with v4 format
DECODE_GENERICS_INST_CONTEXT = 0x80, // stack location of instantiation context for generics
// (this may be either the 'this' ptr or the instantiation secret param)
DECODE_GS_COOKIE = 0x100, // stack location of the GS cookie
Expand All @@ -237,7 +237,7 @@ enum GcInfoHeaderFlags
GC_INFO_IS_VARARG = 0x1,
// unused = 0x2, // was GC_INFO_HAS_SECURITY_OBJECT
GC_INFO_HAS_GS_COOKIE = 0x4,
GC_INFO_HAS_PSP_SYM = 0x8,
GC_INFO_HAS_PSP_SYM = 0x8, // Unused starting with v4 format
GC_INFO_HAS_GENERICS_INST_CONTEXT_MASK = 0x30,
GC_INFO_HAS_GENERICS_INST_CONTEXT_NONE = 0x00,
GC_INFO_HAS_GENERICS_INST_CONTEXT_MT = 0x10,
Expand Down Expand Up @@ -583,6 +583,7 @@ class TGcInfoDecoder
INT32 GetReversePInvokeFrameStackSlot();
bool HasMethodDescGenericsInstContext();
bool HasMethodTableGenericsInstContext();
bool HasStackBaseRegister();
bool GetIsVarArg();
bool WantsReportOnlyLeaf();
#if defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
Expand Down
9 changes: 3 additions & 6 deletions src/coreclr/inc/gcinfoencoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
- Flag: isVarArg,
unused (was hasSecurityObject),
hasGSCookie,
hasPSPSymStackSlot,
unused (was hasPSPSymStackSlot),
hasGenericsInstContextStackSlot,
hasStackBaseregister,
wantsReportOnlyLeaf (AMD64 use only),
Expand All @@ -34,9 +34,9 @@
- CodeLength
- Prolog (if hasGenericsInstContextStackSlot || hasGSCookie)
- Epilog (if hasGSCookie)
- SecurityObjectStackSlot (if any)
- SecurityObjectStackSlot (if any; no longer used)
- GSCookieStackSlot (if any)
- PSPSymStackSlot (if any)
- PSPSymStackSlot (if any; no longer used)
- GenericsInstContextStackSlot (if any)
- StackBaseRegister (if any)
- SizeOfEditAndContinuePreservedArea (if any)
Expand Down Expand Up @@ -128,7 +128,6 @@ struct GcInfoSize
size_t ProEpilogSize;
size_t SecObjSize;
size_t GsCookieSize;
size_t PspSymSize;
size_t GenericsCtxSize;
size_t StackBaseSize;
size_t ReversePInvokeFrameSize;
Expand Down Expand Up @@ -408,7 +407,6 @@ class TGcInfoEncoder

void SetPrologSize( UINT32 prologSize );
void SetGSCookieStackSlot( INT32 spOffsetGSCookie, UINT32 validRangeStart, UINT32 validRangeEnd );
void SetPSPSymStackSlot( INT32 spOffsetPSPSym );
void SetGenericsInstContextStackSlot( INT32 spOffsetGenericsContext, GENERIC_CONTEXTPARAM_TYPE type);
void SetReversePInvokeFrameSlot(INT32 spOffset);
void SetIsVarArg();
Expand Down Expand Up @@ -492,7 +490,6 @@ class TGcInfoEncoder
INT32 m_GSCookieStackSlot;
UINT32 m_GSCookieValidRangeStart;
UINT32 m_GSCookieValidRangeEnd;
INT32 m_PSPSymStackSlot;
INT32 m_GenericsInstContextStackSlot;
GENERIC_CONTEXTPARAM_TYPE m_contextParamType;
UINT32 m_CodeLength;
Expand Down
7 changes: 5 additions & 2 deletions src/coreclr/inc/readytorun.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
// src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h
// If you update this, ensure you run `git grep MINIMUM_READYTORUN_MAJOR_VERSION`
// and handle pending work.
#define READYTORUN_MAJOR_VERSION 12
#define READYTORUN_MAJOR_VERSION 13
#define READYTORUN_MINOR_VERSION 0x0000

#define MINIMUM_READYTORUN_MAJOR_VERSION 12
#define MINIMUM_READYTORUN_MAJOR_VERSION 13

// R2R Version 2.1 adds the InliningInfo section
// R2R Version 2.2 adds the ProfileDataInfo section
Expand All @@ -40,6 +40,9 @@
// R2R Version 10.1 adds Unbox_TypeTest helper
// R2R Version 11 uses GCInfo v4, which encodes safe points without -1 offset and does not track return kinds in GCInfo
// R2R Version 12 requires all return buffers to be always on the stack
// R2R Version 13 removes usage of PSPSym, changes ABI for funclets to match NativeAOT, changes register for
// exception parameter on AMD64, and redefines generics instance context stack slot in GCInfo v4
// to be SP/FP relative

struct READYTORUN_CORE_HEADER
{
Expand Down
Loading
Loading