Skip to content
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

[WIP] Adjust dynamic static variables to need less code #73185

Closed
wants to merge 4 commits into from
Closed
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 @@ -543,16 +543,28 @@ internal unsafe struct MethodTable

private const int ParentMethodTableOffset = 0x10 + DebugClassNamePtr;

private const int DebugLastVerifedGCCnt = // adjust for m_dwLastVerifedGCCnt
#if DEBUG
#if TARGET_64BIT
8
#else
4
#endif
#else
0
#endif
;

#if TARGET_64BIT
private const int ElementTypeOffset = 0x30 + DebugClassNamePtr;
private const int ElementTypeOffset = 0x38 + DebugClassNamePtr + DebugLastVerifedGCCnt;
#else
private const int ElementTypeOffset = 0x20 + DebugClassNamePtr;
private const int ElementTypeOffset = 0x24 + DebugClassNamePtr + DebugLastVerifedGCCnt;
#endif

#if TARGET_64BIT
private const int InterfaceMapOffset = 0x38 + DebugClassNamePtr;
private const int InterfaceMapOffset = 0x40 + DebugClassNamePtr + DebugLastVerifedGCCnt;
#else
private const int InterfaceMapOffset = 0x24 + DebugClassNamePtr;
private const int InterfaceMapOffset = 0x28 + DebugClassNamePtr + DebugLastVerifedGCCnt;
#endif

public bool HasComponentSize
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/vm/amd64/asmconstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,18 +163,18 @@ ASMCONSTANTS_C_ASSERT(OFFSETOF__MethodTable__m_wNumInterfaces
ASMCONSTANTS_C_ASSERT(OFFSETOF__MethodTable__m_pParentMethodTable
== offsetof(MethodTable, m_pParentMethodTable));

#define OFFSETOF__MethodTable__m_pEEClass DBG_FRE(0x30, 0x28)
#define OFFSETOF__MethodTable__m_pEEClass DBG_FRE(0x40, 0x30)
ASMCONSTANTS_C_ASSERT(OFFSETOF__MethodTable__m_pEEClass
== offsetof(MethodTable, m_pEEClass));

#define METHODTABLE_OFFSET_VTABLE DBG_FRE(0x48, 0x40)
#define METHODTABLE_OFFSET_VTABLE DBG_FRE(0x58, 0x48)
ASMCONSTANTS_C_ASSERT(METHODTABLE_OFFSET_VTABLE == sizeof(MethodTable));

#define OFFSETOF__MethodTable__m_ElementType DBG_FRE(0x38, 0x30)
#define OFFSETOF__MethodTable__m_ElementType DBG_FRE(0x48, 0x38)
ASMCONSTANTS_C_ASSERT(OFFSETOF__MethodTable__m_ElementType
== offsetof(MethodTable, m_pMultipurposeSlot1));

#define OFFSETOF__MethodTable__m_pInterfaceMap DBG_FRE(0x40, 0x38)
#define OFFSETOF__MethodTable__m_pInterfaceMap DBG_FRE(0x50, 0x40)
ASMCONSTANTS_C_ASSERT(OFFSETOF__MethodTable__m_pInterfaceMap
== offsetof(MethodTable, m_pMultipurposeSlot2));

Expand Down
151 changes: 49 additions & 102 deletions src/coreclr/vm/appdomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@

static const WCHAR DEFAULT_DOMAIN_FRIENDLY_NAME[] = W("DefaultDomain");

#define STATIC_OBJECT_TABLE_BUCKET_SIZE 1020

// Statics

SPTR_IMPL(AppDomain, AppDomain, m_pTheAppDomain);
Expand All @@ -109,7 +107,7 @@ CrstStatic SystemDomain::m_SystemDomainCrst;
CrstStatic SystemDomain::m_DelayedUnloadCrst;

// Constructor for the PinnedHeapHandleBucket class.
PinnedHeapHandleBucket::PinnedHeapHandleBucket(PinnedHeapHandleBucket *pNext, PTRARRAYREF pinnedHandleArrayObj, DWORD size, BaseDomain *pDomain)
PinnedHeapHandleBucket::PinnedHeapHandleBucket(PinnedHeapHandleBucket *pNext, PTRARRAYREF pinnedHandleArrayObj, DWORD size, LoaderAllocator *pLoaderAllocator)
: m_pNext(pNext)
, m_ArraySize(size)
, m_CurrentPos(0)
Expand All @@ -120,7 +118,7 @@ PinnedHeapHandleBucket::PinnedHeapHandleBucket(PinnedHeapHandleBucket *pNext, PT
THROWS;
GC_NOTRIGGER;
MODE_COOPERATIVE;
PRECONDITION(CheckPointer(pDomain));
PRECONDITION(CheckPointer(pLoaderAllocator));
INJECT_FAULT(COMPlusThrowOM(););
}
CONTRACTL_END;
Expand All @@ -130,10 +128,13 @@ PinnedHeapHandleBucket::PinnedHeapHandleBucket(PinnedHeapHandleBucket *pNext, PT
m_pArrayDataPtr = (OBJECTREF *)pinnedHandleArrayObj->GetDataPtr();

// Store the array in a strong handle to keep it alive.
m_hndHandleArray = pDomain->CreateStrongHandle((OBJECTREF)pinnedHandleArrayObj);
m_collectible = pLoaderAllocator->IsCollectible();
if (m_collectible)
m_hndHandleArray = GetAppDomain()->CreateDependentHandle(ObjectFromHandle(pLoaderAllocator->GetLoaderAllocatorObjectHandle()), (OBJECTREF)pinnedHandleArrayObj);
else
m_hndHandleArray = GetAppDomain()->CreateStrongHandle((OBJECTREF)pinnedHandleArrayObj);
}


// Destructor for the PinnedHeapHandleBucket class.
PinnedHeapHandleBucket::~PinnedHeapHandleBucket()
{
Expand All @@ -146,7 +147,15 @@ PinnedHeapHandleBucket::~PinnedHeapHandleBucket()

if (m_hndHandleArray)
{
DestroyStrongHandle(m_hndHandleArray);
if (m_collectible)
{
DestroyStrongHandle(m_hndHandleArray);
}
else
{
DestroyDependentHandle(m_hndHandleArray);
}

m_hndHandleArray = NULL;
}
}
Expand All @@ -164,8 +173,19 @@ OBJECTREF *PinnedHeapHandleBucket::AllocateHandles(DWORD nRequested)
CONTRACTL_END;

_ASSERTE(nRequested > 0 && nRequested <= GetNumRemainingHandles());
_ASSERTE(m_pArrayDataPtr == (OBJECTREF*)((PTRARRAYREF)ObjectFromHandle(m_hndHandleArray))->GetDataPtr());

#ifdef _DEBUG
OBJECTREF handleArrayObj;
if (m_collectible)
{
Object* handleArrayRawObj = GCHandleUtilities::GetGCHandleManager()->GetDependentHandleSecondary(m_hndHandleArray);
handleArrayObj = ObjectToOBJECTREF(handleArrayRawObj);
}
else
{
handleArrayObj = ObjectFromHandle(m_hndHandleArray);
}
_ASSERTE(m_pArrayDataPtr == (OBJECTREF*)((PTRARRAYREF)handleArrayObj)->GetDataPtr());
#endif
// Store the handles in the buffer that was passed in
OBJECTREF* ret = &m_pArrayDataPtr[m_CurrentPos];
m_CurrentPos += nRequested;
Expand Down Expand Up @@ -220,9 +240,9 @@ void PinnedHeapHandleBucket::EnumStaticGCRefs(promote_func* fn, ScanContext* sc)
#define MAX_BUCKETSIZE (16384 - 4)

// Constructor for the PinnedHeapHandleTable class.
PinnedHeapHandleTable::PinnedHeapHandleTable(BaseDomain *pDomain, DWORD InitialBucketSize)
PinnedHeapHandleTable::PinnedHeapHandleTable(LoaderAllocator *pLoaderAllocator, DWORD InitialBucketSize)
: m_pHead(NULL)
, m_pDomain(pDomain)
, m_pLoaderAllocator(pLoaderAllocator)
, m_NextBucketSize(InitialBucketSize)
, m_pFreeSearchHint(NULL)
, m_cEmbeddedFree(0)
Expand All @@ -232,7 +252,7 @@ PinnedHeapHandleTable::PinnedHeapHandleTable(BaseDomain *pDomain, DWORD InitialB
THROWS;
GC_TRIGGERS;
MODE_COOPERATIVE;
PRECONDITION(CheckPointer(pDomain));
PRECONDITION(CheckPointer(pLoaderAllocator));
INJECT_FAULT(COMPlusThrowOM(););
}
CONTRACTL_END;
Expand Down Expand Up @@ -364,7 +384,7 @@ OBJECTREF* PinnedHeapHandleTable::AllocateHandles(DWORD nRequested)
m_pHead->ConsumeRemaining();
}

m_pHead = new PinnedHeapHandleBucket(m_pHead, pinnedHandleArrayObj, newBucketSize, m_pDomain);
m_pHead = new PinnedHeapHandleBucket(m_pHead, pinnedHandleArrayObj, newBucketSize, m_pLoaderAllocator);

// we already computed nextBucketSize to be double the previous size above, but it is possible that
// other threads increased m_NextBucketSize while the lock was unheld. We want to ensure
Expand Down Expand Up @@ -576,9 +596,6 @@ BaseDomain::BaseDomain()

m_pDefaultBinder = NULL;

// Make sure the container is set to NULL so that it gets loaded when it is used.
m_pPinnedHeapHandleTable = NULL;

// Note that m_handleStore is overridden by app domains
m_handleStore = GCHandleUtilities::GetGCHandleManager()->GetGlobalHandleStore();

Expand Down Expand Up @@ -799,33 +816,7 @@ OBJECTREF* BaseDomain::AllocateObjRefPtrsInLargeTable(int nRequested, OBJECTREF*
}
CONTRACTL_END;

if (ppLazyAllocate && *ppLazyAllocate)
{
// Allocation already happened
return *ppLazyAllocate;
}

GCX_COOP();

// Make sure the large heap handle table is initialized.
if (!m_pPinnedHeapHandleTable)
InitPinnedHeapHandleTable();

// Allocate the handles.
OBJECTREF* result = m_pPinnedHeapHandleTable->AllocateHandles(nRequested);
if (ppLazyAllocate)
{
// race with other threads that might be doing the same concurrent allocation
if (InterlockedCompareExchangeT<OBJECTREF*>(ppLazyAllocate, result, NULL) != NULL)
{
// we lost the race, release our handles and use the handles from the
// winning thread
m_pPinnedHeapHandleTable->ReleaseHandles(result, nRequested);
result = *ppLazyAllocate;
}
}

return result;
return GetLoaderAllocator()->AllocateObjRefPtrsInLargeTable(nRequested, ppLazyAllocate);
}

#endif // !DACCESS_COMPILE
Expand Down Expand Up @@ -899,26 +890,6 @@ STRINGREF *BaseDomain::GetOrInternString(STRINGREF *pString)
return GetLoaderAllocator()->GetOrInternString(pString);
}

void BaseDomain::InitPinnedHeapHandleTable()
{
CONTRACTL
{
THROWS;
GC_TRIGGERS;
MODE_COOPERATIVE;
INJECT_FAULT(COMPlusThrowOM(););
}
CONTRACTL_END;

PinnedHeapHandleTable* pTable = new PinnedHeapHandleTable(this, STATIC_OBJECT_TABLE_BUCKET_SIZE);
if(InterlockedCompareExchangeT<PinnedHeapHandleTable*>(&m_pPinnedHeapHandleTable, pTable, NULL) != NULL)
{
// another thread beat us to initializing the field, delete our copy
delete pTable;
}
}


//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
Expand Down Expand Up @@ -4229,64 +4200,43 @@ void DomainLocalModule::AllocateDynamicClass(MethodTable *pMT)
{
if (pDynamicStatics == NULL)
{
LoaderHeap * pLoaderAllocator = GetDomainAssembly()->GetLoaderAllocator()->GetHighFrequencyHeap();
LoaderAllocator * pLoaderAllocator = GetDomainAssembly()->GetLoaderAllocator();

SIZE_T dynamicEntrySize = DynamicEntry::GetOffsetOfDataBlob() + dwStaticBytes;

if (pMT->Collectible())
{
pDynamicStatics = (DynamicEntry*)(void*)pLoaderAllocator->AllocMem(S_SIZE_T(sizeof(CollectibleDynamicEntry)));
size_t alignment = TARGET_POINTER_SIZE;
#ifdef FEATURE_64BIT_ALIGNMENT
if (dwStaticBytes >= MAX_PRIMITIVE_FIELD_SIZE)
alignment = MAX_PRIMITIVE_FIELD_SIZE;
#endif
pDynamicStatics = (DynamicEntry*)pLoaderAllocator->AllocateDataOnGCHeapWithLoaderAllocatorLifetime(dynamicEntrySize, alignment);
}
else
{
SIZE_T dynamicEntrySize = DynamicEntry::GetOffsetOfDataBlob() + dwStaticBytes;

LoaderHeap * pLoaderHeap = pLoaderAllocator->GetHighFrequencyHeap();
#ifdef FEATURE_64BIT_ALIGNMENT
// Allocate memory with extra alignment only if it is really necessary
if (dwStaticBytes >= MAX_PRIMITIVE_FIELD_SIZE)
{
static_assert_no_msg(sizeof(NormalDynamicEntry) % MAX_PRIMITIVE_FIELD_SIZE == 0);
pDynamicStatics = (DynamicEntry*)(void*)pLoaderAllocator->AllocAlignedMem(dynamicEntrySize, MAX_PRIMITIVE_FIELD_SIZE);
pDynamicStatics = (DynamicEntry*)(void*)pLoaderHeap->AllocAlignedMem(dynamicEntrySize, MAX_PRIMITIVE_FIELD_SIZE);
}
else
#endif
pDynamicStatics = (DynamicEntry*)(void*)pLoaderAllocator->AllocMem(S_SIZE_T(dynamicEntrySize));
pDynamicStatics = (DynamicEntry*)(void*)pLoaderHeap->AllocMem(S_SIZE_T(dynamicEntrySize));
}

// Note: Memory allocated on loader heap is zero filled

m_pDynamicClassTable[dynamicEntryIDIndex].m_pDynamicEntry = pDynamicStatics;
}

if (pMT->Collectible() && (dwStaticBytes != 0))
{
GCX_COOP();
OBJECTREF nongcStaticsArray = NULL;
GCPROTECT_BEGIN(nongcStaticsArray);
#ifdef FEATURE_64BIT_ALIGNMENT
// Allocate memory with extra alignment only if it is really necessary
if (dwStaticBytes >= MAX_PRIMITIVE_FIELD_SIZE)
nongcStaticsArray = AllocatePrimitiveArray(ELEMENT_TYPE_I8, (dwStaticBytes + (sizeof(CLR_I8)-1)) / (sizeof(CLR_I8)));
else
#endif
nongcStaticsArray = AllocatePrimitiveArray(ELEMENT_TYPE_U1, dwStaticBytes);
((CollectibleDynamicEntry *)pDynamicStatics)->m_hNonGCStatics = GetDomainAssembly()->GetModule()->GetLoaderAllocator()->AllocateHandle(nongcStaticsArray);
GCPROTECT_END();
}
if (dwNumHandleStatics > 0)
{
if (!pMT->Collectible())
{
GetAppDomain()->AllocateStaticFieldObjRefPtrs(dwNumHandleStatics,
&((NormalDynamicEntry *)pDynamicStatics)->m_pGCStatics);
}
else
{
GCX_COOP();
OBJECTREF gcStaticsArray = NULL;
GCPROTECT_BEGIN(gcStaticsArray);
gcStaticsArray = AllocateObjectArray(dwNumHandleStatics, g_pObjectClass);
((CollectibleDynamicEntry *)pDynamicStatics)->m_hGCStatics = GetDomainAssembly()->GetModule()->GetLoaderAllocator()->AllocateHandle(gcStaticsArray);
GCPROTECT_END();
}
GetDomainAssembly()->GetModule()->GetLoaderAllocator()->AllocateStaticFieldObjRefPtrs(dwNumHandleStatics,
&((NormalDynamicEntry *)pDynamicStatics)->m_pGCStatics);
}
}
}
Expand Down Expand Up @@ -4591,10 +4541,7 @@ void AppDomain::EnumStaticGCRefs(promote_func* fn, ScanContext* sc)
GCHeapUtilities::IsServerHeap() &&
IsGCSpecialThread());

if (m_pPinnedHeapHandleTable != nullptr)
{
m_pPinnedHeapHandleTable->EnumStaticGCRefs(fn, sc);
}
GetLoaderAllocator()->EnumStaticGCRefs(fn, sc);

RETURN;
}
Expand Down
Loading