_gchandle string intern

This commit is contained in:
2024-03-11 22:46:52 +02:00
parent 8a41e04641
commit a5ffe8893a
2 changed files with 27 additions and 3 deletions

View File

@@ -139,7 +139,7 @@ namespace FlaxEngine.Interop
private ManagedArray(IntPtr ptr, int length, Type arrayType, Type elementType)
{
Assert.IsTrue(arrayType.IsArray);
//Assert.IsTrue(arrayType.IsArray);
_elementType = elementType;
_elementSize = NativeInterop.GetTypeSize(elementType);
_unmanagedData = ptr;
@@ -313,7 +313,7 @@ namespace FlaxEngine.Interop
return IntPtr.Zero;
else if (str == string.Empty)
return ManagedHandle.ToIntPtr(EmptyStringHandle);
Assert.IsTrue(str.Length > 0);
//Assert.IsTrue(str.Length > 0);
return ManagedHandle.ToIntPtr(str);
}
@@ -324,7 +324,7 @@ namespace FlaxEngine.Interop
return IntPtr.Zero;
else if (str == string.Empty)
return ManagedHandle.ToIntPtr(EmptyStringHandle);
Assert.IsTrue(str.Length > 0);
//Assert.IsTrue(str.Length > 0);
return ManagedHandle.ToIntPtr(str, GCHandleType.Weak);
}
@@ -336,6 +336,25 @@ namespace FlaxEngine.Interop
return Unsafe.As<string>(ManagedHandle.FromIntPtr(ptr).Target);
}
internal static Dictionary<string, ManagedHandle> strHandles = new(512);
//[System.Diagnostics.DebuggerStepThrough]
public static unsafe IntPtr ToNativeIntern(string str)
{
if (str == null)
return IntPtr.Zero;
else if (string.IsInterned(str) == null && str.Length > 128)
return ManagedHandle.ToIntPtr(str, GCHandleType.Weak);
// Allocate normal handle for interned strings as those should never change
if (!strHandles.TryGetValue(str, out ManagedHandle handle))
{
handle = ManagedHandle.Alloc(str, GCHandleType.Normal);
strHandles.Add(str, handle);
}
return ((IntPtr)handle);
}
[System.Diagnostics.DebuggerStepThrough]
public static void Free(IntPtr ptr)
{

View File

@@ -613,7 +613,12 @@ namespace FlaxEngine.Interop
public static class ManagedToNative
{
public static string ConvertToManaged(IntPtr unmanaged) => ManagedString.ToManaged(unmanaged);
#if true
// TODO: interned string pool
public static unsafe IntPtr ConvertToUnmanaged(string managed) => ManagedString.ToNativeIntern(managed);
#else
public static unsafe IntPtr ConvertToUnmanaged(string managed) => managed == null ? IntPtr.Zero : ManagedHandle.ToIntPtr(managed, GCHandleType.Weak);
#endif
public static void Free(IntPtr unmanaged)
{
//ManagedString.Free(unmanaged); // No need to free weak handles