From dde6d74cd81294b6d9991db03da9fbdef37af82f Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Wed, 21 Aug 2019 01:48:52 +0300 Subject: [PATCH] Remove the copying of returned values This improves performance and more importantly, fixes a memory leak caused by the original value not being destroyed. Signed-off-by: Dimitar Dobrev --- src/Generator/Generators/CSharp/CSharpMarshal.cs | 9 +++++++-- src/Generator/Generators/CSharp/CSharpSources.cs | 15 ++++++--------- src/Generator/Types/Std/Stdlib.cs | 3 +-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs index 9064ac37ad..70e5817f07 100644 --- a/src/Generator/Generators/CSharp/CSharpMarshal.cs +++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs @@ -289,8 +289,13 @@ public override bool VisitClassDecl(Class @class) if (returnType.IsAddress()) Context.Return.Write(HandleReturnedPointer(@class, qualifiedClass.Type)); - else - Context.Return.Write($"{qualifiedClass}.{Helpers.CreateInstanceIdentifier}({Context.ReturnVarName})"); + else if (Context.MarshalKind == MarshalKind.NativeField || + Context.Function?.HasIndirectReturnTypeParameter == true || + Context.Function?.OperatorKind == CXXOperatorKind.Subscript) + Context.Return.Write($@"{qualifiedClass}.{Helpers.CreateInstanceIdentifier}({ + Context.ReturnVarName})"); + else Context.Return.Write($@"{qualifiedClass}.{Helpers.CreateInstanceIdentifier}(new { + typePrinter.IntPtrType}(&{Context.ReturnVarName}))"); return true; } diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index db7e0a302c..e831d1a949 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -2808,6 +2808,7 @@ public void GenerateFunctionCall(string functionName, List parameters var originalFunction = function.OriginalFunction ?? function; + var names = new List(); if (originalFunction.HasIndirectReturnTypeParameter) { var indirectRetType = originalFunction.Parameters.First( @@ -2825,8 +2826,8 @@ public void GenerateFunctionCall(string functionName, List parameters Class retClass; type.TryGetClass(out retClass); var @class = retClass.OriginalClass ?? retClass; - WriteLine($@"var {Helpers.ReturnIdentifier} = new { - TypePrinter.PrintNative(@class)}();"); + WriteLine($@"var {Helpers.ReturnIdentifier} = Marshal.AllocHGlobal({ + @class.Layout.GetSize()});"); } else { @@ -2839,13 +2840,15 @@ public void GenerateFunctionCall(string functionName, List parameters WriteLine("{0} {1};", typeMap.CSharpSignatureType(typePrinterContext), Helpers.ReturnIdentifier); + names.Add($"new IntPtr(&{Helpers.ReturnIdentifier})"); } else WriteLine("var {0} = {1};", construct); } + if (names.Count == 0) + names.Add(Helpers.ReturnIdentifier); } - var names = new List(); foreach (var param in @params) { if (param.Param == operatorParam && needsInstance) @@ -2862,12 +2865,6 @@ public void GenerateFunctionCall(string functionName, List parameters var needsFixedThis = needsInstance && isValueType; - if (originalFunction.HasIndirectReturnTypeParameter) - { - var name = string.Format("new IntPtr(&{0})", Helpers.ReturnIdentifier); - names.Insert(0, name); - } - if (needsInstance) { var instanceIndex = GetInstanceParamIndex(method); diff --git a/src/Generator/Types/Std/Stdlib.cs b/src/Generator/Types/Std/Stdlib.cs index c563c7c186..09cfb2a8db 100644 --- a/src/Generator/Types/Std/Stdlib.cs +++ b/src/Generator/Types/Std/Stdlib.cs @@ -382,8 +382,7 @@ public override void CSharpMarshalToManaged(CSharpMarshalContext ctx) ctx.MarshalKind == MarshalKind.ReturnVariableArray; ctx.Before.WriteLine($@"var {varBasicString} = { basicString.Visit(typePrinter)}.{Helpers.CreateInstanceIdentifier}({ - (usePointer ? string.Empty : $"new {typePrinter.IntPtrType}(&")}{ - ctx.ReturnVarName}{(usePointer ? string.Empty : ")")});"); + ctx.ReturnVarName});"); string @string = $"{qualifiedBasicString}Extensions.{data.Name}({varBasicString})"; if (usePointer) {