@@ -1221,13 +1221,15 @@ CacheAllocator<CacheTrait>::findEviction(PoolId pid, ClassId cid) {
12211221 ++searchTries;
12221222
12231223 Item* candidate = itr.get ();
1224+ mmContainer.remove (itr);
1225+ itr.destroy ();
1226+
12241227 // for chained items, the ownership of the parent can change. We try to
12251228 // evict what we think as parent and see if the eviction of parent
12261229 // recycles the child we intend to.
1227- auto toReleaseHandle =
1228- itr->isChainedItem ()
1229- ? advanceIteratorAndTryEvictChainedItem (itr)
1230- : advanceIteratorAndTryEvictRegularItem (mmContainer, itr);
1230+ auto toReleaseHandle = candidate->isChainedItem ()
1231+ ? tryEvictChainedItem (*candidate)
1232+ : tryEvictRegularItem (mmContainer, *candidate);
12311233
12321234 if (toReleaseHandle) {
12331235 if (toReleaseHandle->hasChainedItem ()) {
@@ -1236,10 +1238,6 @@ CacheAllocator<CacheTrait>::findEviction(PoolId pid, ClassId cid) {
12361238 (*stats_.regularItemEvictions )[pid][cid].inc ();
12371239 }
12381240
1239- // Invalidate iterator since later on we may use this mmContainer
1240- // again, which cannot be done unless we drop this iterator
1241- itr.destroy ();
1242-
12431241 // we must be the last handle and for chained items, this will be
12441242 // the parent.
12451243 XDCHECK (toReleaseHandle.get () == candidate || candidate->isChainedItem ());
@@ -1263,11 +1261,9 @@ CacheAllocator<CacheTrait>::findEviction(PoolId pid, ClassId cid) {
12631261 }
12641262 }
12651263
1266- // If we destroyed the itr to possibly evict and failed, we restart
1267- // from the beginning again
1268- if (!itr) {
1269- itr.resetToBegin ();
1270- }
1264+ // Insert item back to the mmContainer if eviction failed.
1265+ mmContainer.add (*candidate);
1266+ itr.resetToBegin ();
12711267 }
12721268 return nullptr ;
12731269}
@@ -1322,19 +1318,17 @@ bool CacheAllocator<CacheTrait>::shouldWriteToNvmCacheExclusive(
13221318
13231319template <typename CacheTrait>
13241320typename CacheAllocator<CacheTrait>::WriteHandle
1325- CacheAllocator<CacheTrait>::advanceIteratorAndTryEvictRegularItem(
1326- MMContainer& mmContainer, EvictionIterator& itr ) {
1321+ CacheAllocator<CacheTrait>::tryEvictRegularItem(MMContainer& mmContainer,
1322+ Item& item ) {
13271323 // we should flush this to nvmcache if it is not already present in nvmcache
13281324 // and the item is not expired.
1329- Item& item = *itr;
13301325 const bool evictToNvmCache = shouldWriteToNvmCache (item);
13311326
13321327 auto token = evictToNvmCache ? nvmCache_->createPutToken (item.getKey ())
13331328 : typename NvmCacheT::PutToken{};
13341329 // record the in-flight eviciton. If not, we move on to next item to avoid
13351330 // stalling eviction.
13361331 if (evictToNvmCache && !token.isValid ()) {
1337- ++itr;
13381332 stats_.evictFailConcurrentFill .inc ();
13391333 return WriteHandle{};
13401334 }
@@ -1346,12 +1340,10 @@ CacheAllocator<CacheTrait>::advanceIteratorAndTryEvictRegularItem(
13461340 auto evictHandle = accessContainer_->removeIf (item, &itemEvictionPredicate);
13471341
13481342 if (!evictHandle) {
1349- ++itr;
13501343 stats_.evictFailAC .inc ();
13511344 return evictHandle;
13521345 }
13531346
1354- mmContainer.remove (itr);
13551347 XDCHECK_EQ (reinterpret_cast <uintptr_t >(evictHandle.get ()),
13561348 reinterpret_cast <uintptr_t >(&item));
13571349 XDCHECK (!evictHandle->isInMMContainer ());
@@ -1366,15 +1358,6 @@ CacheAllocator<CacheTrait>::advanceIteratorAndTryEvictRegularItem(
13661358 return WriteHandle{};
13671359 }
13681360
1369- // Invalidate iterator since later on if we are not evicting this
1370- // item, we may need to rely on the handle we created above to ensure
1371- // proper cleanup if the item's raw refcount has dropped to 0.
1372- // And since this item may be a parent item that has some child items
1373- // in this very same mmContainer, we need to make sure we drop this
1374- // exclusive iterator so we can gain access to it when we're cleaning
1375- // up the child items
1376- itr.destroy ();
1377-
13781361 // Ensure that there are no accessors after removing from the access
13791362 // container
13801363 XDCHECK (evictHandle->getRefCount () == 1 );
@@ -1388,12 +1371,10 @@ CacheAllocator<CacheTrait>::advanceIteratorAndTryEvictRegularItem(
13881371
13891372template <typename CacheTrait>
13901373typename CacheAllocator<CacheTrait>::WriteHandle
1391- CacheAllocator<CacheTrait>::advanceIteratorAndTryEvictChainedItem(
1392- EvictionIterator& itr) {
1393- XDCHECK (itr->isChainedItem ());
1374+ CacheAllocator<CacheTrait>::tryEvictChainedItem(Item& item) {
1375+ XDCHECK (item.isChainedItem ());
13941376
1395- ChainedItem* candidate = &itr->asChainedItem ();
1396- ++itr;
1377+ ChainedItem* candidate = &item.asChainedItem ();
13971378
13981379 // The parent could change at any point through transferChain. However, if
13991380 // that happens, we would realize that the releaseBackToAllocator return
@@ -1420,23 +1401,11 @@ CacheAllocator<CacheTrait>::advanceIteratorAndTryEvictChainedItem(
14201401 return parentHandle;
14211402 }
14221403
1423- // Invalidate iterator since later on we may use the mmContainer
1424- // associated with this iterator which cannot be done unless we
1425- // drop this iterator
1426- //
1427- // This must be done once we know the parent is not nullptr.
1428- // Since we can very well be the last holder of this parent item,
1429- // which may have a chained item that is linked in this MM container.
1430- itr.destroy ();
1431-
14321404 // Ensure we have the correct parent and we're the only user of the
14331405 // parent, then free it from access container. Otherwise, we abort
14341406 XDCHECK_EQ (reinterpret_cast <uintptr_t >(&parent),
14351407 reinterpret_cast <uintptr_t >(parentHandle.get ()));
14361408 XDCHECK_EQ (1u , parent.getRefCount ());
1437-
1438- removeFromMMContainer (*parentHandle);
1439-
14401409 XDCHECK (!parent.isInMMContainer ());
14411410 XDCHECK (!parent.isAccessible ());
14421411
0 commit comments