diff options
author | Jan Kotas <jkotas@microsoft.com> | 2015-12-18 10:13:31 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2015-12-18 10:13:31 +0300 |
commit | 6372118f2f477a101cc2f74c6c94c8e0e652a897 (patch) | |
tree | a4d3af9f28918e2001555875583023c31ca9f8af /src/Native/Runtime/MiscHelpers.cpp | |
parent | 5f64fd1c6b3d026a1b77a42d34f692d6de268a4f (diff) |
Add helpers that perform memory copy and gc-write barrier as a single operation
[tfs-changeset: 1558883]
Diffstat (limited to 'src/Native/Runtime/MiscHelpers.cpp')
-rw-r--r-- | src/Native/Runtime/MiscHelpers.cpp | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/src/Native/Runtime/MiscHelpers.cpp b/src/Native/Runtime/MiscHelpers.cpp index a08d113b7..81475383d 100644 --- a/src/Native/Runtime/MiscHelpers.cpp +++ b/src/Native/Runtime/MiscHelpers.cpp @@ -601,6 +601,31 @@ COOP_PINVOKE_CDECL_HELPER(void *, memcpyGCRefs, (void * dest, const void *src, s return dest; } +EXTERN_C void REDHAWK_CALLCONV RhpBulkWriteBarrier(void* pMemStart, UInt32 cbMemSize); + +// This is a GC-safe variant of memcpy. It guarantees that the object references in the GC heap are updated atomically. +// This is required for type safety and proper operation of the background GC. +// Writebarrier is included. +// +// USAGE: +// 1) The caller is responsible for hoisting any null reference exceptions to a place where the hardware +// exception can be properly translated to a managed exception. This is handled by RhpCopyMultibyte. +// 2) The caller must ensure that all three parameters are pointer-size-aligned. This should be the case for +// value types which contain GC refs anyway, so if you want to copy structs without GC refs which might be +// unaligned, then you must use RhpCopyMultibyteNoGCRefs. +COOP_PINVOKE_CDECL_HELPER(void *, memcpyGCRefsWithWriteBarrier, (void * dest, const void *src, size_t len)) +{ + // null pointers are not allowed (they are checked by RhpCopyMultibyteWithWriteBarrier) + ASSERT(dest != nullptr); + ASSERT(src != nullptr); + + ForwardGCSafeCopy(dest, src, len); + RhpBulkWriteBarrier(dest, (UInt32)len); + + // memcpy returns the destination buffer + return dest; +} + // This function clears a piece of memory in a GC safe way. It makes the guarantee that it will clear memory in at // least pointer sized chunks whenever possible. Unaligned memory at the beginning and remaining bytes at the end are // written bytewise. We must make this guarantee whenever we clear memory in the GC heap that could contain object @@ -632,8 +657,6 @@ COOP_PINVOKE_CDECL_HELPER(void *, RhpInitMultibyte, (void * mem, int c, size_t s return mem; } -EXTERN_C void * __cdecl memmove(void *, const void *, size_t); - // // Return true if the array slice is valid // @@ -646,6 +669,8 @@ FORCEINLINE bool CheckArraySlice(Array * pArray, Int32 index, Int32 length) (length <= arrayLength - index); } +EXTERN_C void * __cdecl memmove(void *, const void *, size_t); + // // This function handles all cases of Array.Copy that do not require conversions or casting. It returns false if the copy cannot be performed, leaving // the handling of the complex cases or throwing appropriate exception to the higher level framework. |