Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/coreclr/inc/readytorun.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
// If you update this, ensure you run `git grep MINIMUM_READYTORUN_MAJOR_VERSION`
// and handle pending work.
#define READYTORUN_MAJOR_VERSION 27
#define READYTORUN_MINOR_VERSION 0x0000
#define READYTORUN_MINOR_VERSION 0x0001

#define MINIMUM_READYTORUN_MAJOR_VERSION 26

Expand Down Expand Up @@ -68,6 +68,7 @@
// R2R Version 26 changes ARM64 NativeVarInfo register encoding to include V0-V31
// R2R Version 26.1 adds READYTORUN_FIXUP_StoreMultiCallableAddrOfCode for storing a method's MultiCallableAddrOfCode into a location in the R2R image (used on WebAssembly)
// R2R Version 27 redefines READYTORUN_FIXUP_DeclaringTypeHandle to be encoded as a method signature instead of a pair of type signatures
// R2R Version 27.1 adds precompiled unboxing stubs to the InstanceMethodEntryPoints table. They share the metadata token, owner type and instantiation of the method they wrap and are distinguished only by READYTORUN_METHOD_SIG_UnboxingStub.

struct READYTORUN_CORE_HEADER
{
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct ReadyToRunHeaderConstants
static const uint32_t Signature = 0x00525452; // 'RTR'

static const uint32_t CurrentMajorVersion = 27;
static const uint32_t CurrentMinorVersion = 0;
static const uint32_t CurrentMinorVersion = 1;
};
Comment thread
BrzVlad marked this conversation as resolved.

struct ReadyToRunHeader
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ protected override UnboxingThunk CreateValueFromKey(UnboxingThunkHashtableKey ke
/// A type with an identical layout to the layout of a boxed value type.
/// The type has a single field of the type of the valuetype it represents.
/// </summary>
private sealed partial class BoxedValueType : MetadataType, INonEmittableType
private sealed class BoxedValueType : MetadataType, INonEmittableType, IPrefixMangledType
{
public MetadataType ValueTypeRepresented { get; }

Expand All @@ -250,6 +250,10 @@ private sealed partial class BoxedValueType : MetadataType, INonEmittableType
public override DefType[] ExplicitlyImplementedInterfaces => Array.Empty<DefType>();
public override TypeSystemContext Context => ValueTypeRepresented.Context;

TypeDesc IPrefixMangledType.BaseType => ValueTypeRepresented;

ReadOnlySpan<byte> IPrefixMangledType.Prefix => "Boxed"u8;

public BoxedValueType(ModuleDesc owningModule, MetadataType valuetype)
{
// BoxedValueType has the same genericness as the valuetype it's wrapping.
Expand Down Expand Up @@ -309,25 +313,45 @@ public override IEnumerable<FieldDesc> GetFields()
{
return Array.Empty<FieldDesc>();
}

protected override int ClassCode => 1062019524;

protected override int CompareToImpl(TypeDesc other, TypeSystemComparer comparer)
{
return comparer.Compare(ValueTypeRepresented, ((BoxedValueType)other).ValueTypeRepresented);
}
}

/// <summary>
/// Does a method represent an unboxing stub
/// Does a method represent an instantiating unboxing stub
/// </summary>
public bool IsSpecialUnboxingThunk(MethodDesc method)
{
if (method.GetTypicalMethodDefinition().GetType() == typeof(GenericUnboxingThunk))
return true;
return method.GetTypicalMethodDefinition() is GenericUnboxingThunk;
}

return false;
public bool IsUnboxingThunk(MethodDesc method)
{
return method.GetTypicalMethodDefinition() is GenericUnboxingThunk or UnboxingThunk;
}

/// <summary>
/// Convert from an unboxing stub to the actual target method
/// Convert from an instantiating unboxing stub to the actual target method
/// </summary>
public MethodDesc GetTargetOfSpecialUnboxingThunk(MethodDesc method)
{
MethodDesc typicalMethodTarget = ((GenericUnboxingThunk)method.GetTypicalMethodDefinition()).TargetMethod;
Debug.Assert(IsSpecialUnboxingThunk(method));
return GetTargetOfUnboxingThunk(method);
}

public MethodDesc GetTargetOfUnboxingThunk(MethodDesc method)
{
MethodDesc typicalMethodTarget = method.GetTypicalMethodDefinition() switch
{
GenericUnboxingThunk genericUnboxingThunk => genericUnboxingThunk.TargetMethod,
UnboxingThunk unboxingThunk => unboxingThunk.TargetMethod,
_ => throw new InvalidOperationException()
};

MethodDesc methodOnInstantiatedType = typicalMethodTarget;
if (method.OwningType.HasInstantiation)
Expand All @@ -348,7 +372,7 @@ public MethodDesc GetTargetOfSpecialUnboxingThunk(MethodDesc method)
/// <summary>
/// Represents a thunk to call shared instance method on boxed valuetypes.
/// </summary>
private sealed partial class GenericUnboxingThunk : ILStubMethod
private sealed class GenericUnboxingThunk : ILStubMethod, IPrefixMangledMethod
{
private MethodDesc _targetMethod;
private BoxedValueType _owningType;
Expand All @@ -370,6 +394,10 @@ public GenericUnboxingThunk(BoxedValueType owningType, MethodDesc targetMethod)

public MethodDesc TargetMethod => _targetMethod;

MethodDesc IPrefixMangledMethod.BaseMethod => _targetMethod;

ReadOnlySpan<byte> IPrefixMangledMethod.Prefix => "unbox"u8;

public override Utf8Span Name
{
get
Expand Down Expand Up @@ -403,16 +431,26 @@ public override MethodIL EmitIL()
ILEmitter emit = new ILEmitter();
ILCodeStream codeStream = emit.NewCodeStream();

FieldDesc eeTypeField = Context.GetWellKnownType(WellKnownType.Object).GetKnownField("m_pEEType"u8);
FieldDesc rawDataField = Context.SystemModule
.GetKnownType("System.Runtime.CompilerServices"u8, "RawData"u8)
.GetField("Data"u8);

// Load ByRef to the field with the value of the boxed valuetype
codeStream.EmitLdArg(0);
codeStream.Emit(ILOpcode.ldflda, emit.NewToken(Context.SystemModule.GetKnownType("System.Runtime.CompilerServices"u8, "RawData"u8).GetField("Data"u8)));
codeStream.Emit(ILOpcode.ldflda, emit.NewToken(rawDataField));

// Load the MethodTable of the boxed valuetype (this is the hidden generic context parameter expected
// by the (canonical) instance method, but normally not part of the signature in IL).
codeStream.EmitLdArg(0);
#if READYTORUN
codeStream.Emit(ILOpcode.ldflda, emit.NewToken(rawDataField));
codeStream.EmitLdc(Context.Target.PointerSize);
codeStream.Emit(ILOpcode.sub);
codeStream.Emit(ILOpcode.ldind_i);
#else
FieldDesc eeTypeField = Context.GetWellKnownType(WellKnownType.Object).GetKnownField("m_pEEType"u8);
codeStream.Emit(ILOpcode.ldfld, emit.NewToken(eeTypeField));
#endif

codeStream.Emit(ILOpcode.call, emit.NewToken(Context.GetCoreLibEntryPoint("System.Runtime.CompilerServices"u8, "RuntimeHelpers"u8, "SetNextCallGenericContext"u8, null)));

Expand All @@ -429,15 +467,25 @@ public override MethodIL EmitIL()

codeStream.Emit(ILOpcode.call, emit.NewToken(_targetMethod.InstantiateAsOpen()));
codeStream.Emit(ILOpcode.ret);
#if READYTORUN
emit.SetHasGeneratedTokens();
#endif

return emit.Link(this);
}

protected override int ClassCode => -247515475;

protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
{
return comparer.Compare(_targetMethod, ((GenericUnboxingThunk)other)._targetMethod);
}
}

/// <summary>
/// Represents a thunk to call instance method on boxed valuetypes.
/// </summary>
private sealed partial class UnboxingThunk : ILStubMethod
private sealed class UnboxingThunk : ILStubMethod, IPrefixMangledMethod
Comment thread
BrzVlad marked this conversation as resolved.
{
private MethodDesc _targetMethod;
private BoxedValueType _owningType;
Expand All @@ -459,6 +507,10 @@ public UnboxingThunk(BoxedValueType owningType, MethodDesc targetMethod)

public MethodDesc TargetMethod => _targetMethod;

MethodDesc IPrefixMangledMethod.BaseMethod => _targetMethod;

ReadOnlySpan<byte> IPrefixMangledMethod.Prefix => "unbox"u8;

public override Utf8Span Name
{
get
Expand Down Expand Up @@ -486,6 +538,7 @@ public override MethodIL EmitIL()
Array.Empty<object>());
}

#if !READYTORUN
// TODO: mirror what was done in the commit that introduced this comment. Not doing it in that
// commit since this can't be tested in dotnet/runtime repo main right now.
if (_targetMethod.IsAsyncCall())
Expand All @@ -496,6 +549,7 @@ public override MethodIL EmitIL()
c.EmitCallThrowHelper(e, Context.GetCoreLibEntryPoint("System.Runtime"u8, "InternalCalls"u8, "RhpFallbackFailFast"u8, null));
return e.Link(this);
}
#endif

// Generate the unboxing stub. This loosely corresponds to following C#:
// return BoxedValue.InstanceMethod([rest of parameters])
Expand Down Expand Up @@ -535,11 +589,21 @@ public override MethodIL EmitIL()

codeStream.Emit(ILOpcode.call, emit.NewToken(methodToInstantiate));
codeStream.Emit(ILOpcode.ret);
#if READYTORUN
emit.SetHasGeneratedTokens();
#endif

return emit.Link(this);
}

public override Instantiation Instantiation => _targetMethod.Instantiation;

protected override int ClassCode => 446545583;

protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
{
return comparer.Compare(_targetMethod, ((UnboxingThunk)other)._targetMethod);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,13 @@ public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependenci

MethodDesc canonImpl = implementingMethodInstantiation.GetCanonMethodTarget(CanonicalFormKind.Specific);

#if READYTORUN
if (factory.NeedsUnboxingStub(canonImpl))
{
dynamicDependencies.Add(new CombinedDependencyListEntry(factory.UnboxingStub(canonImpl), null, "Unboxing thunk for interface GVM"));
}
#endif

// Static virtuals cannot be further overridden so this is an impl use. Otherwise it's a virtual slot use.
if (implementingMethodInstantiation.Signature.IsStatic)
Comment thread
BrzVlad marked this conversation as resolved.
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ internal struct ReadyToRunHeaderConstants
public const uint Signature = 0x00525452; // 'RTR'

public const ushort CurrentMajorVersion = 27;
public const ushort CurrentMinorVersion = 0;
public const ushort CurrentMinorVersion = 1;
}
#if READYTORUN
#pragma warning disable 0169
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,6 @@ namespace ILCompiler
// Functionality related to deterministic ordering of types and members
public partial class CompilerTypeSystemContext
{
private partial class BoxedValueType
{
protected override int ClassCode => 1062019524;

protected override int CompareToImpl(TypeDesc other, TypeSystemComparer comparer)
{
return comparer.Compare(ValueTypeRepresented, ((BoxedValueType)other).ValueTypeRepresented);
}
}

private partial class GenericUnboxingThunk
{
protected override int ClassCode => -247515475;

protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
{
var otherMethod = (GenericUnboxingThunk)other;
return comparer.Compare(_targetMethod, otherMethod._targetMethod);
}
}

private partial class UnboxingThunk
{
protected override int ClassCode => 446545583;

protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
{
var otherMethod = (UnboxingThunk)other;
return comparer.Compare(_targetMethod, otherMethod._targetMethod);
}
}

private partial class DefaultInterfaceMethodImplementationInstantiationThunk
{
protected override int ClassCode => -789598;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,9 +421,10 @@
<Compile Include="Compiler\CompilationBuilder.Aot.cs" />
<Compile Include="Compiler\CompilationModuleGroup.Aot.cs" />
<Compile Include="Compiler\CompilerTypeSystemContext.Aot.cs" />
<Compile Include="Compiler\CompilerTypeSystemContext.BoxedTypes.cs" />
<Compile Include="..\..\Common\Compiler\CompilerTypeSystemContext.BoxedTypes.cs">
<Link>Compiler\CompilerTypeSystemContext.BoxedTypes.cs</Link>
</Compile>
<Compile Include="Compiler\CompilerTypeSystemContext.InterfaceThunks.cs" />
<Compile Include="Compiler\CompilerTypeSystemContext.Mangling.cs" />
<Compile Include="Compiler\CompilerTypeSystemContext.Sorting.cs" />
<Compile Include="Compiler\CompilerTypeSystemContext.DelegateInfo.cs" />
<Compile Include="Compiler\CompilerTypeSystemContext.DynamicInvoke.cs" />
Expand Down
Loading
Loading