diff options
author | Vlad Brezae <brezaevlad@gmail.com> | 2018-10-15 17:09:52 +0300 |
---|---|---|
committer | Marek Safar <marek.safar@gmail.com> | 2018-11-05 23:09:55 +0300 |
commit | ef78b582a18b6a9124c3773e5a4011b37e28b8da (patch) | |
tree | a55f6a88a7d361cadb1f287d1bc944eb6f754bc3 | |
parent | 0947b7b289226e9bde3d791c8409f831d64b5332 (diff) |
[corlib] Icall for Buffer.Memcpy
Jitted code is too slow. For larger sizes, doing an icall to memcpy is 4-5 times faster than using the managed implementation.
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | mcs/class/corlib/ReferenceSources/Buffer.cs | 10 | ||||
-rw-r--r-- | mono/metadata/icall-decl.h | 1 | ||||
-rw-r--r-- | mono/metadata/icall-def.h | 1 | ||||
-rw-r--r-- | mono/metadata/icall.c | 6 |
5 files changed, 18 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac index 19e70ff460a..fa7a2d939ad 100644 --- a/configure.ac +++ b/configure.ac @@ -46,7 +46,7 @@ MONO_VERSION_BUILD=`echo $VERSION | cut -d . -f 3` # There is no ordering of corlib versions, no old or new, # the runtime expects an exact match. # -MONO_CORLIB_VERSION=893F4575-474B-47A4-831E-E36181251FCB +MONO_CORLIB_VERSION=109afe51-a298-4c14-a076-cfc83a5e755a # # Put a quoted #define in config.h. diff --git a/mcs/class/corlib/ReferenceSources/Buffer.cs b/mcs/class/corlib/ReferenceSources/Buffer.cs index b04390195ed..5de72a7bc32 100644 --- a/mcs/class/corlib/ReferenceSources/Buffer.cs +++ b/mcs/class/corlib/ReferenceSources/Buffer.cs @@ -11,6 +11,9 @@ namespace System { partial class Buffer { + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern unsafe void InternalMemcpy (byte *dest, byte *src, int count); + public static int ByteLength (Array array) { // note: the other methods in this class also use ByteLength to test for @@ -191,6 +194,11 @@ namespace System } internal static unsafe void Memcpy (byte *dest, byte *src, int len) { + // For bigger lengths, we use the heavily optimized native code + if (len > 32) { + InternalMemcpy (dest, src, len); + return; + } // FIXME: if pointers are not aligned, try to align them // so a faster routine can be used. Handle the case where // the pointers can't be reduced to have the same alignment @@ -246,4 +254,4 @@ namespace System } } } -}
\ No newline at end of file +} diff --git a/mono/metadata/icall-decl.h b/mono/metadata/icall-decl.h index 4beade9a29b..65b924f4042 100644 --- a/mono/metadata/icall-decl.h +++ b/mono/metadata/icall-decl.h @@ -167,6 +167,7 @@ ICALL_EXPORT void mono_ArgIterator_Setup (MonoArgIterator*, char*, char*); ICALL_EXPORT void ves_icall_Mono_Runtime_RegisterReportingForNativeLib (const char*, const char*); ICALL_EXPORT void ves_icall_System_Array_GetGenericValueImpl (MonoArray*, guint32, gpointer); ICALL_EXPORT void ves_icall_System_Array_SetGenericValueImpl (MonoArray*, guint32, gpointer); +ICALL_EXPORT void ves_icall_System_Buffer_MemcpyInternal (gpointer dest, gconstpointer src, gint32 count); ICALL_EXPORT void ves_icall_System_Buffer_SetByteInternal (MonoArray*, gint32, gint8); ICALL_EXPORT void ves_icall_System_Environment_Exit (int); ICALL_EXPORT void ves_icall_System_GCHandle_FreeHandle (guint32 handle); diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 4ba68dee1ae..452c4777ac7 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -219,6 +219,7 @@ HANDLES(ARRAY_13, "SetValueImpl", ves_icall_System_Array_SetValueImpl, void, 3, ICALL_TYPE(BUFFER, "System.Buffer", BUFFER_1) ICALL(BUFFER_1, "InternalBlockCopy", ves_icall_System_Buffer_BlockCopyInternal) +NOHANDLES(ICALL(BUFFER_5, "InternalMemcpy", ves_icall_System_Buffer_MemcpyInternal)) ICALL(BUFFER_2, "_ByteLength", ves_icall_System_Buffer_ByteLengthInternal) ICALL(BUFFER_3, "_GetByte", ves_icall_System_Buffer_GetByteInternal) ICALL(BUFFER_4, "_SetByte", ves_icall_System_Buffer_SetByteInternal) diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index 9d82771f0e3..715229ba843 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -6634,6 +6634,12 @@ ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 val mono_array_set_internal (array, gint8, idx, value); } +void +ves_icall_System_Buffer_MemcpyInternal (gpointer dest, gconstpointer src, gint32 count) +{ + memcpy (dest, src, count); +} + MonoBoolean ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count) { |