Skip to content

Commit b7b91cb

Browse files
Convert some handle APIs to QCalls (#107513)
Convert RuntimeTypeHandle.GetAssembly() Convert RuntimeTypeHandle.GetModule() Convert RuntimeAssembly.GetManifestModule()
1 parent 600f6bd commit b7b91cb

File tree

8 files changed

+134
-92
lines changed

8 files changed

+134
-92
lines changed

src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ public override string? CodeBase
115115
}
116116
}
117117

118-
internal RuntimeAssembly GetNativeHandle() => this;
119-
120118
// If the assembly is copied before it is loaded, the codebase will be set to the
121119
// actual file loaded if copiedName is true. If it is false, then the original code base
122120
// is returned.
@@ -263,7 +261,7 @@ public override Type[] GetExportedTypes()
263261
public override IEnumerable<TypeInfo> DefinedTypes
264262
{
265263
[RequiresUnreferencedCode("Types might be removed")]
266-
get => GetManifestModule(GetNativeHandle()).GetDefinedTypes();
264+
get => GetManifestModule().GetDefinedTypes();
267265
}
268266

269267
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "AssemblyNative_GetIsCollectible")]
@@ -324,7 +322,7 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont
324322
public override Module ManifestModule =>
325323
// We don't need to return the "external" ModuleBuilder because
326324
// it is meant to be read-only
327-
GetManifestModule(GetNativeHandle());
325+
GetManifestModule();
328326

329327
public override object[] GetCustomAttributes(bool inherit)
330328
{
@@ -588,7 +586,7 @@ private CultureInfo GetLocale()
588586
[MethodImpl(MethodImplOptions.InternalCall)]
589587
private static extern bool FCallIsDynamic(RuntimeAssembly assembly);
590588

591-
public override bool IsDynamic => FCallIsDynamic(GetNativeHandle());
589+
public override bool IsDynamic => FCallIsDynamic(this);
592590

593591
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "AssemblyNative_GetSimpleName")]
594592
private static partial void GetSimpleName(QCallAssembly assembly, StringHandleOnStack retSimpleName);
@@ -701,8 +699,24 @@ public override Module[] GetLoadedModules(bool getResourceModules)
701699
return GetModulesInternal(false, getResourceModules);
702700
}
703701

702+
private RuntimeModule GetManifestModule()
703+
{
704+
return GetManifestModule(this) ?? GetManifestModuleWorker(this);
705+
706+
[MethodImpl(MethodImplOptions.NoInlining)]
707+
static RuntimeModule GetManifestModuleWorker(RuntimeAssembly assembly)
708+
{
709+
RuntimeModule? module = null;
710+
GetManifestModuleSlow(ObjectHandleOnStack.Create(ref assembly), ObjectHandleOnStack.Create(ref module));
711+
return module!;
712+
}
713+
}
714+
704715
[MethodImpl(MethodImplOptions.InternalCall)]
705-
internal static extern RuntimeModule GetManifestModule(RuntimeAssembly assembly);
716+
private static extern RuntimeModule? GetManifestModule(RuntimeAssembly assembly);
717+
718+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "AssemblyHandle_GetManifestModuleSlow")]
719+
private static partial void GetManifestModuleSlow(ObjectHandleOnStack assembly, ObjectHandleOnStack module);
706720

707721
[MethodImpl(MethodImplOptions.InternalCall)]
708722
internal static extern int GetToken(RuntimeAssembly assembly);
@@ -713,7 +727,7 @@ public sealed override Type[] GetForwardedTypes()
713727
List<Type> types = new List<Type>();
714728
List<Exception> exceptions = new List<Exception>();
715729

716-
MetadataImport scope = GetManifestModule(GetNativeHandle()).MetadataImport;
730+
MetadataImport scope = GetManifestModule().MetadataImport;
717731
scope.Enum(MetadataTokenType.ExportedType, 0, out MetadataEnumResult enumResult);
718732
RuntimeAssembly runtimeAssembly = this;
719733
QCallAssembly pAssembly = new QCallAssembly(ref runtimeAssembly);

src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ internal static IList<CustomAttributeData> GetCustomAttributesInternal(RuntimeAs
8282

8383
// No pseudo attributes for RuntimeAssembly
8484

85-
return GetCustomAttributes((RuntimeModule)target.ManifestModule, RuntimeAssembly.GetToken(target.GetNativeHandle()));
85+
return GetCustomAttributes((RuntimeModule)target.ManifestModule, RuntimeAssembly.GetToken(target));
8686
}
8787

8888
internal static IList<CustomAttributeData> GetCustomAttributesInternal(RuntimeParameterInfo target)
@@ -1227,7 +1227,7 @@ internal static bool IsDefined(RuntimeAssembly assembly, RuntimeType caType)
12271227
Debug.Assert(caType is not null);
12281228

12291229
// No pseudo attributes for RuntimeAssembly
1230-
return IsCustomAttributeDefined((assembly.ManifestModule as RuntimeModule)!, RuntimeAssembly.GetToken(assembly.GetNativeHandle()), caType);
1230+
return IsCustomAttributeDefined((assembly.ManifestModule as RuntimeModule)!, RuntimeAssembly.GetToken(assembly), caType);
12311231
}
12321232

12331233
internal static bool IsDefined(RuntimeModule module, RuntimeType caType)
@@ -1388,7 +1388,7 @@ internal static object[] GetCustomAttributes(RuntimeAssembly assembly, RuntimeTy
13881388

13891389
// No pseudo attributes for RuntimeAssembly
13901390

1391-
int assemblyToken = RuntimeAssembly.GetToken(assembly.GetNativeHandle());
1391+
int assemblyToken = RuntimeAssembly.GetToken(assembly);
13921392
return GetCustomAttributes((assembly.ManifestModule as RuntimeModule)!, assemblyToken, 0, caType);
13931393
}
13941394

src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,11 +306,43 @@ internal RuntimeType GetRuntimeType()
306306
[MethodImpl(MethodImplOptions.InternalCall)]
307307
internal static extern CorElementType GetCorElementType(RuntimeType type);
308308

309+
internal static RuntimeAssembly GetAssembly(RuntimeType type)
310+
{
311+
return GetAssemblyIfExists(type) ?? GetAssemblyWorker(type);
312+
313+
[MethodImpl(MethodImplOptions.NoInlining)]
314+
static RuntimeAssembly GetAssemblyWorker(RuntimeType type)
315+
{
316+
RuntimeAssembly? assembly = null;
317+
GetAssemblySlow(ObjectHandleOnStack.Create(ref type), ObjectHandleOnStack.Create(ref assembly));
318+
return assembly!;
319+
}
320+
}
321+
309322
[MethodImpl(MethodImplOptions.InternalCall)]
310-
internal static extern RuntimeAssembly GetAssembly(RuntimeType type);
323+
private static extern RuntimeAssembly? GetAssemblyIfExists(RuntimeType type);
324+
325+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetAssemblySlow")]
326+
private static partial void GetAssemblySlow(ObjectHandleOnStack type, ObjectHandleOnStack assembly);
327+
328+
internal static RuntimeModule GetModule(RuntimeType type)
329+
{
330+
return GetModuleIfExists(type) ?? GetModuleWorker(type);
331+
332+
[MethodImpl(MethodImplOptions.NoInlining)]
333+
static RuntimeModule GetModuleWorker(RuntimeType type)
334+
{
335+
RuntimeModule? module = null;
336+
GetModuleSlow(ObjectHandleOnStack.Create(ref type), ObjectHandleOnStack.Create(ref module));
337+
return module!;
338+
}
339+
}
311340

312341
[MethodImpl(MethodImplOptions.InternalCall)]
313-
internal static extern RuntimeModule GetModule(RuntimeType type);
342+
private static extern RuntimeModule? GetModuleIfExists(RuntimeType type);
343+
344+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetModuleSlow")]
345+
private static partial void GetModuleSlow(ObjectHandleOnStack type, ObjectHandleOnStack module);
314346

315347
public ModuleHandle GetModuleHandle()
316348
{

src/coreclr/vm/ecalllist.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ FCFuncStart(gCOMTypeHandleFuncs)
109109
FCFuncElement("GetFirstIntroducedMethod", RuntimeTypeHandle::GetFirstIntroducedMethod)
110110
FCFuncElement("GetNextIntroducedMethod", RuntimeTypeHandle::GetNextIntroducedMethod)
111111
FCFuncElement("GetCorElementType", RuntimeTypeHandle::GetCorElementType)
112-
FCFuncElement("GetAssembly", RuntimeTypeHandle::GetAssembly)
113-
FCFuncElement("GetModule", RuntimeTypeHandle::GetModule)
112+
FCFuncElement("GetAssemblyIfExists", RuntimeTypeHandle::GetAssemblyIfExists)
113+
FCFuncElement("GetModuleIfExists", RuntimeTypeHandle::GetModuleIfExists)
114114
FCFuncElement("GetBaseType", RuntimeTypeHandle::GetBaseType)
115115
FCFuncElement("GetElementType", RuntimeTypeHandle::GetElementType)
116116
FCFuncElement("GetArrayRank", RuntimeTypeHandle::GetArrayRank)

src/coreclr/vm/object.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,13 +1219,6 @@ class ReflectModuleBaseObject : public Object
12191219
}
12201220
};
12211221

1222-
NOINLINE ReflectModuleBaseObject* GetRuntimeModuleHelper(LPVOID __me, Module *pModule, OBJECTREF keepAlive);
1223-
#define FC_RETURN_MODULE_OBJECT(pModule, refKeepAlive) FC_INNER_RETURN(ReflectModuleBaseObject*, GetRuntimeModuleHelper(__me, pModule, refKeepAlive))
1224-
1225-
1226-
1227-
1228-
12291222
class ThreadBaseObject;
12301223
class SynchronizationContextObject: public Object
12311224
{
@@ -1439,8 +1432,6 @@ class AssemblyBaseObject : public Object
14391432
SetObjectReference(&m_pSyncRoot, pSyncRoot);
14401433
}
14411434
};
1442-
NOINLINE AssemblyBaseObject* GetRuntimeAssemblyHelper(LPVOID __me, Assembly *pAssembly, OBJECTREF keepAlive);
1443-
#define FC_RETURN_ASSEMBLY_OBJECT(pAssembly, refKeepAlive) FC_INNER_RETURN(AssemblyBaseObject*, GetRuntimeAssemblyHelper(__me, pAssembly, refKeepAlive))
14441435

14451436
// AssemblyLoadContextBaseObject
14461437
// This class is the base class for AssemblyLoadContext

src/coreclr/vm/qcallentrypoints.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ static const Entry s_QCall[] =
118118
DllImportEntry(RuntimeTypeHandle_MakeArray)
119119
DllImportEntry(RuntimeTypeHandle_IsCollectible)
120120
DllImportEntry(RuntimeTypeHandle_GetConstraints)
121+
DllImportEntry(RuntimeTypeHandle_GetAssemblySlow)
122+
DllImportEntry(RuntimeTypeHandle_GetModuleSlow)
121123
DllImportEntry(RuntimeTypeHandle_GetNumVirtualsAndStaticVirtuals)
122124
DllImportEntry(RuntimeTypeHandle_VerifyInterfaceIsImplemented)
123125
DllImportEntry(RuntimeTypeHandle_GetInterfaceMethodImplementation)
@@ -158,6 +160,7 @@ static const Entry s_QCall[] =
158160
DllImportEntry(ModuleHandle_ResolveMethod)
159161
DllImportEntry(ModuleHandle_ResolveField)
160162
DllImportEntry(ModuleHandle_GetPEKind)
163+
DllImportEntry(AssemblyHandle_GetManifestModuleSlow)
161164
DllImportEntry(TypeBuilder_DefineGenericParam)
162165
DllImportEntry(TypeBuilder_DefineType)
163166
DllImportEntry(TypeBuilder_SetParentType)

src/coreclr/vm/runtimehandles.cpp

Lines changed: 63 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -161,43 +161,6 @@ NOINLINE static ReflectClassBaseObject* GetRuntimeTypeHelper(LPVOID __me, TypeHa
161161

162162
#define RETURN_CLASS_OBJECT(typeHandle, keepAlive) FC_INNER_RETURN(ReflectClassBaseObject*, GetRuntimeTypeHelper(__me, typeHandle, keepAlive))
163163

164-
NOINLINE ReflectModuleBaseObject* GetRuntimeModuleHelper(LPVOID __me, Module *pModule, OBJECTREF keepAlive)
165-
{
166-
FC_INNER_PROLOG_NO_ME_SETUP();
167-
if (pModule == NULL)
168-
return NULL;
169-
170-
OBJECTREF refModule = pModule->GetExposedObjectIfExists();
171-
if (refModule != NULL)
172-
return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
173-
174-
HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
175-
refModule = pModule->GetExposedObject();
176-
HELPER_METHOD_FRAME_END();
177-
178-
FC_INNER_EPILOG();
179-
return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
180-
}
181-
182-
NOINLINE AssemblyBaseObject* GetRuntimeAssemblyHelper(LPVOID __me, Assembly *pAssembly, OBJECTREF keepAlive)
183-
{
184-
FC_INNER_PROLOG_NO_ME_SETUP();
185-
if (pAssembly == NULL)
186-
return NULL;
187-
188-
OBJECTREF refAssembly = (pAssembly != NULL) ? pAssembly->GetExposedObjectIfExists() : NULL;
189-
190-
if(refAssembly != NULL)
191-
return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
192-
193-
HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
194-
refAssembly = pAssembly->GetExposedObject();
195-
HELPER_METHOD_FRAME_END();
196-
197-
FC_INNER_EPILOG();
198-
return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
199-
}
200-
201164
FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetRuntimeType, EnregisteredTypeHandle th)
202165
{
203166
FCALL_CONTRACT;
@@ -298,23 +261,35 @@ FCIMPL1(INT32, RuntimeTypeHandle::GetCorElementType, ReflectClassBaseObject *pTy
298261
}
299262
FCIMPLEND
300263

301-
FCIMPL1(AssemblyBaseObject*, RuntimeTypeHandle::GetAssembly, ReflectClassBaseObject *pTypeUNSAFE) {
302-
CONTRACTL {
303-
FCALL_CHECK;
304-
}
305-
CONTRACTL_END;
264+
FCIMPL1(AssemblyBaseObject*, RuntimeTypeHandle::GetAssemblyIfExists, ReflectClassBaseObject *pTypeUNSAFE)
265+
{
266+
FCALL_CONTRACT;
306267

307268
REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
308-
309269
if (refType == NULL)
310-
FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
270+
return NULL;
311271

312272
Assembly* pAssembly = refType->GetType().GetAssembly();
313-
314-
FC_RETURN_ASSEMBLY_OBJECT(pAssembly, refType);
273+
OBJECTREF refAssembly = pAssembly->GetExposedObjectIfExists();
274+
return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
315275
}
316276
FCIMPLEND
317277

278+
extern "C" void QCALLTYPE RuntimeTypeHandle_GetAssemblySlow(QCall::ObjectHandleOnStack type, QCall::ObjectHandleOnStack assembly)
279+
{
280+
QCALL_CONTRACT;
281+
282+
BEGIN_QCALL;
283+
GCX_COOP();
284+
285+
if (type.Get() == NULL)
286+
COMPlusThrow(kArgumentNullException, W("Arg_InvalidHandle"));
287+
288+
Assembly* pAssembly = ((REFLECTCLASSBASEREF)type.Get())->GetType().GetAssembly();
289+
assembly.Set(pAssembly->GetExposedObject());
290+
END_QCALL;
291+
}
292+
318293
FCIMPL1(FC_BOOL_RET, RuntimeFieldHandle::AcquiresContextFromThis, FieldDesc* pField)
319294
{
320295
CONTRACTL {
@@ -351,25 +326,35 @@ FCIMPL1(Object*, RuntimeFieldHandle::GetLoaderAllocator, FieldDesc* pField)
351326
}
352327
FCIMPLEND
353328

354-
FCIMPL1(ReflectModuleBaseObject*, RuntimeTypeHandle::GetModule, ReflectClassBaseObject *pTypeUNSAFE) {
355-
CONTRACTL {
356-
FCALL_CHECK;
357-
}
358-
CONTRACTL_END;
359-
360-
Module *result;
329+
FCIMPL1(ReflectModuleBaseObject*, RuntimeTypeHandle::GetModuleIfExists, ReflectClassBaseObject *pTypeUNSAFE)
330+
{
331+
FCALL_CONTRACT;
361332

362333
REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
363-
364334
if (refType == NULL)
365-
FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
366-
367-
result = refType->GetType().GetModule();
335+
return NULL;
368336

369-
FC_RETURN_MODULE_OBJECT(result, refType);
337+
Module* pModule = refType->GetType().GetModule();
338+
OBJECTREF refModule = pModule->GetExposedObjectIfExists();
339+
return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
370340
}
371341
FCIMPLEND
372342

343+
extern "C" void QCALLTYPE RuntimeTypeHandle_GetModuleSlow(QCall::ObjectHandleOnStack type, QCall::ObjectHandleOnStack module)
344+
{
345+
QCALL_CONTRACT;
346+
347+
BEGIN_QCALL;
348+
GCX_COOP();
349+
350+
if (type.Get() == NULL)
351+
COMPlusThrow(kArgumentNullException, W("Arg_InvalidHandle"));
352+
353+
Module* pModule = ((REFLECTCLASSBASEREF)type.Get())->GetType().GetModule();
354+
module.Set(pModule->GetExposedObject());
355+
END_QCALL;
356+
}
357+
373358
FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetBaseType, ReflectClassBaseObject *pTypeUNSAFE) {
374359
CONTRACTL {
375360
FCALL_CHECK;
@@ -2679,17 +2664,17 @@ FCIMPL2(FieldDesc*, RuntimeFieldHandle::GetStaticFieldForGenericType, FieldDesc
26792664
}
26802665
FCIMPLEND
26812666

2682-
FCIMPL1(ReflectModuleBaseObject*, AssemblyHandle::GetManifestModule, AssemblyBaseObject* pAssemblyUNSAFE) {
2667+
FCIMPL1(ReflectModuleBaseObject*, AssemblyHandle::GetManifestModule, AssemblyBaseObject* pAssemblyUNSAFE)
2668+
{
26832669
FCALL_CONTRACT;
26842670

26852671
ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2686-
26872672
if (refAssembly == NULL)
2688-
FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2689-
2690-
Assembly* currentAssembly = refAssembly->GetAssembly();
2673+
return NULL;
26912674

2692-
FC_RETURN_MODULE_OBJECT(currentAssembly->GetModule(), refAssembly);
2675+
Module* pModule = refAssembly->GetAssembly()->GetModule();
2676+
OBJECTREF refModule = pModule->GetExposedObjectIfExists();
2677+
return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
26932678
}
26942679
FCIMPLEND
26952680

@@ -2716,6 +2701,20 @@ FCIMPL1(INT32, AssemblyHandle::GetToken, AssemblyBaseObject* pAssemblyUNSAFE) {
27162701
}
27172702
FCIMPLEND
27182703

2704+
extern "C" void QCALLTYPE AssemblyHandle_GetManifestModuleSlow(QCall::ObjectHandleOnStack assembly, QCall::ObjectHandleOnStack module)
2705+
{
2706+
QCALL_CONTRACT;
2707+
2708+
BEGIN_QCALL;
2709+
GCX_COOP();
2710+
2711+
if (assembly.Get() == NULL)
2712+
COMPlusThrow(kArgumentNullException, W("Arg_InvalidHandle"));
2713+
2714+
Module* pModule = ((ASSEMBLYREF)assembly.Get())->GetAssembly()->GetModule();
2715+
module.Set(pModule->GetExposedObject());
2716+
END_QCALL;
2717+
}
27192718

27202719
extern "C" void QCALLTYPE ModuleHandle_GetPEKind(QCall::ModuleHandle pModule, DWORD* pdwPEKind, DWORD* pdwMachine)
27212720
{

0 commit comments

Comments
 (0)