Closed
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
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc
Original file line numberDiff line numberDiff line change
Expand Up@@ -400,6 +400,9 @@ EXTERN g_highest_address : QWORD
EXTERN g_ephemeral_low : QWORD
EXTERN g_ephemeral_high : QWORD
EXTERN g_card_table : QWORD
EXTERN g_region_shr : BYTE
EXTERN g_region_use_bitwise_write_barrier : BYTE
EXTERN g_region_to_generation_table : QWORD

ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
EXTERN g_card_bundle_table : QWORD
Expand Down
103 changes: 103 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.asm
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,55 @@ endif
cmp REFREG, [g_ephemeral_high]
jae &BASENAME&_NoBarrierRequired_&REFREG&

mov r10, REFREG
mov r11, rcx

mov cl, [g_region_shr]
test cl, cl
je &BASENAME&_SkipCheck_&REFREG&

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je &BASENAME&_NoBarrierRequired_&REFREG&

; check if the destination happens to be in gen 0
mov r10, r11
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je &BASENAME&_NoBarrierRequired_&REFREG&
&BASENAME&_SkipCheck_&REFREG&:

cmp [g_region_use_bitwise_write_barrier], 0
mov rcx, r11
je &BASENAME&_CheckCardTableByte_&REFREG&

; compute card table bit
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, r11
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne &BASENAME&_NoBarrierRequired_&REFREG&

lock or byte ptr [rcx], r10b

mov rcx, r11
shr rcx, 15h
jmp &BASENAME&_CheckCardBundle_&REFREG&

&BASENAME&_CheckCardTableByte_&REFREG&:

;; 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
;; an entire byte in the card table since it's quicker than messing around with bitmasks and we only write
Expand All@@ -137,11 +186,14 @@ endif
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0x0B already)
shr rcx, 0Ah
&BASENAME&_CheckCardBundle_&REFREG&:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je &BASENAME&_NoBarrierRequired_&REFREG&

mov byte ptr [rcx], 0FFh
else
&BASENAME&_CheckCardBundle_&REFREG&:
endif

&BASENAME&_NoBarrierRequired_&REFREG&:
Expand DownExpand Up@@ -317,6 +369,54 @@ RhpByRefAssignRef_CheckCardTable:
cmp rcx, [g_ephemeral_high]
jae RhpByRefAssignRef_NoBarrierRequired

mov r10, rcx

mov cl, [g_region_shr]
test cl, cl
je RhpByRefAssignRef_SkipCheck

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je RhpByRefAssignRef_NoBarrierRequired

; check if the destination happens to be in gen 0
mov r10, rdi
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je RhpByRefAssignRef_NoBarrierRequired
RhpByRefAssignRef_SkipCheck:

cmp [g_region_use_bitwise_write_barrier], 0
je RhpByRefAssignRef_CheckCardTableByte

; compute card table bit
mov rcx, rdi
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, rdi
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne RhpByRefAssignRef_NoBarrierRequired

lock or byte ptr [rcx], r10b

mov rcx, rdi
shr rcx, 15h
jmp RhpByRefAssignRef_CheckCardBundle

RhpByRefAssignRef_CheckCardTableByte:

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

Expand All@@ -335,11 +435,14 @@ RhpByRefAssignRef_CheckCardTable:
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0Bh already)
shr rcx, 0Ah
RhpByRefAssignRef_CheckCardBundle:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je RhpByRefAssignRef_NoBarrierRequired

mov byte ptr [rcx], 0FFh
else
RhpByRefAssignRef_CheckCardBundle:
endif

RhpByRefAssignRef_NoBarrierRequired:
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcenv.ee.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -415,6 +415,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
assert(args->ephemeral_high != nullptr);
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
return;
case WriteBarrierOp::Initialize:
// This operation should only be invoked once, upon initialization.
Expand DownExpand Up@@ -442,6 +445,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)

g_lowest_address = args->lowest_address;
g_highest_address = args->highest_address;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
return;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,6 +21,9 @@ GPTR_IMPL_INIT(uint8_t, g_highest_address, nullptr);
GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_INVALID);
uint8_t* g_ephemeral_low = (uint8_t*)1;
uint8_t* g_ephemeral_high = (uint8_t*)~0;
uint8_t* g_region_to_generation_table = nullptr;
uint8_t g_region_shr = 0;
bool g_region_use_bitwise_write_barrier = false;

#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
uint32_t* g_card_bundle_table = nullptr;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,9 @@ extern "C" uint32_t* g_card_bundle_table;

extern "C" uint8_t* g_ephemeral_low;
extern "C" uint8_t* g_ephemeral_high;
extern "C" uint8_t* g_region_to_generation_table;
extern "C" uint8_t g_region_shr;
extern "C" bool g_region_use_bitwise_write_barrier;

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
extern "C" bool g_sw_ww_enabled_for_gc_heap;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Closed
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
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc
Original file line numberDiff line numberDiff line change
Expand Up@@ -400,6 +400,9 @@ EXTERN g_highest_address : QWORD
EXTERN g_ephemeral_low : QWORD
EXTERN g_ephemeral_high : QWORD
EXTERN g_card_table : QWORD
EXTERN g_region_shr : BYTE
EXTERN g_region_use_bitwise_write_barrier : BYTE
EXTERN g_region_to_generation_table : QWORD

ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
EXTERN g_card_bundle_table : QWORD
Expand Down
103 changes: 103 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.asm
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,55 @@ endif
cmp REFREG, [g_ephemeral_high]
jae &BASENAME&_NoBarrierRequired_&REFREG&

mov r10, REFREG
mov r11, rcx

mov cl, [g_region_shr]
test cl, cl
je &BASENAME&_SkipCheck_&REFREG&

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je &BASENAME&_NoBarrierRequired_&REFREG&

; check if the destination happens to be in gen 0
mov r10, r11
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je &BASENAME&_NoBarrierRequired_&REFREG&
&BASENAME&_SkipCheck_&REFREG&:

cmp [g_region_use_bitwise_write_barrier], 0
mov rcx, r11
je &BASENAME&_CheckCardTableByte_&REFREG&

; compute card table bit
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, r11
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne &BASENAME&_NoBarrierRequired_&REFREG&

lock or byte ptr [rcx], r10b

mov rcx, r11
shr rcx, 15h
jmp &BASENAME&_CheckCardBundle_&REFREG&

&BASENAME&_CheckCardTableByte_&REFREG&:

;; 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
;; an entire byte in the card table since it's quicker than messing around with bitmasks and we only write
Expand All@@ -137,11 +186,14 @@ endif
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0x0B already)
shr rcx, 0Ah
&BASENAME&_CheckCardBundle_&REFREG&:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je &BASENAME&_NoBarrierRequired_&REFREG&

mov byte ptr [rcx], 0FFh
else
&BASENAME&_CheckCardBundle_&REFREG&:
endif

&BASENAME&_NoBarrierRequired_&REFREG&:
Expand DownExpand Up@@ -317,6 +369,54 @@ RhpByRefAssignRef_CheckCardTable:
cmp rcx, [g_ephemeral_high]
jae RhpByRefAssignRef_NoBarrierRequired

mov r10, rcx

mov cl, [g_region_shr]
test cl, cl
je RhpByRefAssignRef_SkipCheck

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je RhpByRefAssignRef_NoBarrierRequired

; check if the destination happens to be in gen 0
mov r10, rdi
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je RhpByRefAssignRef_NoBarrierRequired
RhpByRefAssignRef_SkipCheck:

cmp [g_region_use_bitwise_write_barrier], 0
je RhpByRefAssignRef_CheckCardTableByte

; compute card table bit
mov rcx, rdi
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, rdi
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne RhpByRefAssignRef_NoBarrierRequired

lock or byte ptr [rcx], r10b

mov rcx, rdi
shr rcx, 15h
jmp RhpByRefAssignRef_CheckCardBundle

RhpByRefAssignRef_CheckCardTableByte:

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

Expand All@@ -335,11 +435,14 @@ RhpByRefAssignRef_CheckCardTable:
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0Bh already)
shr rcx, 0Ah
RhpByRefAssignRef_CheckCardBundle:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je RhpByRefAssignRef_NoBarrierRequired

mov byte ptr [rcx], 0FFh
else
RhpByRefAssignRef_CheckCardBundle:
endif

RhpByRefAssignRef_NoBarrierRequired:
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcenv.ee.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -415,6 +415,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
assert(args->ephemeral_high != nullptr);
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
return;
case WriteBarrierOp::Initialize:
// This operation should only be invoked once, upon initialization.
Expand DownExpand Up@@ -442,6 +445,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)

g_lowest_address = args->lowest_address;
g_highest_address = args->highest_address;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
return;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,6 +21,9 @@ GPTR_IMPL_INIT(uint8_t, g_highest_address, nullptr);
GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_INVALID);
uint8_t* g_ephemeral_low = (uint8_t*)1;
uint8_t* g_ephemeral_high = (uint8_t*)~0;
uint8_t* g_region_to_generation_table = nullptr;
uint8_t g_region_shr = 0;
bool g_region_use_bitwise_write_barrier = false;

#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
uint32_t* g_card_bundle_table = nullptr;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,9 @@ extern "C" uint32_t* g_card_bundle_table;

extern "C" uint8_t* g_ephemeral_low;
extern "C" uint8_t* g_ephemeral_high;
extern "C" uint8_t* g_region_to_generation_table;
extern "C" uint8_t g_region_shr;
extern "C" bool g_region_use_bitwise_write_barrier;

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
extern "C" bool g_sw_ww_enabled_for_gc_heap;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
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
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc
Original file line numberDiff line numberDiff line change
Expand Up@@ -400,6 +400,9 @@ EXTERN g_highest_address : QWORD
EXTERN g_ephemeral_low : QWORD
EXTERN g_ephemeral_high : QWORD
EXTERN g_card_table : QWORD
EXTERN g_region_shr : BYTE
EXTERN g_region_use_bitwise_write_barrier : BYTE
EXTERN g_region_to_generation_table : QWORD

ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
EXTERN g_card_bundle_table : QWORD
Expand Down
103 changes: 103 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.asm
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,55 @@ endif
cmp REFREG, [g_ephemeral_high]
jae &BASENAME&_NoBarrierRequired_&REFREG&

mov r10, REFREG
mov r11, rcx

mov cl, [g_region_shr]
test cl, cl
je &BASENAME&_SkipCheck_&REFREG&

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je &BASENAME&_NoBarrierRequired_&REFREG&

; check if the destination happens to be in gen 0
mov r10, r11
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je &BASENAME&_NoBarrierRequired_&REFREG&
&BASENAME&_SkipCheck_&REFREG&:

cmp [g_region_use_bitwise_write_barrier], 0
mov rcx, r11
je &BASENAME&_CheckCardTableByte_&REFREG&

; compute card table bit
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, r11
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne &BASENAME&_NoBarrierRequired_&REFREG&

lock or byte ptr [rcx], r10b

mov rcx, r11
shr rcx, 15h
jmp &BASENAME&_CheckCardBundle_&REFREG&

&BASENAME&_CheckCardTableByte_&REFREG&:

;; 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
;; an entire byte in the card table since it's quicker than messing around with bitmasks and we only write
Expand All@@ -137,11 +186,14 @@ endif
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0x0B already)
shr rcx, 0Ah
&BASENAME&_CheckCardBundle_&REFREG&:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je &BASENAME&_NoBarrierRequired_&REFREG&

mov byte ptr [rcx], 0FFh
else
&BASENAME&_CheckCardBundle_&REFREG&:
endif

&BASENAME&_NoBarrierRequired_&REFREG&:
Expand DownExpand Up@@ -317,6 +369,54 @@ RhpByRefAssignRef_CheckCardTable:
cmp rcx, [g_ephemeral_high]
jae RhpByRefAssignRef_NoBarrierRequired

mov r10, rcx

mov cl, [g_region_shr]
test cl, cl
je RhpByRefAssignRef_SkipCheck

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je RhpByRefAssignRef_NoBarrierRequired

; check if the destination happens to be in gen 0
mov r10, rdi
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je RhpByRefAssignRef_NoBarrierRequired
RhpByRefAssignRef_SkipCheck:

cmp [g_region_use_bitwise_write_barrier], 0
je RhpByRefAssignRef_CheckCardTableByte

; compute card table bit
mov rcx, rdi
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, rdi
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne RhpByRefAssignRef_NoBarrierRequired

lock or byte ptr [rcx], r10b

mov rcx, rdi
shr rcx, 15h
jmp RhpByRefAssignRef_CheckCardBundle

RhpByRefAssignRef_CheckCardTableByte:

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

Expand All@@ -335,11 +435,14 @@ RhpByRefAssignRef_CheckCardTable:
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0Bh already)
shr rcx, 0Ah
RhpByRefAssignRef_CheckCardBundle:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je RhpByRefAssignRef_NoBarrierRequired

mov byte ptr [rcx], 0FFh
else
RhpByRefAssignRef_CheckCardBundle:
endif

RhpByRefAssignRef_NoBarrierRequired:
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcenv.ee.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -415,6 +415,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
assert(args->ephemeral_high != nullptr);
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
return;
case WriteBarrierOp::Initialize:
// This operation should only be invoked once, upon initialization.
Expand DownExpand Up@@ -442,6 +445,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)

g_lowest_address = args->lowest_address;
g_highest_address = args->highest_address;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
return;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,6 +21,9 @@ GPTR_IMPL_INIT(uint8_t, g_highest_address, nullptr);
GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_INVALID);
uint8_t* g_ephemeral_low = (uint8_t*)1;
uint8_t* g_ephemeral_high = (uint8_t*)~0;
uint8_t* g_region_to_generation_table = nullptr;
uint8_t g_region_shr = 0;
bool g_region_use_bitwise_write_barrier = false;

#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
uint32_t* g_card_bundle_table = nullptr;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,9 @@ extern "C" uint32_t* g_card_bundle_table;

extern "C" uint8_t* g_ephemeral_low;
extern "C" uint8_t* g_ephemeral_high;
extern "C" uint8_t* g_region_to_generation_table;
extern "C" uint8_t g_region_shr;
extern "C" bool g_region_use_bitwise_write_barrier;

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
extern "C" bool g_sw_ww_enabled_for_gc_heap;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
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
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc
Original file line numberDiff line numberDiff line change
Expand Up@@ -400,6 +400,9 @@ EXTERN g_highest_address : QWORD
EXTERN g_ephemeral_low : QWORD
EXTERN g_ephemeral_high : QWORD
EXTERN g_card_table : QWORD
EXTERN g_region_shr : BYTE
EXTERN g_region_use_bitwise_write_barrier : BYTE
EXTERN g_region_to_generation_table : QWORD

ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
EXTERN g_card_bundle_table : QWORD
Expand Down
103 changes: 103 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.asm
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,55 @@ endif
cmp REFREG, [g_ephemeral_high]
jae &BASENAME&_NoBarrierRequired_&REFREG&

mov r10, REFREG
mov r11, rcx

mov cl, [g_region_shr]
test cl, cl
je &BASENAME&_SkipCheck_&REFREG&

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je &BASENAME&_NoBarrierRequired_&REFREG&

; check if the destination happens to be in gen 0
mov r10, r11
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je &BASENAME&_NoBarrierRequired_&REFREG&
&BASENAME&_SkipCheck_&REFREG&:

cmp [g_region_use_bitwise_write_barrier], 0
mov rcx, r11
je &BASENAME&_CheckCardTableByte_&REFREG&

; compute card table bit
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, r11
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne &BASENAME&_NoBarrierRequired_&REFREG&

lock or byte ptr [rcx], r10b

mov rcx, r11
shr rcx, 15h
jmp &BASENAME&_CheckCardBundle_&REFREG&

&BASENAME&_CheckCardTableByte_&REFREG&:

;; 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
;; an entire byte in the card table since it's quicker than messing around with bitmasks and we only write
Expand All@@ -137,11 +186,14 @@ endif
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0x0B already)
shr rcx, 0Ah
&BASENAME&_CheckCardBundle_&REFREG&:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je &BASENAME&_NoBarrierRequired_&REFREG&

mov byte ptr [rcx], 0FFh
else
&BASENAME&_CheckCardBundle_&REFREG&:
endif

&BASENAME&_NoBarrierRequired_&REFREG&:
Expand DownExpand Up@@ -317,6 +369,54 @@ RhpByRefAssignRef_CheckCardTable:
cmp rcx, [g_ephemeral_high]
jae RhpByRefAssignRef_NoBarrierRequired

mov r10, rcx

mov cl, [g_region_shr]
test cl, cl
je RhpByRefAssignRef_SkipCheck

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je RhpByRefAssignRef_NoBarrierRequired

; check if the destination happens to be in gen 0
mov r10, rdi
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je RhpByRefAssignRef_NoBarrierRequired
RhpByRefAssignRef_SkipCheck:

cmp [g_region_use_bitwise_write_barrier], 0
je RhpByRefAssignRef_CheckCardTableByte

; compute card table bit
mov rcx, rdi
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, rdi
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne RhpByRefAssignRef_NoBarrierRequired

lock or byte ptr [rcx], r10b

mov rcx, rdi
shr rcx, 15h
jmp RhpByRefAssignRef_CheckCardBundle

RhpByRefAssignRef_CheckCardTableByte:

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

Expand All@@ -335,11 +435,14 @@ RhpByRefAssignRef_CheckCardTable:
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0Bh already)
shr rcx, 0Ah
RhpByRefAssignRef_CheckCardBundle:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je RhpByRefAssignRef_NoBarrierRequired

mov byte ptr [rcx], 0FFh
else
RhpByRefAssignRef_CheckCardBundle:
endif

RhpByRefAssignRef_NoBarrierRequired:
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcenv.ee.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -415,6 +415,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
assert(args->ephemeral_high != nullptr);
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
return;
case WriteBarrierOp::Initialize:
// This operation should only be invoked once, upon initialization.
Expand DownExpand Up@@ -442,6 +445,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)

g_lowest_address = args->lowest_address;
g_highest_address = args->highest_address;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
return;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,6 +21,9 @@ GPTR_IMPL_INIT(uint8_t, g_highest_address, nullptr);
GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_INVALID);
uint8_t* g_ephemeral_low = (uint8_t*)1;
uint8_t* g_ephemeral_high = (uint8_t*)~0;
uint8_t* g_region_to_generation_table = nullptr;
uint8_t g_region_shr = 0;
bool g_region_use_bitwise_write_barrier = false;

#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
uint32_t* g_card_bundle_table = nullptr;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,9 @@ extern "C" uint32_t* g_card_bundle_table;

extern "C" uint8_t* g_ephemeral_low;
extern "C" uint8_t* g_ephemeral_high;
extern "C" uint8_t* g_region_to_generation_table;
extern "C" uint8_t g_region_shr;
extern "C" bool g_region_use_bitwise_write_barrier;

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
extern "C" bool g_sw_ww_enabled_for_gc_heap;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Closed
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
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc
Original file line numberDiff line numberDiff line change
Expand Up@@ -400,6 +400,9 @@ EXTERN g_highest_address : QWORD
EXTERN g_ephemeral_low : QWORD
EXTERN g_ephemeral_high : QWORD
EXTERN g_card_table : QWORD
EXTERN g_region_shr : BYTE
EXTERN g_region_use_bitwise_write_barrier : BYTE
EXTERN g_region_to_generation_table : QWORD

ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
EXTERN g_card_bundle_table : QWORD
Expand Down
103 changes: 103 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.asm
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,55 @@ endif
cmp REFREG, [g_ephemeral_high]
jae &BASENAME&_NoBarrierRequired_&REFREG&

mov r10, REFREG
mov r11, rcx

mov cl, [g_region_shr]
test cl, cl
je &BASENAME&_SkipCheck_&REFREG&

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je &BASENAME&_NoBarrierRequired_&REFREG&

; check if the destination happens to be in gen 0
mov r10, r11
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je &BASENAME&_NoBarrierRequired_&REFREG&
&BASENAME&_SkipCheck_&REFREG&:

cmp [g_region_use_bitwise_write_barrier], 0
mov rcx, r11
je &BASENAME&_CheckCardTableByte_&REFREG&

; compute card table bit
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, r11
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne &BASENAME&_NoBarrierRequired_&REFREG&

lock or byte ptr [rcx], r10b

mov rcx, r11
shr rcx, 15h
jmp &BASENAME&_CheckCardBundle_&REFREG&

&BASENAME&_CheckCardTableByte_&REFREG&:

;; 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
;; an entire byte in the card table since it's quicker than messing around with bitmasks and we only write
Expand All@@ -137,11 +186,14 @@ endif
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0x0B already)
shr rcx, 0Ah
&BASENAME&_CheckCardBundle_&REFREG&:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je &BASENAME&_NoBarrierRequired_&REFREG&

mov byte ptr [rcx], 0FFh
else
&BASENAME&_CheckCardBundle_&REFREG&:
endif

&BASENAME&_NoBarrierRequired_&REFREG&:
Expand DownExpand Up@@ -317,6 +369,54 @@ RhpByRefAssignRef_CheckCardTable:
cmp rcx, [g_ephemeral_high]
jae RhpByRefAssignRef_NoBarrierRequired

mov r10, rcx

mov cl, [g_region_shr]
test cl, cl
je RhpByRefAssignRef_SkipCheck

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je RhpByRefAssignRef_NoBarrierRequired

; check if the destination happens to be in gen 0
mov r10, rdi
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je RhpByRefAssignRef_NoBarrierRequired
RhpByRefAssignRef_SkipCheck:

cmp [g_region_use_bitwise_write_barrier], 0
je RhpByRefAssignRef_CheckCardTableByte

; compute card table bit
mov rcx, rdi
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, rdi
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne RhpByRefAssignRef_NoBarrierRequired

lock or byte ptr [rcx], r10b

mov rcx, rdi
shr rcx, 15h
jmp RhpByRefAssignRef_CheckCardBundle

RhpByRefAssignRef_CheckCardTableByte:

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

Expand All@@ -335,11 +435,14 @@ RhpByRefAssignRef_CheckCardTable:
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0Bh already)
shr rcx, 0Ah
RhpByRefAssignRef_CheckCardBundle:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je RhpByRefAssignRef_NoBarrierRequired

mov byte ptr [rcx], 0FFh
else
RhpByRefAssignRef_CheckCardBundle:
endif

RhpByRefAssignRef_NoBarrierRequired:
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcenv.ee.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -415,6 +415,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
assert(args->ephemeral_high != nullptr);
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
return;
case WriteBarrierOp::Initialize:
// This operation should only be invoked once, upon initialization.
Expand DownExpand Up@@ -442,6 +445,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)

g_lowest_address = args->lowest_address;
g_highest_address = args->highest_address;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
return;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,6 +21,9 @@ GPTR_IMPL_INIT(uint8_t, g_highest_address, nullptr);
GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_INVALID);
uint8_t* g_ephemeral_low = (uint8_t*)1;
uint8_t* g_ephemeral_high = (uint8_t*)~0;
uint8_t* g_region_to_generation_table = nullptr;
uint8_t g_region_shr = 0;
bool g_region_use_bitwise_write_barrier = false;

#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
uint32_t* g_card_bundle_table = nullptr;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,9 @@ extern "C" uint32_t* g_card_bundle_table;

extern "C" uint8_t* g_ephemeral_low;
extern "C" uint8_t* g_ephemeral_high;
extern "C" uint8_t* g_region_to_generation_table;
extern "C" uint8_t g_region_shr;
extern "C" bool g_region_use_bitwise_write_barrier;

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
extern "C" bool g_sw_ww_enabled_for_gc_heap;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
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
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc
Original file line numberDiff line numberDiff line change
Expand Up@@ -400,6 +400,9 @@ EXTERN g_highest_address : QWORD
EXTERN g_ephemeral_low : QWORD
EXTERN g_ephemeral_high : QWORD
EXTERN g_card_table : QWORD
EXTERN g_region_shr : BYTE
EXTERN g_region_use_bitwise_write_barrier : BYTE
EXTERN g_region_to_generation_table : QWORD

ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
EXTERN g_card_bundle_table : QWORD
Expand Down
103 changes: 103 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.asm
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,55 @@ endif
cmp REFREG, [g_ephemeral_high]
jae &BASENAME&_NoBarrierRequired_&REFREG&

mov r10, REFREG
mov r11, rcx

mov cl, [g_region_shr]
test cl, cl
je &BASENAME&_SkipCheck_&REFREG&

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je &BASENAME&_NoBarrierRequired_&REFREG&

; check if the destination happens to be in gen 0
mov r10, r11
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je &BASENAME&_NoBarrierRequired_&REFREG&
&BASENAME&_SkipCheck_&REFREG&:

cmp [g_region_use_bitwise_write_barrier], 0
mov rcx, r11
je &BASENAME&_CheckCardTableByte_&REFREG&

; compute card table bit
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, r11
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne &BASENAME&_NoBarrierRequired_&REFREG&

lock or byte ptr [rcx], r10b

mov rcx, r11
shr rcx, 15h
jmp &BASENAME&_CheckCardBundle_&REFREG&

&BASENAME&_CheckCardTableByte_&REFREG&:

;; 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
;; an entire byte in the card table since it's quicker than messing around with bitmasks and we only write
Expand All@@ -137,11 +186,14 @@ endif
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0x0B already)
shr rcx, 0Ah
&BASENAME&_CheckCardBundle_&REFREG&:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je &BASENAME&_NoBarrierRequired_&REFREG&

mov byte ptr [rcx], 0FFh
else
&BASENAME&_CheckCardBundle_&REFREG&:
endif

&BASENAME&_NoBarrierRequired_&REFREG&:
Expand DownExpand Up@@ -317,6 +369,54 @@ RhpByRefAssignRef_CheckCardTable:
cmp rcx, [g_ephemeral_high]
jae RhpByRefAssignRef_NoBarrierRequired

mov r10, rcx

mov cl, [g_region_shr]
test cl, cl
je RhpByRefAssignRef_SkipCheck

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je RhpByRefAssignRef_NoBarrierRequired

; check if the destination happens to be in gen 0
mov r10, rdi
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je RhpByRefAssignRef_NoBarrierRequired
RhpByRefAssignRef_SkipCheck:

cmp [g_region_use_bitwise_write_barrier], 0
je RhpByRefAssignRef_CheckCardTableByte

; compute card table bit
mov rcx, rdi
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, rdi
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne RhpByRefAssignRef_NoBarrierRequired

lock or byte ptr [rcx], r10b

mov rcx, rdi
shr rcx, 15h
jmp RhpByRefAssignRef_CheckCardBundle

RhpByRefAssignRef_CheckCardTableByte:

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

Expand All@@ -335,11 +435,14 @@ RhpByRefAssignRef_CheckCardTable:
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0Bh already)
shr rcx, 0Ah
RhpByRefAssignRef_CheckCardBundle:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je RhpByRefAssignRef_NoBarrierRequired

mov byte ptr [rcx], 0FFh
else
RhpByRefAssignRef_CheckCardBundle:
endif

RhpByRefAssignRef_NoBarrierRequired:
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcenv.ee.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -415,6 +415,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
assert(args->ephemeral_high != nullptr);
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
return;
case WriteBarrierOp::Initialize:
// This operation should only be invoked once, upon initialization.
Expand DownExpand Up@@ -442,6 +445,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)

g_lowest_address = args->lowest_address;
g_highest_address = args->highest_address;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
return;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,6 +21,9 @@ GPTR_IMPL_INIT(uint8_t, g_highest_address, nullptr);
GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_INVALID);
uint8_t* g_ephemeral_low = (uint8_t*)1;
uint8_t* g_ephemeral_high = (uint8_t*)~0;
uint8_t* g_region_to_generation_table = nullptr;
uint8_t g_region_shr = 0;
bool g_region_use_bitwise_write_barrier = false;

#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
uint32_t* g_card_bundle_table = nullptr;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,9 @@ extern "C" uint32_t* g_card_bundle_table;

extern "C" uint8_t* g_ephemeral_low;
extern "C" uint8_t* g_ephemeral_high;
extern "C" uint8_t* g_region_to_generation_table;
extern "C" uint8_t g_region_shr;
extern "C" bool g_region_use_bitwise_write_barrier;

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
extern "C" bool g_sw_ww_enabled_for_gc_heap;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
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
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc
Original file line numberDiff line numberDiff line change
Expand Up@@ -400,6 +400,9 @@ EXTERN g_highest_address : QWORD
EXTERN g_ephemeral_low : QWORD
EXTERN g_ephemeral_high : QWORD
EXTERN g_card_table : QWORD
EXTERN g_region_shr : BYTE
EXTERN g_region_use_bitwise_write_barrier : BYTE
EXTERN g_region_to_generation_table : QWORD

ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
EXTERN g_card_bundle_table : QWORD
Expand Down
103 changes: 103 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.asm
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,55 @@ endif
cmp REFREG, [g_ephemeral_high]
jae &BASENAME&_NoBarrierRequired_&REFREG&

mov r10, REFREG
mov r11, rcx

mov cl, [g_region_shr]
test cl, cl
je &BASENAME&_SkipCheck_&REFREG&

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je &BASENAME&_NoBarrierRequired_&REFREG&

; check if the destination happens to be in gen 0
mov r10, r11
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je &BASENAME&_NoBarrierRequired_&REFREG&
&BASENAME&_SkipCheck_&REFREG&:

cmp [g_region_use_bitwise_write_barrier], 0
mov rcx, r11
je &BASENAME&_CheckCardTableByte_&REFREG&

; compute card table bit
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, r11
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne &BASENAME&_NoBarrierRequired_&REFREG&

lock or byte ptr [rcx], r10b

mov rcx, r11
shr rcx, 15h
jmp &BASENAME&_CheckCardBundle_&REFREG&

&BASENAME&_CheckCardTableByte_&REFREG&:

;; 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
;; an entire byte in the card table since it's quicker than messing around with bitmasks and we only write
Expand All@@ -137,11 +186,14 @@ endif
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0x0B already)
shr rcx, 0Ah
&BASENAME&_CheckCardBundle_&REFREG&:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je &BASENAME&_NoBarrierRequired_&REFREG&

mov byte ptr [rcx], 0FFh
else
&BASENAME&_CheckCardBundle_&REFREG&:
endif

&BASENAME&_NoBarrierRequired_&REFREG&:
Expand DownExpand Up@@ -317,6 +369,54 @@ RhpByRefAssignRef_CheckCardTable:
cmp rcx, [g_ephemeral_high]
jae RhpByRefAssignRef_NoBarrierRequired

mov r10, rcx

mov cl, [g_region_shr]
test cl, cl
je RhpByRefAssignRef_SkipCheck

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je RhpByRefAssignRef_NoBarrierRequired

; check if the destination happens to be in gen 0
mov r10, rdi
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je RhpByRefAssignRef_NoBarrierRequired
RhpByRefAssignRef_SkipCheck:

cmp [g_region_use_bitwise_write_barrier], 0
je RhpByRefAssignRef_CheckCardTableByte

; compute card table bit
mov rcx, rdi
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, rdi
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne RhpByRefAssignRef_NoBarrierRequired

lock or byte ptr [rcx], r10b

mov rcx, rdi
shr rcx, 15h
jmp RhpByRefAssignRef_CheckCardBundle

RhpByRefAssignRef_CheckCardTableByte:

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

Expand All@@ -335,11 +435,14 @@ RhpByRefAssignRef_CheckCardTable:
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0Bh already)
shr rcx, 0Ah
RhpByRefAssignRef_CheckCardBundle:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je RhpByRefAssignRef_NoBarrierRequired

mov byte ptr [rcx], 0FFh
else
RhpByRefAssignRef_CheckCardBundle:
endif

RhpByRefAssignRef_NoBarrierRequired:
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcenv.ee.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -415,6 +415,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
assert(args->ephemeral_high != nullptr);
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
return;
case WriteBarrierOp::Initialize:
// This operation should only be invoked once, upon initialization.
Expand DownExpand Up@@ -442,6 +445,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)

g_lowest_address = args->lowest_address;
g_highest_address = args->highest_address;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
return;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,6 +21,9 @@ GPTR_IMPL_INIT(uint8_t, g_highest_address, nullptr);
GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_INVALID);
uint8_t* g_ephemeral_low = (uint8_t*)1;
uint8_t* g_ephemeral_high = (uint8_t*)~0;
uint8_t* g_region_to_generation_table = nullptr;
uint8_t g_region_shr = 0;
bool g_region_use_bitwise_write_barrier = false;

#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
uint32_t* g_card_bundle_table = nullptr;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,9 @@ extern "C" uint32_t* g_card_bundle_table;

extern "C" uint8_t* g_ephemeral_low;
extern "C" uint8_t* g_ephemeral_high;
extern "C" uint8_t* g_region_to_generation_table;
extern "C" uint8_t g_region_shr;
extern "C" bool g_region_use_bitwise_write_barrier;

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
extern "C" bool g_sw_ww_enabled_for_gc_heap;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Closed
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
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/AsmMacros.inc
Original file line numberDiff line numberDiff line change
Expand Up@@ -400,6 +400,9 @@ EXTERN g_highest_address : QWORD
EXTERN g_ephemeral_low : QWORD
EXTERN g_ephemeral_high : QWORD
EXTERN g_card_table : QWORD
EXTERN g_region_shr : BYTE
EXTERN g_region_use_bitwise_write_barrier : BYTE
EXTERN g_region_to_generation_table : QWORD

ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
EXTERN g_card_bundle_table : QWORD
Expand Down
103 changes: 103 additions & 0 deletions src/coreclr/nativeaot/Runtime/amd64/WriteBarriers.asm
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,6 +122,55 @@ endif
cmp REFREG, [g_ephemeral_high]
jae &BASENAME&_NoBarrierRequired_&REFREG&

mov r10, REFREG
mov r11, rcx

mov cl, [g_region_shr]
test cl, cl
je &BASENAME&_SkipCheck_&REFREG&

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je &BASENAME&_NoBarrierRequired_&REFREG&

; check if the destination happens to be in gen 0
mov r10, r11
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je &BASENAME&_NoBarrierRequired_&REFREG&
&BASENAME&_SkipCheck_&REFREG&:

cmp [g_region_use_bitwise_write_barrier], 0
mov rcx, r11
je &BASENAME&_CheckCardTableByte_&REFREG&

; compute card table bit
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, r11
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne &BASENAME&_NoBarrierRequired_&REFREG&

lock or byte ptr [rcx], r10b

mov rcx, r11
shr rcx, 15h
jmp &BASENAME&_CheckCardBundle_&REFREG&

&BASENAME&_CheckCardTableByte_&REFREG&:

;; 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
;; an entire byte in the card table since it's quicker than messing around with bitmasks and we only write
Expand All@@ -137,11 +186,14 @@ endif
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0x0B already)
shr rcx, 0Ah
&BASENAME&_CheckCardBundle_&REFREG&:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je &BASENAME&_NoBarrierRequired_&REFREG&

mov byte ptr [rcx], 0FFh
else
&BASENAME&_CheckCardBundle_&REFREG&:
endif

&BASENAME&_NoBarrierRequired_&REFREG&:
Expand DownExpand Up@@ -317,6 +369,54 @@ RhpByRefAssignRef_CheckCardTable:
cmp rcx, [g_ephemeral_high]
jae RhpByRefAssignRef_NoBarrierRequired

mov r10, rcx

mov cl, [g_region_shr]
test cl, cl
je RhpByRefAssignRef_SkipCheck

; check if the source is in gen 2 - then it's not an ephemeral pointer
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 82h
je RhpByRefAssignRef_NoBarrierRequired

; check if the destination happens to be in gen 0
mov r10, rdi
shr r10, cl
add r10, [g_region_to_generation_table]
cmp byte ptr [r10], 0
je RhpByRefAssignRef_NoBarrierRequired
RhpByRefAssignRef_SkipCheck:

cmp [g_region_use_bitwise_write_barrier], 0
je RhpByRefAssignRef_CheckCardTableByte

; compute card table bit
mov rcx, rdi
mov r10b, 1
shr rcx, 8
and cl, 7
shl r10b, cl

; Check if we need to update the card table
; Calc pCardByte
mov rcx, rdi
shr rcx, 0Bh
add rcx, [g_card_table]

; Check if this card table bit is already set
test byte ptr [rcx], r10b
jne RhpByRefAssignRef_NoBarrierRequired

lock or byte ptr [rcx], r10b

mov rcx, rdi
shr rcx, 15h
jmp RhpByRefAssignRef_CheckCardBundle

RhpByRefAssignRef_CheckCardTableByte:

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

Expand All@@ -335,11 +435,14 @@ RhpByRefAssignRef_CheckCardTable:
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
;; Shift rcx by 0Ah more to get the card bundle byte (we shifted by 0Bh already)
shr rcx, 0Ah
RhpByRefAssignRef_CheckCardBundle:
add rcx, [g_card_bundle_table]
cmp byte ptr [rcx], 0FFh
je RhpByRefAssignRef_NoBarrierRequired

mov byte ptr [rcx], 0FFh
else
RhpByRefAssignRef_CheckCardBundle:
endif

RhpByRefAssignRef_NoBarrierRequired:
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcenv.ee.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -415,6 +415,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
assert(args->ephemeral_high != nullptr);
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
return;
case WriteBarrierOp::Initialize:
// This operation should only be invoked once, upon initialization.
Expand DownExpand Up@@ -442,6 +445,9 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)

g_lowest_address = args->lowest_address;
g_highest_address = args->highest_address;
g_region_to_generation_table = args->region_to_generation_table;
g_region_shr = args->region_shr;
g_region_use_bitwise_write_barrier = args->region_use_bitwise_write_barrier;
g_ephemeral_low = args->ephemeral_low;
g_ephemeral_high = args->ephemeral_high;
return;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,6 +21,9 @@ GPTR_IMPL_INIT(uint8_t, g_highest_address, nullptr);
GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_INVALID);
uint8_t* g_ephemeral_low = (uint8_t*)1;
uint8_t* g_ephemeral_high = (uint8_t*)~0;
uint8_t* g_region_to_generation_table = nullptr;
uint8_t g_region_shr = 0;
bool g_region_use_bitwise_write_barrier = false;

#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
uint32_t* g_card_bundle_table = nullptr;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,9 @@ extern "C" uint32_t* g_card_bundle_table;

extern "C" uint8_t* g_ephemeral_low;
extern "C" uint8_t* g_ephemeral_high;
extern "C" uint8_t* g_region_to_generation_table;
extern "C" uint8_t g_region_shr;
extern "C" bool g_region_use_bitwise_write_barrier;

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
extern "C" bool g_sw_ww_enabled_for_gc_heap;
Expand Down