Index: /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 38955)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 38956)
@@ -958,5 +958,7 @@
          */
         pMap = (PPGMCHUNKR3MAP)RTAvlU32Get(&pVM->pgm.s.ChunkR3Map.pTree, idChunk);
-        if (!pMap)
+        if (pMap)
+            pMap->iLastUsed = pVM->pgm.s.ChunkR3Map.iNow;
+        else
         {
 # ifdef IN_RING0
@@ -977,5 +979,4 @@
         pTlbe->idChunk = idChunk;
         pTlbe->pChunk = pMap;
-        pMap->iAge = 0;
     }
 
@@ -1074,5 +1075,8 @@
         pMap = (PPGMCHUNKR3MAP)RTAvlU32Get(&pVM->pgm.s.ChunkR3Map.pTree, idChunk);
         if (pMap)
+        {
             AssertPtr(pMap->pv);
+            pMap->iLastUsed = pVM->pgm.s.ChunkR3Map.iNow;
+        }
         else
         {
@@ -1095,5 +1099,4 @@
         pTlbe->idChunk = idChunk;
         pTlbe->pChunk = pMap;
-        pMap->iAge = 0;
     }
 
@@ -1865,5 +1868,4 @@
         Assert(pMap->cRefs >= 1);
         pMap->cRefs--;
-        pMap->iAge = 0;
     }
     pgmUnlock(pVM);
Index: /trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp	(revision 38955)
+++ /trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp	(revision 38956)
@@ -3703,50 +3703,13 @@
     /* Age compression - ASSUMES iNow == 4. */
     PPGMCHUNKR3MAP pChunk = (PPGMCHUNKR3MAP)pNode;
-    if (pChunk->iAge >= UINT32_C(0xffffff00))
-        pChunk->iAge = 3;
-    else if (pChunk->iAge >= UINT32_C(0xfffff000))
-        pChunk->iAge = 2;
-    else if (pChunk->iAge)
-        pChunk->iAge = 1;
-    else /* iAge = 0 */
-        pChunk->iAge = 4;
+    if (pChunk->iLastUsed >= UINT32_C(0xffffff00))
+        pChunk->iLastUsed = 3;
+    else if (pChunk->iLastUsed >= UINT32_C(0xfffff000))
+        pChunk->iLastUsed = 2;
+    else if (pChunk->iLastUsed)
+        pChunk->iLastUsed = 1;
+    else /* iLastUsed = 0 */
+        pChunk->iLastUsed = 4;
     return 0;
-}
-
-
-/**
- * Tree enumeration callback that updates the chunks that have
- * been used since the last
- */
-static DECLCALLBACK(int) pgmR3PhysChunkAgeingCallback(PAVLU32NODECORE pNode, void *pvUser)
-{
-    PPGMCHUNKR3MAP pChunk = (PPGMCHUNKR3MAP)pNode;
-    if (!pChunk->iAge)
-    {
-        PVM pVM = (PVM)pvUser;
-        pChunk->iAge = pVM->pgm.s.ChunkR3Map.iNow;
-    }
-    return 0;
-}
-
-
-/**
- * Performs ageing of the ring-3 chunk mappings.
- *
- * @param   pVM         The VM handle.
- */
-VMMR3DECL(void) PGMR3PhysChunkAgeing(PVM pVM)
-{
-    pgmLock(pVM);
-    pVM->pgm.s.ChunkR3Map.AgeingCountdown = RT_MIN(pVM->pgm.s.ChunkR3Map.cMax / 4, 1024);
-    pVM->pgm.s.ChunkR3Map.iNow++;
-    if (pVM->pgm.s.ChunkR3Map.iNow == 0)
-    {
-        pVM->pgm.s.ChunkR3Map.iNow = 4;
-        RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkAgeingRolloverCallback, pVM);
-    }
-    else
-        RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkAgeingCallback, pVM);
-    pgmUnlock(pVM);
 }
 
@@ -3759,5 +3722,4 @@
     PVM                 pVM;            /**< The VM handle. */
     PPGMCHUNKR3MAP      pChunk;         /**< The chunk to unmap. */
-    uint32_t            iLastAge;       /**< Highest age found so far. */
 } PGMR3PHYSCHUNKUNMAPCB, *PPGMR3PHYSCHUNKUNMAPCB;
 
@@ -3773,11 +3735,12 @@
 
     /*
-     * Check for locks and age.
+     * Check for locks and compare when last used.
      */
     if (pChunk->cRefs)
         return 0;
-    if (!pChunk->iAge)
+    if (pChunk->cPermRefs)
         return 0;
-    if (pArg->iLastAge >= pChunk->iAge)
+    if (   pArg->pChunk
+        && pChunk->iLastUsed >= pArg->pChunk->iLastUsed)
         return 0;
 
@@ -3804,6 +3767,5 @@
             return 0;
 
-    pArg->pChunk   = pChunk;
-    pArg->iLastAge = pChunk->iAge;
+    pArg->pChunk = pChunk;
     return 0;
 }
@@ -3824,21 +3786,10 @@
 
     /*
-     * Do tree ageing first?
-     */
-    if (pVM->pgm.s.ChunkR3Map.AgeingCountdown-- == 0)
-    {
-        STAM_PROFILE_START(&pVM->pgm.s.CTX_SUFF(pStats)->StatChunkAging, a);
-        PGMR3PhysChunkAgeing(pVM);
-        STAM_PROFILE_STOP(&pVM->pgm.s.CTX_SUFF(pStats)->StatChunkAging, a);
-    }
-
-    /*
      * Enumerate the age tree starting with the left most node.
      */
     STAM_PROFILE_START(&pVM->pgm.s.CTX_SUFF(pStats)->StatChunkFindCandidate, a);
     PGMR3PHYSCHUNKUNMAPCB Args;
-    Args.pVM      = pVM;
-    Args.pChunk   = NULL;
-    Args.iLastAge = 0;
+    Args.pVM    = pVM;
+    Args.pChunk = NULL;
     RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkUnmapCandidateCallback, &Args);
     Assert(Args.pChunk);
@@ -3983,4 +3934,14 @@
 
     /*
+     * Move the chunk time forward.
+     */
+    pVM->pgm.s.ChunkR3Map.iNow++;
+    if (pVM->pgm.s.ChunkR3Map.iNow == 0)
+    {
+        pVM->pgm.s.ChunkR3Map.iNow = 4;
+        RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkAgeingRolloverCallback, NULL);
+    }
+
+    /*
      * Allocate a new tracking structure first.
      */
@@ -3991,5 +3952,6 @@
 #endif
     AssertReturn(pChunk, VERR_NO_MEMORY);
-    pChunk->Core.Key = idChunk;
+    pChunk->Core.Key  = idChunk;
+    pChunk->iLastUsed = pVM->pgm.s.ChunkR3Map.iNow;
 
     /*
@@ -3998,7 +3960,7 @@
     GMMMAPUNMAPCHUNKREQ Req;
     Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
-    Req.Hdr.cbReq = sizeof(Req);
-    Req.pvR3 = NULL;
-    Req.idChunkMap = idChunk;
+    Req.Hdr.cbReq    = sizeof(Req);
+    Req.pvR3         = NULL;
+    Req.idChunkMap   = idChunk;
     Req.idChunkUnmap = NIL_GMM_CHUNKID;
 
@@ -4009,4 +3971,6 @@
     if (RT_SUCCESS(rc))
     {
+        pChunk->pv = Req.pvR3;
+
         /*
          * If we're running out of virtual address space, then we should
@@ -4053,7 +4017,5 @@
          * the chunk we're going to return isn't unmapped by accident.
          */
-        /* insert the new one. */
         AssertPtr(Req.pvR3);
-        pChunk->pv = Req.pvR3;
         bool fRc = RTAvlU32Insert(&pVM->pgm.s.ChunkR3Map.pTree, &pChunk->Core);
         AssertRelease(fRc);
Index: /trunk/src/VBox/VMM/include/PGMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/PGMInternal.h	(revision 38955)
+++ /trunk/src/VBox/VMM/include/PGMInternal.h	(revision 38956)
@@ -1620,6 +1620,7 @@
     /** The key is the chunk id. */
     AVLU32NODECORE                      Core;
-    /** The current age thingy. */
-    uint32_t                            iAge;
+    /** The time (ChunkR3Map.iNow) this chunk was last used.  Used for unmap
+     *  selection. */
+    uint32_t                            iLastUsed;
     /** The current reference count. */
     uint32_t volatile                   cRefs;
@@ -3174,5 +3175,5 @@
 #endif
 #if HC_ARCH_BITS == 32
-        uint32_t                    u32Alignment;
+        uint32_t                    u32Alignment0;
 #endif
         /** The chunk mapping TLB. */
@@ -3183,8 +3184,8 @@
          * @cfgm    PGM/MaxRing3Chunks */
         uint32_t                    cMax;
-        /** The current time. */
+        /** The current time.  This is incremented whenever a chunk is inserted. */
         uint32_t                    iNow;
-        /** Number of pgmR3PhysChunkFindUnmapCandidate calls left to the next ageing. */
-        uint32_t                    AgeingCountdown;
+        /** Alignment padding. */
+        uint32_t                    u32Alignment1;
     } ChunkR3Map;
 
Index: /trunk/src/VBox/VMM/testcase/tstVMStructRC.cpp
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstVMStructRC.cpp	(revision 38955)
+++ /trunk/src/VBox/VMM/testcase/tstVMStructRC.cpp	(revision 38956)
@@ -610,5 +610,4 @@
     GEN_CHECK_OFF(PGM, ChunkR3Map.cMax);
     GEN_CHECK_OFF(PGM, ChunkR3Map.iNow);
-    GEN_CHECK_OFF(PGM, ChunkR3Map.AgeingCountdown);
     GEN_CHECK_OFF(PGM, PhysTlbHC);
     GEN_CHECK_OFF(PGM, PhysTlbHC.aEntries[0]);
