Skip to content

API proposal: Obsolete RuntimeHelpers.OffsetToStringData #31406

Closed
@GrabYourPitchforks

Description

@GrabYourPitchforks

API proposal

namespace System.Runtime.CompilerServices
{
    public sealed class RuntimeHelpers
    {
        [Obsolete("Use string.GetPinnableReference() instead.")]
        public static int OffsetToStringData { get; }
    }
}

Justification

The RuntimeHelpers.OffsetToStringData property is the last remaining public API which exposes the concept of the string object containing inline UTF-16 data just after the object header. It's used by compilers to pin string instances, generally (but not always) using the following pseudocode:

fixed string fixedLocal = theStringInstance;
char* pchStr = (char*)((byte*)theStringInstance + RuntimeHelpers.OffsetToStringData);
// use 'pchStr' here

Because of this pattern throughout existing libraries, adding support for things like string compaction (where the backing data might be ASCII instead of UTF-16) becomes difficult and error-prone.

In .NET Core 3.0, we added an API string.GetPinnableReference() which takes advantage of the new pattern-based fixed statement support added in C# 7.3. This new API would allow us to intercept the call immediately before the pin operation, allowing the runtime to fix up the data as necessary. When targeting netcoreapp3.0, the compiler will prefer the new GetPinnableReference API over the old RuntimeHelpers API.

As more and more DLLs are built which target netcoreapp3.0+, we should gradually see the ecosystem move over to the new API, allowing us to experiment with changing the internal layout of the string type once a critical mass of DLLs has migrated away from the old APIs.

Since the main consumer of the old API is the C# compiler itself, I don't anticipate most code bases seeing new warnings after upgrade. The compiler will automatically prefer the new API anyway. The reason I propose obsoleting the old API is so tooling authors and devs writing ref emit code or otherwise manipulating IL directly will see the warning and know that they should instead be calling a new more future-proof API.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions