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
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,16 @@ public override IEnumerable<TypeInfo> DefinedTypes
get => GetManifestModule().GetDefinedTypes();
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "AssemblyNative_GetIsCollectible")]
internal static partial Interop.BOOL GetIsCollectible(QCallAssembly assembly);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool GetIsCollectible(IntPtr assembly);

public override bool IsCollectible
{
get
{
RuntimeAssembly runtimeAssembly = this;
return GetIsCollectible(new QCallAssembly(ref runtimeAssembly)) != Interop.BOOL.FALSE;
bool isCollectible = GetIsCollectible(GetUnderlyingNativeHandle());
GC.KeepAlive(this); // We directly pass the native handle above - make sure this object stays alive for the call
return isCollectible;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,15 @@ internal void InvokePropertySetter(object? obj, BindingFlags invokeAttr, Binder?

public override ParameterInfo ReturnParameter => FetchReturnParameter();

public override bool IsCollectible => RuntimeMethodHandle.GetIsCollectible(new RuntimeMethodHandleInternal(m_handle)) != Interop.BOOL.FALSE;
public override bool IsCollectible
{
get
{
bool isCollectible = RuntimeMethodHandle.IsCollectible(new RuntimeMethodHandleInternal(m_handle));
GC.KeepAlive(this); // We directly pass the native handle above - make sure this object stays alive for the call
return isCollectible;
}
}

public override MethodInfo GetBaseDefinition()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,7 @@ internal unsafe struct MethodTable
private const uint enum_flag_HasTypeEquivalence = 0x02000000;
#endif // FEATURE_TYPEEQUIVALENCE
private const uint enum_flag_HasFinalizer = 0x00100000;
private const uint enum_flag_Collectible = 0x00200000;
private const uint enum_flag_Category_Mask = 0x000F0000;
private const uint enum_flag_Category_ValueType = 0x00040000;
private const uint enum_flag_Category_Nullable = 0x00050000;
Expand Down Expand Up @@ -841,6 +842,8 @@ internal unsafe struct MethodTable

public bool HasFinalizer => (Flags & enum_flag_HasFinalizer) != 0;

public bool IsCollectible => (Flags & enum_flag_Collectible) != 0;

internal static bool AreSameType(MethodTable* mt1, MethodTable* mt2) => mt1 == mt2;

public bool HasDefaultConstructor => (Flags & (enum_flag_HasComponentSize | enum_flag_HasDefaultCtor)) == enum_flag_HasDefaultCtor;
Expand Down Expand Up @@ -978,13 +981,23 @@ internal unsafe struct TypeDesc
private uint _typeAndFlags;
private nint _exposedClassObject;

private const uint enum_flag_IsCollectible = 0x00000100;

public RuntimeType? ExposedClassObject
{
get
{
return *(RuntimeType*)Unsafe.AsPointer(ref _exposedClassObject);
}
}

public bool IsCollectible
{
get
{
return (_typeAndFlags & enum_flag_IsCollectible) != 0;
}
}
}

[StructLayout(LayoutKind.Sequential)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -824,9 +824,6 @@ internal RuntimeType MakePointer()
return type!;
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_IsCollectible")]
internal static partial Interop.BOOL IsCollectible(QCallTypeHandle handle);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetGenericTypeDefinition")]
internal static partial void GetGenericTypeDefinition(QCallTypeHandle type, ObjectHandleOnStack retType);

Expand Down Expand Up @@ -1053,8 +1050,8 @@ public IntPtr GetFunctionPointer()
return ptr;
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetIsCollectible")]
internal static partial Interop.BOOL GetIsCollectible(RuntimeMethodHandleInternal handle);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool IsCollectible(RuntimeMethodHandleInternal method);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_IsCAVisibleFromDecoratedType")]
internal static partial Interop.BOOL IsCAVisibleFromDecoratedType(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3227,12 +3227,15 @@ public override MemberInfo GetMemberWithSameMetadataDefinitionAs(MemberInfo memb

#region Identity

public sealed override bool IsCollectible
public sealed override unsafe bool IsCollectible
{
get
{
RuntimeType thisType = this;
return RuntimeTypeHandle.IsCollectible(new QCallTypeHandle(ref thisType)) != Interop.BOOL.FALSE;
TypeHandle th = GetNativeTypeHandle();

bool isCollectible = th.IsTypeDesc ? th.AsTypeDesc()->IsCollectible : th.AsMethodTable()->IsCollectible;
GC.KeepAlive(this);
return isCollectible;
}
}

Expand Down
20 changes: 9 additions & 11 deletions src/coreclr/vm/assemblynative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,20 +742,18 @@ extern "C" void QCALLTYPE AssemblyNative_GetModules(QCall::AssemblyHandle pAssem
END_QCALL;
}

extern "C" BOOL QCALLTYPE AssemblyNative_GetIsCollectible(QCall::AssemblyHandle pAssembly)
FCIMPL1(FC_BOOL_RET, AssemblyNative::GetIsCollectible, Assembly* pAssembly)
{
QCALL_CONTRACT;

BOOL retVal = FALSE;

BEGIN_QCALL;

retVal = pAssembly->IsCollectible();

END_QCALL;
CONTRACTL
{
FCALL_CHECK;
PRECONDITION(CheckPointer(pAssembly));
}
CONTRACTL_END;

return retVal;
FC_RETURN_BOOL(pAssembly->IsCollectible());
}
FCIMPLEND

extern volatile uint32_t g_cAssemblies;

Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/vm/assemblynative.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class AssemblyNative

static
FCDECL1(FC_BOOL_RET, GetIsDynamic, Assembly* pAssembly);

static
FCDECL1(FC_BOOL_RET, GetIsCollectible, Assembly* pAssembly);
};

extern "C" uint32_t QCALLTYPE AssemblyNative_GetAssemblyCount();
Expand Down Expand Up @@ -108,8 +111,6 @@ extern "C" void QCALLTYPE AssemblyNative_GetEntryPoint(QCall::AssemblyHandle pAs
extern "C" void QCALLTYPE AssemblyNative_GetImageRuntimeVersion(QCall::AssemblyHandle pAssembly, QCall::StringHandleOnStack retString);


extern "C" BOOL QCALLTYPE AssemblyNative_GetIsCollectible(QCall::AssemblyHandle pAssembly);

extern "C" INT_PTR QCALLTYPE AssemblyNative_InitializeAssemblyLoadContext(INT_PTR ptrAssemblyLoadContext, BOOL fRepresentsTPALoadContext, BOOL fIsCollectible);

extern "C" void QCALLTYPE AssemblyNative_PrepareForAssemblyLoadContextRelease(INT_PTR ptrNativeAssemblyBinder, INT_PTR ptrManagedStrongAssemblyLoadContext);
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ FCFuncEnd()

FCFuncStart(gRuntimeMethodHandle)
FCFuncElement("GetImplAttributes", RuntimeMethodHandle::GetImplAttributes)
FCFuncElement("IsCollectible", RuntimeMethodHandle::IsCollectible)
FCFuncElement("GetAttributes", RuntimeMethodHandle::GetAttributes)
FCFuncElement("GetMethodTable", RuntimeMethodHandle::GetMethodTable)
FCFuncElement("GetSlot", RuntimeMethodHandle::GetSlot)
Expand Down Expand Up @@ -166,6 +167,7 @@ FCFuncEnd()

FCFuncStart(gRuntimeAssemblyFuncs)
FCFuncElement("GetIsDynamic", AssemblyNative::GetIsDynamic)
FCFuncElement("GetIsCollectible", AssemblyNative::GetIsCollectible)
FCFuncElement("GetManifestModule", AssemblyHandle::GetManifestModule)
FCFuncElement("GetTokenInternal", AssemblyHandle::GetTokenInternal)
FCFuncEnd()
Expand Down
8 changes: 7 additions & 1 deletion src/coreclr/vm/method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3856,9 +3856,15 @@ MethodDesc *MethodDesc::GetInterfaceMD()
}
#endif // !DACCESS_COMPILE

bool MethodDesc::IsCollectible()
{
LIMITED_METHOD_DAC_CONTRACT;
return GetLoaderAllocator()->IsCollectible();
}

PTR_LoaderAllocator MethodDesc::GetLoaderAllocator()
{
WRAPPER_NO_CONTRACT;
LIMITED_METHOD_DAC_CONTRACT;
return GetLoaderModule()->GetLoaderAllocator();
}

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,8 @@ class MethodDesc

MethodDescBackpatchInfoTracker* GetBackpatchInfoTracker();

bool IsCollectible();

PTR_LoaderAllocator GetLoaderAllocator();

Module* GetLoaderModule();
Expand Down
3 changes: 0 additions & 3 deletions src/coreclr/vm/qcallentrypoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ static const Entry s_QCall[] =
DllImportEntry(RuntimeTypeHandle_MakeByRef)
DllImportEntry(RuntimeTypeHandle_MakeSZArray)
DllImportEntry(RuntimeTypeHandle_MakeArray)
DllImportEntry(RuntimeTypeHandle_IsCollectible)
DllImportEntry(RuntimeTypeHandle_GetConstraints)
DllImportEntry(RuntimeTypeHandle_GetArgumentTypesFromFunctionPointer)
DllImportEntry(RuntimeTypeHandle_GetAssemblySlow)
Expand Down Expand Up @@ -159,7 +158,6 @@ static const Entry s_QCall[] =
DllImportEntry(RuntimeMethodHandle_InvokeMethod)
DllImportEntry(RuntimeMethodHandle_ConstructInstantiation)
DllImportEntry(RuntimeMethodHandle_GetFunctionPointer)
DllImportEntry(RuntimeMethodHandle_GetIsCollectible)
DllImportEntry(RuntimeMethodHandle_GetMethodInstantiation)
DllImportEntry(RuntimeMethodHandle_GetTypicalMethodDefinition)
DllImportEntry(RuntimeMethodHandle_StripMethodInstantiation)
Expand Down Expand Up @@ -249,7 +247,6 @@ static const Entry s_QCall[] =
DllImportEntry(AssemblyNative_GetExportedTypes)
DllImportEntry(AssemblyNative_GetEntryPoint)
DllImportEntry(AssemblyNative_GetImageRuntimeVersion)
DllImportEntry(AssemblyNative_GetIsCollectible)
DllImportEntry(AssemblyNative_InternalTryGetRawMetadata)
DllImportEntry(AssemblyNative_ApplyUpdate)
DllImportEntry(AssemblyNative_IsApplyUpdateSupported)
Expand Down
36 changes: 8 additions & 28 deletions src/coreclr/vm/runtimehandles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1092,19 +1092,6 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_MakeByRef(QCall::TypeHandle pTypeHan
return;
}

extern "C" BOOL QCALLTYPE RuntimeTypeHandle_IsCollectible(QCall::TypeHandle pTypeHandle)
{
QCALL_CONTRACT;

BOOL retVal = FALSE;

BEGIN_QCALL;
retVal = pTypeHandle.AsTypeHandle().GetLoaderAllocator()->IsCollectible();
END_QCALL;

return retVal;
}

extern "C" void QCALLTYPE RuntimeTypeHandle_Instantiate(QCall::TypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType)
{
QCALL_CONTRACT;
Expand Down Expand Up @@ -1292,21 +1279,6 @@ extern "C" void * QCALLTYPE RuntimeMethodHandle_GetFunctionPointer(MethodDesc *
return funcPtr;
}

extern "C" BOOL QCALLTYPE RuntimeMethodHandle_GetIsCollectible(MethodDesc* pMethod)
{
QCALL_CONTRACT;

BOOL isCollectible = FALSE;

BEGIN_QCALL;

isCollectible = pMethod->GetLoaderAllocator()->IsCollectible();

END_QCALL;

return isCollectible;
}

FCIMPL1(LPCUTF8, RuntimeMethodHandle::GetUtf8Name, MethodDesc* pMethod)
{
CONTRACTL
Expand All @@ -1320,6 +1292,14 @@ FCIMPL1(LPCUTF8, RuntimeMethodHandle::GetUtf8Name, MethodDesc* pMethod)
}
FCIMPLEND

FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsCollectible, MethodDesc *pMethod)
{
FCALL_CONTRACT;
_ASSERTE(pMethod != NULL);
FC_RETURN_BOOL(pMethod->IsCollectible());
}
FCIMPLEND

FCIMPL1(INT32, RuntimeMethodHandle::GetAttributes, MethodDesc *pMethod)
{
FCALL_CONTRACT;
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/runtimehandles.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_MakeByRef(QCall::TypeHandle pTypeHan
extern "C" void QCALLTYPE RuntimeTypeHandle_MakePointer(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType);
extern "C" void QCALLTYPE RuntimeTypeHandle_MakeSZArray(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType);
extern "C" void QCALLTYPE RuntimeTypeHandle_MakeArray(QCall::TypeHandle pTypeHandle, INT32 rank, QCall::ObjectHandleOnStack retType);
extern "C" BOOL QCALLTYPE RuntimeTypeHandle_IsCollectible(QCall::TypeHandle pTypeHandle);
extern "C" void QCALLTYPE RuntimeTypeHandle_PrepareMemberInfoCache(QCall::TypeHandle pMemberInfoCache);
extern "C" void QCALLTYPE RuntimeTypeHandle_ConstructName(QCall::TypeHandle pTypeHandle, DWORD format, QCall::StringHandleOnStack retString);
extern "C" void QCALLTYPE RuntimeTypeHandle_GetInterfaces(MethodTable* pMT, QCall::ObjectHandleOnStack result);
Expand All @@ -185,6 +184,7 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_RegisterCollectibleTypeDependency(QC
class RuntimeMethodHandle
{
public:
static FCDECL1(FC_BOOL_RET, IsCollectible, MethodDesc *pMethod);
static FCDECL1(INT32, GetAttributes, MethodDesc *pMethod);
static FCDECL1(INT32, GetImplAttributes, ReflectMethodObject *pMethodUNSAFE);
static FCDECL1(MethodTable*, GetMethodTable, MethodDesc *pMethod);
Expand Down
21 changes: 13 additions & 8 deletions src/coreclr/vm/typedesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ class TypeDesc
{
public:
#ifndef DACCESS_COMPILE
TypeDesc(CorElementType type) {
TypeDesc(CorElementType type, bool isCollectible) {
LIMITED_METHOD_CONTRACT;

_typeAndFlags = type;
_typeAndFlags = type | (isCollectible ? enum_flag_IsCollectible : 0);
}
#endif

Expand Down Expand Up @@ -112,14 +112,19 @@ class TypeDesc
// Is actually ParamTypeDesc (BYREF, PTR)
BOOL HasTypeParam();

bool IsCollectible() const
{
LIMITED_METHOD_CONTRACT;
return (_typeAndFlags & TypeDesc::enum_flag_IsCollectible) != 0;
}

BOOL HasTypeEquivalence() const
bool HasTypeEquivalence() const
{
LIMITED_METHOD_CONTRACT;
return (_typeAndFlags & TypeDesc::enum_flag_HasTypeEquivalence) != 0;
}

BOOL IsFullyLoaded() const
bool IsFullyLoaded() const
{
LIMITED_METHOD_CONTRACT;

Expand Down Expand Up @@ -186,7 +191,7 @@ class TypeDesc
// See methodtable.h for details of the flags with the same name there
enum
{
// unused = 0x00000100,
enum_flag_IsCollectible = 0x00000100,
// unused = 0x00000200,
// unused = 0x00000400,
// unused = 0x00000800,
Expand Down Expand Up @@ -228,7 +233,7 @@ class ParamTypeDesc : public TypeDesc {
public:
#ifndef DACCESS_COMPILE
ParamTypeDesc(CorElementType type, TypeHandle arg)
: TypeDesc(type), m_Arg(arg) {
: TypeDesc(type, arg.IsCollectible()), m_Arg(arg) {

LIMITED_METHOD_CONTRACT;

Expand Down Expand Up @@ -291,7 +296,7 @@ class TypeVarTypeDesc : public TypeDesc
#ifndef DACCESS_COMPILE

TypeVarTypeDesc(PTR_Module pModule, mdToken typeOrMethodDef, unsigned int index, mdGenericParam token) :
TypeDesc(TypeFromToken(typeOrMethodDef) == mdtTypeDef ? ELEMENT_TYPE_VAR : ELEMENT_TYPE_MVAR)
TypeDesc(TypeFromToken(typeOrMethodDef) == mdtTypeDef ? ELEMENT_TYPE_VAR : ELEMENT_TYPE_MVAR, pModule->IsCollectible())
{
CONTRACTL
{
Expand Down Expand Up @@ -416,7 +421,7 @@ class FnPtrTypeDesc : public TypeDesc
public:
#ifndef DACCESS_COMPILE
FnPtrTypeDesc(BYTE callConv, DWORD numArgs, TypeHandle * retAndArgTypes, PTR_Module pLoaderModule)
: TypeDesc(ELEMENT_TYPE_FNPTR), m_pLoaderModule(pLoaderModule), m_NumArgs(numArgs), m_CallConv(callConv)
: TypeDesc(ELEMENT_TYPE_FNPTR, pLoaderModule->IsCollectible()), m_pLoaderModule(pLoaderModule), m_NumArgs(numArgs), m_CallConv(callConv)
{
LIMITED_METHOD_CONTRACT;
for (DWORD i = 0; i <= numArgs; i++)
Expand Down
Loading
Loading