Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement software write watch for GC heap feature for arm32. #113017

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/coreclr/clrdefinitions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,9 @@ if (CLR_CMAKE_TARGET_ARCH_AMD64)
add_definitions(-DUNIX_AMD64_ABI_ITF)
endif (CLR_CMAKE_TARGET_ARCH_AMD64)
add_definitions(-DFEATURE_USE_ASM_GC_WRITE_BARRIERS)
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64 OR CLR_CMAKE_TARGET_ARCH_RISCV64)
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64 OR CLR_CMAKE_TARGET_ARCH_RISCV64 OR CLR_CMAKE_TARGET_ARCH_ARM)
add_definitions(-DFEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP)
endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64 OR CLR_CMAKE_TARGET_ARCH_RISCV64)
endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64 OR CLR_CMAKE_TARGET_ARCH_RISCV64 OR CLR_CMAKE_TARGET_ARCH_ARM)
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64 OR CLR_CMAKE_TARGET_ARCH_RISCV64)
add_definitions(-DFEATURE_MANUALLY_MANAGED_CARD_BUNDLES)
endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64 OR CLR_CMAKE_TARGET_ARCH_RISCV64)
Expand Down
40 changes: 40 additions & 0 deletions src/coreclr/vm/arm/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,9 @@ LOCAL_LABEL(stackProbe_loop):
__\name\()__g_ephemeral_low_offset = 0xffff
__\name\()__g_ephemeral_high_offset = 0xffff
__\name\()__g_card_table_offset = 0xffff
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
__\name\()__g_sw_ww_table_offset = 0xffff
#endif
.endm

.macro LOAD_GC_GLOBAL name, regName, globalName
Expand Down Expand Up @@ -603,6 +606,28 @@ LOCAL_LABEL(stackProbe_loop):
0:
.endm

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
.macro UPDATE_WRITE_WATCH_TABLE name, ptrReg, mp, tmpReg

LOAD_GC_GLOBAL \name, __wbScratch, g_sw_ww_table
cbz __wbScratch, 2f
add __wbScratch, __wbScratch, \ptrReg, lsr #0xc // SoftwareWriteWatch::AddressToTableByteIndexShift

.if(\mp)
ldrb \tmpReg, [__wbScratch]
cmp \tmpReg, #0xff
itt ne
movne \tmpReg, 0xff
strbne \tmpReg, [__wbScratch]
.else
mov \tmpReg, #0xff
strb \tmpReg, [__wbScratch]
.endif

2:
.endm
#endif

.macro CHECK_GC_HEAP_RANGE name, ptrReg, label
LOAD_GC_GLOBAL \name, __wbScratch, g_lowest_address
cmp \ptrReg, __wbScratch
Expand All @@ -621,6 +646,9 @@ LOCAL_LABEL(stackProbe_loop):

str r1, [r0]
UPDATE_GC_SHADOW \name, r0, r1
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
UPDATE_WRITE_WATCH_TABLE \name, r0, \mp, r12
#endif
UPDATE_CARD_TABLE \name, r0, r1, \mp, \post, r0
bx lr
LEAF_END_MARKED \name, _TEXT
Expand All @@ -632,6 +660,9 @@ LOCAL_LABEL(stackProbe_loop):
str r1, [r0]
CHECK_GC_HEAP_RANGE \name, r0, 1f
UPDATE_GC_SHADOW \name, r0, r1
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
UPDATE_WRITE_WATCH_TABLE \name, r0, 0, r12
#endif
UPDATE_CARD_TABLE \name, r0, r1, 0, \post, r0
1:
bx lr
Expand All @@ -645,6 +676,9 @@ LOCAL_LABEL(stackProbe_loop):
str r1, [r0]
CHECK_GC_HEAP_RANGE \name, r0, 1f
UPDATE_GC_SHADOW \name, r0, r1
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
UPDATE_WRITE_WATCH_TABLE \name, r0, 1, r12
#endif
UPDATE_CARD_TABLE \name, r0, r1, 1, \post, r0
bx lr
1:
Expand All @@ -664,6 +698,9 @@ LOCAL_LABEL(stackProbe_loop):
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
Expand All @@ -681,6 +718,9 @@ LOCAL_LABEL(stackProbe_loop):
.word __\name\()__g_ephemeral_low_offset
.word __\name\()__g_ephemeral_high_offset
.word __\name\()__g_card_table_offset
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
.word __\name\()__g_sw_ww_table_offset
#endif
.endm

// There 4 versions of each write barriers. A 2x2 combination of multi-proc/single-proc and pre/post grow version
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/vm/arm/patchedcode.S
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@
// See ValidateWriteBarriers on how the sizes of these should be calculated
.align 4
LEAF_ENTRY JIT_WriteBarrier, _TEXT
.space (0x84)
.space (0xA8)
LEAF_END_MARKED JIT_WriteBarrier, _TEXT

.align 4
LEAF_ENTRY JIT_CheckedWriteBarrier, _TEXT
.space (0x9C)
.space (0xC0)
LEAF_END_MARKED JIT_CheckedWriteBarrier, _TEXT

.align 4
LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT
.space (0xA0)
.space (0xC4)
LEAF_END_MARKED JIT_ByRefWriteBarrier , _TEXT

LEAF_ENTRY JIT_PatchedWriteBarrierLast, _TEXT
Expand Down
24 changes: 24 additions & 0 deletions src/coreclr/vm/arm/stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ struct WriteBarrierDescriptor
DWORD m_dw_g_ephemeral_low_offset; // Offset of the instruction reading g_ephemeral_low
DWORD m_dw_g_ephemeral_high_offset; // Offset of the instruction reading g_ephemeral_high
DWORD m_dw_g_card_table_offset; // Offset of the instruction reading g_card_table
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
DWORD m_dw_g_sw_ww_table_offset; // Offset of the instruction reading g_sw_ww_table
#endif
};

// Infrastructure used for mapping of the source and destination of current WB patching
Expand Down Expand Up @@ -455,6 +458,9 @@ void UpdateGCWriteBarriers(bool postGrow = false)
GWB_PATCH_OFFSET(g_ephemeral_low);
GWB_PATCH_OFFSET(g_ephemeral_high);
GWB_PATCH_OFFSET(g_card_table);
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
GWB_PATCH_OFFSET(g_sw_ww_table);
#endif
}

pDesc++;
Expand Down Expand Up @@ -494,6 +500,24 @@ int StompWriteBarrierEphemeral(bool isRuntimeSuspended)
return SWB_ICACHE_FLUSH;
}

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
int SwitchToWriteWatchBarrier(bool isRuntimeSuspended)
{
UNREFERENCED_PARAMETER(isRuntimeSuspended);
_ASSERTE(isRuntimeSuspended);
UpdateGCWriteBarriers();
return SWB_ICACHE_FLUSH;
}

int SwitchToNonWriteWatchBarrier(bool isRuntimeSuspended)
{
UNREFERENCED_PARAMETER(isRuntimeSuspended);
_ASSERTE(isRuntimeSuspended);
UpdateGCWriteBarriers();
return SWB_ICACHE_FLUSH;
}
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP

void FlushWriteBarrierInstructionCache()
{
// We've changed code so we must flush the instruction cache.
Expand Down