From 1f26ac4bb2d70f47ecdd7344342b971d793e5831 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 8 Apr 2022 17:38:53 -0700 Subject: [PATCH 1/2] Use CRT implementation of memset/memcpy --- src/coreclr/vm/arm64/crthelpers.asm | 233 +++++++++------------------- 1 file changed, 74 insertions(+), 159 deletions(-) diff --git a/src/coreclr/vm/arm64/crthelpers.asm b/src/coreclr/vm/arm64/crthelpers.asm index cb3c4d73bd3b22..0eb7ed4f7315ba 100644 --- a/src/coreclr/vm/arm64/crthelpers.asm +++ b/src/coreclr/vm/arm64/crthelpers.asm @@ -1,176 +1,91 @@ ; Licensed to the .NET Foundation under one or more agreements. ; The .NET Foundation licenses this file to you under the MIT license. -;; ==++== -;; +; ==++== +; -;; -;; ==--== +; +; ==--== +; *********************************************************************** +; File: CrtHelpers.asm, see history in asmhelpers.asm +; +; *********************************************************************** #include "ksarm64.h" +#include "asmconstants.h" +#include "asmmacros.h" - TEXTAREA + IMPORT memset + IMPORT memmove + +; JIT_MemSet/JIT_MemCpy +; +; It is IMPORTANT that the exception handling code is able to find these guys +; on the stack, but on windows platforms we can just defer to the platform +; implementation. +; -;void JIT_MemSet(void *dst, int val, SIZE_T count) -;{ -; uint64_t valEx = (unsigned char)val; -; valEx = valEx | valEx << 8; -; valEx = valEx | valEx << 16; -; valEx = valEx | valEx << 32; -; -; count-=16; -; -; while(count >= 0) -; { -; *(uint64_t*)dst = valEx; -; dst = (uint64_t*)dst + 1; -; *(uint64_t*)dst = valEx; -; dst = (uint64_t*)dst + 1; -; count-=16; -; } -; -; if(count & 8) -; { -; *(uint64_t*)dst = valEx; -; dst = (uint64_t*)dst + 1; -; } -; -; if(count & 4) -; { -; *(uint32_t*)dst = (uint32_t)valEx; -; dst = (uint32_t*)dst + 1; -; } -; -; if(count & 2) -; { -; *(uint16_t*)dst = (uint16_t)valEx; -; dst = (uint16_t*)dst + 1; -; } -; -; if(count & 1) -; { -; *(uint8_t*)dst = (uint8_t)valEx; -; } -;} -; - -; Assembly code corresponding to above C++ method. JIT_MemSet can AV and clr exception personality routine needs to -; determine if the exception has taken place inside JIT_Memset in order to throw corresponding managed exception. -; Determining this is slow if the method were implemented as C++ method (using unwind info). In .asm file by adding JIT_MemSet_End -; marker it can be easily determined if exception happened in JIT_MemSet. Therefore, JIT_MemSet has been written in assembly instead of -; as C++ method. +; void JIT_MemSet(void* dest, int c, size_t count) +; +; Purpose: +; Sets the first "count" bytes of the block of memory pointed byte +; "dest" to the specified value (interpreted as an unsigned char). +; +; Entry: +; RCX: void* dest - Pointer to the block of memory to fill. +; RDX: int c - Value to be set. +; R8: size_t count - Number of bytes to be set to the value. +; +; Exit: +; +; Uses: +; +; Exceptions: +; + TEXTAREA + LEAF_ENTRY JIT_MemSet - ands w1, w1, #0xff - orr w1, w1, w1, lsl #8 - orr w1, w1, w1, lsl #0x10 - orr x1, x1, x1, lsl #0x20 - - b JIT_MemSet_bottom -JIT_MemSet_top - stp x1, x1, [x0], #16 -JIT_MemSet_bottom - subs x2, x2, #16 - bge JIT_MemSet_top - - tbz x2, #3, JIT_MemSet_tbz4 - str x1, [x0], #8 -JIT_MemSet_tbz4 - tbz x2, #2, JIT_MemSet_tbz2 - str w1, [x0], #4 -JIT_MemSet_tbz2 - tbz x2, #1, JIT_MemSet_tbz1 - strh w1, [x0], #2 -JIT_MemSet_tbz1 - tbz x2, #0, JIT_MemSet_ret - strb w1, [x0] + cbz x2, JIT_MemSet_ret ; check if count is zero, no bytes to set + + ldrb wzr, [x0] ; check dest for null + + b memset ; forward to the CRT implementation + JIT_MemSet_ret - ret lr - LEAF_END - - LEAF_ENTRY JIT_MemSet_End - nop - LEAF_END - - -; See comments above for JIT_MemSet - -;void JIT_MemCpy(void *dst, const void *src, SIZE_T count) -;{ -; count-=16; -; -; while(count >= 0) -; { -; *(unit64_t*)dst = *(unit64_t*)src; -; dst = (unit64_t*)dst + 1; -; src = (unit64_t*)src + 1; -; *(unit64_t*)dst = *(unit64_t*)src; -; dst = (unit64_t*)dst + 1; -; src = (unit64_t*)src + 1; -; count-=16; -; } -; -; if(count & 8) -; { -; *(unit64_t*)dst = *(unit64_t*)src; -; dst = (unit64_t*)dst + 1; -; src = (unit64_t*)src + 1; -; } -; -; if(count & 4) -; { -; *(unit32_t*)dst = *(unit32_t*)src; -; dst = (unit32_t*)dst + 1; -; src = (unit32_t*)src + 1; -; } -; -; if(count & 2) -; { -; *(unit16_t*)dst = *(unit16_t*)src; -; dst = (unit16_t*)dst + 1; -; src = (unit16_t*)src + 1; -; } -; -; if(count & 1) -; { -; *(unit8_t*)dst = *(unit8_t*)src; -; } -;} -; - -; Assembly code corresponding to above C++ method. -; See comments above for JIT_MemSet method + ret lr + + LEAF_END_MARKED JIT_MemSet + +; void JIT_MemCpy(void* dest, const void* src, size_t count) +; +; Purpose: +; Copies the values of "count" bytes from the location pointed to +; by "src" to the memory block pointed by "dest". +; +; Entry: +; RCX: void* dest - Pointer to the destination array where content is to be copied. +; RDX: const void* src - Pointer to the source of the data to be copied. +; R8: size_t count - Number of bytes to copy. +; +; Exit: +; +; Uses: +; +; Exceptions: +; LEAF_ENTRY JIT_MemCpy - b JIT_MemCpy_bottom -JIT_MemCpy_top - ldp x8, x9, [x1], #16 - stp x8, x9, [x0], #16 -JIT_MemCpy_bottom - subs x2, x2, #16 - bge JIT_MemCpy_top - - tbz x2, #3, JIT_MemCpy_tbz4 - ldr x8, [x1], #8 - str x8, [x0], #8 -JIT_MemCpy_tbz4 - tbz x2, #2, JIT_MemCpy_tbz2 - ldr w8, [x1], #4 - str w8, [x0], #4 -JIT_MemCpy_tbz2 - tbz x2, #1, JIT_MemCpy_tbz1 - ldrsh w8, [x1], #2 - strh w8, [x0], #2 -JIT_MemCpy_tbz1 - tbz x2, #0, JIT_MemCpy_ret - ldrsb w8, [x1] - strb w8, [x0] + cbz x2, JIT_MemCpy_ret ; check if count is zero, no bytes to set + + ldrb wzr, [x0] ; check dest for null + ldrb wzr, [x1] ; check src for null + + b memmove ; forward to the CRT implementation + JIT_MemCpy_ret ret lr - LEAF_END - LEAF_ENTRY JIT_MemCpy_End - nop - LEAF_END + LEAF_END_MARKED JIT_MemCpy ; Must be at very end of file - END + END \ No newline at end of file From c9d9e546c53358d2d9e4d162bbe5448c5b1ed997 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Sat, 9 Apr 2022 20:41:02 -0700 Subject: [PATCH 2/2] Remove the outdated comment: --- src/coreclr/vm/amd64/CrtHelpers.asm | 5 ----- src/coreclr/vm/arm64/crthelpers.asm | 5 ----- 2 files changed, 10 deletions(-) diff --git a/src/coreclr/vm/amd64/CrtHelpers.asm b/src/coreclr/vm/amd64/CrtHelpers.asm index f3b7a94f9bc3ee..8e945d118ff715 100644 --- a/src/coreclr/vm/amd64/CrtHelpers.asm +++ b/src/coreclr/vm/amd64/CrtHelpers.asm @@ -6,11 +6,6 @@ ; ; ==--== -; *********************************************************************** -; File: CrtHelpers.asm, see history in asmhelpers.asm -; -; *********************************************************************** - include AsmMacros.inc extern memset:proc diff --git a/src/coreclr/vm/arm64/crthelpers.asm b/src/coreclr/vm/arm64/crthelpers.asm index 0eb7ed4f7315ba..da28c2ae80b58c 100644 --- a/src/coreclr/vm/arm64/crthelpers.asm +++ b/src/coreclr/vm/arm64/crthelpers.asm @@ -6,11 +6,6 @@ ; ; ==--== -; *********************************************************************** -; File: CrtHelpers.asm, see history in asmhelpers.asm -; -; *********************************************************************** - #include "ksarm64.h" #include "asmconstants.h" #include "asmmacros.h"