Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion docs/design/coreclr/botr/readytorun-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ enum ReadyToRunHelper
// Write barriers
READYTORUN_HELPER_WriteBarrier = 0x30,
READYTORUN_HELPER_CheckedWriteBarrier = 0x31,
READYTORUN_HELPER_ByRefWriteBarrier = 0x32,
READYTORUN_HELPER_ByRefWriteBarrier = 0x32, // Unused since READYTORUN_MAJOR_VERSION 19.0

// Array helpers
READYTORUN_HELPER_Stelem_Ref = 0x38,
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,6 @@ enum CorInfoHelpFunc
CORINFO_HELP_ASSIGN_REF, // universal helpers with F_CALL_CONV calling convention
CORINFO_HELP_CHECKED_ASSIGN_REF,

CORINFO_HELP_ASSIGN_BYREF,
CORINFO_HELP_BULK_WRITEBARRIER,

/* Accessing fields */
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@

#include <minipal/guid.h>

constexpr GUID JITEEVersionIdentifier = { /* fc5f63e7-921b-4091-b920-8df8d7b872c1 */
0xfc5f63e7,
0x921b,
0x4091,
{0xb9, 0x20, 0x8d, 0xf8, 0xd7, 0xb8, 0x72, 0xc1}
constexpr GUID JITEEVersionIdentifier = { /* 31a04b06-915e-42a0-bbd2-c9c397677ae5 */
0x31a04b06,
0x915e,
0x42a0,
{0xbb, 0xd2, 0xc9, 0xc3, 0x97, 0x67, 0x7a, 0xe5}
};

#endif // JIT_EE_VERSIONING_GUID_H
6 changes: 0 additions & 6 deletions src/coreclr/inc/jithelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,6 @@
DYNAMICJITHELPER(CORINFO_HELP_ASSIGN_REF, RhpAssignRef, METHOD__NIL)
DYNAMICJITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF, RhpCheckedAssignRef,METHOD__NIL)

#ifdef TARGET_WASM
JITHELPER(CORINFO_HELP_ASSIGN_BYREF, NULL, METHOD__NIL)
#else
DYNAMICJITHELPER(CORINFO_HELP_ASSIGN_BYREF, RhpByRefAssignRef,METHOD__NIL)
#endif // TARGET_WASM

DYNAMICJITHELPER(CORINFO_HELP_BULK_WRITEBARRIER, NULL, METHOD__BUFFER__MEMCOPYGC)

// Accessing fields
Expand Down
9 changes: 5 additions & 4 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 18
#define READYTORUN_MINOR_VERSION 0x0007
#define READYTORUN_MAJOR_VERSION 19
#define READYTORUN_MINOR_VERSION 0x0000

#define MINIMUM_READYTORUN_MAJOR_VERSION 18
#define MINIMUM_READYTORUN_MAJOR_VERSION 19
Comment thread
EgorBo marked this conversation as resolved.
Comment thread
EgorBo marked this conversation as resolved.
Comment thread
EgorBo marked this conversation as resolved.

// R2R Version 2.1 adds the InliningInfo section
// R2R Version 2.2 adds the ProfileDataInfo section
Expand Down Expand Up @@ -58,6 +58,7 @@
// R2R Version 18.5 adds READYTORUN_FLAG_STRIPPED_IL_BODIES, READYTORUN_FLAG_STRIPPED_INLINING_INFO, and READYTORUN_FLAG_STRIPPED_DEBUG_INFO flags
// R2R Version 18.6 adds READYTORUN_FIXUP_InjectStringThunks for mapping strings to pregenerated code thunks
// R2R Version 18.7 adds READYTORUN_HELPER_R2RToInterpreter
// R2R Version 19 removes the READYTORUN_HELPER_ByRefWriteBarrier helper

struct READYTORUN_CORE_HEADER
{
Expand Down Expand Up @@ -363,7 +364,7 @@ enum ReadyToRunHelper
// Write barriers
READYTORUN_HELPER_WriteBarrier = 0x30,
READYTORUN_HELPER_CheckedWriteBarrier = 0x31,
READYTORUN_HELPER_ByRefWriteBarrier = 0x32,
READYTORUN_HELPER_ByRefWriteBarrier = 0x32, // No longer supported as of READYTORUN_MAJOR_VERSION 19.0
READYTORUN_HELPER_BulkWriteBarrier = 0x33,

// Array helpers
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/inc/readytorunhelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ HELPER(READYTORUN_HELPER_ThrowNotImplemented, CORINFO_HELP_THROW_NOT_IMPLE

HELPER(READYTORUN_HELPER_WriteBarrier, CORINFO_HELP_ASSIGN_REF, )
HELPER(READYTORUN_HELPER_CheckedWriteBarrier, CORINFO_HELP_CHECKED_ASSIGN_REF, )
HELPER(READYTORUN_HELPER_ByRefWriteBarrier, CORINFO_HELP_ASSIGN_BYREF, )
HELPER(READYTORUN_HELPER_BulkWriteBarrier, CORINFO_HELP_BULK_WRITEBARRIER, )

HELPER(READYTORUN_HELPER_Stelem_Ref, CORINFO_HELP_ARRADDR_ST, )
Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/jit/codegenwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3222,8 +3222,6 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp)
emit->emitIns_I(INS_local_get, EA_PTRSIZE, WasmRegToIndex(destReg));
emit->emitIns_I(INS_I_const, EA_PTRSIZE, destOffset);
emit->emitIns(INS_I_add);
// Do an I_load here instead of I_const + I_add because we're using the (Object **, Object *) write barrier,
// not the (Object **, Object **) BYREF write barrier used on other architectures.
emit->emitIns_I(INS_local_get, EA_PTRSIZE, WasmRegToIndex(srcReg));
emit->emitIns_I(INS_I_load, EA_PTRSIZE, srcOffset);
// NOTE: This helper's signature omits SP/PEP so all we need on the stack is dst and ref.
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/jit/targetarm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@
// x15: the object reference to be stored
// On exit:
// x12: trashed
// x14: incremented by 8
// x14: preserved (the destination address is not modified)
// x15: trashed
// x17: trashed (ip1) if FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
//
Expand All @@ -175,7 +175,8 @@
#define RBM_CALLEE_TRASH_NOGC (RBM_R12|RBM_R15|RBM_IP0|RBM_IP1|RBM_DEFAULT_HELPER_CALL_TARGET)

// Registers killed by CORINFO_HELP_ASSIGN_REF and CORINFO_HELP_CHECKED_ASSIGN_REF.
#define RBM_CALLEE_TRASH_WRITEBARRIER (RBM_R14|RBM_CALLEE_TRASH_NOGC)
// Note: the destination register (x14) is preserved by the helper, so it is not in the kill set.
#define RBM_CALLEE_TRASH_WRITEBARRIER RBM_CALLEE_TRASH_NOGC

// Registers no longer containing GC pointers after CORINFO_HELP_ASSIGN_REF and CORINFO_HELP_CHECKED_ASSIGN_REF.
#define RBM_CALLEE_GCTRASH_WRITEBARRIER RBM_CALLEE_TRASH_NOGC
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/jit/targetloongarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
// t1: trashed
// t3: trashed
// t4: trashed
// t6: incremented by 8
// t6: preserved (the destination address is not modified)
// t7: trashed
//

Expand All @@ -156,7 +156,8 @@
#define RBM_CALLEE_TRASH_NOGC (RBM_T0|RBM_T1|RBM_T3|RBM_T4|RBM_T7|RBM_DEFAULT_HELPER_CALL_TARGET)

// Registers killed by CORINFO_HELP_ASSIGN_REF and CORINFO_HELP_CHECKED_ASSIGN_REF.
#define RBM_CALLEE_TRASH_WRITEBARRIER (RBM_WRITE_BARRIER_DST|RBM_CALLEE_TRASH_NOGC)
// Note: the destination register (t6) is preserved by the helper, so it is not in the kill set.
#define RBM_CALLEE_TRASH_WRITEBARRIER RBM_CALLEE_TRASH_NOGC

// Registers no longer containing GC pointers after CORINFO_HELP_ASSIGN_REF and CORINFO_HELP_CHECKED_ASSIGN_REF.
#define RBM_CALLEE_GCTRASH_WRITEBARRIER RBM_CALLEE_TRASH_NOGC
Expand Down
16 changes: 15 additions & 1 deletion src/coreclr/jit/targetriscv64.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,19 @@
#define REG_JUMP_THUNK_PARAM REG_T2
#define RBM_JUMP_THUNK_PARAM RBM_T2

// RISCV64 write barrier ABI (see vm/riscv64/asmhelpers.S):
// CORINFO_HELP_ASSIGN_REF (JIT_WriteBarrier), CORINFO_HELP_CHECKED_ASSIGN_REF (JIT_CheckedWriteBarrier):
// On entry:
// t3: the destination address of the store
// t4: the object reference to be stored
// On exit:
// t0: trashed
// t1: trashed
// t3: preserved (the destination address is not modified)
// t4: trashed
// t6: trashed
//

#define REG_WRITE_BARRIER_DST REG_T3
#define RBM_WRITE_BARRIER_DST RBM_T3

Expand All @@ -138,7 +151,8 @@
#define RBM_CALLEE_TRASH_NOGC (RBM_T0|RBM_T1|RBM_T2|RBM_T4|RBM_T6|RBM_DEFAULT_HELPER_CALL_TARGET)

// Registers killed by CORINFO_HELP_ASSIGN_REF and CORINFO_HELP_CHECKED_ASSIGN_REF.
#define RBM_CALLEE_TRASH_WRITEBARRIER (RBM_WRITE_BARRIER_DST|RBM_CALLEE_TRASH_NOGC)
// Note: the destination register (t3) is preserved by the helper, so it is not in the kill set.
#define RBM_CALLEE_TRASH_WRITEBARRIER RBM_CALLEE_TRASH_NOGC

// Registers no longer containing GC pointers after CORINFO_HELP_ASSIGN_REF and CORINFO_HELP_CHECKED_ASSIGN_REF.
#define RBM_CALLEE_GCTRASH_WRITEBARRIER RBM_CALLEE_TRASH_NOGC
Expand Down
9 changes: 0 additions & 9 deletions src/coreclr/nativeaot/Runtime/EHHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,6 @@ EXTERN_C CODE_LOCATION RhpCheckedAssignRefESIAVLocation;
EXTERN_C CODE_LOCATION RhpCheckedAssignRefEDIAVLocation;
EXTERN_C CODE_LOCATION RhpCheckedAssignRefEBPAVLocation;
#endif
EXTERN_C CODE_LOCATION RhpByRefAssignRefAVLocation1;

#if !defined(HOST_ARM64) && !defined(HOST_LOONGARCH64) && !defined(HOST_RISCV64)
EXTERN_C CODE_LOCATION RhpByRefAssignRefAVLocation2;
#endif

#if defined(HOST_ARM64) && !defined(LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT)
EXTERN_C CODE_LOCATION RhpCheckedLockCmpXchgAVLocation2;
Expand Down Expand Up @@ -252,10 +247,6 @@ static bool InWriteBarrierHelper(uintptr_t faultingIP)
(uintptr_t)&RhpCheckedAssignRefESIAVLocation,
(uintptr_t)&RhpCheckedAssignRefEDIAVLocation,
(uintptr_t)&RhpCheckedAssignRefEBPAVLocation,
#endif
(uintptr_t)&RhpByRefAssignRefAVLocation1,
#if !defined(HOST_ARM64) && !defined(HOST_LOONGARCH64) && !defined(HOST_RISCV64)
(uintptr_t)&RhpByRefAssignRefAVLocation2,
#endif
};

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ struct ReadyToRunHeaderConstants
{
static const uint32_t Signature = 0x00525452; // 'RTR'

static const uint32_t CurrentMajorVersion = 18;
static const uint32_t CurrentMinorVersion = 7;
static const uint32_t CurrentMajorVersion = 19;
static const uint32_t CurrentMinorVersion = 0;
};

struct ReadyToRunHeader
Expand Down
93 changes: 0 additions & 93 deletions src/coreclr/runtime/amd64/WriteBarriers.S
Original file line number Diff line number Diff line change
Expand Up @@ -249,96 +249,3 @@ LEAF_ENTRY RhpCheckedXchg, _TEXT

LEAF_END RhpCheckedXchg, _TEXT

//
// RhpByRefAssignRef simulates movs instruction for object references.
//
// On entry:
// rdi: address of ref-field (assigned to)
// rsi: address of the data (source)
//
// On exit:
// rdi, rsi are incremented by 8,
// rcx, rax: trashed
//
// NOTE: Keep in sync with RBM_CALLEE_TRASH_WRITEBARRIER_BYREF and RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF
// if you add more trashed registers.
//
// WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular:
// - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpByRefAssignRefAVLocation1/2
// - Function "UnwindSimpleHelperToCaller" assumes the stack contains just the pushed return address
LEAF_ENTRY RhpByRefAssignRef, _TEXT
ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1
mov rcx, [rsi]
#ifdef TARGET_APPLE
// Apple's linker has issues which break unwind info if
// an ALTERNATE_ENTRY is present in the middle of a function see https://github.com/dotnet/runtime/pull/114982#discussion_r2083272768
.cfi_endproc
#endif
ALTERNATE_ENTRY RhpByRefAssignRefAVLocation2
#ifdef TARGET_APPLE
.cfi_startproc
#endif
mov [rdi], rcx

// Check whether the writes were even into the heap. If not there's no card update required.
cmp rdi, [C_VAR(g_lowest_address)]
jb LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired)
cmp rdi, [C_VAR(g_highest_address)]
jae LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired)

// Update the shadow copy of the heap with the same value just written to the same heap. (A no-op unless
// we're in a debug build and write barrier checking has been enabled).
UPDATE_GC_SHADOW BASENAME, rcx, rdi

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
cmp qword ptr [C_VAR(g_write_watch_table)], 0x0
je LOCAL_LABEL(RhpByRefAssignRef_CheckCardTable)

mov rax, rdi
shr rax, 0xC // SoftwareWriteWatch::AddressToTableByteIndexShift
add rax, [C_VAR(g_write_watch_table)]
cmp byte ptr [rax], 0x0
jne LOCAL_LABEL(RhpByRefAssignRef_CheckCardTable)
mov byte ptr [rax], 0xFF
#endif

LOCAL_LABEL(RhpByRefAssignRef_CheckCardTable):

// If the reference is to an object that's not in an ephemeral generation we have no need to track it
// (since the object won't be collected or moved by an ephemeral collection).
cmp rcx, [C_VAR(g_ephemeral_low)]
jb LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired)
cmp rcx, [C_VAR(g_ephemeral_high)]
jae LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired)

// move current rdi value into rcx, we need to keep rdi and eventually increment by 8
mov rcx, rdi

// We have a location on the GC heap being updated with a reference to an ephemeral object so we must
// track this write. The location address is translated into an offset in the card table bitmap. We set
// an entire byte in the card table since it's quicker than messing around with bitmasks and we only write
// the byte if it hasn't already been done since writes are expensive and impact scaling.
shr rcx, 0x0B
mov rax, [C_VAR(g_card_table)]
cmp byte ptr [rcx + rax], 0x0FF
je LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired)

// We get here if it's necessary to update the card table.
mov byte ptr [rcx + rax], 0xFF

#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
// Shift rcx by 0x0A more to get the card bundle byte (we shifted by 0x0B already)
shr rcx, 0x0A
add rcx, [C_VAR(g_card_bundle_table)]
cmp byte ptr [rcx], 0xFF
je LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired)

mov byte ptr [rcx], 0xFF
#endif

LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired):
// Increment the pointers before leaving
add rdi, 0x8
add rsi, 0x8
ret
LEAF_END RhpByRefAssignRef, _TEXT
86 changes: 0 additions & 86 deletions src/coreclr/runtime/amd64/WriteBarriers.asm
Original file line number Diff line number Diff line change
Expand Up @@ -257,90 +257,4 @@ LEAF_ENTRY RhpCheckedXchg, _TEXT

LEAF_END RhpCheckedXchg, _TEXT

;;
;; RhpByRefAssignRef simulates movs instruction for object references.
;;
;; On entry:
;; rdi: address of ref-field (assigned to)
;; rsi: address of the data (source)
;;
;; On exit:
;; rdi, rsi are incremented by 8,
;; rcx, rax: trashed
;;
;; NOTE: Keep in sync with RBM_CALLEE_TRASH_WRITEBARRIER_BYREF and RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF
;; if you add more trashed registers.
;;
;; WARNING: Code in EHHelpers.cpp makes assumptions about write barrier code, in particular:
;; - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpByRefAssignRefAVLocation1/2
;; - Function "UnwindSimpleHelperToCaller" assumes the stack contains just the pushed return address
LEAF_ENTRY RhpByRefAssignRef, _TEXT
ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1
mov rcx, [rsi]
ALTERNATE_ENTRY RhpByRefAssignRefAVLocation2
mov [rdi], rcx

;; Check whether the writes were even into the heap. If not there's no card update required.
cmp rdi, [g_lowest_address]
jb RhpByRefAssignRef_NoBarrierRequired
cmp rdi, [g_highest_address]
jae RhpByRefAssignRef_NoBarrierRequired

;; Update the shadow copy of the heap with the same value just written to the same heap. (A no-op unless
;; we're in a debug build and write barrier checking has been enabled).
UPDATE_GC_SHADOW BASENAME, rcx, rdi

ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
cmp [g_write_watch_table], 0
je RhpByRefAssignRef_CheckCardTable

mov rax, rdi
shr rax, 0Ch ;; SoftwareWriteWatch::AddressToTableByteIndexShift
add rax, [g_write_watch_table]
cmp byte ptr [rax], 0
jne RhpByRefAssignRef_CheckCardTable
mov byte ptr [rax], 0FFh
endif

RhpByRefAssignRef_CheckCardTable:

;; If the reference is to an object that's not in an ephemeral generation we have no need to track it
;; (since the object won't be collected or moved by an ephemeral collection).
cmp rcx, [g_ephemeral_low]
jb RhpByRefAssignRef_NoBarrierRequired
cmp rcx, [g_ephemeral_high]
jae RhpByRefAssignRef_NoBarrierRequired

;; move current rdi value into rcx, we need to keep rdi and eventually increment by 8
mov rcx, rdi

;; We have a location on the GC heap being updated with a reference to an ephemeral object so we must
;; track this write. The location address is translated into an offset in the card table bitmap. We set
;; an entire byte in the card table since it's quicker than messing around with bitmasks and we only write
;; the byte if it hasn't already been done since writes are expensive and impact scaling.
shr rcx, 0Bh
mov rax, [g_card_table]
cmp byte ptr [rcx + rax], 0FFh
je RhpByRefAssignRef_NoBarrierRequired

;; We get here if it's necessary to update the card table.
mov byte ptr [rcx + rax], 0FFh

ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0Bh already)
shr rcx, 0Ah
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je RhpByRefAssignRef_NoBarrierRequired

mov byte ptr [rcx], 0FFh
endif

RhpByRefAssignRef_NoBarrierRequired:
;; Increment the pointers before leaving
add rdi, 8h
add rsi, 8h
ret
LEAF_END RhpByRefAssignRef, _TEXT

end
Loading
Loading