diff --git a/docs/design/coreclr/botr/readytorun-format.md b/docs/design/coreclr/botr/readytorun-format.md index 59dead55ab2bf3..a165b7c5d61502 100644 --- a/docs/design/coreclr/botr/readytorun-format.md +++ b/docs/design/coreclr/botr/readytorun-format.md @@ -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, diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index a5b039ce632298..5ac1524d19c6f1 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -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 */ diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 9816fd7d1744fa..3f1d8e566f18f4 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -37,11 +37,11 @@ #include -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 diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index 9e449ab9f6dac0..281302ccbc742c 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -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 diff --git a/src/coreclr/inc/readytorun.h b/src/coreclr/inc/readytorun.h index ebcec465ce4e2a..44808a73fbe821 100644 --- a/src/coreclr/inc/readytorun.h +++ b/src/coreclr/inc/readytorun.h @@ -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 // R2R Version 2.1 adds the InliningInfo section // R2R Version 2.2 adds the ProfileDataInfo section @@ -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 { @@ -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 diff --git a/src/coreclr/inc/readytorunhelpers.h b/src/coreclr/inc/readytorunhelpers.h index e4402eaf0743e7..4c3fca575d0ae5 100644 --- a/src/coreclr/inc/readytorunhelpers.h +++ b/src/coreclr/inc/readytorunhelpers.h @@ -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, ) diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index 58136ff77820b0..e8f750d8f9e9dd 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -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. diff --git a/src/coreclr/jit/targetarm64.h b/src/coreclr/jit/targetarm64.h index 1102fc888a9533..b9f2d9a54ea7a3 100644 --- a/src/coreclr/jit/targetarm64.h +++ b/src/coreclr/jit/targetarm64.h @@ -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 // @@ -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 diff --git a/src/coreclr/jit/targetloongarch64.h b/src/coreclr/jit/targetloongarch64.h index a130a9cc2c3f68..dbec9053238b42 100644 --- a/src/coreclr/jit/targetloongarch64.h +++ b/src/coreclr/jit/targetloongarch64.h @@ -143,7 +143,7 @@ // t1: trashed // t3: trashed // t4: trashed -// t6: incremented by 8 +// t6: preserved (the destination address is not modified) // t7: trashed // @@ -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 diff --git a/src/coreclr/jit/targetriscv64.h b/src/coreclr/jit/targetriscv64.h index d81b12b947cc31..32532c6f4a84a6 100644 --- a/src/coreclr/jit/targetriscv64.h +++ b/src/coreclr/jit/targetriscv64.h @@ -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 @@ -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 diff --git a/src/coreclr/nativeaot/Runtime/EHHelpers.cpp b/src/coreclr/nativeaot/Runtime/EHHelpers.cpp index 8d9ecb261f9783..30d6ab453632bd 100644 --- a/src/coreclr/nativeaot/Runtime/EHHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/EHHelpers.cpp @@ -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; @@ -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 }; diff --git a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h index 27eac374c5893d..ba32bc4e904442 100644 --- a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h +++ b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h @@ -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 diff --git a/src/coreclr/runtime/amd64/WriteBarriers.S b/src/coreclr/runtime/amd64/WriteBarriers.S index c15ee30e5dffea..cbcca9970114a7 100644 --- a/src/coreclr/runtime/amd64/WriteBarriers.S +++ b/src/coreclr/runtime/amd64/WriteBarriers.S @@ -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 diff --git a/src/coreclr/runtime/amd64/WriteBarriers.asm b/src/coreclr/runtime/amd64/WriteBarriers.asm index c08109d65ea62b..ec5c81296c5231 100644 --- a/src/coreclr/runtime/amd64/WriteBarriers.asm +++ b/src/coreclr/runtime/amd64/WriteBarriers.asm @@ -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 diff --git a/src/coreclr/runtime/arm/WriteBarriers.S b/src/coreclr/runtime/arm/WriteBarriers.S index 30afebc760d0a1..ee906187b99271 100644 --- a/src/coreclr/runtime/arm/WriteBarriers.S +++ b/src/coreclr/runtime/arm/WriteBarriers.S @@ -252,78 +252,3 @@ LOCAL_LABEL(RhpCheckedXchgRetry): LEAF_END RhpCheckedXchg, _TEXT #endif // FEATURE_NATIVEAOT -// -// RhpByRefAssignRef simulates movs instruction for object references. -// -// On entry: -// r0: address of ref-field (assigned to) -// r1: address of the data (source) -// r2, r3: be trashed -// -// On exit: -// r0, r1 are incremented by 4, -// r2, r3: trashed -// -// 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 no registers were pushed and LR contains the return address -LEAF_ENTRY RhpByRefAssignRef, _TEXT - // See comment in RhpAssignRef - dmb - -GLOBAL_LABEL RhpByRefAssignRefAVLocation1 - ldr r2, [r1] -GLOBAL_LABEL RhpByRefAssignRefAVLocation2 - str r2, [r0] - - // Check whether the writes were even into the heap. If not there's no card update required. - PREPARE_EXTERNAL_VAR_INDIRECT g_lowest_address, r3 - cmp r0, r3 - blo LOCAL_LABEL(RhpByRefAssignRef_NotInHeap) - PREPARE_EXTERNAL_VAR_INDIRECT g_highest_address, r3 - cmp r0, r3 - bhs LOCAL_LABEL(RhpByRefAssignRef_NotInHeap) - - // 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, r2, r0 - - UPDATE_WRITE_WATCH_TABLE r0, r12, r3 - - // 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). - PREPARE_EXTERNAL_VAR_INDIRECT g_ephemeral_low, r3 - cmp r2, r3 - blo LOCAL_LABEL(RhpByRefAssignRef_NotInHeap) - PREPARE_EXTERNAL_VAR_INDIRECT g_ephemeral_high, r3 - cmp r2, r3 - bhs LOCAL_LABEL(RhpByRefAssignRef_NotInHeap) - - // move current r0 value into r2 and then increment the pointers - mov r2, r0 - add r1, #4 - add r0, #4 - - // 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. - PREPARE_EXTERNAL_VAR_INDIRECT g_card_table, r3 - add r2, r3, r2, lsr #10 - ldrb r3, [r2] - cmp r3, #0x0FF - bne LOCAL_LABEL(RhpByRefAssignRef_UpdateCardTable) - bx lr - -// We get here if it's necessary to update the card table. -LOCAL_LABEL(RhpByRefAssignRef_UpdateCardTable): - mov r3, #0x0FF - strb r3, [r2] - bx lr - -LOCAL_LABEL(RhpByRefAssignRef_NotInHeap): - // Increment the pointers before leaving - add r0, #4 - add r1, #4 - bx lr -LEAF_END RhpByRefAssignRef, _TEXT diff --git a/src/coreclr/runtime/arm64/WriteBarriers.S b/src/coreclr/runtime/arm64/WriteBarriers.S index 74ab04fad7fa47..1fb11043fe07f7 100644 --- a/src/coreclr/runtime/arm64/WriteBarriers.S +++ b/src/coreclr/runtime/arm64/WriteBarriers.S @@ -187,31 +187,6 @@ // Exit label .endm -// void RhpByRefAssignRef -// On entry: -// x13 : the source address (points to object reference to write) -// x14 : the destination address (object reference written here) -// -// On exit: -// x13 : incremented by 8 -// x14 : incremented by 8 -// x15 : trashed -// x12, x17 : 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 -// - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address -LEAF_ENTRY RhpByRefAssignRefArm64, _TEXT - - ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1 - ldr x15, [x13], 8 - b C_FUNC(RhpCheckedAssignRefArm64) - -LEAF_END RhpByRefAssignRefArm64, _TEXT - // RhpCheckedAssignRef(Object** dst, Object* src) // // Write barrier for writes to objects that may reside @@ -224,7 +199,7 @@ LEAF_END RhpByRefAssignRefArm64, _TEXT // // On exit: // x12, x17 : trashed -// x14 : incremented by 8 +// x14 : preserved (the destination address is not modified) LEAF_ENTRY RhpCheckedAssignRefArm64, _TEXT // is destReg within the heap? @@ -246,7 +221,7 @@ LOCAL_LABEL(NotInHeap): #ifdef TARGET_APPLE .cfi_startproc #endif - str x15, [x14], 8 + str x15, [x14] ret LEAF_END RhpCheckedAssignRefArm64, _TEXT @@ -261,7 +236,7 @@ LEAF_END RhpCheckedAssignRefArm64, _TEXT // // On exit: // x12, x17 : trashed -// x14 : incremented by 8 +// x14 : preserved (the destination address is not modified) LEAF_ENTRY RhpAssignRefArm64, _TEXT ALTERNATE_ENTRY RhpAssignRefAVLocation @@ -269,7 +244,6 @@ LEAF_ENTRY RhpAssignRefArm64, _TEXT INSERT_UNCHECKED_WRITE_BARRIER_CORE x14, x15 - add x14, x14, 8 ret LEAF_END RhpAssignRefArm64, _TEXT diff --git a/src/coreclr/runtime/arm64/WriteBarriers.asm b/src/coreclr/runtime/arm64/WriteBarriers.asm index 0d7d39db9da98f..55caf1a6811f49 100644 --- a/src/coreclr/runtime/arm64/WriteBarriers.asm +++ b/src/coreclr/runtime/arm64/WriteBarriers.asm @@ -189,32 +189,6 @@ INVALIDGCVALUE EQU 0xCCCCCCCD ;; Exit label MEND -;; void RhpByRefAssignRef -;; On entry: -;; x13 : the source address (points to object reference to write) -;; x14 : the destination address (object reference written here) -;; -;; On exit: -;; x13 : incremented by 8 -;; x14 : incremented by 8 -;; x15 : trashed -;; x12, x17 : 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 -;; - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address - LEAF_ENTRY RhpByRefAssignRefArm64 - - ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1 - ldr x15, [x13], 8 - b RhpCheckedAssignRefArm64 - - LEAF_END RhpByRefAssignRefArm64 - - ;; RhpCheckedAssignRef(Object** dst, Object* src) ;; ;; Write barrier for writes to objects that may reside @@ -227,7 +201,7 @@ INVALIDGCVALUE EQU 0xCCCCCCCD ;; ;; On exit: ;; x12, x17 : trashed -;; x14 : incremented by 8 +;; x14 : preserved (the destination address is not modified) LEAF_ENTRY RhpCheckedAssignRefArm64 ;; is destReg within the heap? @@ -239,7 +213,7 @@ INVALIDGCVALUE EQU 0xCCCCCCCD NotInHeap ALTERNATE_ENTRY RhpCheckedAssignRefAVLocation - str x15, [x14], 8 + str x15, [x14] ret LEAF_END RhpCheckedAssignRefArm64 @@ -255,7 +229,7 @@ NotInHeap ;; ;; On exit: ;; x12, x17 : trashed -;; x14 : incremented by 8 +;; x14 : preserved (the destination address is not modified) LEAF_ENTRY RhpAssignRefArm64 ALTERNATE_ENTRY RhpAssignRefAVLocation @@ -263,7 +237,6 @@ NotInHeap INSERT_UNCHECKED_WRITE_BARRIER_CORE x14, x15 - add x14, x14, 8 ret LEAF_END RhpAssignRefArm64 diff --git a/src/coreclr/runtime/i386/WriteBarriers.S b/src/coreclr/runtime/i386/WriteBarriers.S index e9bad9c715db2a..a848632aeb8ca4 100644 --- a/src/coreclr/runtime/i386/WriteBarriers.S +++ b/src/coreclr/runtime/i386/WriteBarriers.S @@ -246,57 +246,3 @@ LEAF_ENTRY RhpCheckedXchg, _TEXT ret LEAF_END RhpCheckedXchg, _TEXT -// -// RhpByRefAssignRef simulates movs instruction for object references. -// -// On entry: -// edi: address of ref-field (assigned to) -// esi: address of the data (source) -// -// On exit: -// edi, esi are incremented by 4, -// ecx: trashed -// -LEAF_ENTRY RhpByRefAssignRef, _TEXT -ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1 - mov ecx, [esi] -ALTERNATE_ENTRY RhpByRefAssignRefAVLocation2 - mov [edi], ecx - - push eax - - // Check whether the writes were even into the heap. If not there's no card update required. - PREPARE_EXTERNAL_VAR g_lowest_address, eax - cmp edi, [eax] - jb LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired) - PREPARE_EXTERNAL_VAR g_highest_address, eax - cmp edi, [eax] - jae LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired) - - UPDATE_GC_SHADOW RhpByRefAssignRef, ecx, edi, eax - - // 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). - PREPARE_EXTERNAL_VAR g_ephemeral_low, eax - cmp ecx, [eax] - jb LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired) - PREPARE_EXTERNAL_VAR g_ephemeral_high, eax - cmp ecx, [eax] - jae LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired) - - mov ecx, edi - shr ecx, 10 - PREPARE_EXTERNAL_VAR g_card_table, eax - add ecx, [eax] - cmp byte ptr [ecx], 0xFF - je LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired) - - mov byte ptr [ecx], 0xFF - -LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired): - // Increment the pointers before leaving - add esi,4 - add edi,4 - pop eax - ret -LEAF_END RhpByRefAssignRef, _TEXT diff --git a/src/coreclr/runtime/i386/WriteBarriers.asm b/src/coreclr/runtime/i386/WriteBarriers.asm index 6437762161626f..c9a38eae56fc95 100644 --- a/src/coreclr/runtime/i386/WriteBarriers.asm +++ b/src/coreclr/runtime/i386/WriteBarriers.asm @@ -258,51 +258,4 @@ FASTCALL_FUNC RhpCheckedXchg, 8 FASTCALL_ENDFUNC -;; -;; RhpByRefAssignRef simulates movs instruction for object references. -;; -;; On entry: -;; edi: address of ref-field (assigned to) -;; esi: address of the data (source) -;; -;; On exit: -;; edi, esi are incremented by 4, -;; ecx: trashed -;; -FASTCALL_FUNC RhpByRefAssignRef, 8 -ALTERNATE_ENTRY _RhpByRefAssignRefAVLocation1 - mov ecx, [esi] -ALTERNATE_ENTRY _RhpByRefAssignRefAVLocation2 - mov [edi], ecx - - ;; Check whether the writes were even into the heap. If not there's no card update required. - cmp edi, [G_LOWEST_ADDRESS] - jb RhpByRefAssignRef_NoBarrierRequired - cmp edi, [G_HIGHEST_ADDRESS] - jae RhpByRefAssignRef_NoBarrierRequired - - UPDATE_GC_SHADOW BASENAME, ecx, edi - - ;; 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 ecx, [G_EPHEMERAL_LOW] - jb RhpByRefAssignRef_NoBarrierRequired - cmp ecx, [G_EPHEMERAL_HIGH] - jae RhpByRefAssignRef_NoBarrierRequired - - mov ecx, edi - shr ecx, 10 - add ecx, [G_CARD_TABLE] - cmp byte ptr [ecx], 0FFh - je RhpByRefAssignRef_NoBarrierRequired - - mov byte ptr [ecx], 0FFh - -RhpByRefAssignRef_NoBarrierRequired: - ;; Increment the pointers before leaving - add esi,4 - add edi,4 - ret -FASTCALL_ENDFUNC - end diff --git a/src/coreclr/runtime/loongarch64/WriteBarriers.S b/src/coreclr/runtime/loongarch64/WriteBarriers.S index b7ffa658921c8c..0680b77d922589 100644 --- a/src/coreclr/runtime/loongarch64/WriteBarriers.S +++ b/src/coreclr/runtime/loongarch64/WriteBarriers.S @@ -177,32 +177,6 @@ // Exit label .endm -// void RhpByRefAssignRef -// On entry: -// t8 : the source address (points to object reference to write) -// t6 : the destination address (object reference written here) -// -// On exit: -// t8 : incremented by 8 -// t6 : incremented by 8 -// t7 : trashed -// t3, t4 : 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 -// - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and RA contains the return address -LEAF_ENTRY RhpByRefAssignRef, _TEXT - - ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1 - ld.d $t7, $t8, 0 - addi.d $t8, $t8, 8 - b C_FUNC(RhpCheckedAssignRef) - -LEAF_END RhpByRefAssignRef, _TEXT - // RhpCheckedAssignRef(Object** dst, Object* src) // // Write barrier for writes to objects that may reside @@ -215,7 +189,7 @@ LEAF_END RhpByRefAssignRef, _TEXT // // On exit: // $t3 : trashed -// $t6 : incremented by 8 to implement JIT_ByRefWriteBarrier contract +// $t6 : preserved (the destination address is not modified) LEAF_ENTRY RhpCheckedAssignRef, _TEXT // is destReg within the heap? @@ -228,7 +202,6 @@ LEAF_END RhpByRefAssignRef, _TEXT LOCAL_LABEL(NotInHeap): ALTERNATE_ENTRY RhpCheckedAssignRefAVLocation st.d $t7, $t6, 0 - addi.d $t6, $t6, 8 jirl $r0, $ra, 0 LEAF_END RhpCheckedAssignRef, _TEXT @@ -244,7 +217,7 @@ LEAF_END RhpCheckedAssignRef, _TEXT // // On exit: // t3, t4 : trashed -// t6 : incremented by 8 +// t6 : preserved (the destination address is not modified) LEAF_ENTRY RhpAssignRefLoongArch64, _TEXT dbar 0 @@ -253,7 +226,6 @@ LEAF_ENTRY RhpAssignRefLoongArch64, _TEXT INSERT_UNCHECKED_WRITE_BARRIER_CORE $t6, $t7 - addi.d $t6, $t6, 8 jirl $r0, $ra, 0 LEAF_END RhpAssignRefLoongArch64, _TEXT diff --git a/src/coreclr/runtime/portable/WriteBarriers.cpp b/src/coreclr/runtime/portable/WriteBarriers.cpp index c863b1399f58dd..d80912e017d373 100644 --- a/src/coreclr/runtime/portable/WriteBarriers.cpp +++ b/src/coreclr/runtime/portable/WriteBarriers.cpp @@ -17,10 +17,3 @@ FCIMPL2_RAW(VOID, RhpCheckedAssignRef, Object **dst, Object *ref) PORTABILITY_ASSERT("RhpCheckedAssignRef is not yet implemented"); } FCIMPLEND - -EXTERN_C FCDECL2_RAW(VOID, RhpByRefAssignRef, Object **dst, Object **ref); -FCIMPL2_RAW(VOID, RhpByRefAssignRef, Object **dst, Object **ref) -{ - PORTABILITY_ASSERT("RhpByRefAssignRef is not yet implemented"); -} -FCIMPLEND diff --git a/src/coreclr/runtime/riscv64/WriteBarriers.S b/src/coreclr/runtime/riscv64/WriteBarriers.S index 8be86b6801333c..c4a336be1caeb4 100644 --- a/src/coreclr/runtime/riscv64/WriteBarriers.S +++ b/src/coreclr/runtime/riscv64/WriteBarriers.S @@ -187,32 +187,6 @@ // Exit label .endm -// void RhpByRefAssignRef -// On entry: -// t5 : the source address (points to object reference to write) -// t3 : the destination address (object reference written here) -// -// On exit: -// t5 : incremented by 8 -// t3 : incremented by 8 -// t4 : trashed -// t2, t3 : 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 -// - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and RA contains the return address -LEAF_ENTRY RhpByRefAssignRef, _TEXT - - ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1 - ld t4, 0(t5) - addi t5, t5, 8 - j C_FUNC(RhpCheckedAssignRef) - -LEAF_END RhpByRefAssignRef, _TEXT - // RhpCheckedAssignRef(Object** dst, Object* src) // // Write barrier for writes to objects that may reside @@ -225,7 +199,7 @@ LEAF_END RhpByRefAssignRef, _TEXT // // On exit: // t2, t6 : trashed -// t3 : incremented by 8 +// t3 : preserved (the destination address is not modified) LEAF_ENTRY RhpCheckedAssignRef, _TEXT # Check if the destination is within the heap bounds @@ -242,7 +216,6 @@ LEAF_ENTRY RhpCheckedAssignRef, _TEXT LOCAL_LABEL(NotInHeap): ALTERNATE_ENTRY RhpCheckedAssignRefAVLocation sd t4, 0(t3) - addi t3, t3, 8 ret @@ -259,7 +232,7 @@ LEAF_END RhpCheckedAssignRef, _TEXT // // On exit: // t2, t6 : trashed -// t3 : incremented by 8 +// t3 : preserved (the destination address is not modified) LEAF_ENTRY RhpAssignRefRiscV64, _TEXT fence rw, rw @@ -268,8 +241,6 @@ LEAF_ENTRY RhpAssignRefRiscV64, _TEXT INSERT_UNCHECKED_WRITE_BARRIER_CORE t3, t4 - addi t3, t3, 8 - ret LEAF_END RhpAssignRefRiscV64, _TEXT diff --git a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs index 4fc612e2b92dd0..dea16528262cd3 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs @@ -15,8 +15,8 @@ internal struct ReadyToRunHeaderConstants { public const uint Signature = 0x00525452; // 'RTR' - public const ushort CurrentMajorVersion = 18; - public const ushort CurrentMinorVersion = 7; + public const ushort CurrentMajorVersion = 19; + public const ushort CurrentMinorVersion = 0; } #if READYTORUN #pragma warning disable 0169 diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs index a68b32c2b6c7d7..f70b278f2de695 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs @@ -247,7 +247,7 @@ public enum ReadyToRunHelper // Write barriers WriteBarrier = 0x30, CheckedWriteBarrier = 0x31, - ByRefWriteBarrier = 0x32, + ByRefWriteBarrier = 0x32, // No longer supported as of READYTORUN_MAJOR_VERSION 19.0 BulkWriteBarrier = 0x33, // Array helpers diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs index 15acd0dd2ef791..68f7b52f6ec048 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs @@ -129,7 +129,6 @@ which is the right helper to use to allocate an object of a given type. */ 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 */ diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs index 0204c7bf5cef0d..332aa401bca13b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs @@ -79,9 +79,6 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, case ReadyToRunHelper.BulkWriteBarrier: methodDesc = context.GetCoreLibEntryPoint("System"u8, "Buffer"u8, "BulkMoveWithWriteBarrier"u8, null); break; - case ReadyToRunHelper.ByRefWriteBarrier: - mangledName = context.Target.Architecture == TargetArchitecture.ARM64 ? "RhpByRefAssignRefArm64" : "RhpByRefAssignRef"; - break; case ReadyToRunHelper.WriteBarrier_EAX: mangledName = "RhpAssignRefEAX"; break; diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 1826c1f491a608..8c4af968d66747 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -1041,9 +1041,6 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF: id = ReadyToRunHelper.CheckedWriteBarrier; break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_BYREF: - id = ReadyToRunHelper.ByRefWriteBarrier; - break; case CorInfoHelpFunc.CORINFO_HELP_BULK_WRITEBARRIER: id = ReadyToRunHelper.BulkWriteBarrier; break; diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 39ac85ec166390..6c22da04d78a90 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -512,9 +512,6 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) case CorInfoHelpFunc.CORINFO_HELP_BULK_WRITEBARRIER: id = ReadyToRunHelper.BulkWriteBarrier; break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_BYREF: - id = ReadyToRunHelper.ByRefWriteBarrier; - break; case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_EAX: id = ReadyToRunHelper.WriteBarrier_EAX; break; diff --git a/src/coreclr/vm/amd64/JitHelpers_Fast.asm b/src/coreclr/vm/amd64/JitHelpers_Fast.asm index 149b38f11754e9..0549b139d1bc51 100644 --- a/src/coreclr/vm/amd64/JitHelpers_Fast.asm +++ b/src/coreclr/vm/amd64/JitHelpers_Fast.asm @@ -48,215 +48,6 @@ extern JIT_WriteBarrier_Debug:proc endif -; JIT_ByRefWriteBarrier has weird semantics, see usage in StubLinkerX86.cpp -; -; Entry: -; RDI - address of ref-field (assigned to) -; RSI - address of the data (source) -; RCX is trashed -; RAX is trashed -; -; NOTE: Keep in sync with RBM_CALLEE_TRASH_WRITEBARRIER_BYREF and RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF -; if you add more trashed registers. -; -; Exit: -; RDI, RSI are incremented by SIZEOF(LPVOID) -; -LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT - mov rcx, [rsi] - -; If !WRITE_BARRIER_CHECK do the write first, otherwise we might have to do some ShadowGC stuff -ifndef WRITE_BARRIER_CHECK - ; rcx is [rsi] - mov [rdi], rcx -endif - - ; When WRITE_BARRIER_CHECK is defined _NotInHeap will write the reference - ; but if it isn't then it will just return. - ; - ; See if this is in GCHeap - cmp rdi, [g_lowest_address] - jb NotInHeap - cmp rdi, [g_highest_address] - jnb NotInHeap - -ifdef WRITE_BARRIER_CHECK - ; we can only trash rcx in this function so in _DEBUG we need to save - ; some scratch registers. - push r10 - push r11 - push rax - - ; **ALSO update the shadow GC heap if that is enabled** - ; Do not perform the work if g_GCShadow is 0 - cmp g_GCShadow, 0 - je NoShadow - - ; If we end up outside of the heap don't corrupt random memory - mov r10, rdi - sub r10, [g_lowest_address] - jb NoShadow - - ; Check that our adjusted destination is somewhere in the shadow gc - add r10, [g_GCShadow] - cmp r10, [g_GCShadowEnd] - jnb NoShadow - - ; Write ref into real GC - mov [rdi], rcx - ; Write ref into shadow GC - mov [r10], rcx - - ; Ensure that the write to the shadow heap occurs before the read from - ; the GC heap so that race conditions are caught by INVALIDGCVALUE - mfence - - ; Check that GC/ShadowGC values match - mov r11, [rdi] - mov rax, [r10] - cmp rax, r11 - je DoneShadow - mov r11, INVALIDGCVALUE - mov [r10], r11 - - jmp DoneShadow - - ; If we don't have a shadow GC we won't have done the write yet - NoShadow: - mov [rdi], rcx - - ; If we had a shadow GC then we already wrote to the real GC at the same time - ; as the shadow GC so we want to jump over the real write immediately above. - ; Additionally we know for sure that we are inside the heap and therefore don't - ; need to replicate the above checks. - DoneShadow: - pop rax - pop r11 - pop r10 -endif - -ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP - ; Update the write watch table if necessary - cmp byte ptr [g_sw_ww_enabled_for_gc_heap], 0h - je CheckCardTable - mov rax, rdi - shr rax, 0Ch ; SoftwareWriteWatch::AddressToTableByteIndexShift - add rax, qword ptr [g_write_watch_table] - cmp byte ptr [rax], 0h - jne CheckCardTable - mov byte ptr [rax], 0FFh -endif - - ; See if we can just quick out - CheckCardTable: - cmp rcx, [g_ephemeral_low] - jb Exit - cmp rcx, [g_ephemeral_high] - jnb Exit - -ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP - mov rax, rcx - - mov cl, [g_region_shr] - test cl, cl - je SkipCheck - - ; check if the source is in gen 2 - then it's not an ephemeral pointer - shr rax, cl - add rax, [g_region_to_generation_table] - cmp byte ptr [rax], 82h - je Exit - - ; check if the destination happens to be in gen 0 - mov rax, rdi - shr rax, cl - add rax, [g_region_to_generation_table] - cmp byte ptr [rax], 0 - je Exit - SkipCheck: - - cmp [g_region_use_bitwise_write_barrier], 0 - je CheckCardTableByte - - ; compute card table bit - mov rcx, rdi - mov al, 1 - shr rcx, 8 - and cl, 7 - shl al, cl - - ; move current rdi value into rcx and then increment the pointers - mov rcx, rdi - add rsi, 8h - add rdi, 8h - - ; Check if we need to update the card table - ; Calc pCardByte - shr rcx, 0Bh - add rcx, [g_card_table] - - ; Check if this card table bit is already set - test byte ptr [rcx], al - je SetCardTableBit - REPRET - - SetCardTableBit: - lock or byte ptr [rcx], al - jmp CheckCardBundle -endif -CheckCardTableByte: - - ; move current rdi value into rcx and then increment the pointers - mov rcx, rdi - add rsi, 8h - add rdi, 8h - - ; Check if we need to update the card table - ; Calc pCardByte - shr rcx, 0Bh - add rcx, [g_card_table] - - ; Check if this card is dirty - cmp byte ptr [rcx], 0FFh - jne UpdateCardTable - REPRET - - UpdateCardTable: - mov byte ptr [rcx], 0FFh - - CheckCardBundle: - -ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES - ; check if we need to update the card bundle table - ; restore destination address from rdi - rdi has been incremented by 8 already - lea rcx, [rdi-8] - shr rcx, 15h - add rcx, [g_card_bundle_table] - cmp byte ptr [rcx], 0FFh - jne UpdateCardBundleTable - REPRET - - UpdateCardBundleTable: - mov byte ptr [rcx], 0FFh -endif - ret - - align 16 - NotInHeap: -; If WRITE_BARRIER_CHECK then we won't have already done the mov and should do it here -; If !WRITE_BARRIER_CHECK we want _NotInHeap and _Leave to be the same and have both -; 16 byte aligned. -ifdef WRITE_BARRIER_CHECK - ; rcx is [rsi] - mov [rdi], rcx -endif - Exit: - ; Increment the pointers before leaving - add rdi, 8h - add rsi, 8h - ret -LEAF_END_MARKED JIT_ByRefWriteBarrier, _TEXT - Section segment para 'DATA' align 16 diff --git a/src/coreclr/vm/amd64/jithelpers_fast.S b/src/coreclr/vm/amd64/jithelpers_fast.S index d559ee8e844987..eeda953bd63f3f 100644 --- a/src/coreclr/vm/amd64/jithelpers_fast.S +++ b/src/coreclr/vm/amd64/jithelpers_fast.S @@ -5,213 +5,6 @@ #include "unixasmmacros.inc" #include "asmconstants.h" -// JIT_ByRefWriteBarrier has weird semantics, see usage in StubLinkerX86.cpp -// -// Entry: -// RDI - address of ref-field (assigned to) -// RSI - address of the data (source) -// RCX is trashed -// RAX is trashed -// -// NOTE: Keep in sync with RBM_CALLEE_TRASH_WRITEBARRIER_BYREF and RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF -// if you add more trashed registers. -// -// Exit: -// RDI, RSI are incremented by SIZEOF(LPVOID) -// -LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT - mov rcx, [rsi] - -// If !WRITE_BARRIER_CHECK do the write first, otherwise we might have to do some ShadowGC stuff -#ifndef WRITE_BARRIER_CHECK - // rcx is [rsi] - mov [rdi], rcx -#endif - - // When WRITE_BARRIER_CHECK is defined _NotInHeap will write the reference - // but if it isn't then it will just return. - // - // See if this is in GCHeap - cmp rdi, [C_VAR(g_lowest_address)] - jb LOCAL_LABEL(NotInHeap_ByRefWriteBarrier) - cmp rdi, [C_VAR(g_highest_address)] - jnb LOCAL_LABEL(NotInHeap_ByRefWriteBarrier) - -#ifdef WRITE_BARRIER_CHECK - // we can only trash rcx in this function so in _DEBUG we need to save - // some scratch registers. - push r10 - push r11 - push rax - - // **ALSO update the shadow GC heap if that is enabled** - // Do not perform the work if g_GCShadow is 0 - cmp qword ptr [C_VAR(g_GCShadow)], 0 - je LOCAL_LABEL(NoShadow_ByRefWriteBarrier) - - // If we end up outside of the heap don't corrupt random memory - mov r10, rdi - sub r10, [C_VAR(g_lowest_address)] - jb LOCAL_LABEL(NoShadow_ByRefWriteBarrier) - - // Check that our adjusted destination is somewhere in the shadow gc - add r10, [C_VAR(g_GCShadow)] - cmp r10, [C_VAR(g_GCShadowEnd)] - jnb LOCAL_LABEL(NoShadow_ByRefWriteBarrier) - - // Write ref into real GC - mov [rdi], rcx - // Write ref into shadow GC - mov [r10], rcx - - // Ensure that the write to the shadow heap occurs before the read from - // the GC heap so that race conditions are caught by INVALIDGCVALUE - mfence - - // Check that GC/ShadowGC values match - mov r11, [rdi] - mov rax, [r10] - cmp rax, r11 - je LOCAL_LABEL(DoneShadow_ByRefWriteBarrier) - movabs r11, INVALIDGCVALUE - mov [r10], r11 - - jmp LOCAL_LABEL(DoneShadow_ByRefWriteBarrier) - - // If we don't have a shadow GC we won't have done the write yet - LOCAL_LABEL(NoShadow_ByRefWriteBarrier): - mov [rdi], rcx - - // If we had a shadow GC then we already wrote to the real GC at the same time - // as the shadow GC so we want to jump over the real write immediately above. - // Additionally we know for sure that we are inside the heap and therefore don't - // need to replicate the above checks. - LOCAL_LABEL(DoneShadow_ByRefWriteBarrier): - pop rax - pop r11 - pop r10 -#endif - -#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP - // Update the write watch table if necessary - cmp byte ptr [C_VAR(g_sw_ww_enabled_for_gc_heap)], 0x0 - je LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier) - mov rax, rdi - shr rax, 0xC // SoftwareWriteWatch::AddressToTableByteIndexShift - add rax, qword ptr [C_VAR(g_write_watch_table)] - cmp byte ptr [rax], 0x0 - jne LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier) - mov byte ptr [rax], 0xFF -#endif - - // See if we can just quick out - LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier): - cmp rcx, [C_VAR(g_ephemeral_low)] - jb LOCAL_LABEL(Exit_ByRefWriteBarrier) - cmp rcx, [C_VAR(g_ephemeral_high)] - jnb LOCAL_LABEL(Exit_ByRefWriteBarrier) - - mov rax, rcx - - mov cl, [C_VAR(g_region_shr)] - test cl, cl - je LOCAL_LABEL(SkipCheck_ByRefWriteBarrier) - - // check if the source is in gen 2 - then it's not an ephemeral pointer - shr rax, cl - add rax, [C_VAR(g_region_to_generation_table)] - cmp byte ptr [rax], 0x82 - je LOCAL_LABEL(Exit_ByRefWriteBarrier) - - // check if the destination happens to be in gen 0 - mov rax, rdi - shr rax, cl - add rax, [C_VAR(g_region_to_generation_table)] - cmp byte ptr [rax], 0 - je LOCAL_LABEL(Exit_ByRefWriteBarrier) - LOCAL_LABEL(SkipCheck_ByRefWriteBarrier): - - cmp byte ptr [C_VAR(g_region_use_bitwise_write_barrier)], 0 - je LOCAL_LABEL(CheckCardTableByte_ByRefWriteBarrier) - - // compute card table bit - mov rcx, rdi - mov al, 1 - shr rcx, 8 - and cl, 7 - shl al, cl - - // move current rdi value into rcx and then increment the pointers - mov rcx, rdi - add rsi, 0x8 - add rdi, 0x8 - - // Check if we need to update the card table - // Calc pCardByte - shr rcx, 0xB - add rcx, [C_VAR(g_card_table)] - - // Check if this card table bit is already set - test byte ptr [rcx], al - je LOCAL_LABEL(SetCardTableBit_ByRefWriteBarrier) - REPRET - - LOCAL_LABEL(SetCardTableBit_ByRefWriteBarrier): - lock or byte ptr [rcx], al - jmp LOCAL_LABEL(CheckCardBundle_ByRefWriteBarrier) -LOCAL_LABEL(CheckCardTableByte_ByRefWriteBarrier): - - // move current rdi value into rcx and then increment the pointers - mov rcx, rdi - add rsi, 0x8 - add rdi, 0x8 - - // Check if we need to update the card table - // Calc pCardByte - shr rcx, 0xB - add rcx, [C_VAR(g_card_table)] - - // Check if this card is dirty - cmp byte ptr [rcx], 0xFF - jne LOCAL_LABEL(UpdateCardTable_ByRefWriteBarrier) - REPRET - - LOCAL_LABEL(UpdateCardTable_ByRefWriteBarrier): - mov byte ptr [rcx], 0xFF - - LOCAL_LABEL(CheckCardBundle_ByRefWriteBarrier): - -#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES - // check if we need to update the card bundle table - // restore destination address from rdi - rdi has been incremented by 8 already - lea rcx, [rdi-8] - shr rcx, 0x15 - add rcx, [C_VAR(g_card_bundle_table)] - cmp byte ptr [rcx], 0xFF - jne LOCAL_LABEL(UpdateCardBundleTable_ByRefWriteBarrier) - REPRET - - LOCAL_LABEL(UpdateCardBundleTable_ByRefWriteBarrier): - mov byte ptr [rcx], 0xFF -#endif - ret - - .balign 16 - LOCAL_LABEL(NotInHeap_ByRefWriteBarrier): -// If WRITE_BARRIER_CHECK then we won't have already done the mov and should do it here -// If !WRITE_BARRIER_CHECK we want _NotInHeap and _Leave to be the same and have both -// 16 byte aligned. -#ifdef WRITE_BARRIER_CHECK - // rcx is [rsi] - mov [rdi], rcx -#endif - LOCAL_LABEL(Exit_ByRefWriteBarrier): - // Increment the pointers before leaving - add rdi, 0x8 - add rsi, 0x8 - ret -LEAF_END_MARKED JIT_ByRefWriteBarrier, _TEXT - // When JIT_WriteBarrier is copied into an allocated page, // helpers use this global variable to jump to it. This variable is set in InitThreadManager. .global C_FUNC(JIT_WriteBarrier_Loc) diff --git a/src/coreclr/vm/arm/asmhelpers.S b/src/coreclr/vm/arm/asmhelpers.S index 8a57a3fd572f04..994be179585304 100644 --- a/src/coreclr/vm/arm/asmhelpers.S +++ b/src/coreclr/vm/arm/asmhelpers.S @@ -598,28 +598,6 @@ LOCAL_LABEL(stackProbe_loop): LEAF_END_MARKED \name, _TEXT .endm - .macro JIT_BYREFWRITEBARRIER name, mp, post - LEAF_ENTRY \name, _TEXT - START_WRITE_BARRIER \name - .if(\mp) - dmb - .endif - - ldr r2, [r1] - str r2, [r0] - CHECK_GC_HEAP_RANGE \name, r0, 1f - UPDATE_GC_SHADOW \name, r0, r2 -#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP - UPDATE_WRITE_WATCH_TABLE \name, r0, \mp, r12 -#endif - UPDATE_CARD_TABLE \name, r0, r2, \mp, \post, r2 -1: - add r0, #4 - add r1, #4 - bx lr - LEAF_END_MARKED \name, _TEXT - .endm - .macro JIT_WRITEBARRIER_DESCRIPTOR name 1: .word \name-1b @@ -645,11 +623,6 @@ LOCAL_LABEL(stackProbe_loop): JIT_CHECKEDWRITEBARRIER_MP JIT_CheckedWriteBarrier_MP_Pre, 0 JIT_CHECKEDWRITEBARRIER_MP JIT_CheckedWriteBarrier_MP_Post, 1 - JIT_BYREFWRITEBARRIER JIT_ByRefWriteBarrier_SP_Pre, 0, 0 - JIT_BYREFWRITEBARRIER JIT_ByRefWriteBarrier_SP_Post, 0, 1 - JIT_BYREFWRITEBARRIER JIT_ByRefWriteBarrier_MP_Pre, 1, 0 - JIT_BYREFWRITEBARRIER JIT_ByRefWriteBarrier_MP_Post, 1, 1 - // .section .clrwb, "d" g_rgWriteBarrierDescriptors: @@ -663,11 +636,6 @@ g_rgWriteBarrierDescriptors: JIT_WRITEBARRIER_DESCRIPTOR JIT_CheckedWriteBarrier_MP_Pre JIT_WRITEBARRIER_DESCRIPTOR JIT_CheckedWriteBarrier_MP_Post - JIT_WRITEBARRIER_DESCRIPTOR JIT_ByRefWriteBarrier_SP_Pre - JIT_WRITEBARRIER_DESCRIPTOR JIT_ByRefWriteBarrier_SP_Post - JIT_WRITEBARRIER_DESCRIPTOR JIT_ByRefWriteBarrier_MP_Pre - JIT_WRITEBARRIER_DESCRIPTOR JIT_ByRefWriteBarrier_MP_Post - // Sentinel value .word 0 diff --git a/src/coreclr/vm/arm/patchedcode.S b/src/coreclr/vm/arm/patchedcode.S index 94a6b44d285490..f277bddccc137b 100644 --- a/src/coreclr/vm/arm/patchedcode.S +++ b/src/coreclr/vm/arm/patchedcode.S @@ -34,11 +34,6 @@ .space (0xC0) LEAF_END_MARKED JIT_CheckedWriteBarrier, _TEXT - .align 4 - LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT - .space (0xC4) - LEAF_END_MARKED JIT_ByRefWriteBarrier , _TEXT - LEAF_ENTRY JIT_PatchedWriteBarrierLast, _TEXT LEAF_END JIT_PatchedWriteBarrierLast, _TEXT diff --git a/src/coreclr/vm/arm/stubs.cpp b/src/coreclr/vm/arm/stubs.cpp index 6ba3ace5d00607..b7e1b2e42d61cc 100644 --- a/src/coreclr/vm/arm/stubs.cpp +++ b/src/coreclr/vm/arm/stubs.cpp @@ -34,8 +34,6 @@ EXTERN_C void JIT_WriteBarrier(Object **dst, Object *ref); EXTERN_C void JIT_WriteBarrier_End(); EXTERN_C void JIT_CheckedWriteBarrier(Object **dst, Object *ref); EXTERN_C void JIT_CheckedWriteBarrier_End(); -EXTERN_C void JIT_ByRefWriteBarrier_End(); -EXTERN_C void JIT_ByRefWriteBarrier_SP(Object **dst, Object *ref); // source write barriers EXTERN_C void JIT_WriteBarrier_SP_Pre(Object **dst, Object *ref); @@ -56,15 +54,6 @@ EXTERN_C void JIT_CheckedWriteBarrier_MP_Pre_End(); EXTERN_C void JIT_CheckedWriteBarrier_MP_Post(Object **dst, Object *ref); EXTERN_C void JIT_CheckedWriteBarrier_MP_Post_End(); -EXTERN_C void JIT_ByRefWriteBarrier_SP_Pre(); -EXTERN_C void JIT_ByRefWriteBarrier_SP_Pre_End(); -EXTERN_C void JIT_ByRefWriteBarrier_SP_Post(); -EXTERN_C void JIT_ByRefWriteBarrier_SP_Post_End(); -EXTERN_C void JIT_ByRefWriteBarrier_MP_Pre(); -EXTERN_C void JIT_ByRefWriteBarrier_MP_Pre_End(); -EXTERN_C void JIT_ByRefWriteBarrier_MP_Post(Object **dst, Object *ref); -EXTERN_C void JIT_ByRefWriteBarrier_MP_Post_End(); - EXTERN_C void JIT_PatchedWriteBarrierStart(); EXTERN_C void JIT_PatchedWriteBarrierLast(); @@ -305,14 +294,12 @@ struct WriteBarrierMapping const int WriteBarrierIndex = 0; const int CheckedWriteBarrierIndex = 1; -const int ByRefWriteBarrierIndex = 2; -const int MaxWriteBarrierIndex = 3; +const int MaxWriteBarrierIndex = 2; WriteBarrierMapping wbMapping[MaxWriteBarrierIndex] = { {(PBYTE)JIT_WriteBarrier, NULL}, - {(PBYTE)JIT_CheckedWriteBarrier, NULL}, - {(PBYTE)JIT_ByRefWriteBarrier, NULL} + {(PBYTE)JIT_CheckedWriteBarrier, NULL} }; PBYTE FindWBMapping(PBYTE from) @@ -369,10 +356,6 @@ void ValidateWriteBarriers() _ASSERTE( ((PBYTE)JIT_CheckedWriteBarrier_End - (PBYTE)JIT_CheckedWriteBarrier) >= ((PBYTE)JIT_CheckedWriteBarrier_MP_Post_End - (PBYTE)JIT_CheckedWriteBarrier_MP_Post)); _ASSERTE( ((PBYTE)JIT_CheckedWriteBarrier_End - (PBYTE)JIT_CheckedWriteBarrier) >= ((PBYTE)JIT_CheckedWriteBarrier_SP_Post_End - (PBYTE)JIT_CheckedWriteBarrier_SP_Post)); - - _ASSERTE( ((PBYTE)JIT_ByRefWriteBarrier_End - (PBYTE)JIT_ByRefWriteBarrier) >= ((PBYTE)JIT_ByRefWriteBarrier_MP_Post_End - (PBYTE)JIT_ByRefWriteBarrier_MP_Post)); - _ASSERTE( ((PBYTE)JIT_ByRefWriteBarrier_End - (PBYTE)JIT_ByRefWriteBarrier) >= ((PBYTE)JIT_ByRefWriteBarrier_SP_Post_End - (PBYTE)JIT_ByRefWriteBarrier_SP_Post)); - } #endif // _DEBUG @@ -382,9 +365,6 @@ void ValidateWriteBarriers() \ CopyWriteBarrier((PCODE)JIT_CheckedWriteBarrier, (PCODE)JIT_CheckedWriteBarrier_ ## _proc ## _ ## _grow , (PCODE)JIT_CheckedWriteBarrier_ ## _proc ## _ ## _grow ## _End); \ wbMapping[CheckedWriteBarrierIndex].from = (PBYTE)JIT_CheckedWriteBarrier_ ## _proc ## _ ## _grow ; \ - \ - CopyWriteBarrier((PCODE)JIT_ByRefWriteBarrier, (PCODE)JIT_ByRefWriteBarrier_ ## _proc ## _ ## _grow , (PCODE)JIT_ByRefWriteBarrier_ ## _proc ## _ ## _grow ## _End); \ - wbMapping[ByRefWriteBarrierIndex].from = (PBYTE)JIT_ByRefWriteBarrier_ ## _proc ## _ ## _grow ; \ // Update the instructions in our various write barrier implementations that refer directly to the values // of GC globals such as g_lowest_address and g_card_table. We don't particularly care which values have diff --git a/src/coreclr/vm/arm64/patchedcode.S b/src/coreclr/vm/arm64/patchedcode.S index 248375142d2c49..05c0b2ed9a09a3 100644 --- a/src/coreclr/vm/arm64/patchedcode.S +++ b/src/coreclr/vm/arm64/patchedcode.S @@ -65,29 +65,6 @@ LEAF_ENTRY JIT_PatchedCodeStart, _TEXT LEAF_END JIT_PatchedCodeStart, _TEXT #endif -//----------------------------------------------------------------------------- -// void JIT_ByRefWriteBarrier -// On entry: -// x13 : the source address (points to object reference to write) -// x14 : the destination address (object reference written here) -// -// On exit: -// x12 : trashed -// x13 : incremented by 8 -// x14 : incremented by 8 -// x15 : trashed -// x17 : trashed (ip1) -// -// NOTE: Keep in sync with RBM_CALLEE_TRASH_WRITEBARRIER_BYREF and RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF -// if you add more trashed registers. -// -WRITE_BARRIER_ENTRY JIT_ByRefWriteBarrier - - ldr x15, [x13], 8 - b C_FUNC(JIT_CheckedWriteBarrier) - -WRITE_BARRIER_END JIT_ByRefWriteBarrier - //----------------------------------------------------------------------------- // Simple WriteBarriers // void JIT_CheckedWriteBarrier(Object** dst, Object* src) @@ -97,13 +74,10 @@ WRITE_BARRIER_END JIT_ByRefWriteBarrier // // On exit: // x12 : trashed -// x14 : trashed (incremented by 8 to implement JIT_ByRefWriteBarrier contract) +// x14 : preserved (the destination address is not modified) // x15 : trashed // x17 : trashed (ip1) // -// NOTE: Keep in sync with RBM_CALLEE_TRASH_WRITEBARRIER_BYREF and RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF -// if you add more trashed registers. -// WRITE_BARRIER_ENTRY JIT_CheckedWriteBarrier ldr x12, LOCAL_LABEL(wbs_lowest_address) ldr x17, LOCAL_LABEL(wbs_highest_address) @@ -114,7 +88,7 @@ WRITE_BARRIER_ENTRY JIT_CheckedWriteBarrier b C_FUNC(JIT_WriteBarrier) LOCAL_LABEL(NotInHeap): - str x15, [x14], 8 + str x15, [x14] ret lr WRITE_BARRIER_END JIT_CheckedWriteBarrier @@ -130,13 +104,10 @@ WRITE_BARRIER_END JIT_CheckedWriteBarrier // // On exit: // x12 : trashed -// x14 : trashed (incremented by 8 to implement JIT_ByRefWriteBarrier contract) +// x14 : preserved (the destination address is not modified) // x15 : trashed // x17 : trashed (ip1) // -// NOTE: Keep in sync with RBM_CALLEE_TRASH_WRITEBARRIER_BYREF and RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF -// if you add more trashed registers. -// WRITE_BARRIER_ENTRY JIT_WriteBarrier // This must be greater than the largest JIT_WriteBarrier_ function. .space JIT_WriteBarrier_Size, 0 @@ -345,10 +316,6 @@ LOCAL_LABEL(WriteWatchForGCHeapEnd\@): .macro WRITE_BARRIER_RETURN_STUB exit LOCAL_LABEL(\exit): - // Increment by 8 to implement JIT_ByRefWriteBarrier contract. - // TODO: Consider duplicating the logic to get rid of this redundant 'add' - // for JIT_WriteBarrier/JIT_CheckedWriteBarrier - add x14, x14, 8 ret lr .endm diff --git a/src/coreclr/vm/arm64/patchedcode.asm b/src/coreclr/vm/arm64/patchedcode.asm index 500f1044d488d7..029eea5e8faa38 100644 --- a/src/coreclr/vm/arm64/patchedcode.asm +++ b/src/coreclr/vm/arm64/patchedcode.asm @@ -39,29 +39,6 @@ ret lr LEAF_END -;----------------------------------------------------------------------------- -; void JIT_ByRefWriteBarrier -; On entry: -; x13 : the source address (points to object reference to write) -; x14 : the destination address (object reference written here) -; -; On exit: -; x12 : trashed -; x13 : incremented by 8 -; x14 : incremented by 8 -; x15 : trashed -; x17 : trashed (ip1) -; -; NOTE: Keep in sync with RBM_CALLEE_TRASH_WRITEBARRIER_BYREF and RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF -; if you add more trashed registers. -; - WRITE_BARRIER_ENTRY JIT_ByRefWriteBarrier - - ldr x15, [x13], 8 - b JIT_CheckedWriteBarrier - - WRITE_BARRIER_END JIT_ByRefWriteBarrier - ;----------------------------------------------------------------------------- ; Simple WriteBarriers ; void JIT_CheckedWriteBarrier(Object** dst, Object* src) @@ -71,12 +48,9 @@ ; ; On exit: ; x12 : trashed -; x14 : incremented by 8 +; x14 : preserved (the destination address is not modified) ; x15 : trashed ; x17 : trashed (ip1) -; -; NOTE: Keep in sync with RBM_CALLEE_TRASH_WRITEBARRIER_BYREF and RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF -; if you add more trashed registers. ; WRITE_BARRIER_ENTRY JIT_CheckedWriteBarrier ldr x12, wbs_lowest_address @@ -86,7 +60,7 @@ blo JIT_WriteBarrier NotInHeap - str x15, [x14], 8 + str x15, [x14] ret lr WRITE_BARRIER_END JIT_CheckedWriteBarrier @@ -101,12 +75,9 @@ NotInHeap ; ; On exit: ; x12 : trashed -; x14 : incremented by 8 +; x14 : preserved (the destination address is not modified) ; x15 : trashed ; x17 : trashed (ip1) -; -; NOTE: Keep in sync with RBM_CALLEE_TRASH_WRITEBARRIER_BYREF and RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF -; if you add more trashed registers. ; WRITE_BARRIER_ENTRY JIT_WriteBarrier ; This must be greater than the largest JIT_WriteBarrier_ function. @@ -310,10 +281,6 @@ WriteWatchForGCHeapEnd$name MACRO WRITE_BARRIER_RETURN_STUB $name exit$name - ; Increment by 8 to implement JIT_ByRefWriteBarrier contract. - ; TODO: Consider duplicating the logic to get rid of this redundant 'add' - ; for JIT_WriteBarrier/JIT_CheckedWriteBarrier - add x14, x14, 8 ret lr MEND diff --git a/src/coreclr/vm/arm64/patchedcodeconstants.h b/src/coreclr/vm/arm64/patchedcodeconstants.h index 1b4a32d210bd19..e402b9d09a0687 100644 --- a/src/coreclr/vm/arm64/patchedcodeconstants.h +++ b/src/coreclr/vm/arm64/patchedcodeconstants.h @@ -8,16 +8,16 @@ #ifndef PATCHEDCODECONSTANTS_H #define PATCHEDCODECONSTANTS_H -// These are fixed constants becuase MacOS doesn't allow label arithmetic in +// These are fixed constants because MacOS doesn't allow label arithmetic in // LDR instructions. Asserts in writebarriermanager CALC_TABLE_LOCATION ensure // the values are correct. #define JIT_WriteBarrier_Size 0x3a0 #ifdef TARGET_WINDOWS -#define JIT_WriteBarrier_Table_Offset (0x30 + JIT_WriteBarrier_Size) +#define JIT_WriteBarrier_Table_Offset (0x3c + JIT_WriteBarrier_Size) #else -#define JIT_WriteBarrier_Table_Offset (0x2c + JIT_WriteBarrier_Size) +#define JIT_WriteBarrier_Table_Offset (0x38 + JIT_WriteBarrier_Size) #endif #define JIT_WriteBarrier_Offset_CardTable (0x0 + JIT_WriteBarrier_Table_Offset) diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index fafc3bc5219aad..a12bde70e8980f 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -5275,7 +5275,6 @@ EXTERN_C void JIT_StackProbe_End(); #ifndef TARGET_X86 EXTERN_C void JIT_WriteBarrier_End(); EXTERN_C void JIT_CheckedWriteBarrier_End(); -EXTERN_C void JIT_ByRefWriteBarrier_End(); #endif // TARGET_X86 #if defined(TARGET_AMD64) && defined(_DEBUG) @@ -5341,11 +5340,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 static uintptr_t writeBarrierAVLocations[] = { @@ -5366,10 +5360,6 @@ static uintptr_t writeBarrierAVLocations[] = (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 }; @@ -5399,7 +5389,6 @@ bool IsIPInMarkedJitHelper(PCODE uControlPc) #ifndef TARGET_X86 CHECK_RANGE(JIT_WriteBarrier) CHECK_RANGE(JIT_CheckedWriteBarrier) - CHECK_RANGE(JIT_ByRefWriteBarrier) #if !defined(TARGET_ARM64) && !defined(TARGET_LOONGARCH64) && !defined(TARGET_RISCV64) CHECK_RANGE(JIT_StackProbe) #endif // !TARGET_ARM64 && !TARGET_LOONGARCH64 && !TARGET_RISCV64 diff --git a/src/coreclr/vm/i386/jithelp.S b/src/coreclr/vm/i386/jithelp.S index 13a6f48f167f86..2b99cc949f229a 100644 --- a/src/coreclr/vm/i386/jithelp.S +++ b/src/coreclr/vm/i386/jithelp.S @@ -204,172 +204,6 @@ NESTED_END JIT_CheckedWriteBarrier\rg, _TEXT .endm -// *** -// JIT_ByRefWriteBarrier* - GC write barrier helper -// -// Purpose: -// Helper calls in order to assign an object to a byref field -// Enables book-keeping of the GC. -// -// Entry: -// EDI - address of ref-field (assigned to) -// ESI - address of the data (source) -// ECX can be trashed -// -// Exit: -// -// Uses: -// EDI and ESI are incremented by a DWORD -// -// Exceptions: -// -// ******************************************************************************* -// -// The code here is tightly coupled with AdjustContextForJITHelpers, if you change -// anything here, you might need to change AdjustContextForJITHelpers as well -// -.macro ByRefWriteBarrierHelper -.align 4 - -LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT - // test for dest in range - mov ecx, [esi] - push eax - PREPARE_EXTERNAL_VAR g_lowest_address, eax - cmp edi, [eax] - pop eax - jb LOCAL_LABEL(ByRefWriteBarrier_NotInHeap) - push eax - PREPARE_EXTERNAL_VAR g_highest_address, eax - cmp edi, [eax] - pop eax - jae LOCAL_LABEL(ByRefWriteBarrier_NotInHeap) - -#ifndef WRITE_BARRIER_CHECK - // write barrier - mov [edi], ecx -#endif // !WRITE_BARRIER_CHECK - -#ifdef WRITE_BARRIER_CHECK - // Test dest here so if it is bad AV would happen before we change register/stack - // status. This makes job of AdjustContextForJITHelpers easier. - cmp BYTE PTR [edi], 0 - - // ALSO update the shadow GC heap if that is enabled - - // use edx for address in GC Shadow, - push edx - - // if g_GCShadow is 0, don't do the update - push ebx - PREPARE_EXTERNAL_VAR g_GCShadow, ebx - cmp DWORD PTR [ebx], 0 - pop ebx - je LOCAL_LABEL(ByRefWriteBarrier_NoShadow) - - mov edx, edi - push ebx - PREPARE_EXTERNAL_VAR g_lowest_address, ebx - sub edx, [ebx] // U/V - pop ebx - jb LOCAL_LABEL(ByRefWriteBarrier_NoShadow) - push eax - PREPARE_EXTERNAL_VAR g_GCShadow, eax - mov eax, [eax] - add edx, [eax] - PREPARE_EXTERNAL_VAR g_GCShadowEnd, eax - mov eax, [eax] - cmp edx, [eax] - pop eax - jae LOCAL_LABEL(ByRefWriteBarrier_NoShadow) - - // TODO: In Orcas timeframe if we move to P4+ only on X86 we should enable - // mfence barriers on either side of these two writes to make sure that - // they stay as close together as possible - - // edi contains address in GC - // edx contains address in ShadowGC - // ecx is the value to assign - - // When we're writing to the shadow GC heap we want to be careful to minimize - // the risk of a race that can occur here where the GC and ShadowGC don't match - mov DWORD PTR [edi], ecx - mov DWORD PTR [edx], ecx - - // We need a scratch register to verify the shadow heap. We also need to - // construct a memory barrier so that the write to the shadow heap happens - // before the read from the GC heap. We can do both by using SUB/XCHG - // rather than PUSH. - // - // TODO: Should be changed to a push if the mfence described above is added. - // - sub esp, 4 - xchg [esp], eax - - // As part of our race avoidance (see above) we will now check whether the values - // in the GC and ShadowGC match. There is a possibility that we're wrong here but - // being overaggressive means we might mask a case where someone updates GC refs - // without going to a write barrier, but by its nature it will be indeterminant - // and we will find real bugs whereas the current implementation is indeterminant - // but only leads to investigations that find that this code is fundamentally flawed - - mov eax, [edi] - cmp [edx], eax - je LOCAL_LABEL(ByRefWriteBarrier_CleanupShadowCheck) - mov DWORD PTR [edx], INVALIDGCVALUE -LOCAL_LABEL(ByRefWriteBarrier_CleanupShadowCheck): - pop eax - jmp LOCAL_LABEL(ByRefWriteBarrier_ShadowCheckEnd) - -LOCAL_LABEL(ByRefWriteBarrier_NoShadow): - // If we come here then we haven't written the value to the GC and need to. - mov DWORD PTR [edi], ecx - -LOCAL_LABEL(ByRefWriteBarrier_ShadowCheckEnd): - pop edx -#endif // WRITE_BARRIER_CHECK - - // test for *src in ephemeral segement - push eax - PREPARE_EXTERNAL_VAR g_ephemeral_low, eax - cmp ecx, [eax] - pop eax - jb LOCAL_LABEL(ByRefWriteBarrier_NotInEphemeral) - push eax - PREPARE_EXTERNAL_VAR g_ephemeral_high, eax - cmp ecx, [eax] - pop eax - jae LOCAL_LABEL(ByRefWriteBarrier_NotInEphemeral) - - mov ecx, edi - add esi, 4 - add edi, 4 - - shr ecx, 10 - push eax - PREPARE_EXTERNAL_VAR g_card_table, eax - add ecx, [eax] - pop eax - cmp BYTE PTR [ecx], 0xFF - jne LOCAL_LABEL(ByRefWriteBarrier_UpdateCardTable) - ret -LOCAL_LABEL(ByRefWriteBarrier_UpdateCardTable): - mov BYTE PTR [ecx], 0xFF - ret - -LOCAL_LABEL(ByRefWriteBarrier_NotInHeap): - // If it wasn't in the heap then we haven't updated the dst in memory yet - mov [edi], ecx -LOCAL_LABEL(ByRefWriteBarrier_NotInEphemeral): - // If it is in the GC Heap but isn't in the ephemeral range we've already - // updated the Heap with the Object*. - add esi, 4 - add edi, 4 - ret -NESTED_END JIT_ByRefWriteBarrier, _TEXT - -.endm - // JIT_WriteBarrierGroup and JIT_WriteBarrierGroup_End are used // to determine bounds of WriteBarrier functions so can determine if got AV in them. // @@ -414,8 +248,6 @@ WriteBarrierHelper ESI WriteBarrierHelper EDI WriteBarrierHelper EBP -ByRefWriteBarrierHelper - // This is the first function outside the "keep together range". Used by BBT scripts. LEAF_ENTRY JIT_WriteBarrierGroup_End, _TEXT ret diff --git a/src/coreclr/vm/i386/jithelp.asm b/src/coreclr/vm/i386/jithelp.asm index cfbe93ccd6d38e..e8535454472671 100644 --- a/src/coreclr/vm/i386/jithelp.asm +++ b/src/coreclr/vm/i386/jithelp.asm @@ -267,143 +267,6 @@ _JIT_CheckedWriteBarrier&rg&@0 ENDP ENDM -;*** -;JIT_ByRefWriteBarrier* - GC write barrier helper -; -;Purpose: -; Helper calls in order to assign an object to a byref field -; Enables book-keeping of the GC. -; -;Entry: -; EDI - address of ref-field (assigned to) -; ESI - address of the data (source) -; ECX can be trashed -; -;Exit: -; -;Uses: -; EDI and ESI are incremented by a DWORD -; -;Exceptions: -; -;******************************************************************************* - -; The code here is tightly coupled with AdjustContextForJITHelpers, if you change -; anything here, you might need to change AdjustContextForJITHelpers as well - -ByRefWriteBarrierHelper MACRO - ALIGN 4 -PUBLIC _JIT_ByRefWriteBarrier@0 -_JIT_ByRefWriteBarrier@0 PROC - ;;test for dest in range - mov ecx, [esi] - cmp edi, g_lowest_address - jb ByRefWriteBarrier_NotInHeap - cmp edi, g_highest_address - jae ByRefWriteBarrier_NotInHeap - -ifndef WRITE_BARRIER_CHECK - ;;write barrier - mov [edi],ecx -endif - -ifdef WRITE_BARRIER_CHECK - ; Test dest here so if it is bad AV would happen before we change register/stack - ; status. This makes job of AdjustContextForJITHelpers easier. - cmp [edi], 0 - - ;; ALSO update the shadow GC heap if that is enabled - - ; use edx for address in GC Shadow, - push edx - - ;if g_GCShadow is 0, don't do the update - cmp g_GCShadow, 0 - je ByRefWriteBarrier_NoShadow - - mov edx, edi - sub edx, g_lowest_address ; U/V - jb ByRefWriteBarrier_NoShadow - add edx, [g_GCShadow] - cmp edx, [g_GCShadowEnd] - jae ByRefWriteBarrier_NoShadow - - ; TODO: In Orcas timeframe if we move to P4+ only on X86 we should enable - ; mfence barriers on either side of these two writes to make sure that - ; they stay as close together as possible - - ; edi contains address in GC - ; edx contains address in ShadowGC - ; ecx is the value to assign - - ;; When we're writing to the shadow GC heap we want to be careful to minimize - ;; the risk of a race that can occur here where the GC and ShadowGC don't match - mov DWORD PTR [edi], ecx - mov DWORD PTR [edx], ecx - - ;; We need a scratch register to verify the shadow heap. We also need to - ;; construct a memory barrier so that the write to the shadow heap happens - ;; before the read from the GC heap. We can do both by using SUB/XCHG - ;; rather than PUSH. - ;; - ;; TODO: Should be changed to a push if the mfence described above is added. - ;; - sub esp, 4 - xchg [esp], eax - - ;; As part of our race avoidance (see above) we will now check whether the values - ;; in the GC and ShadowGC match. There is a possibility that we're wrong here but - ;; being overaggressive means we might mask a case where someone updates GC refs - ;; without going to a write barrier, but by its nature it will be indeterminant - ;; and we will find real bugs whereas the current implementation is indeterminant - ;; but only leads to investigations that find that this code is fundamentally flawed - - mov eax, [edi] - cmp [edx], eax - je ByRefWriteBarrier_CleanupShadowCheck - mov [edx], INVALIDGCVALUE -ByRefWriteBarrier_CleanupShadowCheck: - pop eax - jmp ByRefWriteBarrier_ShadowCheckEnd - -ByRefWriteBarrier_NoShadow: - ; If we come here then we haven't written the value to the GC and need to. - mov DWORD PTR [edi], ecx - -ByRefWriteBarrier_ShadowCheckEnd: - pop edx -endif - ;;test for *src in ephemeral segement - cmp ecx, g_ephemeral_low - jb ByRefWriteBarrier_NotInEphemeral - cmp ecx, g_ephemeral_high - jae ByRefWriteBarrier_NotInEphemeral - - mov ecx, edi - add esi,4 - add edi,4 - - shr ecx, 10 - add ecx, [g_card_table] - cmp byte ptr [ecx], 0FFh - jne ByRefWriteBarrier_UpdateCardTable - ret -ByRefWriteBarrier_UpdateCardTable: - mov byte ptr [ecx], 0FFh - ret - -ByRefWriteBarrier_NotInHeap: - ; If it wasn't in the heap then we haven't updated the dst in memory yet - mov [edi],ecx -ByRefWriteBarrier_NotInEphemeral: - ; If it is in the GC Heap but isn't in the ephemeral range we've already - ; updated the Heap with the Object*. - add esi,4 - add edi,4 - ret -_JIT_ByRefWriteBarrier@0 ENDP -ENDM - ;******************************************************************************* ; Write barrier wrappers with fcall calling convention ; @@ -448,8 +311,6 @@ WriteBarrierHelper WriteBarrierHelper WriteBarrierHelper -ByRefWriteBarrierHelper - ; This is the first function outside the "keep together range". Used by BBT scripts. PUBLIC _JIT_WriteBarrierGroup_End@0 _JIT_WriteBarrierGroup_End@0 PROC diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 7edb58ba06162d..c5c8445d957a45 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -192,7 +192,6 @@ extern "C" FCDECL2_RAW(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref) #ifdef TARGET_ARM64 #define RhpCheckedAssignRef RhpCheckedAssignRefArm64 -#define RhpByRefAssignRef RhpByRefAssignRefArm64 #define RhpAssignRef RhpAssignRefArm64 #elif defined (TARGET_LOONGARCH64) #define RhpAssignRef RhpAssignRefLoongArch64 @@ -203,7 +202,6 @@ extern "C" FCDECL2_RAW(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref) #endif // FEATURE_USE_ASM_GC_WRITE_BARRIERS && defined(FEATURE_COUNT_GC_WRITE_BARRIERS) extern "C" FCDECL2_RAW(VOID, RhpCheckedAssignRef, Object **dst, Object *ref); -extern "C" FCDECL2_RAW(VOID, RhpByRefAssignRef, Object **dst, Object **ref); extern "C" FCDECL2_RAW(VOID, RhpAssignRef, Object **dst, Object *ref); extern "C" FCDECL2_RAW(VOID, JIT_WriteBarrier, Object **dst, Object *ref); @@ -259,8 +257,6 @@ void ValidateWriteBarrierHelpers(); extern "C" { - void STDCALL JIT_ByRefWriteBarrier(); // JIThelp.asm/JIThelp.s - #if defined(TARGET_X86) && !defined(UNIX_X86_ABI) void STDCALL JIT_TailCall(); // JIThelp.asm #endif // defined(TARGET_X86) && !defined(UNIX_X86_ABI) diff --git a/src/coreclr/vm/loongarch64/asmhelpers.S b/src/coreclr/vm/loongarch64/asmhelpers.S index 3b47125fa8dfdb..8b4b4736a629c1 100644 --- a/src/coreclr/vm/loongarch64/asmhelpers.S +++ b/src/coreclr/vm/loongarch64/asmhelpers.S @@ -120,22 +120,6 @@ LEAF_ENTRY JIT_PatchedCodeStart, _TEXT jirl $r0, $ra, 0 LEAF_END JIT_PatchedCodeStart, _TEXT -// void JIT_ByRefWriteBarrier -// -// On entry: -// t8 : the source address (points to object reference to write) -// t6: the destination address (object reference written here) -// -// On exit: -// t8 : incremented by 8 -// t7 : trashed -// -WRITE_BARRIER_ENTRY JIT_ByRefWriteBarrier - ld.d $t7, $t8, 0 - addi.d $t8, $t8, 8 - b C_FUNC(JIT_CheckedWriteBarrier) -WRITE_BARRIER_END JIT_ByRefWriteBarrier - //----------------------------------------------------------------------------- // Simple WriteBarriers // void JIT_CheckedWriteBarrier(Object** dst, Object* src) @@ -149,7 +133,7 @@ WRITE_BARRIER_END JIT_ByRefWriteBarrier // $t0 : trashed // $t3 : trashed // $t4 : trashed -// $t6 : trashed (incremented by 8 to implement JIT_ByRefWriteBarrier contract) +// $t6 : preserved (the destination address is not modified) // WRITE_BARRIER_ENTRY JIT_CheckedWriteBarrier @@ -168,7 +152,6 @@ WRITE_BARRIER_ENTRY JIT_CheckedWriteBarrier beq $t4, $zero, C_FUNC(JIT_WriteBarrier) st.d $t7, $t6, 0 - addi.d $t6, $t6, 8 jirl $r0, $ra, 0 WRITE_BARRIER_END JIT_CheckedWriteBarrier @@ -182,7 +165,7 @@ WRITE_BARRIER_END JIT_CheckedWriteBarrier // $t1 : trashed // $t3 : trashed // $t4 : trashed -// $t6 : trashed (incremented by 8 to implement JIT_ByRefWriteBarrier contract) +// $t6 : preserved (the destination address is not modified) // $t7 : trashed // WRITE_BARRIER_ENTRY JIT_WriteBarrier @@ -297,7 +280,6 @@ LOCAL_LABEL(SkipEphemeralCheck): st.b $t4, $t7, 0 #endif LOCAL_LABEL(Exit): - addi.d $t6, $t6, 8 jirl $r0, $ra, 0 WRITE_BARRIER_END JIT_WriteBarrier diff --git a/src/coreclr/vm/riscv64/asmhelpers.S b/src/coreclr/vm/riscv64/asmhelpers.S index 771dab4df4402e..c180a1e2e4a2c5 100644 --- a/src/coreclr/vm/riscv64/asmhelpers.S +++ b/src/coreclr/vm/riscv64/asmhelpers.S @@ -106,24 +106,6 @@ LEAF_ENTRY JIT_PatchedCodeStart, _TEXT ret LEAF_END JIT_PatchedCodeStart, _TEXT -// void JIT_ByRefWriteBarrier -// -// On entry: -// t5 : the source address (points to object reference to write) -// t3: the destination address (object reference written here) -// -// On exit: -// t5 : incremented by 8 -// t4 : trashed -// - -// void JIT_ByRefWriteBarrier -WRITE_BARRIER_ENTRY JIT_ByRefWriteBarrier - ld t4, 0(t5) - addi t5, t5, 8 - tail C_FUNC(JIT_CheckedWriteBarrier) -WRITE_BARRIER_END JIT_ByRefWriteBarrier - //----------------------------------------------------------------------------- // Simple WriteBarriers // void JIT_CheckedWriteBarrier(Object** dst, Object* src) @@ -136,7 +118,7 @@ WRITE_BARRIER_END JIT_ByRefWriteBarrier // t1 : trashed // t0 : trashed // t6 : trashed -// t3 : trashed (incremented by 8 to implement JIT_ByRefWriteBarrier contract) +// t3 : preserved (the destination address is not modified) // WRITE_BARRIER_ENTRY JIT_CheckedWriteBarrier @@ -149,7 +131,6 @@ WRITE_BARRIER_ENTRY JIT_CheckedWriteBarrier beq t6, zero, C_FUNC(JIT_WriteBarrier) sd t4, 0(t3) - addi t3, t3, 8 ret WRITE_BARRIER_END JIT_CheckedWriteBarrier @@ -163,7 +144,7 @@ WRITE_BARRIER_END JIT_CheckedWriteBarrier // t1 : trashed // t6 : trashed // t4 : trashed -// t3 : trashed (incremented by 8 to implement JIT_ByRefWriteBarrier contract) +// t3 : preserved (the destination address is not modified) // WRITE_BARRIER_ENTRY JIT_WriteBarrier // TODO: sync_release (runtime detection required) @@ -258,7 +239,6 @@ LOCAL_LABEL(SkipEphemeralCheck): sb t0, 0(t4) #endif LOCAL_LABEL(Exit): - addi t3, t3, 8 ret WRITE_BARRIER_END JIT_WriteBarrier diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index 0601b14e1995f6..e820c8678586e0 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -1104,16 +1104,12 @@ void InitThreadManager() SetJitHelperFunction(CORINFO_HELP_CHECKED_ASSIGN_REF, GetWriteBarrierCodeLocation((void*)JIT_CheckedWriteBarrier)); SetAuxiliarySymbol(GetWriteBarrierCodeLocation((void*)JIT_CheckedWriteBarrier), "JIT_CheckedWriteBarrier"); ETW::MethodLog::StubInitialized((ULONGLONG)GetWriteBarrierCodeLocation((void*)JIT_CheckedWriteBarrier), W("@CheckedWriteBarrier")); - SetJitHelperFunction(CORINFO_HELP_ASSIGN_BYREF, GetWriteBarrierCodeLocation((void*)JIT_ByRefWriteBarrier)); - SetAuxiliarySymbol(GetWriteBarrierCodeLocation((void*)JIT_ByRefWriteBarrier), "JIT_ByRefWriteBarrier"); - ETW::MethodLog::StubInitialized((ULONGLONG)GetWriteBarrierCodeLocation((void*)JIT_ByRefWriteBarrier), W("@ByRefWriteBarrier")); #endif // TARGET_ARM64 || TARGET_ARM || TARGET_LOONGARCH64 || TARGET_RISCV64 #if defined(TARGET_AMD64) - // On AMD64 the Checked/ByRef variants of the helpers jump through an indirection - // to the patched barrier, but are not part of the patched set of helpers. + // On AMD64 the Checked variant of the helper jumps through an indirection + // to the patched barrier, but is not part of the patched set of helpers. SetJitHelperFunction(CORINFO_HELP_CHECKED_ASSIGN_REF, (void*)JIT_CheckedWriteBarrier); - SetJitHelperFunction(CORINFO_HELP_ASSIGN_BYREF, (void*)JIT_ByRefWriteBarrier); #endif // TARGET_AMD64 } diff --git a/src/coreclr/vm/wasm/helpers.cpp b/src/coreclr/vm/wasm/helpers.cpp index f82a4826b37dec..7b55adb4ecc49f 100644 --- a/src/coreclr/vm/wasm/helpers.cpp +++ b/src/coreclr/vm/wasm/helpers.cpp @@ -526,11 +526,6 @@ EXTERN_C void JIT_CheckedWriteBarrier_End() PORTABILITY_ASSERT("JIT_CheckedWriteBarrier_End is not implemented on wasm"); } -EXTERN_C void JIT_ByRefWriteBarrier_End() -{ - PORTABILITY_ASSERT("JIT_ByRefWriteBarrier_End is not implemented on wasm"); -} - EXTERN_C void JIT_StackProbe_End() { PORTABILITY_ASSERT("JIT_StackProbe_End is not implemented on wasm"); @@ -622,8 +617,6 @@ extern "C" void RhpVTableOffsetDispatch() typedef uint8_t CODE_LOCATION; CODE_LOCATION RhpAssignRefAVLocation; CODE_LOCATION RhpCheckedAssignRefAVLocation; -CODE_LOCATION RhpByRefAssignRefAVLocation1; -CODE_LOCATION RhpByRefAssignRefAVLocation2; extern "C" void ThisPtrRetBufPrecodeWorker() { diff --git a/src/tests/JIT/Regression/JitBlue/GitHub_19361/GitHub_19361.cs b/src/tests/JIT/Regression/JitBlue/GitHub_19361/GitHub_19361.cs index 703d40d319811d..2162678a88a892 100644 --- a/src/tests/JIT/Regression/JitBlue/GitHub_19361/GitHub_19361.cs +++ b/src/tests/JIT/Regression/JitBlue/GitHub_19361/GitHub_19361.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// The test exposed a bug in CORINFO_HELP_ASSIGN_BYREF GC kill set on Unix x64. +// The test exposed a bug in the GC write barrier kill set on Unix x64 // that caused segfault. using System; diff --git a/src/tests/JIT/Regression/JitBlue/GitHub_19444/GitHub_19444.cs b/src/tests/JIT/Regression/JitBlue/GitHub_19444/GitHub_19444.cs index 447b06c0b4029d..a10af2d58d8049 100644 --- a/src/tests/JIT/Regression/JitBlue/GitHub_19444/GitHub_19444.cs +++ b/src/tests/JIT/Regression/JitBlue/GitHub_19444/GitHub_19444.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// This test case illustrates a bug where the JIT_ByRefWriteBarrier was not +// This test case illustrates a bug where the byref GC write barrier was not // included in IsIPInMarkedJitHelper on non-32-bit-x86 platforms. diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_125169/Runtime_125169.cs b/src/tests/JIT/Regression/JitBlue/Runtime_125169/Runtime_125169.cs index c8053e1c7e5bd0..3873689a5c5a17 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_125169/Runtime_125169.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_125169/Runtime_125169.cs @@ -22,7 +22,7 @@ public readonly ref struct RefWrapper public class Runtime_125169 { // Regression test for bug in JIT where ref struct static fields of reference type initialized in - // its static constructor were missing calls to JIT_ByRefWriteBarrier for each such static field. + // its static constructor were missing write barriers for each such static field. [Fact] public static void TestEntryPoint() {