diff --git a/docs/design/coreclr/botr/readytorun-format.md b/docs/design/coreclr/botr/readytorun-format.md index a165b7c5d61502..34dd3b10627358 100644 --- a/docs/design/coreclr/botr/readytorun-format.md +++ b/docs/design/coreclr/botr/readytorun-format.md @@ -982,20 +982,6 @@ enum ReadyToRunHelper // Deprecated/legacy // - // JIT32 x86-specific write barriers - READYTORUN_HELPER_WriteBarrier_EAX = 0x100, - READYTORUN_HELPER_WriteBarrier_EBX = 0x101, - READYTORUN_HELPER_WriteBarrier_ECX = 0x102, - READYTORUN_HELPER_WriteBarrier_ESI = 0x103, - READYTORUN_HELPER_WriteBarrier_EDI = 0x104, - READYTORUN_HELPER_WriteBarrier_EBP = 0x105, - READYTORUN_HELPER_CheckedWriteBarrier_EAX = 0x106, - READYTORUN_HELPER_CheckedWriteBarrier_EBX = 0x107, - READYTORUN_HELPER_CheckedWriteBarrier_ECX = 0x108, - READYTORUN_HELPER_CheckedWriteBarrier_ESI = 0x109, - READYTORUN_HELPER_CheckedWriteBarrier_EDI = 0x10A, - READYTORUN_HELPER_CheckedWriteBarrier_EBP = 0x10B, - // JIT32 x86-specific exception handling READYTORUN_HELPER_EndCatch = 0x110, }; diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 5ac1524d19c6f1..1111a1bb2e748c 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -524,25 +524,6 @@ enum CorInfoHelpFunc CORINFO_HELP_EE_PERSONALITY_ROUTINE,// Not real JIT helper. Used in native images. CORINFO_HELP_EE_PERSONALITY_ROUTINE_FILTER_FUNCLET,// Not real JIT helper. Used in native images to detect filter funclets. - // ASSIGN_REF_EAX - CHECKED_ASSIGN_REF_EBP: NOGC_WRITE_BARRIERS JIT helper calls - // - // For unchecked versions EDX is required to point into GC heap. - // - // NOTE: these helpers are only used for x86. - CORINFO_HELP_ASSIGN_REF_EAX, // EAX holds GC ptr, do a 'mov [EDX], EAX' and inform GC - CORINFO_HELP_ASSIGN_REF_EBX, // EBX holds GC ptr, do a 'mov [EDX], EBX' and inform GC - CORINFO_HELP_ASSIGN_REF_ECX, // ECX holds GC ptr, do a 'mov [EDX], ECX' and inform GC - CORINFO_HELP_ASSIGN_REF_ESI, // ESI holds GC ptr, do a 'mov [EDX], ESI' and inform GC - CORINFO_HELP_ASSIGN_REF_EDI, // EDI holds GC ptr, do a 'mov [EDX], EDI' and inform GC - CORINFO_HELP_ASSIGN_REF_EBP, // EBP holds GC ptr, do a 'mov [EDX], EBP' and inform GC - - CORINFO_HELP_CHECKED_ASSIGN_REF_EAX, // These are the same as ASSIGN_REF above ... - CORINFO_HELP_CHECKED_ASSIGN_REF_EBX, // ... but also check if EDX points into heap. - CORINFO_HELP_CHECKED_ASSIGN_REF_ECX, - CORINFO_HELP_CHECKED_ASSIGN_REF_ESI, - CORINFO_HELP_CHECKED_ASSIGN_REF_EDI, - CORINFO_HELP_CHECKED_ASSIGN_REF_EBP, - CORINFO_HELP_LOOP_CLONE_CHOICE_ADDR, // Return the reference to a counter to decide to take cloned path in debug stress. CORINFO_HELP_DEBUG_LOG_LOOP_CLONING, // Print a message that a loop cloning optimization has occurred in debug mode. diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 3f1d8e566f18f4..2d070c5779e272 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -37,11 +37,11 @@ #include -constexpr GUID JITEEVersionIdentifier = { /* 31a04b06-915e-42a0-bbd2-c9c397677ae5 */ - 0x31a04b06, - 0x915e, - 0x42a0, - {0xbb, 0xd2, 0xc9, 0xc3, 0x97, 0x67, 0x7a, 0xe5} +constexpr GUID JITEEVersionIdentifier = { /* 5fc51288-a3f3-4291-be1d-c626ccdd3235 */ + 0x5fc51288, + 0xa3f3, + 0x4291, + {0xbe, 0x1d, 0xc6, 0x26, 0xcc, 0xdd, 0x32, 0x35} }; #endif // JIT_EE_VERSIONING_GUID_H diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index 281302ccbc742c..dae44145e692fe 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -262,36 +262,6 @@ DYNAMICJITHELPER(CORINFO_HELP_EE_PERSONALITY_ROUTINE, ProcessCLRException, METHOD__NIL) DYNAMICJITHELPER(CORINFO_HELP_EE_PERSONALITY_ROUTINE_FILTER_FUNCLET, ProcessCLRException,METHOD__NIL) -#ifdef TARGET_X86 - DYNAMICJITHELPER(CORINFO_HELP_ASSIGN_REF_EAX, RhpAssignRefEAX, METHOD__NIL) - DYNAMICJITHELPER(CORINFO_HELP_ASSIGN_REF_EBX, RhpAssignRefEBX, METHOD__NIL) - DYNAMICJITHELPER(CORINFO_HELP_ASSIGN_REF_ECX, RhpAssignRefECX, METHOD__NIL) - DYNAMICJITHELPER(CORINFO_HELP_ASSIGN_REF_ESI, RhpAssignRefESI, METHOD__NIL) - DYNAMICJITHELPER(CORINFO_HELP_ASSIGN_REF_EDI, RhpAssignRefEDI, METHOD__NIL) - DYNAMICJITHELPER(CORINFO_HELP_ASSIGN_REF_EBP, RhpAssignRefEBP, METHOD__NIL) - - JITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF_EAX, RhpCheckedAssignRefEAX, METHOD__NIL) - JITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF_EBX, RhpCheckedAssignRefEBX, METHOD__NIL) - JITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF_ECX, RhpCheckedAssignRefECX, METHOD__NIL) - JITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF_ESI, RhpCheckedAssignRefESI, METHOD__NIL) - JITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF_EDI, RhpCheckedAssignRefEDI, METHOD__NIL) - JITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF_EBP, RhpCheckedAssignRefEBP, METHOD__NIL) -#else - JITHELPER(CORINFO_HELP_ASSIGN_REF_EAX, NULL, METHOD__NIL) - JITHELPER(CORINFO_HELP_ASSIGN_REF_EBX, NULL, METHOD__NIL) - JITHELPER(CORINFO_HELP_ASSIGN_REF_ECX, NULL, METHOD__NIL) - JITHELPER(CORINFO_HELP_ASSIGN_REF_ESI, NULL, METHOD__NIL) - JITHELPER(CORINFO_HELP_ASSIGN_REF_EDI, NULL, METHOD__NIL) - JITHELPER(CORINFO_HELP_ASSIGN_REF_EBP, NULL, METHOD__NIL) - - JITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF_EAX, NULL, METHOD__NIL) - JITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF_EBX, NULL, METHOD__NIL) - JITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF_ECX, NULL, METHOD__NIL) - JITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF_ESI, NULL, METHOD__NIL) - JITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF_EDI, NULL, METHOD__NIL) - JITHELPER(CORINFO_HELP_CHECKED_ASSIGN_REF_EBP, NULL, METHOD__NIL) -#endif - JITHELPER(CORINFO_HELP_LOOP_CLONE_CHOICE_ADDR, JIT_LoopCloneChoiceAddr, METHOD__NIL) JITHELPER(CORINFO_HELP_DEBUG_LOG_LOOP_CLONING, JIT_DebugLogLoopCloning, METHOD__NIL) diff --git a/src/coreclr/inc/readytorun.h b/src/coreclr/inc/readytorun.h index 44808a73fbe821..3434137211094b 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 19 +#define READYTORUN_MAJOR_VERSION 20 #define READYTORUN_MINOR_VERSION 0x0000 -#define MINIMUM_READYTORUN_MAJOR_VERSION 19 +#define MINIMUM_READYTORUN_MAJOR_VERSION 20 // R2R Version 2.1 adds the InliningInfo section // R2R Version 2.2 adds the ProfileDataInfo section @@ -59,6 +59,7 @@ // 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 +// R2R Version 20 removes the per-source-register x86 write barrier helpers (READYTORUN_HELPER_(Checked)WriteBarrier_E[reg]) struct READYTORUN_CORE_HEADER { @@ -467,20 +468,6 @@ enum ReadyToRunHelper // Deprecated/legacy // - // JIT32 x86-specific write barriers - READYTORUN_HELPER_WriteBarrier_EAX = 0x100, - READYTORUN_HELPER_WriteBarrier_EBX = 0x101, - READYTORUN_HELPER_WriteBarrier_ECX = 0x102, - READYTORUN_HELPER_WriteBarrier_ESI = 0x103, - READYTORUN_HELPER_WriteBarrier_EDI = 0x104, - READYTORUN_HELPER_WriteBarrier_EBP = 0x105, - READYTORUN_HELPER_CheckedWriteBarrier_EAX = 0x106, - READYTORUN_HELPER_CheckedWriteBarrier_EBX = 0x107, - READYTORUN_HELPER_CheckedWriteBarrier_ECX = 0x108, - READYTORUN_HELPER_CheckedWriteBarrier_ESI = 0x109, - READYTORUN_HELPER_CheckedWriteBarrier_EDI = 0x10A, - READYTORUN_HELPER_CheckedWriteBarrier_EBP = 0x10B, - // JIT32 x86-specific exception handling READYTORUN_HELPER_EndCatch = 0x110, // Unused since READYTORUN_MAJOR_VERSION 14.0 diff --git a/src/coreclr/inc/readytorunhelpers.h b/src/coreclr/inc/readytorunhelpers.h index 4c3fca575d0ae5..a69bf9e7542617 100644 --- a/src/coreclr/inc/readytorunhelpers.h +++ b/src/coreclr/inc/readytorunhelpers.h @@ -99,21 +99,6 @@ HELPER(READYTORUN_HELPER_PersonalityRoutine, CORINFO_HELP_EE_PERSONALITY_ HELPER(READYTORUN_HELPER_PersonalityRoutineFilterFunclet, CORINFO_HELP_EE_PERSONALITY_ROUTINE_FILTER_FUNCLET, OPTIMIZEFORSIZE) #endif -#ifdef TARGET_X86 -HELPER(READYTORUN_HELPER_WriteBarrier_EAX, CORINFO_HELP_ASSIGN_REF_EAX, ) -HELPER(READYTORUN_HELPER_WriteBarrier_EBX, CORINFO_HELP_ASSIGN_REF_EBX, ) -HELPER(READYTORUN_HELPER_WriteBarrier_ECX, CORINFO_HELP_ASSIGN_REF_ECX, ) -HELPER(READYTORUN_HELPER_WriteBarrier_ESI, CORINFO_HELP_ASSIGN_REF_ESI, ) -HELPER(READYTORUN_HELPER_WriteBarrier_EDI, CORINFO_HELP_ASSIGN_REF_EDI, ) -HELPER(READYTORUN_HELPER_WriteBarrier_EBP, CORINFO_HELP_ASSIGN_REF_EBP, ) -HELPER(READYTORUN_HELPER_CheckedWriteBarrier_EAX, CORINFO_HELP_CHECKED_ASSIGN_REF_EAX, ) -HELPER(READYTORUN_HELPER_CheckedWriteBarrier_EBX, CORINFO_HELP_CHECKED_ASSIGN_REF_EBX, ) -HELPER(READYTORUN_HELPER_CheckedWriteBarrier_ECX, CORINFO_HELP_CHECKED_ASSIGN_REF_ECX, ) -HELPER(READYTORUN_HELPER_CheckedWriteBarrier_ESI, CORINFO_HELP_CHECKED_ASSIGN_REF_ESI, ) -HELPER(READYTORUN_HELPER_CheckedWriteBarrier_EDI, CORINFO_HELP_CHECKED_ASSIGN_REF_EDI, ) -HELPER(READYTORUN_HELPER_CheckedWriteBarrier_EBP, CORINFO_HELP_CHECKED_ASSIGN_REF_EBP, ) -#endif - HELPER(READYTORUN_HELPER_PInvokeBegin, CORINFO_HELP_JIT_PINVOKE_BEGIN, ) HELPER(READYTORUN_HELPER_PInvokeEnd, CORINFO_HELP_JIT_PINVOKE_END, ) HELPER(READYTORUN_HELPER_GCPoll, CORINFO_HELP_POLL_GC, ) diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index 30df97543bec50..2f1fa1d73439ee 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -1270,7 +1270,6 @@ class CodeGen final : public CodeGenInterface regNumber targetReg, GenTreeIndir* indir, bool* needsBarrier); - bool genEmitOptimizedGCWriteBarrier(GCInfo::WriteBarrierForm writeBarrierForm, GenTree* addr, GenTree* data); GenTree* getCallTarget(const GenTreeCall* call, CORINFO_METHOD_HANDLE* methHnd); regNumber getCallIndirectionCellReg(GenTreeCall* call); void genCall(GenTreeCall* call); diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 6cc7cb9874d6c8..34521eec152958 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -925,23 +925,6 @@ regMaskTP Compiler::compHelperCallKillSet(CorInfoHelpFunc helper) case CORINFO_HELP_PROF_FCN_TAILCALL: return RBM_PROFILER_TAILCALL_TRASH; -#ifdef TARGET_X86 - case CORINFO_HELP_ASSIGN_REF_EAX: - case CORINFO_HELP_ASSIGN_REF_ECX: - case CORINFO_HELP_ASSIGN_REF_EBX: - case CORINFO_HELP_ASSIGN_REF_EBP: - case CORINFO_HELP_ASSIGN_REF_ESI: - case CORINFO_HELP_ASSIGN_REF_EDI: - - case CORINFO_HELP_CHECKED_ASSIGN_REF_EAX: - case CORINFO_HELP_CHECKED_ASSIGN_REF_ECX: - case CORINFO_HELP_CHECKED_ASSIGN_REF_EBX: - case CORINFO_HELP_CHECKED_ASSIGN_REF_EBP: - case CORINFO_HELP_CHECKED_ASSIGN_REF_ESI: - case CORINFO_HELP_CHECKED_ASSIGN_REF_EDI: - return RBM_EDX; -#endif - case CORINFO_HELP_STOP_FOR_GC: return RBM_STOP_FOR_GC_TRASH; @@ -2663,55 +2646,6 @@ void CodeGen::genReportEHClauses(EHClauseInfo* clauses) } } -#ifndef TARGET_WASM - -//---------------------------------------------------------------------- -// genUseOptimizedWriteBarriers: Determine if an optimized write barrier -// helper should be used. -// -// Arguments: -// wbf - The WriteBarrierForm of the write (GT_STOREIND) that is happening. -// -// Return Value: -// true if an optimized write barrier helper should be used, false otherwise. -// Note: only x86 implements register-specific source optimized write -// barriers currently. -// -bool CodeGenInterface::genUseOptimizedWriteBarriers(GCInfo::WriteBarrierForm wbf) -{ -#if defined(TARGET_X86) && NOGC_WRITE_BARRIERS - return true; -#else - return false; -#endif -} - -//---------------------------------------------------------------------- -// genUseOptimizedWriteBarriers: Determine if an optimized write barrier -// helper should be used. -// -// This has the same functionality as the version of -// genUseOptimizedWriteBarriers that takes a WriteBarrierForm, but avoids -// determining what the required write barrier form is, if possible. -// -// Arguments: -// store - the GT_STOREIND node -// -// Return Value: -// true if an optimized write barrier helper should be used, false otherwise. -// Note: only x86 implements register-specific source optimized write -// barriers currently. -// -bool CodeGenInterface::genUseOptimizedWriteBarriers(GenTreeStoreInd* store) -{ -#if defined(TARGET_X86) && NOGC_WRITE_BARRIERS - return true; -#else - return false; -#endif -} -#endif // !TARGET_WASM - //---------------------------------------------------------------------- // genWriteBarrierHelperForWriteBarrierForm: Given a write barrier form // return the corresponding helper. @@ -2722,9 +2656,6 @@ bool CodeGenInterface::genUseOptimizedWriteBarriers(GenTreeStoreInd* store) // Return Value: // Write barrier helper to use. // -// Note: do not call this function to get an optimized write barrier helper (e.g., -// for x86). -// CorInfoHelpFunc CodeGenInterface::genWriteBarrierHelperForWriteBarrierForm(GCInfo::WriteBarrierForm wbf) { INDEBUG(genWriteBarrierUsed = true); diff --git a/src/coreclr/jit/codegeninterface.h b/src/coreclr/jit/codegeninterface.h index e696c886cd9e28..bba4a46f7eb187 100644 --- a/src/coreclr/jit/codegeninterface.h +++ b/src/coreclr/jit/codegeninterface.h @@ -238,8 +238,6 @@ class CodeGenInterface TreeLifeUpdater* treeLifeUpdater; public: - bool genUseOptimizedWriteBarriers(GCInfo::WriteBarrierForm wbf); - bool genUseOptimizedWriteBarriers(GenTreeStoreInd* store); CorInfoHelpFunc genWriteBarrierHelperForWriteBarrierForm(GCInfo::WriteBarrierForm wbf); #ifdef DEBUG diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 4cc36d3133fde0..7a2c76dfed6f20 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -5325,11 +5325,6 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree) // Consume both registers so that any copies of interfering registers are taken care of. genConsumeOperands(tree); - if (genEmitOptimizedGCWriteBarrier(writeBarrierForm, addr, data)) - { - return; - } - // At this point, we should not have any interference. // That is, 'data' must not be in REG_WRITE_BARRIER_DST, as that is where 'addr' must go. noway_assert(data->GetRegNum() != REG_WRITE_BARRIER_DST); @@ -5668,99 +5663,6 @@ void CodeGen::genCodeForSwap(GenTreeOp* tree) gcInfo.gcMarkRegPtrVal(oldOp1Reg, type2); } -//------------------------------------------------------------------------ -// genEmitOptimizedGCWriteBarrier: Generate write barrier store using the optimized -// helper functions. -// -// Arguments: -// writeBarrierForm - the write barrier form to use -// addr - the address at which to do the store -// data - the data to store -// -// Return Value: -// true if an optimized write barrier form was used, false if not. If this -// function returns false, the caller must emit a "standard" write barrier. - -bool CodeGen::genEmitOptimizedGCWriteBarrier(GCInfo::WriteBarrierForm writeBarrierForm, GenTree* addr, GenTree* data) -{ - assert(writeBarrierForm != GCInfo::WBF_NoBarrier); - -#if defined(TARGET_X86) && NOGC_WRITE_BARRIERS - if (!genUseOptimizedWriteBarriers(writeBarrierForm)) - { - return false; - } - - const static int regToHelper[2][8] = { - // If the target is known to be in managed memory - { - CORINFO_HELP_ASSIGN_REF_EAX, // EAX - CORINFO_HELP_ASSIGN_REF_ECX, // ECX - -1, // EDX (always the target address) - CORINFO_HELP_ASSIGN_REF_EBX, // EBX - -1, // ESP - CORINFO_HELP_ASSIGN_REF_EBP, // EBP - CORINFO_HELP_ASSIGN_REF_ESI, // ESI - CORINFO_HELP_ASSIGN_REF_EDI, // EDI - }, - - // Don't know if the target is in managed memory - { - CORINFO_HELP_CHECKED_ASSIGN_REF_EAX, // EAX - CORINFO_HELP_CHECKED_ASSIGN_REF_ECX, // ECX - -1, // EDX (always the target address) - CORINFO_HELP_CHECKED_ASSIGN_REF_EBX, // EBX - -1, // ESP - CORINFO_HELP_CHECKED_ASSIGN_REF_EBP, // EBP - CORINFO_HELP_CHECKED_ASSIGN_REF_ESI, // ESI - CORINFO_HELP_CHECKED_ASSIGN_REF_EDI, // EDI - }, - }; - - noway_assert(regToHelper[0][REG_EAX] == CORINFO_HELP_ASSIGN_REF_EAX); - noway_assert(regToHelper[0][REG_ECX] == CORINFO_HELP_ASSIGN_REF_ECX); - noway_assert(regToHelper[0][REG_EBX] == CORINFO_HELP_ASSIGN_REF_EBX); - noway_assert(regToHelper[0][REG_ESP] == -1); - noway_assert(regToHelper[0][REG_EBP] == CORINFO_HELP_ASSIGN_REF_EBP); - noway_assert(regToHelper[0][REG_ESI] == CORINFO_HELP_ASSIGN_REF_ESI); - noway_assert(regToHelper[0][REG_EDI] == CORINFO_HELP_ASSIGN_REF_EDI); - - noway_assert(regToHelper[1][REG_EAX] == CORINFO_HELP_CHECKED_ASSIGN_REF_EAX); - noway_assert(regToHelper[1][REG_ECX] == CORINFO_HELP_CHECKED_ASSIGN_REF_ECX); - noway_assert(regToHelper[1][REG_EBX] == CORINFO_HELP_CHECKED_ASSIGN_REF_EBX); - noway_assert(regToHelper[1][REG_ESP] == -1); - noway_assert(regToHelper[1][REG_EBP] == CORINFO_HELP_CHECKED_ASSIGN_REF_EBP); - noway_assert(regToHelper[1][REG_ESI] == CORINFO_HELP_CHECKED_ASSIGN_REF_ESI); - noway_assert(regToHelper[1][REG_EDI] == CORINFO_HELP_CHECKED_ASSIGN_REF_EDI); - - regNumber reg = data->GetRegNum(); - noway_assert((reg != REG_ESP) && (reg != REG_OPTIMIZED_WRITE_BARRIER_DST)); - - // Generate the following code: - // lea edx, addr - // call write_barrier_helper_reg - - // addr goes in REG_OPTIMIZED_WRITE_BARRIER_DST - genCopyRegIfNeeded(addr, REG_OPTIMIZED_WRITE_BARRIER_DST); - - unsigned tgtAnywhere = 0; - if (writeBarrierForm != GCInfo::WBF_BarrierUnchecked) - { - tgtAnywhere = 1; - } - - // Here we might want to call a modified version of genGCWriteBarrier() to get the benefit - // of the FEATURE_COUNT_GC_WRITE_BARRIERS code. For now, just emit the helper call directly. - genEmitHelperCall(regToHelper[tgtAnywhere][reg], - 0, // argSize - EA_PTRSIZE); // retSize - - return true; -#else // !defined(TARGET_X86) || !NOGC_WRITE_BARRIERS - return false; -#endif // !defined(TARGET_X86) || !NOGC_WRITE_BARRIERS -} - // Produce code for a GT_CALL node void CodeGen::genCall(GenTreeCall* call) { diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 8e69cdb7d7102e..13965e01bf10ad 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -677,20 +677,9 @@ regMaskTP LinearScan::getKillSetForStoreInd(GenTreeStoreInd* tree) GCInfo::WriteBarrierForm writeBarrierForm = m_compiler->codeGen->gcInfo.gcIsWriteBarrierCandidate(tree); if (writeBarrierForm != GCInfo::WBF_NoBarrier) { - if (m_compiler->codeGen->genUseOptimizedWriteBarriers(writeBarrierForm)) - { - // We can't determine the exact helper to be used at this point, because it depends on - // the allocated register for the `data` operand. However, all the (x86) optimized - // helpers have the same kill set: EDX. And note that currently, only x86 can return - // `true` for genUseOptimizedWriteBarriers(). - killMask = RBM_CALLEE_TRASH_NOGC; - } - else - { - // Figure out which helper we're going to use, and then get the kill set for that helper. - CorInfoHelpFunc helper = m_compiler->codeGen->genWriteBarrierHelperForWriteBarrierForm(writeBarrierForm); - killMask = m_compiler->compHelperCallKillSet(helper); - } + // Figure out which helper we're going to use, and then get the kill set for that helper. + CorInfoHelpFunc helper = m_compiler->codeGen->genWriteBarrierHelperForWriteBarrierForm(writeBarrierForm); + killMask = m_compiler->compHelperCallKillSet(helper); } return killMask; } @@ -4542,20 +4531,6 @@ int LinearScan::BuildGCWriteBarrier(GenTree* tree) SingleTypeRegSet addrCandidates = RBM_WRITE_BARRIER_DST.GetIntRegSet(); SingleTypeRegSet srcCandidates = RBM_WRITE_BARRIER_SRC.GetIntRegSet(); -#if defined(TARGET_X86) && NOGC_WRITE_BARRIERS - - bool useOptimizedWriteBarrierHelper = m_compiler->codeGen->genUseOptimizedWriteBarriers(tree->AsStoreInd()); - if (useOptimizedWriteBarrierHelper) - { - // Special write barrier: - // op1 (addr) goes into REG_OPTIMIZED_WRITE_BARRIER_DST (rdx) and - // op2 (src) goes into any int register. - addrCandidates = RBM_OPTIMIZED_WRITE_BARRIER_DST.GetIntRegSet(); - srcCandidates = RBM_OPTIMIZED_WRITE_BARRIER_SRC.GetIntRegSet(); - } - -#endif // defined(TARGET_X86) && NOGC_WRITE_BARRIERS - BuildUse(addr, addrCandidates); BuildUse(src, srcCandidates); diff --git a/src/coreclr/jit/targetamd64.h b/src/coreclr/jit/targetamd64.h index 55c0dae697d7b6..07b901642b1ec0 100644 --- a/src/coreclr/jit/targetamd64.h +++ b/src/coreclr/jit/targetamd64.h @@ -61,7 +61,6 @@ // MAX_MULTIREG_COUNT - 1. #endif // !UNIX_AMD64_ABI -#define NOGC_WRITE_BARRIERS 0 // We DO-NOT have specialized WriteBarrier JIT Helpers that DO-NOT trash the RBM_CALLEE_TRASH registers #define USER_ARGS_COME_LAST 1 #define TARGET_POINTER_SIZE 8 // equal to sizeof(void*) and the managed pointer size in bytes for this target #ifdef UNIX_AMD64_ABI diff --git a/src/coreclr/jit/targetarm.h b/src/coreclr/jit/targetarm.h index 7101102f31d9ec..9c9751f707883e 100644 --- a/src/coreclr/jit/targetarm.h +++ b/src/coreclr/jit/targetarm.h @@ -33,7 +33,6 @@ #define MAX_MULTIREG_COUNT 4 // Maximum number of registers defined by a single instruction (including calls). // This is also the maximum number of registers for a MultiReg node. -#define NOGC_WRITE_BARRIERS 0 // We DO-NOT have specialized WriteBarrier JIT Helpers that DO-NOT trash the RBM_CALLEE_TRASH registers #define USER_ARGS_COME_LAST 1 #define TARGET_POINTER_SIZE 4 // equal to sizeof(void*) and the managed pointer size in bytes for this target #define ETW_EBP_FRAMED 1 // if 1 we cannot use REG_FP as a scratch register and must setup the frame pointer for most methods diff --git a/src/coreclr/jit/targetarm64.h b/src/coreclr/jit/targetarm64.h index b9f2d9a54ea7a3..f9ce811721d3f8 100644 --- a/src/coreclr/jit/targetarm64.h +++ b/src/coreclr/jit/targetarm64.h @@ -35,7 +35,6 @@ #define MAX_MULTIREG_COUNT 4 // Maximum number of registers defined by a single instruction (including calls). // This is also the maximum number of registers for a MultiReg node. -#define NOGC_WRITE_BARRIERS 1 // We have specialized WriteBarrier JIT Helpers that DO-NOT trash the RBM_CALLEE_TRASH registers #define USER_ARGS_COME_LAST 1 #define TARGET_POINTER_SIZE 8 // equal to sizeof(void*) and the managed pointer size in bytes for this target #define ETW_EBP_FRAMED 1 // if 1 we cannot use REG_FP as a scratch register and must setup the frame pointer for most methods diff --git a/src/coreclr/jit/targetloongarch64.h b/src/coreclr/jit/targetloongarch64.h index dbec9053238b42..9f12cba369cfdd 100644 --- a/src/coreclr/jit/targetloongarch64.h +++ b/src/coreclr/jit/targetloongarch64.h @@ -40,7 +40,6 @@ #define MAX_MULTIREG_COUNT 2 // Maximum number of registers defined by a single instruction (including calls). // This is also the maximum number of registers for a MultiReg node. -#define NOGC_WRITE_BARRIERS 1 // We have specialized WriteBarrier JIT Helpers that DO-NOT trash the RBM_CALLEE_TRASH registers #define USER_ARGS_COME_LAST 1 #define TARGET_POINTER_SIZE 8 // equal to sizeof(void*) and the managed pointer size in bytes for this target #define ETW_EBP_FRAMED 1 // if 1 we cannot use REG_FP as a scratch register and must setup the frame pointer for most methods diff --git a/src/coreclr/jit/targetriscv64.h b/src/coreclr/jit/targetriscv64.h index 32532c6f4a84a6..76b0fbe3b310fe 100644 --- a/src/coreclr/jit/targetriscv64.h +++ b/src/coreclr/jit/targetriscv64.h @@ -35,7 +35,6 @@ #define MAX_MULTIREG_COUNT 2 // Maximum number of registers defined by a single instruction (including calls). // This is also the maximum number of registers for a MultiReg node. -#define NOGC_WRITE_BARRIERS 1 // We have specialized WriteBarrier JIT Helpers that DO-NOT trash the RBM_CALLEE_TRASH registers #define USER_ARGS_COME_LAST 1 #define TARGET_POINTER_SIZE 8 // equal to sizeof(void*) and the managed pointer size in bytes for this target #define ETW_EBP_FRAMED 1 // if 1 we cannot use REG_FP as a scratch register and must setup the frame pointer for most methods diff --git a/src/coreclr/jit/targetwasm.h b/src/coreclr/jit/targetwasm.h index 0f2f7e24be83e7..0d1e346a1f8081 100644 --- a/src/coreclr/jit/targetwasm.h +++ b/src/coreclr/jit/targetwasm.h @@ -37,7 +37,6 @@ #define MAX_MULTIREG_COUNT 2 // Maximum number of registers defined by a single instruction (including calls). // This is also the maximum number of registers for a MultiReg node. -#define NOGC_WRITE_BARRIERS 0 // No specialized WriteBarrier JIT Helpers #define USER_ARGS_COME_LAST 1 #ifdef TARGET_WASM32 #define TARGET_POINTER_SIZE 4 // equal to sizeof(void*) and the managed pointer size in bytes for this target diff --git a/src/coreclr/jit/targetx86.h b/src/coreclr/jit/targetx86.h index 8fc6001a129a08..ed91b9c13b091b 100644 --- a/src/coreclr/jit/targetx86.h +++ b/src/coreclr/jit/targetx86.h @@ -40,13 +40,6 @@ #define MAX_MULTIREG_COUNT 2 // Maximum number of registers defined by a single instruction (including calls). // This is also the maximum number of registers for a MultiReg node. -#ifdef FEATURE_USE_ASM_GC_WRITE_BARRIERS -#define NOGC_WRITE_BARRIERS 1 // We have specialized WriteBarrier JIT Helpers that DO-NOT trash the - // RBM_CALLEE_TRASH registers -#else -#define NOGC_WRITE_BARRIERS 0 // Do not modify this -- modify the definition above. (If we're not using - // ASM barriers we definitely don't have NOGC barriers). -#endif #define USER_ARGS_COME_LAST 0 #define TARGET_POINTER_SIZE 4 // equal to sizeof(void*) and the managed pointer size in bytes for this // target @@ -188,11 +181,12 @@ // x86 write barrier ABI (see vm\i386\jithelp.asm, vm\i386\jithelp.S): // CORINFO_HELP_ASSIGN_REF (JIT_WriteBarrier), CORINFO_HELP_CHECKED_ASSIGN_REF (JIT_CheckedWriteBarrier): // On entry: -// edx: the destination address (object reference written here) -// For optimized write barriers, one of eax, ecx, ebx, esi, or edi contains the source (object to write). -// (There is a separate write barrier for each of these source options.) +// ecx: the destination address (object reference written here) +// edx: the object reference (RHS of the assignment) // On exit: -// edx: trashed +// eax, edx: trashed +// (See RBM_CALLEE_TRASH_WRITEBARRIER below: only eax and edx are clobbered; +// all callee-saved registers and ecx are preserved across the call.) // #define REG_WRITE_BARRIER_DST REG_ARG_0 @@ -201,20 +195,9 @@ #define REG_WRITE_BARRIER_SRC REG_ARG_1 #define RBM_WRITE_BARRIER_SRC RBM_ARG_1 -#if NOGC_WRITE_BARRIERS -#define REG_OPTIMIZED_WRITE_BARRIER_DST REG_EDX -#define RBM_OPTIMIZED_WRITE_BARRIER_DST RBM_EDX - -// We don't allow using ebp as a source register. Maybe we should only prevent this for ETW_EBP_FRAMED -// (but that is always set right now). -#define RBM_OPTIMIZED_WRITE_BARRIER_SRC (RBM_EAX|RBM_ECX|RBM_EBX|RBM_ESI|RBM_EDI) -#endif // NOGC_WRITE_BARRIERS - #define RBM_CALLEE_TRASH_NOGC RBM_EDX // Registers killed by CORINFO_HELP_ASSIGN_REF and CORINFO_HELP_CHECKED_ASSIGN_REF. -// Note that x86 normally emits an optimized (source-register-specific) write barrier, but can emit -// a call to a "general" write barrier. #ifdef FEATURE_USE_ASM_GC_WRITE_BARRIERS #define RBM_CALLEE_TRASH_WRITEBARRIER (RBM_EAX | RBM_EDX) diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index 3f3b49dc55b933..04932d5b45efa3 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -1670,20 +1670,6 @@ void HelperCallProperties::init() nonNullReturn = true; break; -#ifdef TARGET_X86 - case CORINFO_HELP_ASSIGN_REF_EAX: - case CORINFO_HELP_ASSIGN_REF_ECX: - case CORINFO_HELP_ASSIGN_REF_EBX: - case CORINFO_HELP_ASSIGN_REF_EBP: - case CORINFO_HELP_ASSIGN_REF_ESI: - case CORINFO_HELP_ASSIGN_REF_EDI: - case CORINFO_HELP_CHECKED_ASSIGN_REF_EAX: - case CORINFO_HELP_CHECKED_ASSIGN_REF_ECX: - case CORINFO_HELP_CHECKED_ASSIGN_REF_EBX: - case CORINFO_HELP_CHECKED_ASSIGN_REF_EBP: - case CORINFO_HELP_CHECKED_ASSIGN_REF_ESI: - case CORINFO_HELP_CHECKED_ASSIGN_REF_EDI: -#endif // GC Write barrier support // TODO-ARM64-Bug?: Can these throw or not? case CORINFO_HELP_ASSIGN_REF: diff --git a/src/coreclr/nativeaot/Runtime/EHHelpers.cpp b/src/coreclr/nativeaot/Runtime/EHHelpers.cpp index 30d6ab453632bd..c0d3534da44385 100644 --- a/src/coreclr/nativeaot/Runtime/EHHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/EHHelpers.cpp @@ -202,23 +202,7 @@ LONG WINAPI RhpVectoredExceptionHandler(PEXCEPTION_POINTERS pExPtrs); FCDECL2(void, RhpThrowHwEx, int exceptionCode, TADDR faultingIP); EXTERN_C CODE_LOCATION RhpAssignRefAVLocation; -#if defined(HOST_X86) -EXTERN_C CODE_LOCATION RhpAssignRefEAXAVLocation; -EXTERN_C CODE_LOCATION RhpAssignRefECXAVLocation; -EXTERN_C CODE_LOCATION RhpAssignRefEBXAVLocation; -EXTERN_C CODE_LOCATION RhpAssignRefESIAVLocation; -EXTERN_C CODE_LOCATION RhpAssignRefEDIAVLocation; -EXTERN_C CODE_LOCATION RhpAssignRefEBPAVLocation; -#endif EXTERN_C CODE_LOCATION RhpCheckedAssignRefAVLocation; -#if defined(HOST_X86) -EXTERN_C CODE_LOCATION RhpCheckedAssignRefEAXAVLocation; -EXTERN_C CODE_LOCATION RhpCheckedAssignRefECXAVLocation; -EXTERN_C CODE_LOCATION RhpCheckedAssignRefEBXAVLocation; -EXTERN_C CODE_LOCATION RhpCheckedAssignRefESIAVLocation; -EXTERN_C CODE_LOCATION RhpCheckedAssignRefEDIAVLocation; -EXTERN_C CODE_LOCATION RhpCheckedAssignRefEBPAVLocation; -#endif #if defined(HOST_ARM64) && !defined(LSE_INSTRUCTIONS_ENABLED_BY_DEFAULT) EXTERN_C CODE_LOCATION RhpCheckedLockCmpXchgAVLocation2; @@ -231,23 +215,7 @@ static bool InWriteBarrierHelper(uintptr_t faultingIP) static uintptr_t writeBarrierAVLocations[] = { (uintptr_t)&RhpAssignRefAVLocation, -#if defined(HOST_X86) - (uintptr_t)&RhpAssignRefEAXAVLocation, - (uintptr_t)&RhpAssignRefECXAVLocation, - (uintptr_t)&RhpAssignRefEBXAVLocation, - (uintptr_t)&RhpAssignRefESIAVLocation, - (uintptr_t)&RhpAssignRefEDIAVLocation, - (uintptr_t)&RhpAssignRefEBPAVLocation, -#endif (uintptr_t)&RhpCheckedAssignRefAVLocation, -#if defined(HOST_X86) - (uintptr_t)&RhpCheckedAssignRefEAXAVLocation, - (uintptr_t)&RhpCheckedAssignRefECXAVLocation, - (uintptr_t)&RhpCheckedAssignRefEBXAVLocation, - (uintptr_t)&RhpCheckedAssignRefESIAVLocation, - (uintptr_t)&RhpCheckedAssignRefEDIAVLocation, - (uintptr_t)&RhpCheckedAssignRefEBPAVLocation, -#endif }; // compare the IP against the list of known possible AV locations in the write barrier helpers diff --git a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h index ba32bc4e904442..da2efdd124cb44 100644 --- a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h +++ b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h @@ -11,7 +11,7 @@ struct ReadyToRunHeaderConstants { static const uint32_t Signature = 0x00525452; // 'RTR' - static const uint32_t CurrentMajorVersion = 19; + static const uint32_t CurrentMajorVersion = 20; static const uint32_t CurrentMinorVersion = 0; }; diff --git a/src/coreclr/runtime/i386/WriteBarriers.S b/src/coreclr/runtime/i386/WriteBarriers.S index a848632aeb8ca4..cf84cfdf0dd594 100644 --- a/src/coreclr/runtime/i386/WriteBarriers.S +++ b/src/coreclr/runtime/i386/WriteBarriers.S @@ -207,20 +207,6 @@ LEAF_END RhpCheckedAssignRef\REFREG, _TEXT DEFINE_CHECKED_WRITE_BARRIER ECX, EDX, EAX DEFINE_WRITE_BARRIER ECX, EDX, EAX -DEFINE_WRITE_BARRIER EDX, EAX, ECX -DEFINE_WRITE_BARRIER EDX, ECX, EAX -DEFINE_WRITE_BARRIER EDX, EBX, EAX -DEFINE_WRITE_BARRIER EDX, ESI, EAX -DEFINE_WRITE_BARRIER EDX, EDI, EAX -DEFINE_WRITE_BARRIER EDX, EBP, EAX - -DEFINE_CHECKED_WRITE_BARRIER EDX, EAX, ECX -DEFINE_CHECKED_WRITE_BARRIER EDX, ECX, EAX -DEFINE_CHECKED_WRITE_BARRIER EDX, EBX, EAX -DEFINE_CHECKED_WRITE_BARRIER EDX, ESI, EAX -DEFINE_CHECKED_WRITE_BARRIER EDX, EDI, EAX -DEFINE_CHECKED_WRITE_BARRIER EDX, EBP, EAX - LEAF_ENTRY RhpCheckedLockCmpXchg, _TEXT mov eax, [esp+4] lock cmpxchg [ecx], edx diff --git a/src/coreclr/runtime/i386/WriteBarriers.asm b/src/coreclr/runtime/i386/WriteBarriers.asm index c9a38eae56fc95..d68fbc44ec45a5 100644 --- a/src/coreclr/runtime/i386/WriteBarriers.asm +++ b/src/coreclr/runtime/i386/WriteBarriers.asm @@ -224,20 +224,6 @@ endm DEFINE_CHECKED_WRITE_BARRIER ECX, EDX DEFINE_WRITE_BARRIER ECX, EDX -DEFINE_WRITE_BARRIER EDX, EAX -DEFINE_WRITE_BARRIER EDX, ECX -DEFINE_WRITE_BARRIER EDX, EBX -DEFINE_WRITE_BARRIER EDX, ESI -DEFINE_WRITE_BARRIER EDX, EDI -DEFINE_WRITE_BARRIER EDX, EBP - -DEFINE_CHECKED_WRITE_BARRIER EDX, EAX -DEFINE_CHECKED_WRITE_BARRIER EDX, ECX -DEFINE_CHECKED_WRITE_BARRIER EDX, EBX -DEFINE_CHECKED_WRITE_BARRIER EDX, ESI -DEFINE_CHECKED_WRITE_BARRIER EDX, EDI -DEFINE_CHECKED_WRITE_BARRIER EDX, EBP - FASTCALL_FUNC RhpCheckedLockCmpXchg, 12 mov eax, [esp+4] lock cmpxchg [ecx], edx diff --git a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs index dea16528262cd3..9daafbdd520ca2 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs @@ -15,7 +15,7 @@ internal struct ReadyToRunHeaderConstants { public const uint Signature = 0x00525452; // 'RTR' - public const ushort CurrentMajorVersion = 19; + public const ushort CurrentMajorVersion = 20; public const ushort CurrentMinorVersion = 0; } #if READYTORUN diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs index f70b278f2de695..f3e728252098e7 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs @@ -344,20 +344,6 @@ public enum ReadyToRunHelper MonitorEnter = 0xF8, MonitorExit = 0xF9, - // JIT32 x86-specific write barriers - WriteBarrier_EAX = 0x100, - WriteBarrier_EBX = 0x101, - WriteBarrier_ECX = 0x102, - WriteBarrier_ESI = 0x103, - WriteBarrier_EDI = 0x104, - WriteBarrier_EBP = 0x105, - CheckedWriteBarrier_EAX = 0x106, - CheckedWriteBarrier_EBX = 0x107, - CheckedWriteBarrier_ECX = 0x108, - CheckedWriteBarrier_ESI = 0x109, - CheckedWriteBarrier_EDI = 0x10A, - CheckedWriteBarrier_EBP = 0x10B, - // JIT32 x86-specific exception handling EndCatch = 0x110, diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs index 68f7b52f6ec048..f83c95db643d7f 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs @@ -222,25 +222,6 @@ which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_EE_PERSONALITY_ROUTINE, // Not real JIT helper. Used in native images. CORINFO_HELP_EE_PERSONALITY_ROUTINE_FILTER_FUNCLET, // Not real JIT helper. Used in native images to detect filter funclets. - // ASSIGN_REF_EAX - CHECKED_ASSIGN_REF_EBP: NOGC_WRITE_BARRIERS JIT helper calls - // - // For unchecked versions EDX is required to point into GC heap. - // - // NOTE: these helpers are only used for x86. - CORINFO_HELP_ASSIGN_REF_EAX, // EAX holds GC ptr, do a 'mov [EDX], EAX' and inform GC - CORINFO_HELP_ASSIGN_REF_EBX, // EBX holds GC ptr, do a 'mov [EDX], EBX' and inform GC - CORINFO_HELP_ASSIGN_REF_ECX, // ECX holds GC ptr, do a 'mov [EDX], ECX' and inform GC - CORINFO_HELP_ASSIGN_REF_ESI, // ESI holds GC ptr, do a 'mov [EDX], ESI' and inform GC - CORINFO_HELP_ASSIGN_REF_EDI, // EDI holds GC ptr, do a 'mov [EDX], EDI' and inform GC - CORINFO_HELP_ASSIGN_REF_EBP, // EBP holds GC ptr, do a 'mov [EDX], EBP' and inform GC - - CORINFO_HELP_CHECKED_ASSIGN_REF_EAX, // These are the same as ASSIGN_REF above ... - CORINFO_HELP_CHECKED_ASSIGN_REF_EBX, // ... but also check if EDX points into heap. - CORINFO_HELP_CHECKED_ASSIGN_REF_ECX, - CORINFO_HELP_CHECKED_ASSIGN_REF_ESI, - CORINFO_HELP_CHECKED_ASSIGN_REF_EDI, - CORINFO_HELP_CHECKED_ASSIGN_REF_EBP, - CORINFO_HELP_LOOP_CLONE_CHOICE_ADDR, // Return the reference to a counter to decide to take cloned path in debug stress. CORINFO_HELP_DEBUG_LOG_LOOP_CLONING, // Print a message that a loop cloning optimization has occurred in debug mode. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs index 332aa401bca13b..1268bb49c05d8c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs @@ -79,42 +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.WriteBarrier_EAX: - mangledName = "RhpAssignRefEAX"; - break; - case ReadyToRunHelper.WriteBarrier_EBX: - mangledName = "RhpAssignRefEBX"; - break; - case ReadyToRunHelper.WriteBarrier_ECX: - mangledName = "RhpAssignRefECX"; - break; - case ReadyToRunHelper.WriteBarrier_EDI: - mangledName = "RhpAssignRefEDI"; - break; - case ReadyToRunHelper.WriteBarrier_ESI: - mangledName = "RhpAssignRefESI"; - break; - case ReadyToRunHelper.WriteBarrier_EBP: - mangledName = "RhpAssignRefEBP"; - break; - case ReadyToRunHelper.CheckedWriteBarrier_EAX: - mangledName = "RhpCheckedAssignRefEAX"; - break; - case ReadyToRunHelper.CheckedWriteBarrier_EBX: - mangledName = "RhpCheckedAssignRefEBX"; - break; - case ReadyToRunHelper.CheckedWriteBarrier_ECX: - mangledName = "RhpCheckedAssignRefECX"; - break; - case ReadyToRunHelper.CheckedWriteBarrier_EDI: - mangledName = "RhpCheckedAssignRefEDI"; - break; - case ReadyToRunHelper.CheckedWriteBarrier_ESI: - mangledName = "RhpCheckedAssignRefESI"; - break; - case ReadyToRunHelper.CheckedWriteBarrier_EBP: - mangledName = "RhpCheckedAssignRefEBP"; - break; case ReadyToRunHelper.Box: case ReadyToRunHelper.Box_Nullable: methodDesc = context.GetCoreLibEntryPoint("System.Runtime"u8, "RuntimeExports"u8, "RhBox"u8, null); 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 8c4af968d66747..cf3385474e55af 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -1229,44 +1229,6 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) id = ReadyToRunHelper.MonitorExit; break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_EAX: - id = ReadyToRunHelper.WriteBarrier_EAX; - break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_EBX: - id = ReadyToRunHelper.WriteBarrier_EBX; - break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_ECX: - id = ReadyToRunHelper.WriteBarrier_ECX; - break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_ESI: - id = ReadyToRunHelper.WriteBarrier_ESI; - break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_EDI: - id = ReadyToRunHelper.WriteBarrier_EDI; - break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_EBP: - id = ReadyToRunHelper.WriteBarrier_EBP; - break; - - case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_EAX: - id = ReadyToRunHelper.CheckedWriteBarrier_EAX; - break; - case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_EBX: - id = ReadyToRunHelper.CheckedWriteBarrier_EBX; - break; - case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_ECX: - id = ReadyToRunHelper.CheckedWriteBarrier_ECX; - break; - case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_ESI: - id = ReadyToRunHelper.CheckedWriteBarrier_ESI; - break; - case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_EDI: - id = ReadyToRunHelper.CheckedWriteBarrier_EDI; - break; - case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_EBP: - id = ReadyToRunHelper.CheckedWriteBarrier_EBP; - break; - case CorInfoHelpFunc.CORINFO_HELP_JIT_PINVOKE_BEGIN: id = ReadyToRunHelper.PInvokeBegin; break; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs index 2b54e3b9b3950c..7201e47a01df6a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs @@ -2023,44 +2023,6 @@ private void ParseHelper(StringBuilder builder) // Deprecated/legacy // - // JIT32 x86-specific write barriers - case ReadyToRunHelper.WriteBarrier_EAX: - builder.Append("WRITE_BARRIER_EAX"); - break; - case ReadyToRunHelper.WriteBarrier_EBX: - builder.Append("WRITE_BARRIER_EBX"); - break; - case ReadyToRunHelper.WriteBarrier_ECX: - builder.Append("WRITE_BARRIER_ECX"); - break; - case ReadyToRunHelper.WriteBarrier_ESI: - builder.Append("WRITE_BARRIER_ESI"); - break; - case ReadyToRunHelper.WriteBarrier_EDI: - builder.Append("WRITE_BARRIER_EDI"); - break; - case ReadyToRunHelper.WriteBarrier_EBP: - builder.Append("WRITE_BARRIER_EBP"); - break; - case ReadyToRunHelper.CheckedWriteBarrier_EAX: - builder.Append("CHECKED_WRITE_BARRIER_EAX"); - break; - case ReadyToRunHelper.CheckedWriteBarrier_EBX: - builder.Append("CHECKED_WRITE_BARRIER_EBX"); - break; - case ReadyToRunHelper.CheckedWriteBarrier_ECX: - builder.Append("CHECKED_WRITE_BARRIER_ECX"); - break; - case ReadyToRunHelper.CheckedWriteBarrier_ESI: - builder.Append("CHECKED_WRITE_BARRIER_ESI"); - break; - case ReadyToRunHelper.CheckedWriteBarrier_EDI: - builder.Append("CHECKED_WRITE_BARRIER_EDI"); - break; - case ReadyToRunHelper.CheckedWriteBarrier_EBP: - builder.Append("CHECKED_WRITE_BARRIER_EBP"); - break; - // JIT32 x86-specific exception handling case ReadyToRunHelper.EndCatch: builder.Append("END_CATCH"); 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 6c22da04d78a90..ffeda84f6d3ad8 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -512,36 +512,6 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) case CorInfoHelpFunc.CORINFO_HELP_BULK_WRITEBARRIER: id = ReadyToRunHelper.BulkWriteBarrier; break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_EAX: - id = ReadyToRunHelper.WriteBarrier_EAX; - break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_EBX: - id = ReadyToRunHelper.WriteBarrier_EBX; - break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_ECX: - id = ReadyToRunHelper.WriteBarrier_ECX; - break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_EDI: - id = ReadyToRunHelper.WriteBarrier_EDI; - break; - case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_REF_ESI: - id = ReadyToRunHelper.WriteBarrier_ESI; - break; - case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_EAX: - id = ReadyToRunHelper.CheckedWriteBarrier_EAX; - break; - case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_EBX: - id = ReadyToRunHelper.CheckedWriteBarrier_EBX; - break; - case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_ECX: - id = ReadyToRunHelper.CheckedWriteBarrier_ECX; - break; - case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_EDI: - id = ReadyToRunHelper.CheckedWriteBarrier_EDI; - break; - case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF_ESI: - id = ReadyToRunHelper.CheckedWriteBarrier_ESI; - break; case CorInfoHelpFunc.CORINFO_HELP_ARRADDR_ST: id = ReadyToRunHelper.Stelem_Ref; diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index a12bde70e8980f..6bed5da2de1ea7 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -5323,44 +5323,12 @@ BOOL IsIPinVirtualStub(PCODE f_IP) typedef uint8_t CODE_LOCATION; EXTERN_C CODE_LOCATION RhpAssignRefAVLocation; -#if defined(HOST_X86) -EXTERN_C CODE_LOCATION RhpAssignRefEAXAVLocation; -EXTERN_C CODE_LOCATION RhpAssignRefECXAVLocation; -EXTERN_C CODE_LOCATION RhpAssignRefEBXAVLocation; -EXTERN_C CODE_LOCATION RhpAssignRefESIAVLocation; -EXTERN_C CODE_LOCATION RhpAssignRefEDIAVLocation; -EXTERN_C CODE_LOCATION RhpAssignRefEBPAVLocation; -#endif EXTERN_C CODE_LOCATION RhpCheckedAssignRefAVLocation; -#if defined(HOST_X86) -EXTERN_C CODE_LOCATION RhpCheckedAssignRefEAXAVLocation; -EXTERN_C CODE_LOCATION RhpCheckedAssignRefECXAVLocation; -EXTERN_C CODE_LOCATION RhpCheckedAssignRefEBXAVLocation; -EXTERN_C CODE_LOCATION RhpCheckedAssignRefESIAVLocation; -EXTERN_C CODE_LOCATION RhpCheckedAssignRefEDIAVLocation; -EXTERN_C CODE_LOCATION RhpCheckedAssignRefEBPAVLocation; -#endif static uintptr_t writeBarrierAVLocations[] = { (uintptr_t)&RhpAssignRefAVLocation, -#if defined(HOST_X86) - (uintptr_t)&RhpAssignRefEAXAVLocation, - (uintptr_t)&RhpAssignRefECXAVLocation, - (uintptr_t)&RhpAssignRefEBXAVLocation, - (uintptr_t)&RhpAssignRefESIAVLocation, - (uintptr_t)&RhpAssignRefEDIAVLocation, - (uintptr_t)&RhpAssignRefEBPAVLocation, -#endif (uintptr_t)&RhpCheckedAssignRefAVLocation, -#if defined(HOST_X86) - (uintptr_t)&RhpCheckedAssignRefEAXAVLocation, - (uintptr_t)&RhpCheckedAssignRefECXAVLocation, - (uintptr_t)&RhpCheckedAssignRefEBXAVLocation, - (uintptr_t)&RhpCheckedAssignRefESIAVLocation, - (uintptr_t)&RhpCheckedAssignRefEDIAVLocation, - (uintptr_t)&RhpCheckedAssignRefEBPAVLocation, -#endif }; // Check if the passed in instruction pointer is in one of the diff --git a/src/coreclr/vm/i386/jithelp.S b/src/coreclr/vm/i386/jithelp.S index 2b99cc949f229a..6fff024ca7dafd 100644 --- a/src/coreclr/vm/i386/jithelp.S +++ b/src/coreclr/vm/i386/jithelp.S @@ -234,19 +234,9 @@ LEAF_END JIT_\name, _TEXT // ******************************************************************************* // Write barrier wrappers with fcall calling convention // - -// Only define these if we're using the ASM GC write barriers; if this flag is not defined, -// we'll use C++ versions of these write barriers. -UniversalWriteBarrierHelper CheckedWriteBarrier -UniversalWriteBarrierHelper WriteBarrier #endif // FEATURE_USE_ASM_GC_WRITE_BARRIERS WriteBarrierHelper EAX -WriteBarrierHelper EBX -WriteBarrierHelper ECX -WriteBarrierHelper ESI -WriteBarrierHelper EDI -WriteBarrierHelper EBP // This is the first function outside the "keep together range". Used by BBT scripts. LEAF_ENTRY JIT_WriteBarrierGroup_End, _TEXT @@ -495,11 +485,14 @@ LEAF_END JIT_WriteBarrier\rg, _TEXT .endm PatchedWriteBarrierHelper EAX -PatchedWriteBarrierHelper EBX -PatchedWriteBarrierHelper ECX -PatchedWriteBarrierHelper ESI -PatchedWriteBarrierHelper EDI -PatchedWriteBarrierHelper EBP + +#ifdef FEATURE_USE_ASM_GC_WRITE_BARRIERS +// The universal-ABI trampoline for the write barrier lives inside the +// "patched" code region so that GetWriteBarrierCodeLocation translates its +// address into the copy. The trampoline's relative jmp to JIT_WriteBarrierEAX +// is preserved across the copy because both functions are in the same region. +UniversalWriteBarrierHelper WriteBarrier +#endif // FEATURE_USE_ASM_GC_WRITE_BARRIERS // This is the first function outside the "keep together range". Used by BBT scripts. LEAF_ENTRY JIT_PatchedWriteBarrierGroup_End, _TEXT diff --git a/src/coreclr/vm/i386/jithelp.asm b/src/coreclr/vm/i386/jithelp.asm index e8535454472671..b1de949f51f239 100644 --- a/src/coreclr/vm/i386/jithelp.asm +++ b/src/coreclr/vm/i386/jithelp.asm @@ -297,19 +297,7 @@ PUBLIC @JIT_&name&@8 @JIT_&name&@8 ENDP ENDM -ifdef FEATURE_USE_ASM_GC_WRITE_BARRIERS -; Only define these if we're using the ASM GC write barriers; if this flag is not defined, -; we'll use C++ versions of these write barriers. -UniversalWriteBarrierHelper -UniversalWriteBarrierHelper -endif - WriteBarrierHelper -WriteBarrierHelper -WriteBarrierHelper -WriteBarrierHelper -WriteBarrierHelper -WriteBarrierHelper ; This is the first function outside the "keep together range". Used by BBT scripts. PUBLIC _JIT_WriteBarrierGroup_End@0 @@ -905,11 +893,14 @@ _JIT_WriteBarrier&rg&@0 ENDP ENDM PatchedWriteBarrierHelper -PatchedWriteBarrierHelper -PatchedWriteBarrierHelper -PatchedWriteBarrierHelper -PatchedWriteBarrierHelper -PatchedWriteBarrierHelper + +ifdef FEATURE_USE_ASM_GC_WRITE_BARRIERS +; The universal-ABI trampoline for the write barrier lives inside the +; "patched" code region so that GetWriteBarrierCodeLocation translates its +; address into the copy. The trampoline's relative jmp to _JIT_WriteBarrierEAX@0 +; is preserved across the copy because both functions are in the same region. +UniversalWriteBarrierHelper +endif PUBLIC _JIT_PatchedWriteBarrierGroup_End@0 _JIT_PatchedWriteBarrierGroup_End@0 PROC diff --git a/src/coreclr/vm/i386/jitinterfacex86.cpp b/src/coreclr/vm/i386/jitinterfacex86.cpp index 8c6c4eabf988d2..7dacb5c21a3bf9 100644 --- a/src/coreclr/vm/i386/jitinterfacex86.cpp +++ b/src/coreclr/vm/i386/jitinterfacex86.cpp @@ -78,37 +78,6 @@ void STDCALL JIT_TailCallHelper(Thread * pThread) } #endif // FEATURE_HIJACK -#define NUM_WRITE_BARRIERS 6 - -static const BYTE c_rgWriteBarrierRegs[NUM_WRITE_BARRIERS] = { - 0, // EAX - 1, // ECX - 3, // EBX - 6, // ESI - 7, // EDI - 5, // EBP -}; - -static const void * const c_rgWriteBarriers[NUM_WRITE_BARRIERS] = { - (void *)JIT_WriteBarrierEAX, - (void *)JIT_WriteBarrierECX, - (void *)JIT_WriteBarrierEBX, - (void *)JIT_WriteBarrierESI, - (void *)JIT_WriteBarrierEDI, - (void *)JIT_WriteBarrierEBP, -}; - -#ifdef WRITE_BARRIER_CHECK -static const void * const c_rgDebugWriteBarriers[NUM_WRITE_BARRIERS] = { - (void *)JIT_DebugWriteBarrierEAX, - (void *)JIT_DebugWriteBarrierECX, - (void *)JIT_DebugWriteBarrierEBX, - (void *)JIT_DebugWriteBarrierESI, - (void *)JIT_DebugWriteBarrierEDI, - (void *)JIT_DebugWriteBarrierEBP, -}; -#endif // WRITE_BARRIER_CHECK - /*********************************************************************/ // Initialize the part of the JIT helpers that require very little of // EE infrastructure to be in place. @@ -123,57 +92,49 @@ void InitJITWriteBarrierHelpers() _ASSERTE_ALL_BUILDS((BYTE*)JIT_WriteBarrierGroup_End - (BYTE*)JIT_WriteBarrierGroup < (ptrdiff_t)minipal_getpagesize()); _ASSERTE_ALL_BUILDS((BYTE*)JIT_PatchedWriteBarrierGroup_End - (BYTE*)JIT_PatchedWriteBarrierGroup < (ptrdiff_t)minipal_getpagesize()); - // Copy the write barriers to their final resting place. + // Copy the write barrier to its final resting place. if (IsWriteBarrierCopyEnabled()) { - for (int iBarrier = 0; iBarrier < NUM_WRITE_BARRIERS; iBarrier++) - { - BYTE * pfunc = (BYTE *) JIT_WriteBarrierReg_PreGrow; - - BYTE * pBuf = GetWriteBarrierCodeLocation((BYTE *)c_rgWriteBarriers[iBarrier]); - int reg = c_rgWriteBarrierRegs[iBarrier]; + BYTE * pfunc = (BYTE *) JIT_WriteBarrierReg_PreGrow; - BYTE * pBufRW = pBuf; - ExecutableWriterHolderNoLog barrierWriterHolder; - barrierWriterHolder.AssignExecutableWriterHolder(pBuf, 34); - pBufRW = barrierWriterHolder.GetRW(); + BYTE * pBuf = GetWriteBarrierCodeLocation((BYTE *)JIT_WriteBarrierEAX); - memcpy(pBufRW, pfunc, 34); - - // assert the copied code ends in a ret to make sure we got the right length - _ASSERTE(pBuf[33] == 0xC3); + ExecutableWriterHolderNoLog barrierWriterHolder; + barrierWriterHolder.AssignExecutableWriterHolder(pBuf, 34); + BYTE * pBufRW = barrierWriterHolder.GetRW(); - // We need to adjust registers in a couple of instructions - // It would be nice to have the template contain all zeroes for - // the register fields (corresponding to EAX), but that doesn't - // work because then we get a smaller encoding for the compares - // that only works for EAX but not the other registers. - // So we always have to clear the register fields before updating them. + memcpy(pBufRW, pfunc, 34); - // First instruction to patch is a mov [edx], reg + // assert the copied code ends in a ret to make sure we got the right length + _ASSERTE(pBuf[33] == 0xC3); - _ASSERTE(pBuf[0] == 0x89); - // Update the reg field (bits 3..5) of the ModR/M byte of this instruction - pBufRW[1] &= 0xc7; - pBufRW[1] |= reg << 3; + // The template uses ECX as the source register (encoding 1) because the + // EAX-specific short encodings would not survive register patching when + // we still supported other source registers. We now only emit the EAX + // variant, but the template hasn't been rewritten yet, so we still need + // to patch the source-register field of the first two instructions to + // encode EAX (encoding 0). - // Second instruction to patch is cmp reg, imm32 (low bound) + // First instruction to patch is a mov [edx], reg + _ASSERTE(pBuf[0] == 0x89); + // Clear the reg field (bits 3..5) of the ModR/M byte. EAX = 0, so we + // don't need to OR anything back in. + pBufRW[1] &= 0xc7; - _ASSERTE(pBuf[2] == 0x81); - // Here the lowest three bits in ModR/M field are the register - pBufRW[3] &= 0xf8; - pBufRW[3] |= reg; + // Second instruction to patch is cmp reg, imm32 (low bound) + _ASSERTE(pBuf[2] == 0x81); + // Clear the lowest three bits of the ModR/M field; EAX = 0. + pBufRW[3] &= 0xf8; #ifdef WRITE_BARRIER_CHECK - // Don't do the fancy optimization just jump to the old one - // Use the slow one for write barrier checks build because it has some good asserts - if (g_pConfig->GetHeapVerifyLevel() & EEConfig::HEAPVERIFY_BARRIERCHECK) { - pfunc = &pBufRW[0]; - *pfunc++ = 0xE9; // JMP c_rgDebugWriteBarriers[iBarrier] - *((DWORD*) pfunc) = (BYTE*) c_rgDebugWriteBarriers[iBarrier] - (&pBuf[1] + sizeof(DWORD)); - } -#endif // WRITE_BARRIER_CHECK + // Don't do the fancy optimization just jump to the old one + // Use the slow one for write barrier checks build because it has some good asserts + if (g_pConfig->GetHeapVerifyLevel() & EEConfig::HEAPVERIFY_BARRIERCHECK) { + pfunc = &pBufRW[0]; + *pfunc++ = 0xE9; // JMP JIT_DebugWriteBarrierEAX + *((DWORD*) pfunc) = (BYTE*) JIT_DebugWriteBarrierEAX - (&pBuf[1] + sizeof(DWORD)); } +#endif // WRITE_BARRIER_CHECK #ifndef CODECOVERAGE ValidateWriteBarrierHelpers(); @@ -279,14 +240,12 @@ int StompWriteBarrierEphemeral(bool /* isRuntimeSuspended */) #endif // WRITE_BARRIER_CHECK // Update the lower bound. - for (int iBarrier = 0; iBarrier < NUM_WRITE_BARRIERS; iBarrier++) { - BYTE * pBuf = GetWriteBarrierCodeLocation((BYTE *)c_rgWriteBarriers[iBarrier]); + BYTE * pBuf = GetWriteBarrierCodeLocation((BYTE *)JIT_WriteBarrierEAX); - BYTE * pBufRW = pBuf; ExecutableWriterHolderNoLog barrierWriterHolder; barrierWriterHolder.AssignExecutableWriterHolder(pBuf, 42); - pBufRW = barrierWriterHolder.GetRW(); + BYTE * pBufRW = barrierWriterHolder.GetRW(); // assert there is in fact a cmp r/m32, imm32 there _ASSERTE(pBuf[2] == 0x81); @@ -348,17 +307,14 @@ int StompWriteBarrierResize(bool isRuntimeSuspended, bool bReqUpperBoundsCheck) bool bWriteBarrierIsPreGrow = WriteBarrierIsPreGrow(); bool bStompWriteBarrierEphemeral = false; - for (int iBarrier = 0; iBarrier < NUM_WRITE_BARRIERS; iBarrier++) { - BYTE * pBuf = GetWriteBarrierCodeLocation((BYTE *)c_rgWriteBarriers[iBarrier]); - int reg = c_rgWriteBarrierRegs[iBarrier]; + BYTE * pBuf = GetWriteBarrierCodeLocation((BYTE *)JIT_WriteBarrierEAX); size_t *pfunc; - BYTE * pBufRW = pBuf; ExecutableWriterHolderNoLog barrierWriterHolder; barrierWriterHolder.AssignExecutableWriterHolder(pBuf, 42); - pBufRW = barrierWriterHolder.GetRW(); + BYTE * pBufRW = barrierWriterHolder.GetRW(); // Check if we are still using the pre-grow version of the write barrier. if (bWriteBarrierIsPreGrow) @@ -378,33 +334,21 @@ int StompWriteBarrierResize(bool isRuntimeSuspended, bool bReqUpperBoundsCheck) // assert the copied code ends in a ret to make sure we got the right length _ASSERTE(pBuf[41] == 0xC3); - // We need to adjust registers in a couple of instructions - // It would be nice to have the template contain all zeroes for - // the register fields (corresponding to EAX), but that doesn't - // work because then we get a smaller encoding for the compares - // that only works for EAX but not the other registers - // So we always have to clear the register fields before updating them. + // The template uses ECX as the source register; patch the + // source-register field of the three register-using instructions + // to encode EAX (the only variant we emit now). // First instruction to patch is a mov [edx], reg - _ASSERTE(pBuf[0] == 0x89); - // Update the reg field (bits 3..5) of the ModR/M byte of this instruction pBufRW[1] &= 0xc7; - pBufRW[1] |= reg << 3; // Second instruction to patch is cmp reg, imm32 (low bound) - _ASSERTE(pBuf[2] == 0x81); - // Here the lowest three bits in ModR/M field are the register pBufRW[3] &= 0xf8; - pBufRW[3] |= reg; // Third instruction to patch is another cmp reg, imm32 (high bound) - _ASSERTE(pBuf[10] == 0x81); - // Here the lowest three bits in ModR/M field are the register pBufRW[11] &= 0xf8; - pBufRW[11] |= reg; bStompWriteBarrierEphemeral = true; // What we're trying to update is the offset field of a diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index c5c8445d957a45..dcf7d1b17ab7df 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -223,26 +223,16 @@ EXTERN_C FCDECL2_VV(UINT64, JIT_LRsz, UINT64 num, int shift); #ifdef TARGET_X86 -#define ENUM_X86_WRITE_BARRIER_REGISTERS() \ - X86_WRITE_BARRIER_REGISTER(EAX) \ - X86_WRITE_BARRIER_REGISTER(ECX) \ - X86_WRITE_BARRIER_REGISTER(EBX) \ - X86_WRITE_BARRIER_REGISTER(ESI) \ - X86_WRITE_BARRIER_REGISTER(EDI) \ - X86_WRITE_BARRIER_REGISTER(EBP) - extern "C" { // JIThelp.asm/JIThelp.s -#define X86_WRITE_BARRIER_REGISTER(reg) \ - void STDCALL JIT_DebugWriteBarrier##reg(); \ - void STDCALL JIT_WriteBarrier##reg(); \ - void FASTCALL RhpAssignRef##reg(Object**, Object*); \ - void FASTCALL RhpCheckedAssignRef##reg(Object**, Object*); - - ENUM_X86_WRITE_BARRIER_REGISTERS() -#undef X86_WRITE_BARRIER_REGISTER +// The only per-source-register x86 write barrier helper still kept in the +// runtime is the EAX variant, which is the target of the universal trampoline +// (@JIT_WriteBarrier@8). It is patched at runtime by InitJITWriteBarrierHelpers +// and updated by StompWriteBarrierEphemeral / StompWriteBarrierResize. + void STDCALL JIT_DebugWriteBarrierEAX(); + void STDCALL JIT_WriteBarrierEAX(); void STDCALL JIT_WriteBarrierGroup(); void STDCALL JIT_WriteBarrierGroup_End(); diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index e820c8678586e0..0a4a32bcf15b96 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -1078,16 +1078,6 @@ void InitThreadManager() // can jump to it. #ifdef TARGET_X86 JIT_WriteBarrierEAX_Loc = GetWriteBarrierCodeLocation((void*)JIT_WriteBarrierEAX); - -#define X86_WRITE_BARRIER_REGISTER(reg) \ - SetJitHelperFunction(CORINFO_HELP_ASSIGN_REF_##reg, GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier##reg)); \ - SetAuxiliarySymbol(GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier##reg), "JIT_WriteBarrier" #reg); \ - ETW::MethodLog::StubInitialized((ULONGLONG)GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier##reg), W("@WriteBarrier" #reg)); - - ENUM_X86_WRITE_BARRIER_REGISTERS() - -#undef X86_WRITE_BARRIER_REGISTER - #else // TARGET_X86 JIT_WriteBarrier_Loc = GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier); #endif // TARGET_X86 @@ -1115,9 +1105,7 @@ void InitThreadManager() } else { -#ifdef TARGET_X86 - JIT_WriteBarrierEAX_Loc = (void*)RhpAssignRefEAX; -#else +#ifndef TARGET_X86 JIT_WriteBarrier_Loc = (void*)RhpAssignRef; #endif #if defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)