From cb813e1ffce4498a51fe87487554669dfdcb3903 Mon Sep 17 00:00:00 2001 From: Marc Gravell Date: Sun, 30 Jun 2019 09:59:46 +0100 Subject: [PATCH] check the *actual* length to allow more stack usage *and* allow smaller pool rentals --- src/csharp/Grpc.Core/Grpc.Core.csproj | 2 ++ src/csharp/Grpc.Core/Internal/CallSafeHandle.cs | 10 +++++++++- src/csharp/Grpc.Core/Internal/MarshalUtils.cs | 10 +++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index afd60e73a21..1844ce335bc 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -100,6 +100,8 @@ + + diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index 67efb031629..c62297b0972 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -135,8 +135,16 @@ namespace Grpc.Core.Internal { var ctx = completionQueue.CompletionRegistry.RegisterBatchCompletion(CompletionHandler_ISendStatusFromServerCompletionCallback, callback); var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero; - int maxBytes = MarshalUtils.GetMaxBytesUTF8(status.Detail); + const int MaxStackAllocBytes = 256; + int maxBytes = MarshalUtils.GetMaxByteCountUTF8(status.Detail); + if (maxBytes > MaxStackAllocBytes) + { + // pay the extra to get the *actual* size; this could mean that + // it ends up fitting on the stack after all, but even if not + // it will mean that we ask for a *much* smaller buffer + maxBytes = MarshalUtils.GetByteCountUTF8(status.Detail); + } if (maxBytes <= MaxStackAllocBytes) { // for small status, we can encode on the stack without touching arrays diff --git a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs index ec3ce9ca72d..54b4370935d 100644 --- a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs +++ b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs @@ -66,9 +66,17 @@ namespace Grpc.Core.Internal /// /// Returns the maximum number of bytes required to encode a given string. /// - public static int GetMaxBytesUTF8(string str) + public static int GetMaxByteCountUTF8(string str) { return EncodingUTF8.GetMaxByteCount(str.Length); } + + /// + /// Returns the actual number of bytes required to encode a given string. + /// + public static int GetByteCountUTF8(string str) + { + return EncodingUTF8.GetByteCount(str); + } } }