-
Notifications
You must be signed in to change notification settings - Fork 5k
Arm64: Implement region write barriers #111636
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
Merged
Merged
Changes from 23 commits
Commits
Show all changes
52 commits
Select commit
Hold shift + click to select a range
db6c2cf
Arm64: Implement region write barriers
a74nh 5de7e0f
Fix byte region barriers
a74nh 9315aa1
Fix bit region barriers
a74nh d0e46f0
test instead of cmp for bitwise write barriers
a74nh cb83f53
use LSE to atomically update bitwise write barriers
a74nh c615772
move atomics check into gcenv.ee.cpp
a74nh 1c865f1
Skip ephemeral checks for regionless server GC, and refactor checks
a74nh 15dde1b
Move ephemeral checks back
a74nh b5b28ce
Add GC-write-barriers.md
a74nh c27d516
More variables for the pseudo code
a74nh d014417
WRITE_BARRIER_CHECK instead of TARGET_ARM64
a74nh 6068fb0
Add JIT_CheckedWriteBarrier and fixups to doc
a74nh fe0ab46
Merge main
a74nh a416437
Use writebarriermanager for arm64.
a74nh 86c2576
Add the different write barrier functions
a74nh 38bc2a1
Don't clear ephemeral values
a74nh 5eed451
Only use offsets for inline variables
a74nh 6b29574
Remove jitinterfaceamd64.cpp
a74nh e3bbf96
Don't use m_pRegionShrSrc on Arm64
a74nh 091e265
Remove commented code
a74nh 91eb26f
make writebarriermanager closer to original code
a74nh b947119
undo patchedcode.asm changes
a74nh 580c16f
Add writebarriermanager.h
a74nh 7993687
Update doc
a74nh 90d889b
Replace JIT_WriteBarrier with zeroed memory
a74nh da7b5c0
Fix writebarrier macro labels
a74nh dc6d0a7
Fix JIT_WriteBarrier_PreGrow64 checks
a74nh 6e66842
remove unused label
a74nh 729cb77
Remove JIT_UpdateWriteBarrierState
a74nh e0759b8
first attempt at windows .asm
a74nh e026a06
remove wbs_begin
a74nh 678f8e1
fix ifdefs for windows
a74nh 5a156d3
Remove _TEXT
a74nh b318113
Fix macro arg passing on OSX
a74nh 9312f3c
Fix patching arithmetic to work on MacOS
a74nh 13bd03c
merge main
a74nh 0f21673
Fixup comments in doc and assembly
a74nh 48620bb
fix location casts for windows
a74nh d97e4c1
copy patching changes to windows
a74nh 8f73468
fix location casts again
a74nh b5cbb9e
remove extra labels
a74nh 4dc3f63
fix windows build
a74nh 6ea99c0
fix patched constants on windows
a74nh 75d2443
Fix RegionShr size on windows
a74nh 08c3635
Merge main
a74nh 1c80ab8
Merge main
a74nh aefc2ef
Add WRITE_BARRIER_CHECK and LSE atomics to the doc
a74nh 8e0dbe4
merge main
a74nh 8d164ef
doc typo fixes
a74nh 8b02ab4
Merge main
a74nh 328024e
Merge main
a74nh 801b9cc
Merge main
a74nh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
# GC write barriers | ||
|
||
The GC write barrier function (JIT_WriteBarrier) is generally the hottest function in CoreCLR and is written in assembly. The full pseudo code for the function is as follows: | ||
|
||
|
||
```` | ||
JIT_WriteBarrier(Object **dst, Object *ref) | ||
Set *dst = ref | ||
|
||
// Shadow Heap update | ||
ifdef WRITE_BARRIER_CHECK: | ||
if g_GCShadow != 0: | ||
long *shadow_dst = g_GCShadow + (dst - g_lowest_address) | ||
// Check shadow heap location is within shadow heap | ||
if shadow_dst < g_GCShadowEnd: | ||
*shadow_dst = ref | ||
atomic: wait for stores to complete | ||
if *dst != ref: | ||
*shadow_dst = INVALIDGCVALUE | ||
|
||
// Update the write watch table, if it's in use | ||
ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP: | ||
if g_sw_ww_table != 0: | ||
char *ww_table_dst = g_sw_ww_table + (dst>>11) | ||
if *ww_table_dst != 0: | ||
*ww_table_dst = 0xff | ||
|
||
// Return if the reference is not in Gen 0 | ||
if ref < g_ephemeral_low || ref >= g_ephemeral_high: | ||
return | ||
|
||
// Region Checks | ||
if g_region_to_generation_table != 0: | ||
|
||
// Calculate region locations | ||
a74nh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
char reg_loc_dst = *((dst >> g_region_shr) + g_region_to_generation_table) | ||
char reg_loc_ref = *((ref >> g_region_shr) + g_region_to_generation_table) | ||
|
||
// Return if the region we're storing into is Gen 0 | ||
if reg_loc_dst == 0: | ||
return | ||
|
||
// Check this is going from old to young | ||
if reg_loc_dst >= reg_loc_ref: | ||
return | ||
a74nh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Bitwise write barriers only | ||
if g_region_use_bitwise_write_barrier: | ||
|
||
char *card_table_dst = (dst >> 11) + g_card_table | ||
char dst_bit = 1 << (dst >> 8 && 7) | ||
|
||
// Check if we need to update the card table | ||
if *card_table_dst & dst_bit == 0: | ||
return | ||
|
||
// Atomically update the card table | ||
lock: *card_table_dst |= dst_bit | ||
|
||
goto CardBundle | ||
|
||
// Check if we need to update the card table | ||
char *card_table_dst = (dst >> 11) + g_card_table | ||
if *card_table_dst == 0xff: | ||
return | ||
|
||
// Update the card table | ||
*card_table_dst = 0xff | ||
|
||
CardBundle: | ||
|
||
// Mark the card bundle table as dirty | ||
Ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES: | ||
char card_bundle_dst = (dst >> 21) + g_card_bundle_table | ||
if *card_bundle_dst != 0xff: | ||
*card_bundle_dst = 0xff | ||
|
||
```` | ||
|
||
The Checked Write Barrier has additional checks: | ||
|
||
```` | ||
JIT_CheckedWriteBarrier(Object **dst, Object *ref) | ||
|
||
// Return if the destination is not on the heap | ||
if ref < g_lowest_address || ref >= g_highest_address: | ||
return | ||
|
||
return JIT_WriteBarrier(dst, ref) | ||
```` | ||
|
||
|
||
|
||
## WritebarrierManager | ||
|
||
On AMD64, there several different implementations of the write barrier function. Each implementation assumes different state and so can skip certain checks. The actual write barrier that is called is a copy of one of these implementations. The WritebarrierManager keeps track of which implementation is currently being used. As internal state changes, the WritebarrierManager updates the copy to the correct implementation. In practice, most of the internal state is fixed on startup, with only changes to/from use of write watch barriers changing during runtime. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.