Skip to content

Commit

Permalink
Make HandleStores contain their underlying bucket directly.
Browse files Browse the repository at this point in the history
  • Loading branch information
adityamandaleeka committed Apr 14, 2017
1 parent c9914b7 commit 0bb12f6
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 68 deletions.
35 changes: 25 additions & 10 deletions src/gc/gchandletable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,35 @@ IGCHandleManager* CreateGCHandleManager()

void GCHandleStore::Uproot()
{
Ref_RemoveHandleTableBucket(_underlyingBucket);
Ref_RemoveHandleTableBucket(&_underlyingBucket);
}

bool GCHandleStore::ContainsHandle(OBJECTHANDLE handle)
{
return _underlyingBucket->Contains(handle);
return _underlyingBucket.Contains(handle);
}

OBJECTHANDLE GCHandleStore::CreateHandleOfType(Object* object, int type)
{
HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()];
HHANDLETABLE handletable = _underlyingBucket.pTable[GetCurrentThreadHomeHeapNumber()];
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
}

OBJECTHANDLE GCHandleStore::CreateHandleOfType(Object* object, int type, int heapToAffinitizeTo)
{
HHANDLETABLE handletable = _underlyingBucket->pTable[heapToAffinitizeTo];
HHANDLETABLE handletable = _underlyingBucket.pTable[heapToAffinitizeTo];
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
}

OBJECTHANDLE GCHandleStore::CreateHandleWithExtraInfo(Object* object, int type, void* pExtraInfo)
{
HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()];
HHANDLETABLE handletable = _underlyingBucket.pTable[GetCurrentThreadHomeHeapNumber()];
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object), reinterpret_cast<uintptr_t>(pExtraInfo));
}

OBJECTHANDLE GCHandleStore::CreateDependentHandle(Object* primary, Object* secondary)
{
HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()];
HHANDLETABLE handletable = _underlyingBucket.pTable[GetCurrentThreadHomeHeapNumber()];
OBJECTHANDLE handle = ::HndCreateHandle(handletable, HNDTYPE_DEPENDENT, ObjectToOBJECTREF(primary));
::SetDependentHandleSecondary(handle, ObjectToOBJECTREF(secondary));

Expand All @@ -54,7 +54,7 @@ OBJECTHANDLE GCHandleStore::CreateDependentHandle(Object* primary, Object* secon

GCHandleStore::~GCHandleStore()
{
Ref_DestroyHandleTableBucket(_underlyingBucket);
::Ref_DestroyHandleTableBucket(&_underlyingBucket);
}

bool GCHandleManager::Initialize()
Expand All @@ -64,7 +64,12 @@ bool GCHandleManager::Initialize()

void GCHandleManager::Shutdown()
{
Ref_Shutdown();
if (g_gcGlobalHandleStore != nullptr)
{
DestroyHandleStore(g_gcGlobalHandleStore);
}

::Ref_Shutdown();
}

IGCHandleStore* GCHandleManager::GetGlobalHandleStore()
Expand All @@ -75,8 +80,18 @@ IGCHandleStore* GCHandleManager::GetGlobalHandleStore()
IGCHandleStore* GCHandleManager::CreateHandleStore(void* context)
{
#ifndef FEATURE_REDHAWK
HandleTableBucket* newBucket = ::Ref_CreateHandleTableBucket(ADIndex((DWORD)(uintptr_t)context));
return new (nothrow) GCHandleStore(newBucket);
GCHandleStore* store = new (nothrow) GCHandleStore();
if (store == nullptr)
return nullptr;

bool success = ::Ref_InitializeHandleTableBucket(&store->_underlyingBucket, context);
if (!success)
{
delete store;
return nullptr;
}

return store;
#else
assert("CreateHandleStore is not implemented when FEATURE_REDHAWK is defined!");
return nullptr;
Expand Down
7 changes: 1 addition & 6 deletions src/gc/gchandletableimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
class GCHandleStore : public IGCHandleStore
{
public:
GCHandleStore(HandleTableBucket *bucket)
: _underlyingBucket(bucket)
{ }

virtual void Uproot();

virtual bool ContainsHandle(OBJECTHANDLE handle);
Expand All @@ -29,8 +25,7 @@ class GCHandleStore : public IGCHandleStore

virtual ~GCHandleStore();

private:
HandleTableBucket* _underlyingBucket;
HandleTableBucket _underlyingBucket;
};

extern GCHandleStore* g_gcGlobalHandleStore;
Expand Down
113 changes: 62 additions & 51 deletions src/gc/objecthandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,59 +629,62 @@ bool Ref_Initialize()
if (pBuckets == NULL)
return false;

ZeroMemory(pBuckets,
INITIAL_HANDLE_TABLE_ARRAY_SIZE * sizeof (HandleTableBucket *));
ZeroMemory(pBuckets, INITIAL_HANDLE_TABLE_ARRAY_SIZE * sizeof (HandleTableBucket *));

// Crate the first bucket
HandleTableBucket * pBucket = new (nothrow) HandleTableBucket;
if (pBucket != NULL)
g_gcGlobalHandleStore = new (nothrow) GCHandleStore();
if (g_gcGlobalHandleStore == NULL)
{
pBucket->HandleTableIndex = 0;
delete[] pBuckets;
return false;
}

int n_slots = getNumberOfSlots();
// Initialize the bucket in the global handle store
HandleTableBucket* pBucket = &g_gcGlobalHandleStore->_underlyingBucket;

HandleTableBucketHolder bucketHolder(pBucket, n_slots);
pBucket->HandleTableIndex = 0;

// create the handle table set for the first bucket
pBucket->pTable = new (nothrow) HHANDLETABLE[n_slots];
if (pBucket->pTable == NULL)
goto CleanupAndFail;
int n_slots = getNumberOfSlots();

ZeroMemory(pBucket->pTable,
n_slots * sizeof(HHANDLETABLE));
for (int uCPUindex = 0; uCPUindex < n_slots; uCPUindex++)
{
pBucket->pTable[uCPUindex] = HndCreateHandleTable(s_rgTypeFlags, _countof(s_rgTypeFlags), ADIndex(1));
if (pBucket->pTable[uCPUindex] == NULL)
goto CleanupAndFail;
HandleTableBucketHolder bucketHolder(pBucket, n_slots);

HndSetHandleTableIndex(pBucket->pTable[uCPUindex], 0);
}
// create the handle table set for the first bucket
pBucket->pTable = new (nothrow) HHANDLETABLE[n_slots];
if (pBucket->pTable == NULL)
goto CleanupAndFail;

pBuckets[0] = pBucket;
bucketHolder.SuppressRelease();
ZeroMemory(pBucket->pTable,
n_slots * sizeof(HHANDLETABLE));
for (int uCPUindex = 0; uCPUindex < n_slots; uCPUindex++)
{
pBucket->pTable[uCPUindex] = HndCreateHandleTable(s_rgTypeFlags, _countof(s_rgTypeFlags), ADIndex(1));
if (pBucket->pTable[uCPUindex] == NULL)
goto CleanupAndFail;

g_HandleTableMap.pBuckets = pBuckets;
g_HandleTableMap.dwMaxIndex = INITIAL_HANDLE_TABLE_ARRAY_SIZE;
g_HandleTableMap.pNext = NULL;
HndSetHandleTableIndex(pBucket->pTable[uCPUindex], 0);
}

g_gcGlobalHandleStore = new (nothrow) GCHandleStore(g_HandleTableMap.pBuckets[0]);
if (g_gcGlobalHandleStore == NULL)
goto CleanupAndFail;
pBuckets[0] = pBucket;
bucketHolder.SuppressRelease();

// Allocate contexts used during dependent handle promotion scanning. There's one of these for every GC
// heap since they're scanned in parallel.
g_pDependentHandleContexts = new (nothrow) DhContext[n_slots];
if (g_pDependentHandleContexts == NULL)
goto CleanupAndFail;
g_HandleTableMap.pBuckets = pBuckets;
g_HandleTableMap.dwMaxIndex = INITIAL_HANDLE_TABLE_ARRAY_SIZE;
g_HandleTableMap.pNext = NULL;

return true;
}
// Allocate contexts used during dependent handle promotion scanning. There's one of these for every GC
// heap since they're scanned in parallel.
g_pDependentHandleContexts = new (nothrow) DhContext[n_slots];
if (g_pDependentHandleContexts == NULL)
goto CleanupAndFail;

return true;

CleanupAndFail:
if (pBuckets != NULL)
delete[] pBuckets;

if (g_gcGlobalHandleStore != NULL)
delete g_gcGlobalHandleStore;

return false;
}

Expand All @@ -701,9 +704,6 @@ void Ref_Shutdown()
// don't destroy any of the indexed handle tables; they should
// be destroyed externally.

// destroy the global handle table bucket tables
Ref_DestroyHandleTableBucket(g_HandleTableMap.pBuckets[0]);

// destroy the handle table bucket array
HandleTableMap *walk = &g_HandleTableMap;
while (walk) {
Expand All @@ -721,9 +721,22 @@ void Ref_Shutdown()
}

#ifndef FEATURE_REDHAWK
// ATTENTION: interface changed
// Note: this function called only from AppDomain::Init()
HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex)
HandleTableBucket* Ref_CreateHandleTableBucket(void* context)
{
HandleTableBucket* result = new (nothrow) HandleTableBucket();
if (result == nullptr)
return nullptr;

if (!Ref_InitializeHandleTableBucket(result, context))
{
delete result;
return nullptr;
}

return result;
}

bool Ref_InitializeHandleTableBucket(HandleTableBucket* bucket, void* context)
{
CONTRACTL
{
Expand All @@ -733,26 +746,24 @@ HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex)
}
CONTRACTL_END;

HandleTableBucket *result = NULL;
HandleTableMap *walk;

walk = &g_HandleTableMap;
HandleTableBucket *result = bucket;
HandleTableMap *walk = &g_HandleTableMap;

HandleTableMap *last = NULL;
uint32_t offset = 0;

result = new HandleTableBucket;
result->pTable = NULL;

// create handle table set for the bucket
int n_slots = getNumberOfSlots();

HandleTableBucketHolder bucketHolder(result, n_slots);

result->pTable = new HHANDLETABLE [ n_slots ];
ZeroMemory(result->pTable, n_slots * sizeof (HHANDLETABLE));
result->pTable = new HHANDLETABLE[n_slots];
ZeroMemory(result->pTable, n_slots * sizeof(HHANDLETABLE));

for (int uCPUindex=0; uCPUindex < n_slots; uCPUindex++) {
result->pTable[uCPUindex] = HndCreateHandleTable(s_rgTypeFlags, _countof(s_rgTypeFlags), uADIndex);
result->pTable[uCPUindex] = HndCreateHandleTable(s_rgTypeFlags, _countof(s_rgTypeFlags), ADIndex((DWORD)(uintptr_t)context));
if (!result->pTable[uCPUindex])
COMPlusThrowOM();
}
Expand All @@ -769,7 +780,7 @@ HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex)
if (Interlocked::CompareExchangePointer(&walk->pBuckets[i], result, NULL) == 0) {
// Get a free slot.
bucketHolder.SuppressRelease();
return result;
return true;
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/gc/objecthandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ typedef Holder<OBJECTHANDLE,DoNothing<OBJECTHANDLE>,ResetOBJECTHANDLE> ObjectInH
*/
bool Ref_Initialize();
void Ref_Shutdown();
HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex);
HandleTableBucket* Ref_CreateHandleTableBucket(void* context);
bool Ref_InitializeHandleTableBucket(HandleTableBucket* bucket, void* context);
BOOL Ref_HandleAsyncPinHandles();
void Ref_RelocateAsyncPinHandles(HandleTableBucket *pSource, HandleTableBucket *pTarget);
void Ref_RemoveHandleTableBucket(HandleTableBucket *pBucket);
Expand Down

0 comments on commit 0bb12f6

Please sign in to comment.