Skip to content

Commit f929bed

Browse files
Obsolete RuntimeHelpers.OffsetToStringData (#35722)
1 parent b772f61 commit f929bed

File tree

3 files changed

+31
-33
lines changed

3 files changed

+31
-33
lines changed

src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,31 +1448,44 @@ protected override void TransformManagedToNative(ILCodeStream codeStream)
14481448
if (ShouldBePinned)
14491449
{
14501450
//
1451-
// Pin the string and push a pointer to the first character on the stack.
1451+
// Pin the char& and push a pointer to the first character on the stack.
14521452
//
1453-
TypeDesc stringType = Context.GetWellKnownType(WellKnownType.String);
1453+
TypeDesc charRefType = Context.GetWellKnownType(WellKnownType.Char).MakeByRefType();
14541454

1455-
ILLocalVariable vPinnedString = emitter.NewLocal(stringType, true);
1456-
ILCodeLabel lNullString = emitter.NewCodeLabel();
1455+
ILLocalVariable vPinnedCharRef = emitter.NewLocal(charRefType, true);
14571456

1458-
LoadManagedValue(codeStream);
1459-
codeStream.EmitStLoc(vPinnedString);
1460-
codeStream.EmitLdLoc(vPinnedString);
1457+
ILCodeLabel lNonNullString = emitter.NewCodeLabel();
1458+
ILCodeLabel lCommonExit = emitter.NewCodeLabel();
14611459

1462-
codeStream.Emit(ILOpcode.conv_i);
1463-
codeStream.Emit(ILOpcode.dup);
1460+
LoadManagedValue(codeStream);
1461+
codeStream.Emit(ILOpcode.brtrue, lNonNullString);
14641462

1465-
// Marshalling a null string?
1466-
codeStream.Emit(ILOpcode.brfalse, lNullString);
1463+
//
1464+
// Null input case
1465+
// Don't pin anything - load a zero-value nuint (void*) onto the stack
1466+
//
1467+
codeStream.Emit(ILOpcode.ldc_i4_0);
1468+
codeStream.Emit(ILOpcode.conv_u);
1469+
codeStream.Emit(ILOpcode.br, lCommonExit);
14671470

1471+
//
1472+
// Non-null input case
1473+
// Extract the char& from the string, pin it, then convert it to a nuint (void*)
1474+
//
1475+
codeStream.EmitLabel(lNonNullString);
1476+
LoadManagedValue(codeStream);
14681477
codeStream.Emit(ILOpcode.call, emitter.NewToken(
1469-
Context.SystemModule.
1470-
GetKnownType("System.Runtime.CompilerServices", "RuntimeHelpers").
1471-
GetKnownMethod("get_OffsetToStringData", null)));
1472-
1473-
codeStream.Emit(ILOpcode.add);
1478+
Context.GetWellKnownType(WellKnownType.String).
1479+
GetKnownMethod("GetPinnableReference", null)));
1480+
codeStream.EmitStLoc(vPinnedCharRef);
1481+
codeStream.EmitLdLoc(vPinnedCharRef);
1482+
codeStream.Emit(ILOpcode.conv_u);
14741483

1475-
codeStream.EmitLabel(lNullString);
1484+
//
1485+
// Common exit
1486+
// Top of stack contains a nuint (void*) pointing to start of char data, or nullptr
1487+
//
1488+
codeStream.EmitLabel(lCommonExit);
14761489
StoreNativeValue(codeStream);
14771490
}
14781491
else

src/libraries/System.Runtime/ref/System.Runtime.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9108,6 +9108,7 @@ public static partial class RuntimeFeature
91089108
}
91099109
public static partial class RuntimeHelpers
91109110
{
9111+
[System.ObsoleteAttribute("OffsetToStringData is obsolete. Use string.GetPinnableReference() instead.")]
91119112
public static int OffsetToStringData { get { throw null; } }
91129113
public static IntPtr AllocateTypeAssociatedMemory(Type type, int size) { throw null; }
91139114
public static void EnsureSufficientExecutionStack() { }

src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -70,22 +70,6 @@ public static unsafe void GetObjectValue()
7070
Assert.Equal(i, (int)iOV);
7171
}
7272

73-
[Fact]
74-
public static unsafe void OffsetToStringData()
75-
{
76-
// RuntimeHelpers.OffsetToStringData
77-
char[] expectedValues = new char[] { 'a', 'b', 'c', 'd', 'e', 'f' };
78-
string s = "abcdef";
79-
80-
fixed (char* values = s) // Compiler will use OffsetToStringData with fixed statements
81-
{
82-
for (int i = 0; i < expectedValues.Length; i++)
83-
{
84-
Assert.Equal(expectedValues[i], values[i]);
85-
}
86-
}
87-
}
88-
8973
[Fact]
9074
public static void InitializeArray()
9175
{

0 commit comments

Comments
 (0)