From 44b70d87e5980ffd0c3c8c9558e9f26ecdf6dd13 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Fri, 4 Aug 2023 21:38:05 +0300 Subject: [PATCH] Cache MakeArrayType results in native interop --- Source/Engine/Engine/NativeInterop.Managed.cs | 21 ++++++++++--------- .../Engine/Engine/NativeInterop.Unmanaged.cs | 4 ++-- Source/Engine/Engine/NativeInterop.cs | 10 +++++++++ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Source/Engine/Engine/NativeInterop.Managed.cs b/Source/Engine/Engine/NativeInterop.Managed.cs index 95146a95c..86b41f458 100644 --- a/Source/Engine/Engine/NativeInterop.Managed.cs +++ b/Source/Engine/Engine/NativeInterop.Managed.cs @@ -91,18 +91,19 @@ namespace FlaxEngine.Interop internal void Allocate(int length) where T : unmanaged { + _length = length; + _arrayType = typeof(T[]); + _elementType = typeof(T); + _elementSize = Unsafe.SizeOf(); + // Try to reuse existing allocated buffer - if (length * Unsafe.SizeOf() > _unmanagedAllocationSize) + if (length * _elementSize > _unmanagedAllocationSize) { if (_unmanagedAllocationSize > 0) NativeInterop.NativeFree(_unmanagedData.ToPointer()); - _unmanagedData = (IntPtr)NativeInterop.NativeAlloc(length, Unsafe.SizeOf()); - _unmanagedAllocationSize = Unsafe.SizeOf() * length; + _unmanagedData = (IntPtr)NativeInterop.NativeAlloc(length, _elementSize); + _unmanagedAllocationSize = _elementSize * length; } - _length = length; - _arrayType = typeof(T).MakeArrayType(); - _elementType = typeof(T); - _elementSize = Unsafe.SizeOf(); } private ManagedArray() @@ -112,12 +113,12 @@ namespace FlaxEngine.Interop private ManagedArray(IntPtr ptr, int length, Type arrayType, Type elementType) { Assert.IsTrue(arrayType.IsArray); + _elementType = elementType; + _elementSize = NativeInterop.GetTypeSize(elementType); _unmanagedData = ptr; - _unmanagedAllocationSize = Marshal.SizeOf(elementType) * length; + _unmanagedAllocationSize = _elementSize * length; _length = length; _arrayType = arrayType; - _elementType = elementType; - _elementSize = NativeInterop.GetTypeSize(_elementType); } ~ManagedArray() diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs index d2a8ca55e..86fe3036e 100644 --- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs +++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs @@ -526,7 +526,7 @@ namespace FlaxEngine.Interop { Type elementType = Unsafe.As(typeHandle.Target); Type marshalledType = ArrayFactory.GetMarshalledType(elementType); - Type arrayType = elementType.MakeArrayType(); + Type arrayType = ArrayFactory.GetArrayType(elementType); if (marshalledType.IsValueType) { ManagedArray managedArray = ManagedArray.AllocateNewArray((int)size, arrayType, marshalledType); @@ -544,7 +544,7 @@ namespace FlaxEngine.Interop internal static ManagedHandle GetArrayTypeFromElementType(ManagedHandle elementTypeHandle) { Type elementType = Unsafe.As(elementTypeHandle.Target); - Type classType = elementType.MakeArrayType(); + Type classType = ArrayFactory.GetArrayType(elementType); return GetTypeGCHandle(classType); } diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index da372ac90..0949533ce 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -967,6 +967,7 @@ namespace FlaxEngine.Interop private delegate Array CreateArrayDelegate(long size); private static ConcurrentDictionary marshalledTypes = new ConcurrentDictionary(1, 3); + private static ConcurrentDictionary arrayTypes = new ConcurrentDictionary(1, 3); private static ConcurrentDictionary createArrayDelegates = new ConcurrentDictionary(1, 3); internal static Type GetMarshalledType(Type elementType) @@ -986,6 +987,15 @@ namespace FlaxEngine.Interop return marshalledTypes.GetOrAdd(elementType, Factory); } + internal static Type GetArrayType(Type elementType) + { + static Type Factory(Type type) => type.MakeArrayType(); + + if (arrayTypes.TryGetValue(elementType, out var arrayType)) + return arrayType; + return arrayTypes.GetOrAdd(elementType, Factory); + } + internal static Array CreateArray(Type type, long size) { static CreateArrayDelegate Factory(Type type)