_transitionBlock = TransitionBlock.FromTarget(target);
}
- public void GetCallRefMap(MethodDesc method)
+ public void GetCallRefMap(MethodDesc method, bool isUnboxingStub)
{
TransitionBlock transitionBlock = TransitionBlock.FromTarget(method.Context.Target);
parameterTypes[parameterIndex] = new TypeHandle(method.Signature[parameterIndex]);
}
CallingConventions callingConventions = (hasThis ? CallingConventions.ManagedInstance : CallingConventions.ManagedStatic);
- bool hasParamType = method.GetCanonMethodTarget(CanonicalFormKind.Specific).RequiresInstArg();
+ bool hasParamType = method.RequiresInstArg() && !isUnboxingStub;
bool extraFunctionPointerArg = false;
bool[] forcedByRefParams = new bool[parameterTypes.Length];
bool skipFirstArg = false;
CORCOMPILE_GCREFMAP_TOKENS[] fakeStack = new CORCOMPILE_GCREFMAP_TOKENS[transitionBlock.SizeOfTransitionBlock + nStackBytes];
// Fill it in
- FakeGcScanRoots(method, argit, fakeStack);
+ FakeGcScanRoots(method, argit, fakeStack, isUnboxingStub);
// Encode the ref map
uint nStackSlots;
/// <summary>
/// Fill in the GC-relevant stack frame locations.
/// </summary>
- private void FakeGcScanRoots(MethodDesc method, ArgIterator argit, CORCOMPILE_GCREFMAP_TOKENS[] frame)
+ private void FakeGcScanRoots(MethodDesc method, ArgIterator argit, CORCOMPILE_GCREFMAP_TOKENS[] frame, bool isUnboxingStub)
{
// Encode generic instantiation arg
if (argit.HasParamType)
// If the function has a this pointer, add it to the mask
if (argit.HasThis)
{
- bool isUnboxingStub = false; // TODO: is this correct?
bool interior = method.OwningType.IsValueType && !isUnboxingStub;
frame[_transitionBlock.ThisOffset] = (interior ? CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_INTERIOR : CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_REF);
using System;
using System.Collections.Generic;
using System.Diagnostics;
-
using Internal.Text;
-using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis.ReadyToRun
{
for (int methodIndex = 0; methodIndex < _methods.Count; methodIndex++)
{
IMethodNode methodNode = _methods[methodIndex];
- if (methodNode == null || (methodNode is LocalMethodImport localMethod && localMethod.MethodCodeNode.IsEmpty))
+ if (methodNode == null)
{
// Flush an empty GC ref map block to prevent
// the indexed records from falling out of sync with methods
}
else
{
- builder.GetCallRefMap(methodNode.Method);
+ bool isUnboxingStub = false;
+ if (methodNode is DelayLoadHelperImport methodImport)
+ {
+ isUnboxingStub = ((MethodFixupSignature)methodImport.ImportSignature.Target).IsUnboxingStub;
+ }
+ builder.GetCallRefMap(methodNode.Method, isUnboxingStub);
}
if (methodIndex >= nextMethodIndex)
{