@@ -1202,13 +1202,15 @@ CacheAllocator<CacheTrait>::findEviction(PoolId pid, ClassId cid) {
12021202 ++searchTries;
12031203
12041204 Item* candidate = itr.get ();
1205+ mmContainer.remove (itr);
1206+ itr.destroy ();
1207+
12051208 // for chained items, the ownership of the parent can change. We try to
12061209 // evict what we think as parent and see if the eviction of parent
12071210 // recycles the child we intend to.
1208- auto toReleaseHandle =
1209- itr->isChainedItem ()
1210- ? advanceIteratorAndTryEvictChainedItem (itr)
1211- : advanceIteratorAndTryEvictRegularItem (mmContainer, itr);
1211+ auto toReleaseHandle = candidate->isChainedItem ()
1212+ ? tryEvictChainedItem (*candidate)
1213+ : tryEvictRegularItem (mmContainer, *candidate);
12121214
12131215 if (toReleaseHandle) {
12141216 if (toReleaseHandle->hasChainedItem ()) {
@@ -1217,10 +1219,6 @@ CacheAllocator<CacheTrait>::findEviction(PoolId pid, ClassId cid) {
12171219 (*stats_.regularItemEvictions )[pid][cid].inc ();
12181220 }
12191221
1220- // Invalidate iterator since later on we may use this mmContainer
1221- // again, which cannot be done unless we drop this iterator
1222- itr.destroy ();
1223-
12241222 // we must be the last handle and for chained items, this will be
12251223 // the parent.
12261224 XDCHECK (toReleaseHandle.get () == candidate || candidate->isChainedItem ());
@@ -1244,11 +1242,9 @@ CacheAllocator<CacheTrait>::findEviction(PoolId pid, ClassId cid) {
12441242 }
12451243 }
12461244
1247- // If we destroyed the itr to possibly evict and failed, we restart
1248- // from the beginning again
1249- if (!itr) {
1250- itr.resetToBegin ();
1251- }
1245+ // Insert item back to the mmContainer if eviction failed.
1246+ mmContainer.add (*candidate);
1247+ itr.resetToBegin ();
12521248 }
12531249 return nullptr ;
12541250}
@@ -1303,19 +1299,17 @@ bool CacheAllocator<CacheTrait>::shouldWriteToNvmCacheExclusive(
13031299
13041300template <typename CacheTrait>
13051301typename CacheAllocator<CacheTrait>::ItemHandle
1306- CacheAllocator<CacheTrait>::advanceIteratorAndTryEvictRegularItem(
1307- MMContainer& mmContainer, EvictionIterator& itr ) {
1302+ CacheAllocator<CacheTrait>::tryEvictRegularItem(MMContainer& mmContainer,
1303+ Item& item ) {
13081304 // we should flush this to nvmcache if it is not already present in nvmcache
13091305 // and the item is not expired.
1310- Item& item = *itr;
13111306 const bool evictToNvmCache = shouldWriteToNvmCache (item);
13121307
13131308 auto token = evictToNvmCache ? nvmCache_->createPutToken (item.getKey ())
13141309 : typename NvmCacheT::PutToken{};
13151310 // record the in-flight eviciton. If not, we move on to next item to avoid
13161311 // stalling eviction.
13171312 if (evictToNvmCache && !token.isValid ()) {
1318- ++itr;
13191313 stats_.evictFailConcurrentFill .inc ();
13201314 return ItemHandle{};
13211315 }
@@ -1327,12 +1321,10 @@ CacheAllocator<CacheTrait>::advanceIteratorAndTryEvictRegularItem(
13271321 auto evictHandle = accessContainer_->removeIf (item, &itemEvictionPredicate);
13281322
13291323 if (!evictHandle) {
1330- ++itr;
13311324 stats_.evictFailAC .inc ();
13321325 return evictHandle;
13331326 }
13341327
1335- mmContainer.remove (itr);
13361328 XDCHECK_EQ (reinterpret_cast <uintptr_t >(evictHandle.get ()),
13371329 reinterpret_cast <uintptr_t >(&item));
13381330 XDCHECK (!evictHandle->isInMMContainer ());
@@ -1347,15 +1339,6 @@ CacheAllocator<CacheTrait>::advanceIteratorAndTryEvictRegularItem(
13471339 return ItemHandle{};
13481340 }
13491341
1350- // Invalidate iterator since later on if we are not evicting this
1351- // item, we may need to rely on the handle we created above to ensure
1352- // proper cleanup if the item's raw refcount has dropped to 0.
1353- // And since this item may be a parent item that has some child items
1354- // in this very same mmContainer, we need to make sure we drop this
1355- // exclusive iterator so we can gain access to it when we're cleaning
1356- // up the child items
1357- itr.destroy ();
1358-
13591342 // Ensure that there are no accessors after removing from the access
13601343 // container
13611344 XDCHECK (evictHandle->getRefCount () == 1 );
@@ -1369,12 +1352,10 @@ CacheAllocator<CacheTrait>::advanceIteratorAndTryEvictRegularItem(
13691352
13701353template <typename CacheTrait>
13711354typename CacheAllocator<CacheTrait>::ItemHandle
1372- CacheAllocator<CacheTrait>::advanceIteratorAndTryEvictChainedItem(
1373- EvictionIterator& itr) {
1374- XDCHECK (itr->isChainedItem ());
1355+ CacheAllocator<CacheTrait>::tryEvictChainedItem(Item& item) {
1356+ XDCHECK (item.isChainedItem ());
13751357
1376- ChainedItem* candidate = &itr->asChainedItem ();
1377- ++itr;
1358+ ChainedItem* candidate = &item.asChainedItem ();
13781359
13791360 // The parent could change at any point through transferChain. However, if
13801361 // that happens, we would realize that the releaseBackToAllocator return
@@ -1401,23 +1382,11 @@ CacheAllocator<CacheTrait>::advanceIteratorAndTryEvictChainedItem(
14011382 return parentHandle;
14021383 }
14031384
1404- // Invalidate iterator since later on we may use the mmContainer
1405- // associated with this iterator which cannot be done unless we
1406- // drop this iterator
1407- //
1408- // This must be done once we know the parent is not nullptr.
1409- // Since we can very well be the last holder of this parent item,
1410- // which may have a chained item that is linked in this MM container.
1411- itr.destroy ();
1412-
14131385 // Ensure we have the correct parent and we're the only user of the
14141386 // parent, then free it from access container. Otherwise, we abort
14151387 XDCHECK_EQ (reinterpret_cast <uintptr_t >(&parent),
14161388 reinterpret_cast <uintptr_t >(parentHandle.get ()));
14171389 XDCHECK_EQ (1u , parent.getRefCount ());
1418-
1419- removeFromMMContainer (*parentHandle);
1420-
14211390 XDCHECK (!parent.isInMMContainer ());
14221391 XDCHECK (!parent.isAccessible ());
14231392
0 commit comments