-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Allocate RuntimeType objects on Frozen Object Heap #75573
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
9c15c1f
232033b
f63c941
841e9c7
f168d13
2f50121
3e6d3ba
c939027
c8512a9
bad7cc4
9d8526e
18e1cd4
a7fea6d
f2afedc
6a8cedf
677f94b
15bcad1
81bacbb
b5b7c98
608e6c9
be063b8
59af88b
a8e0786
1f9a348
2fd4384
8f2a767
b4b7128
a2ca5b1
fd099a2
64e7171
ac405a1
7ab7bd1
895e9f5
bcd47b1
c217579
253747e
ca6c69a
93ef525
7394e1e
f6055b9
57b1477
e9a396f
4fbb894
7476a68
bc2292b
7bf7e0e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -353,26 +353,31 @@ bool TypeHandle::IsManagedClassObjectPinned() const | |
| return !GetLoaderAllocator()->CanUnload() || IsFnPtrType(); | ||
| } | ||
|
|
||
| void TypeHandle::AllocateManagedClassObject(LoaderAllocator* allocator, RUNTIMETYPEHANDLE* pDest, TypeHandle type) | ||
| void TypeHandle::AllocateManagedClassObject(RUNTIMETYPEHANDLE* pDest) | ||
| { | ||
| REFLECTCLASSBASEREF refClass = NULL; | ||
|
|
||
| PTR_LoaderAllocator allocator = GetLoaderAllocator(); | ||
|
|
||
| if (!allocator->CanUnload()) | ||
| { | ||
| // Allocate RuntimeType on a frozen segment | ||
| // Take a lock here since we don't want to allocate redundant objects which won't be collected | ||
| CrstHolder exposedClassLock(AppDomain::GetMethodTableExposedClassObjectLock()); | ||
|
|
||
| if (*pDest == NULL) | ||
| { | ||
| // Allocate RuntimeType on a frozen segment | ||
| // Take a lock here since we don't want to allocate redundant objects which won't be collected | ||
|
|
||
| FrozenObjectHeapManager* foh = SystemDomain::GetFrozenObjectHeapManager(); | ||
| Object* obj = foh->TryAllocateObject(g_pRuntimeTypeClass, g_pRuntimeTypeClass->GetBaseSize()); | ||
| _ASSERTE(obj != NULL); | ||
| // Since objects are aligned we can use the lowest bit as a storage for "is pinned object" flag | ||
| _ASSERTE((((SSIZE_T)obj) & 1) == 0); | ||
| refClass = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(obj); | ||
| refClass->SetType(type); | ||
| *pDest = (RUNTIMETYPEHANDLE)obj; | ||
| refClass->SetType(*this); | ||
| RUNTIMETYPEHANDLE handle = (RUNTIMETYPEHANDLE)obj; | ||
| // Set the bit to 1 (we'll have to reset it before use) | ||
| handle |= 1; | ||
| *pDest = handle; | ||
| } | ||
| } | ||
| else | ||
|
|
@@ -381,9 +386,8 @@ void TypeHandle::AllocateManagedClassObject(LoaderAllocator* allocator, RUNTIMET | |
| refClass = (REFLECTCLASSBASEREF)AllocateObject(g_pRuntimeTypeClass); | ||
| refClass->SetKeepAlive(allocator->GetExposedObject()); | ||
| LOADERHANDLE exposedClassObjectHandle = allocator->AllocateHandle(refClass); | ||
| // Set the lowest bit, we use it GetPinnedManagedClassObjectIfExists as a fast detection of the unloadable context | ||
| exposedClassObjectHandle |= 1; | ||
| refClass->SetType(type); | ||
| _ASSERTE((exposedClassObjectHandle & 1) == 0); | ||
| refClass->SetType(*this); | ||
|
|
||
| // Let all threads fight over who wins using InterlockedCompareExchange. | ||
| // Only the winner can set m_ExposedClassObject from NULL. | ||
|
|
@@ -403,9 +407,10 @@ OBJECTREF TypeHandle::GetManagedClassObjectFromHandleFast(RUNTIMETYPEHANDLE hand | |
| // For a non-unloadable context, handle is expected to be either null (is not cached yet) | ||
| // or be a direct pointer to a frozen RuntimeType object | ||
|
|
||
| if (handle != NULL && (handle & 1) == 0) | ||
| if (handle & 1) | ||
| { | ||
| return (OBJECTREF)handle; | ||
| // Clear the "is pinned object" bit from the managed reference | ||
| return (OBJECTREF)((handle >> 1) << 1); // C++ compiler is expected to emit "and reg, mask" | ||
|
||
| } | ||
| return NULL; | ||
| } | ||
|
|
@@ -415,9 +420,10 @@ OBJECTREF TypeHandle::GetManagedClassObjectFromHandle(LoaderAllocator* allocator | |
| LIMITED_METHOD_CONTRACT; | ||
|
|
||
| // First, check if we have a cached reference to an effectively pinned (allocated on FOH) object | ||
| if (handle != NULL && (handle & 1) == 0) | ||
| if (handle & 1) | ||
| { | ||
| return (OBJECTREF)handle; | ||
| // Clear the "is pinned object" bit from the managed reference | ||
| return (OBJECTREF)((handle >> 1) << 1); // C++ compiler is expected to emit "and reg, mask" | ||
| } | ||
|
|
||
| OBJECTREF retVal; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.