Diff
checker
テキスト
テキスト
画像
ドキュメント
Excel
フォルダ
Legal
Enterprise
デスクトップ
料金
ログイン
Diffchecker デスクトップのダウンロード
テキスト比較
2 つのテキスト ファイルの違いを見つける
ツール
履歴
ライブエディター
未変更行を折りたたむ
折り返しなし
レイアウト
分割
統合
比較精度
スマート
単語
文字
シンタックスハイライト
構文を選択
無視
テキスト変換
最初の差分へ移動
入力を編集
Diffchecker Desktop
Diffcheckerを実行する最も安全な方法。Diffchecker Desktopアプリを入手:あなたの差分はコンピューターから出ることはありません!
Desktopを入手
Untitled diff
作成日
2 年前
差分は期限切れになりません
クリア
エクスポート
共有
説明
4 削除
行
合計
削除
文字
合計
削除
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
195 行
すべてコピー
67 追加
行
合計
追加
文字
合計
追加
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
227 行
すべてコピー
コピー
コピー済み
コピー
コピー済み
LEAF_ENTRY JIT_ByRefWriteBarrier
, _TEXT
LEAF_ENTRY JIT_ByRefWriteBarrier
Batch
, _TEXT
LOCAL_LABEL(NextByref_ByRefWriteBarrierBatch):
mov rcx, [rsi]
mov rcx, [rsi]
// If !WRITE_BARRIER_CHECK do the write first, otherwise we might have to do some ShadowGC stuff
// If !WRITE_BARRIER_CHECK do the write first, otherwise we might have to do some ShadowGC stuff
#ifndef WRITE_BARRIER_CHECK
#ifndef WRITE_BARRIER_CHECK
// rcx is [rsi]
// rcx is [rsi]
mov [rdi], rcx
mov [rdi], rcx
#endif
#endif
// When WRITE_BARRIER_CHECK is defined _NotInHeap will write the reference
// When WRITE_BARRIER_CHECK is defined _NotInHeap will write the reference
// but if it isn't then it will just return.
// but if it isn't then it will just return.
//
//
// See if this is in GCHeap
// See if this is in GCHeap
PREPARE_EXTERNAL_VAR g_lowest_address, rax
PREPARE_EXTERNAL_VAR g_lowest_address, rax
cmp rdi, [rax]
cmp rdi, [rax]
コピー
コピー済み
コピー
コピー済み
jb LOCAL_LABEL(NotInHeap_ByRefWriteBarrier
)
jb LOCAL_LABEL(NotInHeap_ByRefWriteBarrier
Batch
)
PREPARE_EXTERNAL_VAR g_highest_address, rax
PREPARE_EXTERNAL_VAR g_highest_address, rax
cmp rdi, [rax]
cmp rdi, [rax]
コピー
コピー済み
コピー
コピー済み
jnb LOCAL_LABEL(NotInHeap_ByRefWriteBarrier
)
jnb LOCAL_LABEL(NotInHeap_ByRefWriteBarrier
Batch
)
#ifdef WRITE_BARRIER_CHECK
#ifdef WRITE_BARRIER_CHECK
// **ALSO update the shadow GC heap if that is enabled**
// **ALSO update the shadow GC heap if that is enabled**
// Do not perform the work if g_GCShadow is 0
// Do not perform the work if g_GCShadow is 0
PREPARE_EXTERNAL_VAR g_GCShadow, rax
PREPARE_EXTERNAL_VAR g_GCShadow, rax
cmp qword ptr [rax], 0
cmp qword ptr [rax], 0
コピー
コピー済み
コピー
コピー済み
je LOCAL_LABEL(NoShadow_ByRefWriteBarrier
)
je LOCAL_LABEL(NoShadow_ByRefWriteBarrier
Batch
)
// If we end up outside of the heap don't corrupt random memory
// If we end up outside of the heap don't corrupt random memory
mov r10, rdi
mov r10, rdi
PREPARE_EXTERNAL_VAR g_lowest_address, rax
PREPARE_EXTERNAL_VAR g_lowest_address, rax
sub r10, [rax]
sub r10, [rax]
コピー
コピー済み
コピー
コピー済み
jb LOCAL_LABEL(NoShadow_ByRefWriteBarrier
)
jb LOCAL_LABEL(NoShadow_ByRefWriteBarrier
Batch
)
// Check that our adjusted destination is somewhere in the shadow gc
// Check that our adjusted destination is somewhere in the shadow gc
PREPARE_EXTERNAL_VAR g_GCShadow, rax
PREPARE_EXTERNAL_VAR g_GCShadow, rax
add r10, [rax]
add r10, [rax]
PREPARE_EXTERNAL_VAR g_GCShadowEnd, rax
PREPARE_EXTERNAL_VAR g_GCShadowEnd, rax
cmp r10, [rax]
cmp r10, [rax]
コピー
コピー済み
コピー
コピー済み
jnb LOCAL_LABEL(NoShadow_ByRefWriteBarrier
)
jnb LOCAL_LABEL(NoShadow_ByRefWriteBarrier
Batch
)
// Write ref into real GC
// Write ref into real GC
mov [rdi], rcx
mov [rdi], rcx
// Write ref into shadow GC
// Write ref into shadow GC
mov [r10], rcx
mov [r10], rcx
// Ensure that the write to the shadow heap occurs before the read from
// Ensure that the write to the shadow heap occurs before the read from
// the GC heap so that race conditions are caught by INVALIDGCVALUE
// the GC heap so that race conditions are caught by INVALIDGCVALUE
mfence
mfence
// Check that GC/ShadowGC values match
// Check that GC/ShadowGC values match
mov r11, [rdi]
mov r11, [rdi]
mov rax, [r10]
mov rax, [r10]
cmp rax, r11
cmp rax, r11
コピー
コピー済み
コピー
コピー済み
je LOCAL_LABEL(DoneShadow_ByRefWriteBarrier
)
je LOCAL_LABEL(DoneShadow_ByRefWriteBarrier
Batch
)
movabs r11, INVALIDGCVALUE
movabs r11, INVALIDGCVALUE
mov [r10], r11
mov [r10], r11
コピー
コピー済み
コピー
コピー済み
jmp LOCAL_LABEL(DoneShadow_ByRefWriteBarrier
)
jmp LOCAL_LABEL(DoneShadow_ByRefWriteBarrier
Batch
)
// If we don't have a shadow GC we won't have done the write yet
// If we don't have a shadow GC we won't have done the write yet
コピー
コピー済み
コピー
コピー済み
LOCAL_LABEL(NoShadow_ByRefWriteBarrier
):
LOCAL_LABEL(NoShadow_ByRefWriteBarrier
Batch
):
mov [rdi], rcx
mov [rdi], rcx
// If we had a shadow GC then we already wrote to the real GC at the same time
// If we had a shadow GC then we already wrote to the real GC at the same time
// as the shadow GC so we want to jump over the real write immediately above.
// as the shadow GC so we want to jump over the real write immediately above.
// Additionally we know for sure that we are inside the heap and therefore don't
// Additionally we know for sure that we are inside the heap and therefore don't
// need to replicate the above checks.
// need to replicate the above checks.
コピー
コピー済み
コピー
コピー済み
LOCAL_LABEL(DoneShadow_ByRefWriteBarrier
):
LOCAL_LABEL(DoneShadow_ByRefWriteBarrier
Batch
):
#endif
#endif
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
// Update the write watch table if necessary
// Update the write watch table if necessary
PREPARE_EXTERNAL_VAR g_sw_ww_enabled_for_gc_heap, rax
PREPARE_EXTERNAL_VAR g_sw_ww_enabled_for_gc_heap, rax
cmp byte ptr [rax], 0x0
cmp byte ptr [rax], 0x0
コピー
コピー済み
コピー
コピー済み
je LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier
)
je LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier
Batch
)
mov rax, rdi
mov rax, rdi
shr rax, 0xC // SoftwareWriteWatch::AddressToTableByteIndexShift
shr rax, 0xC // SoftwareWriteWatch::AddressToTableByteIndexShift
PREPARE_EXTERNAL_VAR g_sw_ww_table, r10
PREPARE_EXTERNAL_VAR g_sw_ww_table, r10
add rax, qword ptr [r10]
add rax, qword ptr [r10]
cmp byte ptr [rax], 0x0
cmp byte ptr [rax], 0x0
コピー
コピー済み
コピー
コピー済み
jne LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier
)
jne LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier
Batch
)
mov byte ptr [rax], 0xFF
mov byte ptr [rax], 0xFF
#endif
#endif
コピー
コピー済み
コピー
コピー済み
LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier
):
LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier
Batch
):
// See if we can just quick out
// See if we can just quick out
PREPARE_EXTERNAL_VAR g_ephemeral_low, rax
PREPARE_EXTERNAL_VAR g_ephemeral_low, rax
cmp rcx, [rax]
cmp rcx, [rax]
コピー
コピー済み
コピー
コピー済み
jb LOCAL_LABEL(Exit_ByRefWriteBarrier
)
jb LOCAL_LABEL(Exit_ByRefWriteBarrier
Batch
)
PREPARE_EXTERNAL_VAR g_ephemeral_high, rax
PREPARE_EXTERNAL_VAR g_ephemeral_high, rax
cmp rcx, [rax]
cmp rcx, [rax]
コピー
コピー済み
コピー
コピー済み
jnb LOCAL_LABEL(Exit_ByRefWriteBarrier
)
jnb LOCAL_LABEL(Exit_ByRefWriteBarrier
Batch
)
mov rax, rcx
mov rax, rcx
PREPARE_EXTERNAL_VAR g_region_shr, rcx
PREPARE_EXTERNAL_VAR g_region_shr, rcx
mov cl, [rcx]
mov cl, [rcx]
test cl, cl
test cl, cl
コピー
コピー済み
コピー
コピー済み
je LOCAL_LABEL(SkipCheck_ByRefWriteBarrier
)
je LOCAL_LABEL(SkipCheck_ByRefWriteBarrier
Batch
)
// check if the source is in gen 2 - then it's not an ephemeral pointer
// check if the source is in gen 2 - then it's not an ephemeral pointer
shr rax, cl
shr rax, cl
PREPARE_EXTERNAL_VAR g_region_to_generation_table, r10
PREPARE_EXTERNAL_VAR g_region_to_generation_table, r10
mov r10, [r10]
mov r10, [r10]
cmp byte ptr [rax + r10], 0x82
cmp byte ptr [rax + r10], 0x82
コピー
コピー済み
コピー
コピー済み
je LOCAL_LABEL(Exit_ByRefWriteBarrier
)
je LOCAL_LABEL(Exit_ByRefWriteBarrier
Batch
)
// check if the destination happens to be in gen 0
// check if the destination happens to be in gen 0
mov rax, rdi
mov rax, rdi
shr rax, cl
shr rax, cl
cmp byte ptr [rax + r10], 0
cmp byte ptr [rax + r10], 0
コピー
コピー済み
コピー
コピー済み
je LOCAL_LABEL(Exit_ByRefWriteBarrier
)
je LOCAL_LABEL(Exit_ByRefWriteBarrier
Batch
)
LOCAL_LABEL(SkipCheck_ByRefWriteBarrier
):
LOCAL_LABEL(SkipCheck_ByRefWriteBarrier
Batch
):
PREPARE_EXTERNAL_VAR g_card_table, r10
PREPARE_EXTERNAL_VAR g_card_table, r10
mov r10, [r10]
mov r10, [r10]
PREPARE_EXTERNAL_VAR g_region_use_bitwise_write_barrier, rax
PREPARE_EXTERNAL_VAR g_region_use_bitwise_write_barrier, rax
cmp byte ptr [rax], 0
cmp byte ptr [rax], 0
コピー
コピー済み
コピー
コピー済み
je LOCAL_LABEL(CheckCardTableByte_ByRefWriteBarrier
)
je LOCAL_LABEL(CheckCardTableByte_ByRefWriteBarrier
Batch
)
// compute card table bit
// compute card table bit
mov ecx, edi
mov ecx, edi
mov al, 1
mov al, 1
shr ecx, 8
shr ecx, 8
and cl, 7
and cl, 7
shl al, cl
shl al, cl
// move current rdi value into rcx and then increment the pointers
// move current rdi value into rcx and then increment the pointers
mov rcx, rdi
mov rcx, rdi
add rsi, 0x8
add rsi, 0x8
add rdi, 0x8
add rdi, 0x8
// Check if we need to update the card table
// Check if we need to update the card table
// Calc pCardByte
// Calc pCardByte
shr rcx, 0xB
shr rcx, 0xB
// Check if this card table bit is already set
// Check if this card table bit is already set
test byte ptr [rcx + r10], al
test byte ptr [rcx + r10], al
コピー
コピー済み
コピー
コピー済み
je LOCAL_LABEL(SetCardTableBit_ByRefWriteBarrier
)
je LOCAL_LABEL(SetCardTableBit_ByRefWriteBarrier
Batch)
// Check if we have more in the batch and run again
dec r8d
jne LOCAL_LABEL(NextByref_ByRefWriteBarrierBatch)
REPRET
REPRET
コピー
コピー済み
コピー
コピー済み
LOCAL_LABEL(SetCardTableBit_ByRefWriteBarrier
):
LOCAL_LABEL(SetCardTableBit_ByRefWriteBarrier
Batch
):
lock or byte ptr [rcx + r10], al
lock or byte ptr [rcx + r10], al
コピー
コピー済み
コピー
コピー済み
jmp LOCAL_LABEL(CheckCardBundle_ByRefWriteBarrier
)
jmp LOCAL_LABEL(CheckCardBundle_ByRefWriteBarrier
Batch
)
コピー
コピー済み
コピー
コピー済み
LOCAL_LABEL(CheckCardTableByte_ByRefWriteBarrier
):
LOCAL_LABEL(CheckCardTableByte_ByRefWriteBarrier
Batch
):
// move current rdi value into rcx and then increment the pointers
// move current rdi value into rcx and then increment the pointers
mov rcx, rdi
mov rcx, rdi
add rsi, 0x8
add rsi, 0x8
add rdi, 0x8
add rdi, 0x8
shr rcx, 0xB
shr rcx, 0xB
cmp byte ptr [rcx + r10], 0xFF
cmp byte ptr [rcx + r10], 0xFF
コピー
コピー済み
コピー
コピー済み
jne LOCAL_LABEL(SetCardTableByte_ByRefWriteBarrier
)
jne LOCAL_LABEL(SetCardTableByte_ByRefWriteBarrier
Batch)
// Check if we have more in the batch and run again
dec r8d
jne LOCAL_LABEL(NextByref_ByRefWriteBarrierBatch)
REPRET
REPRET
コピー
コピー済み
コピー
コピー済み
LOCAL_LABEL(SetCardTableByte_ByRefWriteBarrier
):
LOCAL_LABEL(SetCardTableByte_ByRefWriteBarrier
Batch
):
mov byte ptr [rcx + r10], 0xFF
mov byte ptr [rcx + r10], 0xFF
コピー
コピー済み
コピー
コピー済み
LOCAL_LABEL(CheckCardBundle_ByRefWriteBarrier
):
LOCAL_LABEL(CheckCardBundle_ByRefWriteBarrier
Batch
):
#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
PREPARE_EXTERNAL_VAR g_card_bundle_table, rax
PREPARE_EXTERNAL_VAR g_card_bundle_table, rax
add rcx, [rax]
add rcx, [rax]
// Check if this bundle byte is dirty
// Check if this bundle byte is dirty
cmp byte ptr [rcx], 0xFF
cmp byte ptr [rcx], 0xFF
コピー
コピー済み
コピー
コピー済み
jne LOCAL_LABEL(UpdateCardBundle_ByRefWriteBarrier
)
jne LOCAL_LABEL(UpdateCardBundle_ByRefWriteBarrier
Batch)
// Check if we have more in the batch and run again
dec r8d
jne LOCAL_LABEL(NextByref_ByRefWriteBarrierBatch)
REPRET
REPRET
コピー
コピー済み
コピー
コピー済み
LOCAL_LABEL(UpdateCardBundle_ByRefWriteBarrier
):
LOCAL_LABEL(UpdateCardBundle_ByRefWriteBarrier
Batch
):
mov byte ptr [rcx], 0xFF
mov byte ptr [rcx], 0xFF
#endif
#endif
コピー
コピー済み
コピー
コピー済み
// Check if we have more in the batch and run again
dec r8d
jne LOCAL_LABEL(NextByref_ByRefWriteBarrierBatch)
ret
ret
.balign 16
.balign 16
コピー
コピー済み
コピー
コピー済み
LOCAL_LABEL(NotInHeap_ByRefWriteBarrier
):
LOCAL_LABEL(NotInHeap_ByRefWriteBarrier
Batch
):
// If WRITE_BARRIER_CHECK then we won't have already done the mov and should do it here
// If WRITE_BARRIER_CHECK then we won't have already done the mov and should do it here
// If !WRITE_BARRIER_CHECK we want _NotInHeap and _Leave to be the same and have both
// If !WRITE_BARRIER_CHECK we want _NotInHeap and _Leave to be the same and have both
// 16 byte aligned.
// 16 byte aligned.
#ifdef WRITE_BARRIER_CHECK
#ifdef WRITE_BARRIER_CHECK
// rcx is [rsi]
// rcx is [rsi]
mov [rdi], rcx
mov [rdi], rcx
#endif
#endif
コピー
コピー済み
コピー
コピー済み
LOCAL_LABEL(Exit_ByRefWriteBarrier
):
// At least one write is already done, increment the pointers
add rdi, 0x8
add rsi, 0x8
dec r8d
je LOCAL_LABEL(NotInHeapExit)
// Now we can do the rest of the writes without checking the heap
LOCAL_LABEL(NextByrefUnchecked):
mov rcx, [rsi]
mov [rdi], rcx
add rdi, 0x8
add rsi, 0x8
dec r8d
jne LOCAL_LABEL(NextByrefUnchecked)
LOCAL_LABEL(NotInHeapExit):
ret
LOCAL_LABEL(Exit_ByRefWriteBarrier
Batch
):
// Increment the pointers before leaving
// Increment the pointers before leaving
add rdi, 0x8
add rdi, 0x8
add rsi, 0x8
add rsi, 0x8
コピー
コピー済み
コピー
コピー済み
// Check if we have more in the batch and run again
dec r8d
jne LOCAL_LABEL(NextByref_ByRefWriteBarrierBatch)
ret
ret
コピー
コピー済み
コピー
コピー済み
LEAF_END_MARKED JIT_ByRefWriteBarrier
, _TEXT
LEAF_END_MARKED JIT_ByRefWriteBarrier
Batch
, _TEXT
保存された差分
原文
ファイルを開く
LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT mov rcx, [rsi] // If !WRITE_BARRIER_CHECK do the write first, otherwise we might have to do some ShadowGC stuff #ifndef WRITE_BARRIER_CHECK // rcx is [rsi] mov [rdi], rcx #endif // When WRITE_BARRIER_CHECK is defined _NotInHeap will write the reference // but if it isn't then it will just return. // // See if this is in GCHeap PREPARE_EXTERNAL_VAR g_lowest_address, rax cmp rdi, [rax] jb LOCAL_LABEL(NotInHeap_ByRefWriteBarrier) PREPARE_EXTERNAL_VAR g_highest_address, rax cmp rdi, [rax] jnb LOCAL_LABEL(NotInHeap_ByRefWriteBarrier) #ifdef WRITE_BARRIER_CHECK // **ALSO update the shadow GC heap if that is enabled** // Do not perform the work if g_GCShadow is 0 PREPARE_EXTERNAL_VAR g_GCShadow, rax cmp qword ptr [rax], 0 je LOCAL_LABEL(NoShadow_ByRefWriteBarrier) // If we end up outside of the heap don't corrupt random memory mov r10, rdi PREPARE_EXTERNAL_VAR g_lowest_address, rax sub r10, [rax] jb LOCAL_LABEL(NoShadow_ByRefWriteBarrier) // Check that our adjusted destination is somewhere in the shadow gc PREPARE_EXTERNAL_VAR g_GCShadow, rax add r10, [rax] PREPARE_EXTERNAL_VAR g_GCShadowEnd, rax cmp r10, [rax] jnb LOCAL_LABEL(NoShadow_ByRefWriteBarrier) // Write ref into real GC mov [rdi], rcx // Write ref into shadow GC mov [r10], rcx // Ensure that the write to the shadow heap occurs before the read from // the GC heap so that race conditions are caught by INVALIDGCVALUE mfence // Check that GC/ShadowGC values match mov r11, [rdi] mov rax, [r10] cmp rax, r11 je LOCAL_LABEL(DoneShadow_ByRefWriteBarrier) movabs r11, INVALIDGCVALUE mov [r10], r11 jmp LOCAL_LABEL(DoneShadow_ByRefWriteBarrier) // If we don't have a shadow GC we won't have done the write yet LOCAL_LABEL(NoShadow_ByRefWriteBarrier): mov [rdi], rcx // If we had a shadow GC then we already wrote to the real GC at the same time // as the shadow GC so we want to jump over the real write immediately above. // Additionally we know for sure that we are inside the heap and therefore don't // need to replicate the above checks. LOCAL_LABEL(DoneShadow_ByRefWriteBarrier): #endif #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP // Update the write watch table if necessary PREPARE_EXTERNAL_VAR g_sw_ww_enabled_for_gc_heap, rax cmp byte ptr [rax], 0x0 je LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier) mov rax, rdi shr rax, 0xC // SoftwareWriteWatch::AddressToTableByteIndexShift PREPARE_EXTERNAL_VAR g_sw_ww_table, r10 add rax, qword ptr [r10] cmp byte ptr [rax], 0x0 jne LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier) mov byte ptr [rax], 0xFF #endif LOCAL_LABEL(CheckCardTable_ByRefWriteBarrier): // See if we can just quick out PREPARE_EXTERNAL_VAR g_ephemeral_low, rax cmp rcx, [rax] jb LOCAL_LABEL(Exit_ByRefWriteBarrier) PREPARE_EXTERNAL_VAR g_ephemeral_high, rax cmp rcx, [rax] jnb LOCAL_LABEL(Exit_ByRefWriteBarrier) mov rax, rcx PREPARE_EXTERNAL_VAR g_region_shr, rcx mov cl, [rcx] test cl, cl je LOCAL_LABEL(SkipCheck_ByRefWriteBarrier) // check if the source is in gen 2 - then it's not an ephemeral pointer shr rax, cl PREPARE_EXTERNAL_VAR g_region_to_generation_table, r10 mov r10, [r10] cmp byte ptr [rax + r10], 0x82 je LOCAL_LABEL(Exit_ByRefWriteBarrier) // check if the destination happens to be in gen 0 mov rax, rdi shr rax, cl cmp byte ptr [rax + r10], 0 je LOCAL_LABEL(Exit_ByRefWriteBarrier) LOCAL_LABEL(SkipCheck_ByRefWriteBarrier): PREPARE_EXTERNAL_VAR g_card_table, r10 mov r10, [r10] PREPARE_EXTERNAL_VAR g_region_use_bitwise_write_barrier, rax cmp byte ptr [rax], 0 je LOCAL_LABEL(CheckCardTableByte_ByRefWriteBarrier) // compute card table bit mov ecx, edi mov al, 1 shr ecx, 8 and cl, 7 shl al, cl // move current rdi value into rcx and then increment the pointers mov rcx, rdi add rsi, 0x8 add rdi, 0x8 // Check if we need to update the card table // Calc pCardByte shr rcx, 0xB // Check if this card table bit is already set test byte ptr [rcx + r10], al je LOCAL_LABEL(SetCardTableBit_ByRefWriteBarrier) REPRET LOCAL_LABEL(SetCardTableBit_ByRefWriteBarrier): lock or byte ptr [rcx + r10], al jmp LOCAL_LABEL(CheckCardBundle_ByRefWriteBarrier) LOCAL_LABEL(CheckCardTableByte_ByRefWriteBarrier): // move current rdi value into rcx and then increment the pointers mov rcx, rdi add rsi, 0x8 add rdi, 0x8 shr rcx, 0xB cmp byte ptr [rcx + r10], 0xFF jne LOCAL_LABEL(SetCardTableByte_ByRefWriteBarrier) REPRET LOCAL_LABEL(SetCardTableByte_ByRefWriteBarrier): mov byte ptr [rcx + r10], 0xFF LOCAL_LABEL(CheckCardBundle_ByRefWriteBarrier): #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES // Shift rcx by 0x0A more to get the card bundle byte (we shifted by 0x0B already) shr rcx, 0x0A PREPARE_EXTERNAL_VAR g_card_bundle_table, rax add rcx, [rax] // Check if this bundle byte is dirty cmp byte ptr [rcx], 0xFF jne LOCAL_LABEL(UpdateCardBundle_ByRefWriteBarrier) REPRET LOCAL_LABEL(UpdateCardBundle_ByRefWriteBarrier): mov byte ptr [rcx], 0xFF #endif ret .balign 16 LOCAL_LABEL(NotInHeap_ByRefWriteBarrier): // If WRITE_BARRIER_CHECK then we won't have already done the mov and should do it here // If !WRITE_BARRIER_CHECK we want _NotInHeap and _Leave to be the same and have both // 16 byte aligned. #ifdef WRITE_BARRIER_CHECK // rcx is [rsi] mov [rdi], rcx #endif LOCAL_LABEL(Exit_ByRefWriteBarrier): // Increment the pointers before leaving add rdi, 0x8 add rsi, 0x8 ret LEAF_END_MARKED JIT_ByRefWriteBarrier, _TEXT
変更されたテキスト
ファイルを開く
LEAF_ENTRY JIT_ByRefWriteBarrierBatch, _TEXT LOCAL_LABEL(NextByref_ByRefWriteBarrierBatch): mov rcx, [rsi] // If !WRITE_BARRIER_CHECK do the write first, otherwise we might have to do some ShadowGC stuff #ifndef WRITE_BARRIER_CHECK // rcx is [rsi] mov [rdi], rcx #endif // When WRITE_BARRIER_CHECK is defined _NotInHeap will write the reference // but if it isn't then it will just return. // // See if this is in GCHeap PREPARE_EXTERNAL_VAR g_lowest_address, rax cmp rdi, [rax] jb LOCAL_LABEL(NotInHeap_ByRefWriteBarrierBatch) PREPARE_EXTERNAL_VAR g_highest_address, rax cmp rdi, [rax] jnb LOCAL_LABEL(NotInHeap_ByRefWriteBarrierBatch) #ifdef WRITE_BARRIER_CHECK // **ALSO update the shadow GC heap if that is enabled** // Do not perform the work if g_GCShadow is 0 PREPARE_EXTERNAL_VAR g_GCShadow, rax cmp qword ptr [rax], 0 je LOCAL_LABEL(NoShadow_ByRefWriteBarrierBatch) // If we end up outside of the heap don't corrupt random memory mov r10, rdi PREPARE_EXTERNAL_VAR g_lowest_address, rax sub r10, [rax] jb LOCAL_LABEL(NoShadow_ByRefWriteBarrierBatch) // Check that our adjusted destination is somewhere in the shadow gc PREPARE_EXTERNAL_VAR g_GCShadow, rax add r10, [rax] PREPARE_EXTERNAL_VAR g_GCShadowEnd, rax cmp r10, [rax] jnb LOCAL_LABEL(NoShadow_ByRefWriteBarrierBatch) // Write ref into real GC mov [rdi], rcx // Write ref into shadow GC mov [r10], rcx // Ensure that the write to the shadow heap occurs before the read from // the GC heap so that race conditions are caught by INVALIDGCVALUE mfence // Check that GC/ShadowGC values match mov r11, [rdi] mov rax, [r10] cmp rax, r11 je LOCAL_LABEL(DoneShadow_ByRefWriteBarrierBatch) movabs r11, INVALIDGCVALUE mov [r10], r11 jmp LOCAL_LABEL(DoneShadow_ByRefWriteBarrierBatch) // If we don't have a shadow GC we won't have done the write yet LOCAL_LABEL(NoShadow_ByRefWriteBarrierBatch): mov [rdi], rcx // If we had a shadow GC then we already wrote to the real GC at the same time // as the shadow GC so we want to jump over the real write immediately above. // Additionally we know for sure that we are inside the heap and therefore don't // need to replicate the above checks. LOCAL_LABEL(DoneShadow_ByRefWriteBarrierBatch): #endif #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP // Update the write watch table if necessary PREPARE_EXTERNAL_VAR g_sw_ww_enabled_for_gc_heap, rax cmp byte ptr [rax], 0x0 je LOCAL_LABEL(CheckCardTable_ByRefWriteBarrierBatch) mov rax, rdi shr rax, 0xC // SoftwareWriteWatch::AddressToTableByteIndexShift PREPARE_EXTERNAL_VAR g_sw_ww_table, r10 add rax, qword ptr [r10] cmp byte ptr [rax], 0x0 jne LOCAL_LABEL(CheckCardTable_ByRefWriteBarrierBatch) mov byte ptr [rax], 0xFF #endif LOCAL_LABEL(CheckCardTable_ByRefWriteBarrierBatch): // See if we can just quick out PREPARE_EXTERNAL_VAR g_ephemeral_low, rax cmp rcx, [rax] jb LOCAL_LABEL(Exit_ByRefWriteBarrierBatch) PREPARE_EXTERNAL_VAR g_ephemeral_high, rax cmp rcx, [rax] jnb LOCAL_LABEL(Exit_ByRefWriteBarrierBatch) mov rax, rcx PREPARE_EXTERNAL_VAR g_region_shr, rcx mov cl, [rcx] test cl, cl je LOCAL_LABEL(SkipCheck_ByRefWriteBarrierBatch) // check if the source is in gen 2 - then it's not an ephemeral pointer shr rax, cl PREPARE_EXTERNAL_VAR g_region_to_generation_table, r10 mov r10, [r10] cmp byte ptr [rax + r10], 0x82 je LOCAL_LABEL(Exit_ByRefWriteBarrierBatch) // check if the destination happens to be in gen 0 mov rax, rdi shr rax, cl cmp byte ptr [rax + r10], 0 je LOCAL_LABEL(Exit_ByRefWriteBarrierBatch) LOCAL_LABEL(SkipCheck_ByRefWriteBarrierBatch): PREPARE_EXTERNAL_VAR g_card_table, r10 mov r10, [r10] PREPARE_EXTERNAL_VAR g_region_use_bitwise_write_barrier, rax cmp byte ptr [rax], 0 je LOCAL_LABEL(CheckCardTableByte_ByRefWriteBarrierBatch) // compute card table bit mov ecx, edi mov al, 1 shr ecx, 8 and cl, 7 shl al, cl // move current rdi value into rcx and then increment the pointers mov rcx, rdi add rsi, 0x8 add rdi, 0x8 // Check if we need to update the card table // Calc pCardByte shr rcx, 0xB // Check if this card table bit is already set test byte ptr [rcx + r10], al je LOCAL_LABEL(SetCardTableBit_ByRefWriteBarrierBatch) // Check if we have more in the batch and run again dec r8d jne LOCAL_LABEL(NextByref_ByRefWriteBarrierBatch) REPRET LOCAL_LABEL(SetCardTableBit_ByRefWriteBarrierBatch): lock or byte ptr [rcx + r10], al jmp LOCAL_LABEL(CheckCardBundle_ByRefWriteBarrierBatch) LOCAL_LABEL(CheckCardTableByte_ByRefWriteBarrierBatch): // move current rdi value into rcx and then increment the pointers mov rcx, rdi add rsi, 0x8 add rdi, 0x8 shr rcx, 0xB cmp byte ptr [rcx + r10], 0xFF jne LOCAL_LABEL(SetCardTableByte_ByRefWriteBarrierBatch) // Check if we have more in the batch and run again dec r8d jne LOCAL_LABEL(NextByref_ByRefWriteBarrierBatch) REPRET LOCAL_LABEL(SetCardTableByte_ByRefWriteBarrierBatch): mov byte ptr [rcx + r10], 0xFF LOCAL_LABEL(CheckCardBundle_ByRefWriteBarrierBatch): #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES // Shift rcx by 0x0A more to get the card bundle byte (we shifted by 0x0B already) shr rcx, 0x0A PREPARE_EXTERNAL_VAR g_card_bundle_table, rax add rcx, [rax] // Check if this bundle byte is dirty cmp byte ptr [rcx], 0xFF jne LOCAL_LABEL(UpdateCardBundle_ByRefWriteBarrierBatch) // Check if we have more in the batch and run again dec r8d jne LOCAL_LABEL(NextByref_ByRefWriteBarrierBatch) REPRET LOCAL_LABEL(UpdateCardBundle_ByRefWriteBarrierBatch): mov byte ptr [rcx], 0xFF #endif // Check if we have more in the batch and run again dec r8d jne LOCAL_LABEL(NextByref_ByRefWriteBarrierBatch) ret .balign 16 LOCAL_LABEL(NotInHeap_ByRefWriteBarrierBatch): // If WRITE_BARRIER_CHECK then we won't have already done the mov and should do it here // If !WRITE_BARRIER_CHECK we want _NotInHeap and _Leave to be the same and have both // 16 byte aligned. #ifdef WRITE_BARRIER_CHECK // rcx is [rsi] mov [rdi], rcx #endif // At least one write is already done, increment the pointers add rdi, 0x8 add rsi, 0x8 dec r8d je LOCAL_LABEL(NotInHeapExit) // Now we can do the rest of the writes without checking the heap LOCAL_LABEL(NextByrefUnchecked): mov rcx, [rsi] mov [rdi], rcx add rdi, 0x8 add rsi, 0x8 dec r8d jne LOCAL_LABEL(NextByrefUnchecked) LOCAL_LABEL(NotInHeapExit): ret LOCAL_LABEL(Exit_ByRefWriteBarrierBatch): // Increment the pointers before leaving add rdi, 0x8 add rsi, 0x8 // Check if we have more in the batch and run again dec r8d jne LOCAL_LABEL(NextByref_ByRefWriteBarrierBatch) ret LEAF_END_MARKED JIT_ByRefWriteBarrierBatch, _TEXT
違いを見つける