Repository: dotnet/runtime
File: src/coreclr/debug/daccess/daccess.cpp (C++)

Code before:
    }

    *pFetched = i;

    hr = mIteratorIndex < mList.GetCount() ? S_FALSE : S_OK;

    SOSHelperLeave();

    return hr;
}

void DacHandleWalker::WalkHandles()
{
    SUPPORTS_DAC;

    if (mEnumerated)
        return;

    mEnumerated = true;

    // The table slots are based on the number of GC heaps in the process.
    uint32_t max_slots = 1;

#ifdef FEATURE_SVR_GC
    if (GCHeapUtilities::IsServerHeap())
        max_slots = *g_gcDacGlobals->g_totalCpuCount;
#endif // FEATURE_SVR_GC

    DacHandleWalkerParam param(&mList);


    for (dac_handle_table_map *map = g_gcDacGlobals->handle_table_map; SUCCEEDED(param.Result) && map; map = map->pNext)
    {
        for (int i = 0; i < INITIAL_HANDLE_TABLE_ARRAY_SIZE && SUCCEEDED(param.Result); ++i)
        {
            if (map->pBuckets[i] != NULL)
            {
                for (uint32_t j = 0; j < max_slots && SUCCEEDED(param.Result); ++j)
                {
                    DPTR(dac_handle_table) hTable = map->pBuckets[i]->pTable[(int)j];
                    if (hTable)
                    {
                        // handleType is the integer from 1 -> HANDLE_MAX_INTERNAL_TYPES based on the requested handle kinds to walk.
                        UINT32 handleType = 0;
                        for (UINT32 mask = mTypeMask; mask; mask >>= 1, handleType++)
                        {
                            if (mask & 1)
                            {
                                PTR_AppDomain pDomain = AppDomain::GetCurrentDomain();
                                param.AppDomain = TO_CDADDR(pDomain.GetAddr());
                                param.Type = handleType;

Review comment (suggestion):
That being said - this feels brittle in the sense it's hardcoding policy again (the same thing that drifted here). There's not much to do here in the legacy dac I think - but adding a comment to getnumofslots pointing to the DAC use of the algorithm would be a good thing to do.

Code after:
    }

    *pFetched = i;

    hr = mIteratorIndex < mList.GetCount() ? S_FALSE : S_OK;

    SOSHelperLeave();

    return hr;
}

void DacHandleWalker::WalkHandles()
{
    SUPPORTS_DAC;

    if (mEnumerated)
        return;

    mEnumerated = true;

    // The GC sets the number of slots based on the number of processors. Prior to
    // DATAS, num_processors == GCHeapCount() for ServerGC. Unfortunately the GC DAC
    // contract didn't record the number of processors independently until minor
    // version 8 and DATAS was enabled prior to that. When using a standalone GC version
    // < 8 the DAC approximates the processor count as GCHeapCount() because we don't
    // have more accurate data to work with. This may cause handle enumeration to be
    // incomplete.
    uint32_t max_slots = 1;

#ifdef FEATURE_SVR_GC
    if (GCHeapUtilities::IsServerHeap())
    {
        if (g_gcDacGlobals->minor_version_number >= 8)
            max_slots = *g_gcDacGlobals->g_totalCpuCount;
        else
            max_slots = GCHeapCount();
    }
#endif // FEATURE_SVR_GC

    DacHandleWalkerParam param(&mList);


    for (dac_handle_table_map *map = g_gcDacGlobals->handle_table_map; SUCCEEDED(param.Result) && map; map = map->pNext)
    {
        for (int i = 0; i < INITIAL_HANDLE_TABLE_ARRAY_SIZE && SUCCEEDED(param.Result); ++i)
        {
            if (map->pBuckets[i] != NULL)
            {
                for (uint32_t j = 0; j < max_slots && SUCCEEDED(param.Result); ++j)
                {
                    DPTR(dac_handle_table) hTable = map->pBuckets[i]->pTable[(int)j];