Optimize marshalling managed arrays of object references
This commit is contained in:
@@ -770,12 +770,20 @@ namespace FlaxEngine.Interop
|
|||||||
}
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
[UnmanagedCallersOnly]
|
||||||
internal static void SetArrayValueReference(ManagedHandle arrayHandle, IntPtr valueHandle, int index)
|
internal static void WriteArrayReference(ManagedHandle arrayHandle, IntPtr valueHandle, int index)
|
||||||
{
|
{
|
||||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(arrayHandle.Target);
|
ManagedArray managedArray = Unsafe.As<ManagedArray>(arrayHandle.Target);
|
||||||
managedArray.ToSpan<IntPtr>()[index] = valueHandle;
|
managedArray.ToSpan<IntPtr>()[index] = valueHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
internal static void WriteArrayReferences(ManagedHandle arrayHandle, IntPtr spanPtr, int spanLength)
|
||||||
|
{
|
||||||
|
ManagedArray managedArray = Unsafe.As<ManagedArray>(arrayHandle.Target);
|
||||||
|
var unmanagedSpan = new Span<IntPtr>(spanPtr.ToPointer(), spanLength);
|
||||||
|
unmanagedSpan.CopyTo(managedArray.ToSpan<IntPtr>());
|
||||||
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
[UnmanagedCallersOnly]
|
||||||
internal static ManagedHandle LoadAssemblyImage(IntPtr assemblyPathPtr, IntPtr* assemblyName, IntPtr* assemblyFullName)
|
internal static ManagedHandle LoadAssemblyImage(IntPtr assemblyPathPtr, IntPtr* assemblyName, IntPtr* assemblyFullName)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ public:
|
|||||||
static void WriteRef(void* ptr, MObject* ref);
|
static void WriteRef(void* ptr, MObject* ref);
|
||||||
static void WriteValue(void* dst, void* src, int32 count, const MClass* klass);
|
static void WriteValue(void* dst, void* src, int32 count, const MClass* klass);
|
||||||
static void WriteArrayRef(MArray* dst, MObject* ref, int32 index);
|
static void WriteArrayRef(MArray* dst, MObject* ref, int32 index);
|
||||||
|
static void WriteArrayRef(MArray* dst, Span<MObject*> span);
|
||||||
#if USE_NETCORE
|
#if USE_NETCORE
|
||||||
static void* AllocateMemory(int32 size, bool coTaskMem = false);
|
static void* AllocateMemory(int32 size, bool coTaskMem = false);
|
||||||
static void FreeMemory(void* ptr, bool coTaskMem = false);
|
static void FreeMemory(void* ptr, bool coTaskMem = false);
|
||||||
|
|||||||
@@ -104,8 +104,14 @@ struct MConverter<String>
|
|||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<String>& data)
|
void ToManagedArray(MArray* result, const Span<String>& data)
|
||||||
{
|
{
|
||||||
|
if (data.Length() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Array<MObject*> objects;
|
||||||
|
objects.Resize(data.Length(), false);
|
||||||
for (int32 i = 0; i < data.Length(); i++)
|
for (int32 i = 0; i < data.Length(); i++)
|
||||||
MCore::GC::WriteArrayRef(result, (MObject*)MUtils::ToString(data[i]), i);
|
objects[i] = (MObject*)MUtils::ToString(data[i]);
|
||||||
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects.Get(), objects.Count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToNativeArray(Span<String>& result, const MArray* data)
|
void ToNativeArray(Span<String>& result, const MArray* data)
|
||||||
@@ -132,8 +138,14 @@ struct MConverter<StringAnsi>
|
|||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<StringAnsi>& data)
|
void ToManagedArray(MArray* result, const Span<StringAnsi>& data)
|
||||||
{
|
{
|
||||||
|
if (data.Length() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Array<MObject*> objects;
|
||||||
|
objects.Resize(data.Length(), false);
|
||||||
for (int32 i = 0; i < data.Length(); i++)
|
for (int32 i = 0; i < data.Length(); i++)
|
||||||
MCore::GC::WriteArrayRef(result, (MObject*)MUtils::ToString(data[i]), i);
|
objects[i] = (MObject*)MUtils::ToString(data[i]);
|
||||||
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects.Get(), objects.Count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToNativeArray(Span<StringAnsi>& result, const MArray* data)
|
void ToNativeArray(Span<StringAnsi>& result, const MArray* data)
|
||||||
@@ -160,8 +172,14 @@ struct MConverter<StringView>
|
|||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<StringView>& data)
|
void ToManagedArray(MArray* result, const Span<StringView>& data)
|
||||||
{
|
{
|
||||||
|
if (data.Length() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Array<MObject*> objects;
|
||||||
|
objects.Resize(data.Length(), false);
|
||||||
for (int32 i = 0; i < data.Length(); i++)
|
for (int32 i = 0; i < data.Length(); i++)
|
||||||
MCore::GC::WriteArrayRef(result, (MObject*)MUtils::ToString(data[i]), i);
|
objects[i] = (MObject*)MUtils::ToString(data[i]);
|
||||||
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects.Get(), objects.Count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToNativeArray(Span<StringView>& result, const MArray* data)
|
void ToNativeArray(Span<StringView>& result, const MArray* data)
|
||||||
@@ -188,8 +206,14 @@ struct MConverter<Variant>
|
|||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<Variant>& data)
|
void ToManagedArray(MArray* result, const Span<Variant>& data)
|
||||||
{
|
{
|
||||||
|
if (data.Length() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Array<MObject*> objects;
|
||||||
|
objects.Resize(data.Length(), false);
|
||||||
for (int32 i = 0; i < data.Length(); i++)
|
for (int32 i = 0; i < data.Length(); i++)
|
||||||
MCore::GC::WriteArrayRef(result, MUtils::BoxVariant(data[i]), i);
|
objects[i] = MUtils::BoxVariant(data[i]);
|
||||||
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects.Get(), objects.Count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToNativeArray(Span<Variant>& result, const MArray* data)
|
void ToNativeArray(Span<Variant>& result, const MArray* data)
|
||||||
@@ -216,8 +240,14 @@ struct MConverter<T*, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Va
|
|||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<T*>& data)
|
void ToManagedArray(MArray* result, const Span<T*>& data)
|
||||||
{
|
{
|
||||||
|
if (data.Length() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Array<MObject*> objects;
|
||||||
|
objects.Resize(data.Length(), false);
|
||||||
for (int32 i = 0; i < data.Length(); i++)
|
for (int32 i = 0; i < data.Length(); i++)
|
||||||
MCore::GC::WriteArrayRef(result, data[i] ? data[i]->GetOrCreateManagedInstance() : nullptr, i);
|
objects[i] = data[i] ? data[i]->GetOrCreateManagedInstance() : nullptr;
|
||||||
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects.Get(), objects.Count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToNativeArray(Span<T*>& result, const MArray* data)
|
void ToNativeArray(Span<T*>& result, const MArray* data)
|
||||||
@@ -239,8 +269,14 @@ struct MConverter<T, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Val
|
|||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<T>& data)
|
void ToManagedArray(MArray* result, const Span<T>& data)
|
||||||
{
|
{
|
||||||
|
if (data.Length() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Array<MObject*> objects;
|
||||||
|
objects.Resize(data.Length(), false);
|
||||||
for (int32 i = 0; i < data.Length(); i++)
|
for (int32 i = 0; i < data.Length(); i++)
|
||||||
MCore::GC::WriteArrayRef(result, data[i].GetOrCreateManagedInstance(), i);
|
objects[i] = data[i].GetOrCreateManagedInstance();
|
||||||
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects.Get(), objects.Count()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -263,8 +299,16 @@ struct MConverter<ScriptingObjectReference<T>>
|
|||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<ScriptingObjectReference<T>>& data)
|
void ToManagedArray(MArray* result, const Span<ScriptingObjectReference<T>>& data)
|
||||||
{
|
{
|
||||||
|
if (data.Length() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Array<MObject*> objects;
|
||||||
|
objects.Resize(data.Length(), false);
|
||||||
for (int32 i = 0; i < data.Length(); i++)
|
for (int32 i = 0; i < data.Length(); i++)
|
||||||
MCore::GC::WriteArrayRef(result, data[i].GetManagedInstance(), i);
|
objects[i] = data[i].GetManagedInstance();
|
||||||
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects.Get(), objects.Count()));
|
||||||
|
//for (int32 i = 0; i < data.Length(); i++)
|
||||||
|
// MCore::GC::WriteArrayRef(result, data[i].GetManagedInstance(), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToNativeArray(Span<ScriptingObjectReference<T>>& result, const MArray* data)
|
void ToNativeArray(Span<ScriptingObjectReference<T>>& result, const MArray* data)
|
||||||
@@ -294,8 +338,14 @@ struct MConverter<AssetReference<T>>
|
|||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<AssetReference<T>>& data)
|
void ToManagedArray(MArray* result, const Span<AssetReference<T>>& data)
|
||||||
{
|
{
|
||||||
|
if (data.Length() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Array<MObject*> objects;
|
||||||
|
objects.Resize(data.Length(), false);
|
||||||
for (int32 i = 0; i < data.Length(); i++)
|
for (int32 i = 0; i < data.Length(); i++)
|
||||||
MCore::GC::WriteArrayRef(result, data[i].GetManagedInstance(), i);
|
objects[i] = data[i].GetManagedInstance();
|
||||||
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects.Get(), objects.Count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToNativeArray(Span<AssetReference<T>>& result, const MArray* data)
|
void ToNativeArray(Span<AssetReference<T>>& result, const MArray* data)
|
||||||
|
|||||||
@@ -450,8 +450,14 @@ void MCore::GC::WriteValue(void* dst, void* src, int32 count, const MClass* klas
|
|||||||
|
|
||||||
void MCore::GC::WriteArrayRef(MArray* dst, MObject* ref, int32 index)
|
void MCore::GC::WriteArrayRef(MArray* dst, MObject* ref, int32 index)
|
||||||
{
|
{
|
||||||
static void* SetArrayValueReferencePtr = GetStaticMethodPointer(TEXT("SetArrayValueReference"));
|
static void* WriteArrayReferencePtr = GetStaticMethodPointer(TEXT("WriteArrayReference"));
|
||||||
CallStaticMethod<void, void*, void*, int32>(SetArrayValueReferencePtr, dst, ref, index);
|
CallStaticMethod<void, void*, void*, int32>(WriteArrayReferencePtr, dst, ref, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCore::GC::WriteArrayRef(MArray* dst, Span<MObject*> refs)
|
||||||
|
{
|
||||||
|
static void* WriteArrayReferencesPtr = GetStaticMethodPointer(TEXT("WriteArrayReferences"));
|
||||||
|
CallStaticMethod<void, void*, void*, int32>(WriteArrayReferencesPtr, dst, refs.Get(), refs.Length());
|
||||||
}
|
}
|
||||||
|
|
||||||
void* MCore::GC::AllocateMemory(int32 size, bool coTaskMem)
|
void* MCore::GC::AllocateMemory(int32 size, bool coTaskMem)
|
||||||
|
|||||||
@@ -857,6 +857,13 @@ void MCore::GC::WriteArrayRef(MArray* dst, MObject* ref, int32 index)
|
|||||||
mono_gc_wbarrier_set_arrayref(dst, (byte*)ptr + index * sizeof(void*), ref);
|
mono_gc_wbarrier_set_arrayref(dst, (byte*)ptr + index * sizeof(void*), ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCore::GC::WriteArrayRef(MArray* dst, Span<MObject*> refs)
|
||||||
|
{
|
||||||
|
void* ptr = mono_array_addr_with_size(dst, 0, 0);
|
||||||
|
for (int32 index = 0; index < refs.Length(); index++)
|
||||||
|
mono_gc_wbarrier_set_arrayref(dst, (byte*)ptr + index * sizeof(void*), refs[index]);
|
||||||
|
}
|
||||||
|
|
||||||
void MCore::Thread::Attach()
|
void MCore::Thread::Attach()
|
||||||
{
|
{
|
||||||
if (!IsInMainThread() && !mono_domain_get())
|
if (!IsInMainThread() && !mono_domain_get())
|
||||||
|
|||||||
@@ -176,6 +176,10 @@ void MCore::GC::WriteArrayRef(MArray* dst, MObject* ref, int32 index)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCore::GC::WriteArrayRef(MArray* dst, Span<MObject*> refs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void MCore::Thread::Attach()
|
void MCore::Thread::Attach()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user