@@ -84,6 +84,21 @@ LOCAL_LABEL(\BASENAME\()_UpdateShadowHeap_Done_\REFREG):
8484 // we're in a debug build and write barrier checking has been enabled).
8585 UPDATE_GC_SHADOW \BASENAME , \REFREG , rdi
8686
87+ #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
88+ mov r11 , [ C_VAR(g_write_watch_table) ]
89+ cmp r11 , 0x0
90+ je LOCAL_LABEL(\BASENAME\()_CheckCardTable_\REFREG)
91+
92+ mov r10 , rdi
93+ shr r10 , 0xC // SoftwareWriteWatch::AddressToTableByteIndexShift
94+ add r10 , r11
95+ cmp byte ptr [ r10 ], 0x0
96+ jne LOCAL_LABEL(\BASENAME\()_CheckCardTable_\REFREG)
97+ mov byte ptr [ r10 ], 0xFF
98+ #endif
99+
100+ LOCAL_LABEL(\BASENAME\()_CheckCardTable_\REFREG):
101+
87102 // If the reference is to an object th at 's not in an ephemeral generation we have no need to track it
88103 // (since the object won't be collected or moved by an ephemeral collection).
89104 cmp \REFREG , [ C_VAR(g_ephemeral_low) ]
@@ -95,17 +110,25 @@ LOCAL_LABEL(\BASENAME\()_UpdateShadowHeap_Done_\REFREG):
95110 // track this write. The location address is translated into an offset in the card table bitmap. We set
96111 // an entire byte in the card table since it's quicker than messing around with bitmasks and we only write
97112 // the byte if it hasn't already been done since writes are expensive and impact scaling.
98- shr rdi , 11
99- add rdi , [ C_VAR(g_card_table) ]
100- cmp byte ptr [ rdi ], 0x0FF
101- jne LOCAL_LABEL(\BASENAME\()_UpdateCardTable_\REFREG)
102-
103- LOCAL_LABEL(\BASENAME\()_NoBarrierRequired_\REFREG):
104- ret
113+ shr rdi , 0x0B
114+ mov r10 , [ C_VAR(g_card_table) ]
115+ cmp byte ptr [ rdi + r10 ], 0x0FF
116+ je LOCAL_LABEL(\BASENAME\()_NoBarrierRequired_\REFREG)
105117
106118// We get here if it's necessary to update the card table.
107- LOCAL_LABEL(\BASENAME\()_UpdateCardTable_\REFREG):
108- mov byte ptr [ rdi ], 0x0FF
119+ mov byte ptr [ rdi + r10 ], 0xFF
120+
121+ #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
122+ // Shift rdi by 0x0A more to get the card bundle byte (we shifted by 0x0B already)
123+ shr rdi , 0x0A
124+ add rdi , [ C_VAR(g_card_bundle_table) ]
125+ cmp byte ptr [ rdi ], 0xFF
126+ je LOCAL_LABEL(\BASENAME\()_NoBarrierRequired_\REFREG)
127+
128+ mov byte ptr [ rdi ], 0xFF
129+ #endif
130+
131+ LOCAL_LABEL(\BASENAME\()_NoBarrierRequired_\REFREG):
109132 ret
110133
111134.endm
@@ -252,32 +275,52 @@ LEAF_ENTRY RhpByRefAssignRef, _TEXT
252275 // we're in a debug build and write barrier checking has been enabled).
253276 UPDATE_GC_SHADOW BASENAME , rcx , rdi
254277
278+ #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
279+ mov r11 , [ C_VAR(g_write_watch_table) ]
280+ cmp r11 , 0x0
281+ je LOCAL_LABEL(RhpByRefAssignRef_CheckCardTable)
282+
283+ mov r10 , rdi
284+ shr r10 , 0xC // SoftwareWriteWatch::AddressToTableByteIndexShift
285+ add r10 , r11
286+ cmp byte ptr [ r10 ], 0x0
287+ jne LOCAL_LABEL(RhpByRefAssignRef_CheckCardTable)
288+ mov byte ptr [ r10 ], 0xFF
289+ #endif
290+
291+ LOCAL_LABEL(RhpByRefAssignRef_CheckCardTable):
292+
255293 // If the reference is to an object th at 's not in an ephemeral generation we have no need to track it
256294 // (since the object won't be collected or moved by an ephemeral collection).
257295 cmp rcx , [ C_VAR(g_ephemeral_low) ]
258296 jb LOCAL_LABEL(RhpByRefAssignRef_NotInHeap)
259297 cmp rcx , [ C_VAR(g_ephemeral_high) ]
260298 jae LOCAL_LABEL(RhpByRefAssignRef_NotInHeap)
261299
262- // move current rdi value into rcx and then increment the pointers
300+ // move current rdi value into rcx , we need to keep rdi and eventually increment by 8
263301 mov rcx , rdi
264- add rsi , 0x8
265- add rdi , 0x8
266302
267303 // We have a location on the GC heap being updated with a reference to an ephemeral object so we must
268304 // track this write. The location address is translated into an offset in the card table bitmap. We set
269305 // an entire byte in the card table since it's quicker than messing around with bitmasks and we only write
270306 // the byte if it hasn't already been done since writes are expensive and impact scaling.
271- shr rcx , 11
272- add rcx , [ C_VAR(g_card_table) ]
273- cmp byte ptr [ rcx ], 0x0FF
274- jne LOCAL_LABEL(RhpByRefAssignRef_UpdateCardTable)
275- ret
307+ shr rcx , 0x0B
308+ mov r10 , [ C_VAR(g_card_table) ]
309+ cmp byte ptr [ rcx + r10 ], 0x0FF
310+ je LOCAL_LABEL(RhpByRefAssignRef_NotInHeap)
276311
277312// We get here if it's necessary to update the card table.
278- LOCAL_LABEL(RhpByRefAssignRef_UpdateCardTable):
279- mov byte ptr [ rcx ], 0x0FF
280- ret
313+ mov byte ptr [ rcx + r10 ], 0xFF
314+
315+ #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
316+ // Shift rcx by 0x0A more to get the card bundle byte (we shifted by 0x0B already)
317+ shr rcx , 0x0A
318+ add rcx , [ C_VAR(g_card_bundle_table) ]
319+ cmp byte ptr [ rcx ], 0xFF
320+ je LOCAL_LABEL(RhpByRefAssignRef_NotInHeap)
321+
322+ mov byte ptr [ rcx ], 0xFF
323+ #endif
281324
282325LOCAL_LABEL(RhpByRefAssignRef_NotInHeap):
283326 // Increment the pointers before leaving
0 commit comments