C#: Remove VariantSpanDisposer and use constants in stackalloc
- Remove `VariantSpanDisposer`, no need to dispose of the Variant Spans since we are now borrowing the Variants instead of copying them. - Remove `VariantSpanExtensions.Cleared` that was only used so the Span was initialized for `VariantSpanDisposer` to know what to dispose. - Fix stackalloc Spans to use constant VarArgsSpanThreshold and avoid bound checks.
This commit is contained in:
parent
c7ceb94e37
commit
3ff181096a
5 changed files with 10 additions and 50 deletions
|
@ -2542,15 +2542,13 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
|
|||
<< INDENT2 "int total_length = " << real_argc_str << " + vararg_length;\n";
|
||||
|
||||
r_output << INDENT2 "Span<godot_variant.movable> varargs_span = vararg_length <= VarArgsSpanThreshold ?\n"
|
||||
<< INDENT3 "stackalloc godot_variant.movable[VarArgsSpanThreshold].Cleared() :\n"
|
||||
<< INDENT3 "stackalloc godot_variant.movable[VarArgsSpanThreshold] :\n"
|
||||
<< INDENT3 "new godot_variant.movable[vararg_length];\n";
|
||||
|
||||
r_output << INDENT2 "Span<IntPtr> " C_LOCAL_PTRCALL_ARGS "_span = total_length <= VarArgsSpanThreshold ?\n"
|
||||
<< INDENT3 "stackalloc IntPtr[VarArgsSpanThreshold] :\n"
|
||||
<< INDENT3 "new IntPtr[total_length];\n";
|
||||
|
||||
r_output << INDENT2 "using var variantSpanDisposer = new VariantSpanDisposer(varargs_span);\n";
|
||||
|
||||
r_output << INDENT2 "fixed (godot_variant.movable* varargs = &MemoryMarshal.GetReference(varargs_span))\n"
|
||||
<< INDENT2 "fixed (IntPtr* " C_LOCAL_PTRCALL_ARGS " = "
|
||||
"&MemoryMarshal.GetReference(" C_LOCAL_PTRCALL_ARGS "_span))\n"
|
||||
|
|
|
@ -827,7 +827,7 @@ namespace Godot.Bridge
|
|||
{
|
||||
// Weird limitation, hence the need for aux:
|
||||
// "In the case of pointer types, you can use a stackalloc expression only in a local variable declaration to initialize the variable."
|
||||
var aux = stackalloc godotsharp_property_info[length];
|
||||
var aux = stackalloc godotsharp_property_info[stackMaxLength];
|
||||
interopProperties = aux;
|
||||
}
|
||||
else
|
||||
|
@ -947,7 +947,7 @@ namespace Godot.Bridge
|
|||
{
|
||||
// Weird limitation, hence the need for aux:
|
||||
// "In the case of pointer types, you can use a stackalloc expression only in a local variable declaration to initialize the variable."
|
||||
var aux = stackalloc godotsharp_property_def_val_pair[length];
|
||||
var aux = stackalloc godotsharp_property_def_val_pair[stackMaxLength];
|
||||
interopDefaultValues = aux;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace Godot
|
|||
_trampoline = trampoline;
|
||||
}
|
||||
|
||||
private const int VarArgsSpanThreshold = 5;
|
||||
private const int VarArgsSpanThreshold = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Calls the method represented by this <see cref="Callable"/>.
|
||||
|
@ -92,15 +92,13 @@ namespace Godot
|
|||
int argc = args.Length;
|
||||
|
||||
Span<godot_variant.movable> argsStoreSpan = argc <= VarArgsSpanThreshold ?
|
||||
stackalloc godot_variant.movable[VarArgsSpanThreshold].Cleared() :
|
||||
stackalloc godot_variant.movable[VarArgsSpanThreshold] :
|
||||
new godot_variant.movable[argc];
|
||||
|
||||
Span<IntPtr> argsSpan = argc <= 10 ?
|
||||
stackalloc IntPtr[argc] :
|
||||
Span<IntPtr> argsSpan = argc <= VarArgsSpanThreshold ?
|
||||
stackalloc IntPtr[VarArgsSpanThreshold] :
|
||||
new IntPtr[argc];
|
||||
|
||||
using var variantSpanDisposer = new VariantSpanDisposer(argsStoreSpan);
|
||||
|
||||
fixed (godot_variant* varargs = &MemoryMarshal.GetReference(argsStoreSpan).DangerousSelfRef)
|
||||
fixed (IntPtr* argsPtr = &MemoryMarshal.GetReference(argsSpan))
|
||||
{
|
||||
|
@ -128,15 +126,13 @@ namespace Godot
|
|||
int argc = args.Length;
|
||||
|
||||
Span<godot_variant.movable> argsStoreSpan = argc <= VarArgsSpanThreshold ?
|
||||
stackalloc godot_variant.movable[VarArgsSpanThreshold].Cleared() :
|
||||
stackalloc godot_variant.movable[VarArgsSpanThreshold] :
|
||||
new godot_variant.movable[argc];
|
||||
|
||||
Span<IntPtr> argsSpan = argc <= 10 ?
|
||||
stackalloc IntPtr[argc] :
|
||||
Span<IntPtr> argsSpan = argc <= VarArgsSpanThreshold ?
|
||||
stackalloc IntPtr[VarArgsSpanThreshold] :
|
||||
new IntPtr[argc];
|
||||
|
||||
using var variantSpanDisposer = new VariantSpanDisposer(argsStoreSpan);
|
||||
|
||||
fixed (godot_variant* varargs = &MemoryMarshal.GetReference(argsStoreSpan).DangerousSelfRef)
|
||||
fixed (IntPtr* argsPtr = &MemoryMarshal.GetReference(argsSpan))
|
||||
{
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Godot.NativeInterop
|
||||
{
|
||||
internal readonly ref struct VariantSpanDisposer
|
||||
{
|
||||
private readonly Span<godot_variant.movable> _variantSpan;
|
||||
|
||||
// IMPORTANT: The span element must be default initialized.
|
||||
// Make sure call Clear() on the span if it was created with stackalloc.
|
||||
public VariantSpanDisposer(Span<godot_variant.movable> variantSpan)
|
||||
{
|
||||
_variantSpan = variantSpan;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
for (int i = 0; i < _variantSpan.Length; i++)
|
||||
_variantSpan[i].DangerousSelfRef.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
internal static class VariantSpanExtensions
|
||||
{
|
||||
// Used to make sure we always initialize the span values to the default,
|
||||
// as we need that in order to safely dispose all elements after.
|
||||
public static Span<godot_variant.movable> Cleared(this Span<godot_variant.movable> span)
|
||||
{
|
||||
span.Clear();
|
||||
return span;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -101,7 +101,6 @@
|
|||
<Compile Include="Core\NativeInterop\InteropUtils.cs" />
|
||||
<Compile Include="Core\NativeInterop\NativeFuncs.extended.cs" />
|
||||
<Compile Include="Core\NativeInterop\NativeVariantPtrArgs.cs" />
|
||||
<Compile Include="Core\NativeInterop\VariantSpanHelpers.cs" />
|
||||
<Compile Include="Core\NativeInterop\VariantUtils.cs" />
|
||||
<Compile Include="Core\NativeInterop\VariantUtils.generic.cs" />
|
||||
<Compile Include="Core\NodePath.cs" />
|
||||
|
|
Loading…
Reference in a new issue