Skip to content

Commit 588bc45

Browse files
noahfalkjkotas
andauthored
Add ee_alloc_context (NativeAOT) (#104851)
This change is some preparatory refactoring for the randomized allocation sampling feature. We need to add more state onto allocation context but we don't want to do a breaking change of the GC interface. The new state only needs to be visible to the EE but we want it physically near the existing alloc context state for good cache locality. To accomplish this we created a new ee_alloc_context struct which contains an instance of gc_alloc_context within it. The new ee_alloc_context::combined_limit should be used by fast allocation helpers to determine when to go down the slow path. Most of the time combined_limit has the same value as alloc_limit, but periodically we need to emit an allocation sampling event on an object that is somewhere in the middle of an AC. Using combined_limit rather than alloc_limit as the slow path trigger allows us to keep all the sampling event logic in the slow path. * PR feedback Co-authored-by: Jan Kotas <[email protected]>
1 parent f72179a commit 588bc45

21 files changed

+161
-67
lines changed

src/coreclr/nativeaot/Runtime/AsmOffsets.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,24 @@ ASM_OFFSET( 0, 0, MethodTable, m_uFlags)
4646
ASM_OFFSET( 4, 4, MethodTable, m_uBaseSize)
4747
ASM_OFFSET( 14, 18, MethodTable, m_VTable)
4848

49-
ASM_OFFSET( 0, 0, Thread, m_rgbAllocContextBuffer)
50-
ASM_OFFSET( 28, 38, Thread, m_ThreadStateFlags)
51-
ASM_OFFSET( 2c, 40, Thread, m_pTransitionFrame)
52-
ASM_OFFSET( 30, 48, Thread, m_pDeferredTransitionFrame)
53-
ASM_OFFSET( 40, 68, Thread, m_ppvHijackedReturnAddressLocation)
54-
ASM_OFFSET( 44, 70, Thread, m_pvHijackedReturnAddress)
55-
ASM_OFFSET( 48, 78, Thread, m_uHijackedReturnValueFlags)
56-
ASM_OFFSET( 4c, 80, Thread, m_pExInfoStackHead)
57-
ASM_OFFSET( 50, 88, Thread, m_threadAbortException)
49+
ASM_OFFSET( 0, 0, Thread, m_eeAllocContext)
50+
ASM_OFFSET( 2c, 40, Thread, m_ThreadStateFlags)
51+
ASM_OFFSET( 30, 48, Thread, m_pTransitionFrame)
52+
ASM_OFFSET( 34, 50, Thread, m_pDeferredTransitionFrame)
53+
ASM_OFFSET( 44, 70, Thread, m_ppvHijackedReturnAddressLocation)
54+
ASM_OFFSET( 48, 78, Thread, m_pvHijackedReturnAddress)
55+
ASM_OFFSET( 4c, 80, Thread, m_uHijackedReturnValueFlags)
56+
ASM_OFFSET( 50, 88, Thread, m_pExInfoStackHead)
57+
ASM_OFFSET( 54, 90, Thread, m_threadAbortException)
5858

5959
ASM_SIZEOF( 14, 20, EHEnum)
6060

6161
ASM_OFFSET( 0, 0, gc_alloc_context, alloc_ptr)
6262
ASM_OFFSET( 4, 8, gc_alloc_context, alloc_limit)
6363

64+
ASM_OFFSET( 0, 0, ee_alloc_context, combined_limit)
65+
ASM_OFFSET( 4, 8, ee_alloc_context, m_rgbAllocContextBuffer)
66+
6467
#ifdef FEATURE_CACHED_INTERFACE_DISPATCH
6568
ASM_OFFSET( 4, 8, InterfaceDispatchCell, m_pCache)
6669
#ifdef INTERFACE_DISPATCH_CACHE_HAS_CELL_BACKPOINTER

src/coreclr/nativeaot/Runtime/AsmOffsetsVerify.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
class AsmOffsets
2424
{
25-
static_assert(sizeof(Thread::m_rgbAllocContextBuffer) >= sizeof(gc_alloc_context), "Thread::m_rgbAllocContextBuffer is not big enough to hold a gc_alloc_context");
25+
static_assert(sizeof(ee_alloc_context::m_rgbAllocContextBuffer) >= sizeof(gc_alloc_context), "ee_alloc_context::m_rgbAllocContextBuffer is not big enough to hold a gc_alloc_context");
2626

2727
// Some assembly helpers for arrays and strings are shared and use the fact that arrays and strings have similar layouts)
2828
static_assert(offsetof(Array, m_Length) == offsetof(String, m_Length), "The length field of String and Array have different offsets");

src/coreclr/nativeaot/Runtime/DebugHeader.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ struct DotNetRuntimeDebugHeader
7777
// This counter can be incremented to indicate breaking changes
7878
// This field must be encoded little endian, regardless of the typical endianness of
7979
// the machine
80-
const uint16_t MajorVersion = 4;
80+
// Changes:
81+
// v1-v4 were never doc'ed but history is source control if you need it
82+
// v5 - Thread now has an m_eeAllocContext field and the previous m_rgbAllocContextBuffer
83+
// field is nested inside of it.
84+
//
85+
const uint16_t MajorVersion = 5;
8186

8287
// This counter can be incremented to indicate back-compatible changes
8388
// This field must be encoded little endian, regardless of the typical endianness of
@@ -163,6 +168,9 @@ extern "C" void PopulateDebugHeaders()
163168
MAKE_DEBUG_FIELD_ENTRY(dac_gc_heap, finalize_queue);
164169
MAKE_DEBUG_FIELD_ENTRY(dac_gc_heap, generation_table);
165170

171+
MAKE_SIZE_ENTRY(ee_alloc_context);
172+
MAKE_DEBUG_FIELD_ENTRY(ee_alloc_context, m_rgbAllocContextBuffer);
173+
166174
MAKE_SIZE_ENTRY(gc_alloc_context);
167175
MAKE_DEBUG_FIELD_ENTRY(gc_alloc_context, alloc_ptr);
168176
MAKE_DEBUG_FIELD_ENTRY(gc_alloc_context, alloc_limit);
@@ -194,7 +202,7 @@ extern "C" void PopulateDebugHeaders()
194202

195203
MAKE_SIZE_ENTRY(RuntimeThreadLocals);
196204
MAKE_DEBUG_FIELD_ENTRY(RuntimeThreadLocals, m_pNext);
197-
MAKE_DEBUG_FIELD_ENTRY(RuntimeThreadLocals, m_rgbAllocContextBuffer);
205+
MAKE_DEBUG_FIELD_ENTRY(RuntimeThreadLocals, m_eeAllocContext);
198206
MAKE_DEBUG_FIELD_ENTRY(RuntimeThreadLocals, m_threadId);
199207
MAKE_DEBUG_FIELD_ENTRY(RuntimeThreadLocals, m_pThreadStressLog);
200208
MAKE_DEBUG_FIELD_ENTRY(RuntimeThreadLocals, m_pExInfoStackHead);

src/coreclr/nativeaot/Runtime/GCHelpers.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ static Object* GcAllocInternal(MethodTable* pEEType, uint32_t uFlags, uintptr_t
540540
tls_pLastAllocationEEType = pEEType;
541541

542542
Object* pObject = GCHeapUtilities::GetGCHeap()->Alloc(pThread->GetAllocContext(), cbSize, uFlags);
543+
pThread->GetEEAllocContext()->UpdateCombinedLimit();
543544
if (pObject == NULL)
544545
return NULL;
545546

src/coreclr/nativeaot/Runtime/amd64/AllocFast.S

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ NESTED_ENTRY RhpNewFast, _TEXT, NoHandler
2828

2929
mov rsi, [rax + OFFSETOF__Thread__m_alloc_context__alloc_ptr]
3030
add rdx, rsi
31-
cmp rdx, [rax + OFFSETOF__Thread__m_alloc_context__alloc_limit]
31+
cmp rdx, [rax + OFFSETOF__Thread__m_eeAllocContext__combined_limit]
3232
ja LOCAL_LABEL(RhpNewFast_RarePath)
3333

3434
// set the new alloc pointer
@@ -143,7 +143,7 @@ NESTED_ENTRY RhNewString, _TEXT, NoHandler
143143
// rcx == Thread*
144144
// rdx == string size
145145
// r12 == element count
146-
cmp rax, [rcx + OFFSETOF__Thread__m_alloc_context__alloc_limit]
146+
cmp rax, [rcx + OFFSETOF__Thread__m_eeAllocContext__combined_limit]
147147
ja LOCAL_LABEL(RhNewString_RarePath)
148148

149149
mov [rcx + OFFSETOF__Thread__m_alloc_context__alloc_ptr], rax
@@ -226,7 +226,7 @@ NESTED_ENTRY RhpNewArray, _TEXT, NoHandler
226226
// rcx == Thread*
227227
// rdx == array size
228228
// r12 == element count
229-
cmp rax, [rcx + OFFSETOF__Thread__m_alloc_context__alloc_limit]
229+
cmp rax, [rcx + OFFSETOF__Thread__m_eeAllocContext__combined_limit]
230230
ja LOCAL_LABEL(RhpNewArray_RarePath)
231231

232232
mov [rcx + OFFSETOF__Thread__m_alloc_context__alloc_ptr], rax

src/coreclr/nativeaot/Runtime/amd64/AllocFast.asm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ LEAF_ENTRY RhpNewFast, _TEXT
2525

2626
mov rax, [rdx + OFFSETOF__Thread__m_alloc_context__alloc_ptr]
2727
add r8, rax
28-
cmp r8, [rdx + OFFSETOF__Thread__m_alloc_context__alloc_limit]
28+
cmp r8, [rdx + OFFSETOF__Thread__m_eeAllocContext__combined_limit]
2929
ja RhpNewFast_RarePath
3030

3131
;; set the new alloc pointer
@@ -118,7 +118,7 @@ LEAF_ENTRY RhNewString, _TEXT
118118
; rdx == element count
119119
; r8 == array size
120120
; r10 == thread
121-
cmp rax, [r10 + OFFSETOF__Thread__m_alloc_context__alloc_limit]
121+
cmp rax, [r10 + OFFSETOF__Thread__m_eeAllocContext__combined_limit]
122122
ja RhpNewArrayRare
123123

124124
mov [r10 + OFFSETOF__Thread__m_alloc_context__alloc_ptr], rax
@@ -179,7 +179,7 @@ LEAF_ENTRY RhpNewArray, _TEXT
179179
; rdx == element count
180180
; r8 == array size
181181
; r10 == thread
182-
cmp rax, [r10 + OFFSETOF__Thread__m_alloc_context__alloc_limit]
182+
cmp rax, [r10 + OFFSETOF__Thread__m_eeAllocContext__combined_limit]
183183
ja RhpNewArrayRare
184184

185185
mov [r10 + OFFSETOF__Thread__m_alloc_context__alloc_ptr], rax

src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,8 @@ TSF_DoNotTriggerGc equ 10h
336336
;;
337337
;; Rename fields of nested structs
338338
;;
339-
OFFSETOF__Thread__m_alloc_context__alloc_ptr equ OFFSETOF__Thread__m_rgbAllocContextBuffer + OFFSETOF__gc_alloc_context__alloc_ptr
340-
OFFSETOF__Thread__m_alloc_context__alloc_limit equ OFFSETOF__Thread__m_rgbAllocContextBuffer + OFFSETOF__gc_alloc_context__alloc_limit
339+
OFFSETOF__Thread__m_alloc_context__alloc_ptr equ OFFSETOF__Thread__m_eeAllocContext + OFFSETOF__ee_alloc_context__m_rgbAllocContextBuffer + OFFSETOF__gc_alloc_context__alloc_ptr
340+
OFFSETOF__Thread__m_eeAllocContext__combined_limit equ OFFSETOF__Thread__m_eeAllocContext + OFFSETOF__ee_alloc_context__combined_limit
341341

342342

343343

src/coreclr/nativeaot/Runtime/arm/AllocFast.S

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ LEAF_ENTRY RhpNewFast, _TEXT
2626

2727
ldr r3, [r0, #OFFSETOF__Thread__m_alloc_context__alloc_ptr]
2828
add r2, r3
29-
ldr r1, [r0, #OFFSETOF__Thread__m_alloc_context__alloc_limit]
29+
ldr r1, [r0, #OFFSETOF__Thread__m_eeAllocContext__combined_limit]
3030
cmp r2, r1
3131
bhi LOCAL_LABEL(RhpNewFast_RarePath)
3232

@@ -132,7 +132,7 @@ LEAF_ENTRY RhNewString, _TEXT
132132
adds r6, r12
133133
bcs LOCAL_LABEL(RhNewString_RarePath) // if we get a carry here, the string is too large to fit below 4 GB
134134

135-
ldr r12, [r0, #OFFSETOF__Thread__m_alloc_context__alloc_limit]
135+
ldr r12, [r0, #OFFSETOF__Thread__m_eeAllocContext__combined_limit]
136136
cmp r6, r12
137137
bhi LOCAL_LABEL(RhNewString_RarePath)
138138

@@ -213,7 +213,7 @@ LOCAL_LABEL(ArrayAlignSize):
213213
adds r6, r12
214214
bcs LOCAL_LABEL(RhpNewArray_RarePath) // if we get a carry here, the array is too large to fit below 4 GB
215215

216-
ldr r12, [r0, #OFFSETOF__Thread__m_alloc_context__alloc_limit]
216+
ldr r12, [r0, #OFFSETOF__Thread__m_eeAllocContext__combined_limit]
217217
cmp r6, r12
218218
bhi LOCAL_LABEL(RhpNewArray_RarePath)
219219

@@ -349,7 +349,7 @@ LEAF_ENTRY RhpNewFastAlign8, _TEXT
349349
// Determine whether the end of the object would lie outside of the current allocation context. If so,
350350
// we abandon the attempt to allocate the object directly and fall back to the slow helper.
351351
add r2, r3
352-
ldr r3, [r0, #OFFSETOF__Thread__m_alloc_context__alloc_limit]
352+
ldr r3, [r0, #OFFSETOF__Thread__m_eeAllocContext__combined_limit]
353353
cmp r2, r3
354354
bhi LOCAL_LABEL(Alloc8Failed)
355355

@@ -412,7 +412,7 @@ LEAF_ENTRY RhpNewFastMisalign, _TEXT
412412
// Determine whether the end of the object would lie outside of the current allocation context. If so,
413413
// we abandon the attempt to allocate the object directly and fall back to the slow helper.
414414
add r2, r3
415-
ldr r3, [r0, #OFFSETOF__Thread__m_alloc_context__alloc_limit]
415+
ldr r3, [r0, #OFFSETOF__Thread__m_eeAllocContext__combined_limit]
416416
cmp r2, r3
417417
bhi LOCAL_LABEL(BoxAlloc8Failed)
418418

src/coreclr/nativeaot/Runtime/arm64/AllocFast.S

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
//
1111
// Rename fields of nested structs
1212
//
13-
#define OFFSETOF__Thread__m_alloc_context__alloc_ptr (OFFSETOF__Thread__m_rgbAllocContextBuffer + OFFSETOF__gc_alloc_context__alloc_ptr)
14-
#define OFFSETOF__Thread__m_alloc_context__alloc_limit (OFFSETOF__Thread__m_rgbAllocContextBuffer + OFFSETOF__gc_alloc_context__alloc_limit)
13+
#define OFFSETOF__Thread__m_alloc_context__alloc_ptr (OFFSETOF__Thread__m_eeAllocContext + OFFSETOF__ee_alloc_context__m_rgbAllocContextBuffer + OFFSETOF__gc_alloc_context__alloc_ptr)
14+
#define OFFSETOF__Thread__m_eeAllocContext__combined_limit (OFFSETOF__Thread__m_eeAllocContext + OFFSETOF__ee_alloc_context__combined_limit)
1515

1616

1717

@@ -44,7 +44,7 @@
4444
// Determine whether the end of the object would lie outside of the current allocation context. If so,
4545
// we abandon the attempt to allocate the object directly and fall back to the slow helper.
4646
add x2, x2, x12
47-
ldr x13, [x1, #OFFSETOF__Thread__m_alloc_context__alloc_limit]
47+
ldr x13, [x1, #OFFSETOF__Thread__m_eeAllocContext__combined_limit]
4848
cmp x2, x13
4949
bhi LOCAL_LABEL(RhpNewFast_RarePath)
5050

@@ -139,7 +139,7 @@ LOCAL_LABEL(NewOutOfMemory):
139139
// Determine whether the end of the object would lie outside of the current allocation context. If so,
140140
// we abandon the attempt to allocate the object directly and fall back to the slow helper.
141141
add x2, x2, x12
142-
ldr x12, [x3, #OFFSETOF__Thread__m_alloc_context__alloc_limit]
142+
ldr x12, [x3, #OFFSETOF__Thread__m_eeAllocContext__combined_limit]
143143
cmp x2, x12
144144
bhi LOCAL_LABEL(RhNewString_Rare)
145145

@@ -207,7 +207,7 @@ LOCAL_LABEL(RhNewString_Rare):
207207
// Determine whether the end of the object would lie outside of the current allocation context. If so,
208208
// we abandon the attempt to allocate the object directly and fall back to the slow helper.
209209
add x2, x2, x12
210-
ldr x12, [x3, #OFFSETOF__Thread__m_alloc_context__alloc_limit]
210+
ldr x12, [x3, #OFFSETOF__Thread__m_eeAllocContext__combined_limit]
211211
cmp x2, x12
212212
bhi LOCAL_LABEL(RhpNewArray_Rare)
213213

src/coreclr/nativeaot/Runtime/arm64/AllocFast.asm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
;; Determine whether the end of the object would lie outside of the current allocation context. If so,
3131
;; we abandon the attempt to allocate the object directly and fall back to the slow helper.
3232
add x2, x2, x12
33-
ldr x13, [x1, #OFFSETOF__Thread__m_alloc_context__alloc_limit]
33+
ldr x13, [x1, #OFFSETOF__Thread__m_eeAllocContext__combined_limit]
3434
cmp x2, x13
3535
bhi RhpNewFast_RarePath
3636

@@ -118,7 +118,7 @@ NewOutOfMemory
118118
;; Determine whether the end of the object would lie outside of the current allocation context. If so,
119119
;; we abandon the attempt to allocate the object directly and fall back to the slow helper.
120120
add x2, x2, x12
121-
ldr x12, [x3, #OFFSETOF__Thread__m_alloc_context__alloc_limit]
121+
ldr x12, [x3, #OFFSETOF__Thread__m_eeAllocContext__combined_limit]
122122
cmp x2, x12
123123
bhi RhpNewArrayRare
124124

@@ -179,7 +179,7 @@ StringSizeOverflow
179179
;; Determine whether the end of the object would lie outside of the current allocation context. If so,
180180
;; we abandon the attempt to allocate the object directly and fall back to the slow helper.
181181
add x2, x2, x12
182-
ldr x12, [x3, #OFFSETOF__Thread__m_alloc_context__alloc_limit]
182+
ldr x12, [x3, #OFFSETOF__Thread__m_eeAllocContext__combined_limit]
183183
cmp x2, x12
184184
bhi RhpNewArrayRare
185185

0 commit comments

Comments
 (0)