Skip to content

Commit a7eda3e

Browse files
Fix race condition in DacEnumerableHashTable::BaseFindNextEntryByHash (#75099)
1 parent 71adfb0 commit a7eda3e

File tree

1 file changed

+7
-9
lines changed

1 file changed

+7
-9
lines changed

src/coreclr/vm/dacenumerablehash.inl

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,8 @@ DPTR(VALUE) DacEnumerableHashTable<DAC_ENUM_HASH_ARGS>::BaseFindFirstEntryByHash
309309
// +2 to skip "length" and "next" slots
310310
DWORD dwBucket = iHash % cBuckets + SKIP_SPECIAL_SLOTS;
311311

312-
// Point at the first entry in the bucket chain which would contain any entries with the given hash code.
313-
PTR_VolatileEntry pEntry = curBuckets[dwBucket];
312+
// Point at the first entry in the bucket chain that stores entries with the given hash code.
313+
PTR_VolatileEntry pEntry = VolatileLoadWithoutBarrier(&curBuckets[dwBucket]);
314314

315315
// Walk the bucket chain one entry at a time.
316316
while (pEntry)
@@ -329,13 +329,13 @@ DPTR(VALUE) DacEnumerableHashTable<DAC_ENUM_HASH_ARGS>::BaseFindFirstEntryByHash
329329
}
330330

331331
// Move to the next entry in the chain.
332-
pEntry = pEntry->m_pNextEntry;
332+
pEntry = VolatileLoadWithoutBarrier(&pEntry->m_pNextEntry);
333333
}
334334

335335
// in a rare case if resize is in progress, look in the new table as well.
336336
// if existing entry is not in the old table, it must be in the new
337337
// since we unlink it from old only after linking into the new.
338-
// check for next table must hapen after we looked through the current.
338+
// check for next table must happen after we looked through the current.
339339
VolatileLoadBarrier();
340340
curBuckets = GetNext(curBuckets);
341341
} while (curBuckets != nullptr);
@@ -367,11 +367,9 @@ DPTR(VALUE) DacEnumerableHashTable<DAC_ENUM_HASH_ARGS>::BaseFindNextEntryByHash(
367367
PTR_VolatileEntry pVolatileEntry = dac_cast<PTR_VolatileEntry>(pContext->m_pEntry);
368368
iHash = pVolatileEntry->m_iHashValue;
369369

370-
// Iterate over the bucket chain.
371-
while (pVolatileEntry->m_pNextEntry)
370+
// Iterate over the rest ot the bucket chain.
371+
while ((pVolatileEntry = VolatileLoadWithoutBarrier(&pVolatileEntry->m_pNextEntry)) != nullptr)
372372
{
373-
// Advance to the next entry.
374-
pVolatileEntry = pVolatileEntry->m_pNextEntry;
375373
if (pVolatileEntry->m_iHashValue == iHash)
376374
{
377375
// Found a match on hash code. Update our find context to indicate where we got to and return
@@ -381,7 +379,7 @@ DPTR(VALUE) DacEnumerableHashTable<DAC_ENUM_HASH_ARGS>::BaseFindNextEntryByHash(
381379
}
382380
}
383381

384-
// check for next table must hapen after we looked through the current.
382+
// check for next table must happen after we looked through the current.
385383
VolatileLoadBarrier();
386384

387385
// in a case if resize is in progress, look in the new table as well.

0 commit comments

Comments
 (0)