Skip to content

Commit

Permalink
Split off patched code into separate .S file and disable subsections-…
Browse files Browse the repository at this point in the history
…via-symbols for it (#92555)

* [amd64/arm64] Split off patched code into separate .S file and disable subsections-via-symbols for it

* [amd64/arm64] Split off patched code into separate .asm file

[arm64] Move JIT_UpdateWriteBarrierState out of the patched region to match implementation in .S file

* Remove NO_SUBSECTIONS_VIA_SYMBOLS
  • Loading branch information
filipnavara authored Sep 30, 2023
1 parent 588193f commit 420717e
Show file tree
Hide file tree
Showing 9 changed files with 926 additions and 880 deletions.
4 changes: 4 additions & 0 deletions src/coreclr/vm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ if(CLR_CMAKE_TARGET_ARCH_AMD64)
${ARCH_SOURCES_DIR}/JitHelpers_InlineGetThread.asm
${ARCH_SOURCES_DIR}/JitHelpers_SingleAppDomain.asm
${ARCH_SOURCES_DIR}/JitHelpers_Slow.asm
${ARCH_SOURCES_DIR}/patchedcode.asm
${ARCH_SOURCES_DIR}/PInvokeStubs.asm
${ARCH_SOURCES_DIR}/RedirectedHandledJITCase.asm
${ARCH_SOURCES_DIR}/ThePreStubAMD64.asm
Expand Down Expand Up @@ -683,6 +684,7 @@ elseif(CLR_CMAKE_TARGET_ARCH_ARM64)
${ARCH_SOURCES_DIR}/AsmHelpers.asm
${ARCH_SOURCES_DIR}/CallDescrWorkerARM64.asm
${ARCH_SOURCES_DIR}/CrtHelpers.asm
${ARCH_SOURCES_DIR}/patchedcode.asm
${ARCH_SOURCES_DIR}/PInvokeStubs.asm
${ARCH_SOURCES_DIR}/thunktemplates.asm
)
Expand All @@ -705,6 +707,7 @@ else(CLR_CMAKE_TARGET_WIN32)
${ARCH_SOURCES_DIR}/jithelpers_fastwritebarriers.S
${ARCH_SOURCES_DIR}/jithelpers_singleappdomain.S
${ARCH_SOURCES_DIR}/jithelpers_slow.S
${ARCH_SOURCES_DIR}/patchedcode.S
${ARCH_SOURCES_DIR}/pinvokestubs.S
${ARCH_SOURCES_DIR}/redirectedhandledjitcase.S
${ARCH_SOURCES_DIR}/theprestubamd64.S
Expand Down Expand Up @@ -738,6 +741,7 @@ else(CLR_CMAKE_TARGET_WIN32)
${ARCH_SOURCES_DIR}/asmhelpers.S
${ARCH_SOURCES_DIR}/calldescrworkerarm64.S
${ARCH_SOURCES_DIR}/crthelpers.S
${ARCH_SOURCES_DIR}/patchedcode.S
${ARCH_SOURCES_DIR}/pinvokestubs.S
${ARCH_SOURCES_DIR}/thunktemplates.S
)
Expand Down
182 changes: 0 additions & 182 deletions src/coreclr/vm/amd64/JitHelpers_Fast.asm
Original file line number Diff line number Diff line change
Expand Up @@ -50,188 +50,6 @@ endif
extern JIT_InternalThrow:proc


; Mark start of the code region that we patch at runtime
LEAF_ENTRY JIT_PatchedCodeStart, _TEXT
ret
LEAF_END JIT_PatchedCodeStart, _TEXT


; This is used by the mechanism to hold either the JIT_WriteBarrier_PreGrow
; or JIT_WriteBarrier_PostGrow code (depending on the state of the GC). It _WILL_
; change at runtime as the GC changes. Initially it should simply be a copy of the
; larger of the two functions (JIT_WriteBarrier_PostGrow) to ensure we have created
; enough space to copy that code in.
LEAF_ENTRY JIT_WriteBarrier, _TEXT
align 16

ifdef _DEBUG
; In debug builds, this just contains jump to the debug version of the write barrier by default
mov rax, JIT_WriteBarrier_Debug
jmp rax
endif

ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
; JIT_WriteBarrier_WriteWatch_PostGrow64

; Regarding patchable constants:
; - 64-bit constants have to be loaded into a register
; - The constants have to be aligned to 8 bytes so that they can be patched easily
; - The constant loads have been located to minimize NOP padding required to align the constants
; - Using different registers for successive constant loads helps pipeline better. Should we decide to use a special
; non-volatile calling convention, this should be changed to use just one register.

; Do the move into the GC . It is correct to take an AV here, the EH code
; figures out that this came from a WriteBarrier and correctly maps it back
; to the managed method which called the WriteBarrier (see setup in
; InitializeExceptionHandling, vm\exceptionhandling.cpp).
mov [rcx], rdx

; Update the write watch table if necessary
mov rax, rcx
mov r8, 0F0F0F0F0F0F0F0F0h
shr rax, 0Ch ; SoftwareWriteWatch::AddressToTableByteIndexShift
NOP_2_BYTE ; padding for alignment of constant
mov r9, 0F0F0F0F0F0F0F0F0h
add rax, r8
cmp byte ptr [rax], 0h
jne CheckCardTable
mov byte ptr [rax], 0FFh

NOP_3_BYTE ; padding for alignment of constant

; Check the lower and upper ephemeral region bounds
CheckCardTable:
cmp rdx, r9
jb Exit

NOP_3_BYTE ; padding for alignment of constant

mov r8, 0F0F0F0F0F0F0F0F0h

cmp rdx, r8
jae Exit

nop ; padding for alignment of constant

mov rax, 0F0F0F0F0F0F0F0F0h

; Touch the card table entry, if not already dirty.
shr rcx, 0Bh
cmp byte ptr [rcx + rax], 0FFh
jne UpdateCardTable
REPRET

UpdateCardTable:
mov byte ptr [rcx + rax], 0FFh
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
mov rax, 0F0F0F0F0F0F0F0F0h
shr rcx, 0Ah
cmp byte ptr [rcx + rax], 0FFh
jne UpdateCardBundleTable
REPRET

UpdateCardBundleTable:
mov byte ptr [rcx + rax], 0FFh
endif
ret

align 16
Exit:
REPRET

NOP_3_BYTE
NOP_3_BYTE
NOP_3_BYTE
NOP_3_BYTE
NOP_3_BYTE

NOP_3_BYTE
NOP_3_BYTE
NOP_3_BYTE
NOP_3_BYTE
NOP_3_BYTE

NOP_3_BYTE
NOP_3_BYTE
NOP_3_BYTE
NOP_3_BYTE
NOP_3_BYTE

NOP_3_BYTE
NOP_3_BYTE
NOP_3_BYTE
NOP_3_BYTE
NOP_3_BYTE

else
; JIT_WriteBarrier_PostGrow64

; Do the move into the GC . It is correct to take an AV here, the EH code
; figures out that this came from a WriteBarrier and correctly maps it back
; to the managed method which called the WriteBarrier (see setup in
; InitializeExceptionHandling, vm\exceptionhandling.cpp).
mov [rcx], rdx

NOP_3_BYTE ; padding for alignment of constant

; Can't compare a 64 bit immediate, so we have to move them into a
; register. Values of these immediates will be patched at runtime.
; By using two registers we can pipeline better. Should we decide to use
; a special non-volatile calling convention, this should be changed to
; just one.

mov rax, 0F0F0F0F0F0F0F0F0h

; Check the lower and upper ephemeral region bounds
cmp rdx, rax
jb Exit

nop ; padding for alignment of constant

mov r8, 0F0F0F0F0F0F0F0F0h

cmp rdx, r8
jae Exit

nop ; padding for alignment of constant

mov rax, 0F0F0F0F0F0F0F0F0h

; Touch the card table entry, if not already dirty.
shr rcx, 0Bh
cmp byte ptr [rcx + rax], 0FFh
jne UpdateCardTable
REPRET

UpdateCardTable:
mov byte ptr [rcx + rax], 0FFh
ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
mov rax, 0F0F0F0F0F0F0F0F0h
shr rcx, 0Ah
cmp byte ptr [rcx + rax], 0FFh
jne UpdateCardBundleTable
REPRET

UpdateCardBundleTable:
mov byte ptr [rcx + rax], 0FFh
endif
ret

align 16
Exit:
REPRET
endif

; make sure this is bigger than any of the others
align 16
nop
LEAF_END_MARKED JIT_WriteBarrier, _TEXT

; Mark start of the code region that we patch at runtime
LEAF_ENTRY JIT_PatchedCodeLast, _TEXT
ret
LEAF_END JIT_PatchedCodeLast, _TEXT

; JIT_ByRefWriteBarrier has weird semantics, see usage in StubLinkerX86.cpp
;
; Entry:
Expand Down
Loading

0 comments on commit 420717e

Please sign in to comment.