Skip to content

Commit 2820a1e

Browse files
[NativeAOT] Move Interlocked null checks to managed, RhpLockCmpXchg64 to C (#100021)
* Move RhpLockCmpXchg64 implementation to C; move null checks from RhpLockCmpXchg64/RhpCheckedLockCmpXchg/RhpCheckedXchg to managed code * Removed #ifs per feedback * Update RhpLockCmpXchg[8/16/32] too * Add PalInterlockedOperationBarrier * PR feedback * Move RhpLockCmpXchg32 to C --------- Co-authored-by: Michał Petryka <[email protected]>
1 parent 48aaca5 commit 2820a1e

File tree

16 files changed

+77
-200
lines changed

16 files changed

+77
-200
lines changed

src/coreclr/nativeaot/Runtime/CMakeLists.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,6 @@ if (CLR_CMAKE_TARGET_ARCH_AMD64 AND CLR_CMAKE_TARGET_WIN32)
203203
)
204204
endif (CLR_CMAKE_TARGET_ARCH_AMD64 AND CLR_CMAKE_TARGET_WIN32)
205205

206-
if (NOT (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64))
207-
list(APPEND RUNTIME_SOURCES_ARCH_ASM
208-
${ARCH_SOURCES_DIR}/Interlocked.${ASM_SUFFIX}
209-
)
210-
endif (NOT (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64))
211-
212206
list(APPEND RUNTIME_SOURCES_ARCH_ASM
213207
${ARCH_SOURCES_DIR}/AllocFast.${ASM_SUFFIX}
214208
${ARCH_SOURCES_DIR}/ExceptionHandling.${ASM_SUFFIX}

src/coreclr/nativeaot/Runtime/EHHelpers.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -326,12 +326,6 @@ EXTERN_C CODE_LOCATION RhpCheckedAssignRefESIAVLocation;
326326
EXTERN_C CODE_LOCATION RhpCheckedAssignRefEDIAVLocation;
327327
EXTERN_C CODE_LOCATION RhpCheckedAssignRefEBPAVLocation;
328328
#endif
329-
EXTERN_C CODE_LOCATION RhpCheckedLockCmpXchgAVLocation;
330-
EXTERN_C CODE_LOCATION RhpCheckedXchgAVLocation;
331-
#if !defined(HOST_AMD64) && !defined(HOST_ARM64)
332-
EXTERN_C CODE_LOCATION RhpLockCmpXchg32AVLocation;
333-
EXTERN_C CODE_LOCATION RhpLockCmpXchg64AVLocation;
334-
#endif
335329
EXTERN_C CODE_LOCATION RhpByRefAssignRefAVLocation1;
336330

337331
#if !defined(HOST_ARM64)
@@ -365,22 +359,10 @@ static bool InWriteBarrierHelper(uintptr_t faultingIP)
365359
(uintptr_t)&RhpCheckedAssignRefESIAVLocation,
366360
(uintptr_t)&RhpCheckedAssignRefEDIAVLocation,
367361
(uintptr_t)&RhpCheckedAssignRefEBPAVLocation,
368-
#endif
369-
(uintptr_t)&RhpCheckedLockCmpXchgAVLocation,
370-
(uintptr_t)&RhpCheckedXchgAVLocation,
371-
#if !defined(HOST_AMD64) && !defined(HOST_ARM64)
372-
#if !defined(HOST_X86)
373-
(uintptr_t)&RhpLockCmpXchg32AVLocation,
374-
#endif
375-
(uintptr_t)&RhpLockCmpXchg64AVLocation,
376362
#endif
377363
(uintptr_t)&RhpByRefAssignRefAVLocation1,
378364
#if !defined(HOST_ARM64)
379365
(uintptr_t)&RhpByRefAssignRefAVLocation2,
380-
#endif
381-
#if defined(HOST_ARM64) && !defined(LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT)
382-
(uintptr_t)&RhpCheckedLockCmpXchgAVLocation2,
383-
(uintptr_t)&RhpCheckedXchgAVLocation2,
384366
#endif
385367
};
386368

src/coreclr/nativeaot/Runtime/MiscHelpers.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,3 +416,15 @@ EXTERN_C void QCALLTYPE RhCpuIdEx(int* cpuInfo, int functionId, int subFunctionI
416416
__cpuidex(cpuInfo, functionId, subFunctionId);
417417
}
418418
#endif
419+
420+
FCIMPL3(int32_t, RhpLockCmpXchg32, int32_t * location, int32_t value, int32_t comparand)
421+
{
422+
return PalInterlockedCompareExchange(location, value, comparand);
423+
}
424+
FCIMPLEND
425+
426+
FCIMPL3(int64_t, RhpLockCmpXchg64, int64_t * location, int64_t value, int64_t comparand)
427+
{
428+
return PalInterlockedCompareExchange64(location, value, comparand);
429+
}
430+
FCIMPLEND

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -221,28 +221,20 @@ LEAF_END RhpCheckedAssignRef\EXPORT_REG_NAME, _TEXT
221221
// just one write barrier that assumes the input register is RSI.
222222
DEFINE_CHECKED_WRITE_BARRIER RSI, ESI
223223

224-
// WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular:
225-
// - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpCheckedLockCmpXchgAVLocation
226-
// - Function "UnwindSimpleHelperToCaller" assumes the stack contains just the pushed return address
227224
LEAF_ENTRY RhpCheckedLockCmpXchg, _TEXT
228225
mov rax, rdx
229-
ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation
230226
lock cmpxchg [rdi], rsi
231227
jne LOCAL_LABEL(RhpCheckedLockCmpXchg_NoBarrierRequired_RSI)
232228

233229
DEFINE_CHECKED_WRITE_BARRIER_CORE RhpCheckedLockCmpXchg, RSI
234230

235231
LEAF_END RhpCheckedLockCmpXchg, _TEXT
236232

237-
// WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular:
238-
// - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpCheckedXchgAVLocation
239-
// - Function "UnwindSimpleHelperToCaller" assumes the stack contains just the pushed return address
240233
LEAF_ENTRY RhpCheckedXchg, _TEXT
241234

242235
// Setup rax with the new object for the exchange, that way it will automatically hold the correct result
243236
// afterwards and we can leave rdx unaltered ready for the GC write barrier below.
244237
mov rax, rsi
245-
ALTERNATE_ENTRY RhpCheckedXchgAVLocation
246238
xchg [rdi], rax
247239

248240
DEFINE_CHECKED_WRITE_BARRIER_CORE RhpCheckedXchg, RSI

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -237,28 +237,20 @@ endm
237237
;; just one write barrier that assumes the input register is RDX.
238238
DEFINE_CHECKED_WRITE_BARRIER RDX, EDX
239239

240-
;; WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular:
241-
;; - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpCheckedLockCmpXchgAVLocation
242-
;; - Function "UnwindSimpleHelperToCaller" assumes the stack contains just the pushed return address
243240
LEAF_ENTRY RhpCheckedLockCmpXchg, _TEXT
244241
mov rax, r8
245-
ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation
246242
lock cmpxchg [rcx], rdx
247243
jne RhpCheckedLockCmpXchg_NoBarrierRequired_RDX
248244

249245
DEFINE_CHECKED_WRITE_BARRIER_CORE RhpCheckedLockCmpXchg, RDX
250246

251247
LEAF_END RhpCheckedLockCmpXchg, _TEXT
252248

253-
;; WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular:
254-
;; - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpCheckedXchgAVLocation
255-
;; - Function "UnwindSimpleHelperToCaller" assumes the stack contains just the pushed return address
256249
LEAF_ENTRY RhpCheckedXchg, _TEXT
257250

258251
;; Setup rax with the new object for the exchange, that way it will automatically hold the correct result
259252
;; afterwards and we can leave rdx unaltered ready for the GC write barrier below.
260253
mov rax, rdx
261-
ALTERNATE_ENTRY RhpCheckedXchgAVLocation
262254
xchg [rcx], rax
263255

264256
DEFINE_CHECKED_WRITE_BARRIER_CORE RhpCheckedXchg, RDX

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

Lines changed: 0 additions & 57 deletions
This file was deleted.

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,6 @@ LEAF_END RhpCheckedAssignRef\EXPORT_REG_NAME, _TEXT
250250
// just one write barrier that assumes the input register is RSI.
251251
DEFINE_CHECKED_WRITE_BARRIER r1, r1
252252

253-
// WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular:
254-
// - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpCheckedLockCmpXchgAVLocation
255-
// - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address
256253
// r0 = destination address
257254
// r1 = value
258255
// r2 = comparand
@@ -261,7 +258,6 @@ LEAF_ENTRY RhpCheckedLockCmpXchg, _TEXT
261258
// barrier must occur before the object reference update, so we have to do it unconditionally even
262259
// though the update may fail below.
263260
dmb
264-
GLOBAL_LABEL RhpCheckedLockCmpXchgAVLocation
265261
LOCAL_LABEL(RhpCheckedLockCmpXchgRetry):
266262
ldrex r3, [r0]
267263
cmp r2, r3
@@ -277,16 +273,12 @@ LOCAL_LABEL(RhpCheckedLockCmpXchgRetry):
277273
bx lr
278274
LEAF_END RhpCheckedLockCmpXchg, _TEXT
279275

280-
// WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular:
281-
// - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpCheckedXchgAVLocation
282-
// - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address
283276
// r0 = destination address
284277
// r1 = value
285278
LEAF_ENTRY RhpCheckedXchg, _TEXT
286279
// To implement our chosen memory model for ARM we insert a memory barrier at GC write barriers. This
287280
// barrier must occur before the object reference update.
288281
dmb
289-
GLOBAL_LABEL RhpCheckedXchgAVLocation
290282
LOCAL_LABEL(RhpCheckedXchgRetry):
291283
ldrex r2, [r0]
292284
strex r3, r1, [r0]

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,6 @@ LEAF_END RhpAssignRef, _TEXT
302302
#endif
303303

304304
mov x10, x2
305-
ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation
306305
casal x10, x1, [x0] // exchange
307306
cmp x2, x10
308307
bne LOCAL_LABEL(CmpXchgNoUpdate)
@@ -311,7 +310,6 @@ LEAF_END RhpAssignRef, _TEXT
311310
b LOCAL_LABEL(DoCardsCmpXchg)
312311
LOCAL_LABEL(CmpXchgRetry):
313312
// Check location value is what we expect.
314-
ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation2
315313
ldaxr x10, [x0]
316314
cmp x10, x2
317315
bne LOCAL_LABEL(CmpXchgNoUpdate)
@@ -365,14 +363,12 @@ LOCAL_LABEL(NoBarrierCmpXchg):
365363
tbz w16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, LOCAL_LABEL(ExchangeRetry)
366364
#endif
367365

368-
ALTERNATE_ENTRY RhpCheckedXchgAVLocation
369366
swpal x1, x10, [x0] // exchange
370367

371368
#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT
372369
b LOCAL_LABEL(DoCardsXchg)
373370
LOCAL_LABEL(ExchangeRetry):
374371
// Read the existing memory location.
375-
ALTERNATE_ENTRY RhpCheckedXchgAVLocation2
376372
ldaxr x10, [x0]
377373

378374
// Attempt to update with the new value.

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,6 @@ NotInHeap
286286
;; Interlocked operation helpers where the location is an objectref, thus requiring a GC write barrier upon
287287
;; successful updates.
288288

289-
;; WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular:
290-
;; - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpCheckedLockCmpXchgAVLocation
291-
;; - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address
292-
293289
;; RhpCheckedLockCmpXchg(Object** dest, Object* value, Object* comparand)
294290
;;
295291
;; Interlocked compare exchange on objectref.
@@ -311,7 +307,6 @@ NotInHeap
311307
#endif
312308

313309
mov x10, x2
314-
ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation
315310
casal x10, x1, [x0] ;; exchange
316311
cmp x2, x10
317312
bne CmpXchgNoUpdate
@@ -320,7 +315,6 @@ NotInHeap
320315
b DoCardsCmpXchg
321316
CmpXchgRetry
322317
;; Check location value is what we expect.
323-
ALTERNATE_ENTRY RhpCheckedLockCmpXchgAVLocation2
324318
ldaxr x10, [x0]
325319
cmp x10, x2
326320
bne CmpXchgNoUpdate
@@ -350,10 +344,6 @@ NoBarrierCmpXchg
350344

351345
LEAF_END RhpCheckedLockCmpXchg
352346

353-
;; WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular:
354-
;; - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen within at RhpCheckedXchgAVLocation
355-
;; - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address
356-
357347
;; RhpCheckedXchg(Object** destination, Object* value)
358348
;;
359349
;; Interlocked exchange on objectref.
@@ -374,14 +364,12 @@ NoBarrierCmpXchg
374364
tbz x16, #ARM64_ATOMICS_FEATURE_FLAG_BIT, ExchangeRetry
375365
#endif
376366

377-
ALTERNATE_ENTRY RhpCheckedXchgAVLocation
378367
swpal x1, x10, [x0] ;; exchange
379368

380369
#ifndef LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT
381370
b DoCardsXchg
382371
ExchangeRetry
383372
;; Read the existing memory location.
384-
ALTERNATE_ENTRY RhpCheckedXchgAVLocation2
385373
ldaxr x10, [x0]
386374

387375
;; Attempt to update with the new value.

src/coreclr/nativeaot/Runtime/i386/Interlocked.S

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)