Untitled diff

Created Diff never expires
14 eliminaciones
Líneas
Total
Eliminado
Palabras
Total
Eliminado
Para continuar usando esta función, actualice a
Diffchecker logo
Diffchecker Pro
69 líneas
35 adiciones
Líneas
Total
Añadido
Palabras
Total
Añadido
Para continuar usando esta función, actualice a
Diffchecker logo
Diffchecker Pro
89 líneas
LEAF_ENTRY RhpByRefAssignRef, _TEXT
LEAF_ENTRY RhpByRefAssignRefBatch, _TEXT
ALTERNATE_ENTRY RhpByRefAssignRefAVLocation1
LOCAL_LABEL(RhpByRefAssignRefBatch_NextByref):
ALTERNATE_ENTRY RhpByRefAssignRefBatchAVLocation1
mov rcx, [rsi]
mov rcx, [rsi]
ALTERNATE_ENTRY RhpByRefAssignRefAVLocation2
ALTERNATE_ENTRY RhpByRefAssignRefBatchAVLocation2
mov [rdi], rcx
mov [rdi], rcx


// Check whether the writes were even into the heap. If not there's no card update required.
// Check whether the writes were even into the heap. If not there's no card update required.
cmp rdi, [C_VAR(g_lowest_address)]
cmp rdi, [C_VAR(g_lowest_address)]
jb LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired)
jb LOCAL_LABEL(RhpByRefAssignRefBatch_NotInHeap)
cmp rdi, [C_VAR(g_highest_address)]
cmp rdi, [C_VAR(g_highest_address)]
jae LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired)
jae LOCAL_LABEL(RhpByRefAssignRefBatch_NotInHeap)


// Update the shadow copy of the heap with the same value just written to the same heap. (A no-op unless
// 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).
// we're in a debug build and write barrier checking has been enabled).
UPDATE_GC_SHADOW BASENAME, rcx, rdi
UPDATE_GC_SHADOW BASENAME, rcx, rdi


#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
mov r11, [C_VAR(g_write_watch_table)]
mov r11, [C_VAR(g_write_watch_table)]
cmp r11, 0x0
cmp r11, 0x0
je LOCAL_LABEL(RhpByRefAssignRef_CheckCardTable)
je LOCAL_LABEL(RhpByRefAssignRefBatch_CheckCardTable)


mov r10, rdi
mov r10, rdi
shr r10, 0xC // SoftwareWriteWatch::AddressToTableByteIndexShift
shr r10, 0xC // SoftwareWriteWatch::AddressToTableByteIndexShift
add r10, r11
add r10, r11
cmp byte ptr [r10], 0x0
cmp byte ptr [r10], 0x0
jne LOCAL_LABEL(RhpByRefAssignRef_CheckCardTable)
jne LOCAL_LABEL(RhpByRefAssignRefBatch_CheckCardTable)
mov byte ptr [r10], 0xFF
mov byte ptr [r10], 0xFF
#endif
#endif


LOCAL_LABEL(RhpByRefAssignRef_CheckCardTable):
LOCAL_LABEL(RhpByRefAssignRefBatch_CheckCardTable):


// If the reference is to an object that's not in an ephemeral generation we have no need to track it
// 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).
// (since the object won't be collected or moved by an ephemeral collection).
cmp rcx, [C_VAR(g_ephemeral_low)]
cmp rcx, [C_VAR(g_ephemeral_low)]
jb LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired)
jb LOCAL_LABEL(RhpByRefAssignRefBatch_NoBarrierRequired)
cmp rcx, [C_VAR(g_ephemeral_high)]
cmp rcx, [C_VAR(g_ephemeral_high)]
jae LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired)
jae LOCAL_LABEL(RhpByRefAssignRefBatch_NoBarrierRequired)


// move current rdi value into rcx, we need to keep rdi and eventually increment by 8
// move current rdi value into rcx, we need to keep rdi and eventually increment by 8
mov rcx, rdi
mov rcx, rdi


// We have a location on the GC heap being updated with a reference to an ephemeral object so we must
// 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
// 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
// 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.
// the byte if it hasn't already been done since writes are expensive and impact scaling.
shr rcx, 0x0B
shr rcx, 0x0B
mov r10, [C_VAR(g_card_table)]
mov r10, [C_VAR(g_card_table)]
cmp byte ptr [rcx + r10], 0x0FF
cmp byte ptr [rcx + r10], 0x0FF
je LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired)
je LOCAL_LABEL(RhpByRefAssignRefBatch_NoBarrierRequired)


// We get here if it's necessary to update the card table.
// We get here if it's necessary to update the card table.
mov byte ptr [rcx + r10], 0xFF
mov byte ptr [rcx + r10], 0xFF


#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
// Shift rcx by 0x0A more to get the card bundle byte (we shifted by 0x0B already)
// Shift rcx by 0x0A more to get the card bundle byte (we shifted by 0x0B already)
shr rcx, 0x0A
shr rcx, 0x0A
add rcx, [C_VAR(g_card_bundle_table)]
add rcx, [C_VAR(g_card_bundle_table)]
cmp byte ptr [rcx], 0xFF
cmp byte ptr [rcx], 0xFF
je LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired)
je LOCAL_LABEL(RhpByRefAssignRefBatch_NoBarrierRequired)


mov byte ptr [rcx], 0xFF
mov byte ptr [rcx], 0xFF
#endif
#endif


LOCAL_LABEL(RhpByRefAssignRef_NoBarrierRequired):
LOCAL_LABEL(RhpByRefAssignRefBatch_NotInHeap):
// At least one write is already done, increment the pointers
add rdi, 0x8
add rsi, 0x8
dec r8d
je LOCAL_LABEL(RhpByRefAssignRefBatch_NotInHeapExit)
// Now we can do the rest of the writes without checking the heap
LOCAL_LABEL(RhpByRefAssignRefBatch_NextByrefUnchecked):
mov rcx, [rsi]
mov [rdi], rcx
add rdi, 0x8
add rsi, 0x8
dec r8d
jne LOCAL_LABEL(RhpByRefAssignRefBatch_NextByrefUnchecked)
LOCAL_LABEL(RhpByRefAssignRefBatch_NotInHeapExit):
ret

LOCAL_LABEL(RhpByRefAssignRefBatch_NoBarrierRequired):
// Increment the pointers before leaving
// Increment the pointers before leaving
add rdi, 0x8
add rdi, 0x8
add rsi, 0x8
add rsi, 0x8
dec r8d
jne LOCAL_LABEL(RhpByRefAssignRefBatch_NextByref)
ret
ret
LEAF_END RhpByRefAssignRef, _TEXT
LEAF_END RhpByRefAssignRefBatch, _TEXT