Index: /trunk/include/VBox/vmm/stam.h
===================================================================
--- /trunk/include/VBox/vmm/stam.h	(revision 46492)
+++ /trunk/include/VBox/vmm/stam.h	(revision 46493)
@@ -1201,23 +1201,8 @@
                                         PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint,
                                         const char *pszDesc, const char *pszName, va_list args);
-VMMR3DECL(int)  STAMR3DeregisterU(PUVM pUVM, void *pvSample);
-VMMR3DECL(int)  STAMR3Deregister(PVM pVM, void *pvSample);
-
-/** @def STAM_REL_DEREG
- * Deregisters a statistics sample if statistics are enabled.
- *
- * @param   pVM         VM Handle.
- * @param   pvSample    Pointer to the sample.
- */
-#define STAM_REL_DEREG(pVM, pvSample) \
-    STAM_REL_STATS({ int rcStam = STAMR3Deregister(pVM, pvSample); AssertRC(rcStam); })
-/** @def STAM_DEREG
- * Deregisters a statistics sample if statistics are enabled.
- *
- * @param   pVM         VM Handle.
- * @param   pvSample    Pointer to the sample.
- */
-#define STAM_DEREG(pVM, pvSample) \
-    STAM_STATS({ STAM_REL_DEREG(pVM, pvSample); })
+VMMR3DECL(int)  STAMR3Deregister(PUVM pUVM, const char *pszPat);
+VMMR3DECL(int)  STAMR3DeregisterF(PUVM pUVM, const char *pszPatFmt, ...);
+VMMR3DECL(int)  STAMR3DeregisterV(PUVM pUVM, const char *pszPatFmt, va_list va);
+VMMR3DECL(int)  STAMR3DeregisterByAddr(PUVM pUVM, void *pvSample);
 
 VMMR3DECL(int)  STAMR3Reset(PUVM pUVM, const char *pszPat);
Index: /trunk/src/VBox/VMM/VMMR3/PATM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PATM.cpp	(revision 46492)
+++ /trunk/src/VBox/VMM/VMMR3/PATM.cpp	(revision 46493)
@@ -5631,21 +5631,6 @@
     if (PATM_STAT_INDEX_IS_VALID(pPatchRec->patch.uPatchIdx))
     {
-        STAMR3Deregister(pVM, &pPatchRec->patch);
-#ifndef DEBUG_sandervl
-        STAMR3Deregister(pVM, &pVM->patm.s.pStatsHC[pPatchRec->patch.uPatchIdx]);
-        STAMR3Deregister(pVM, &pPatchRec->patch.cbPatchBlockSize);
-        STAMR3Deregister(pVM, &pPatchRec->patch.cbPatchJump);
-        STAMR3Deregister(pVM, &pPatchRec->patch.cbPrivInstr);
-        STAMR3Deregister(pVM, &pPatchRec->patch.cCodeWrites);
-        STAMR3Deregister(pVM, &pPatchRec->patch.cInvalidWrites);
-        STAMR3Deregister(pVM, &pPatchRec->patch.cTraps);
-        STAMR3Deregister(pVM, &pPatchRec->patch.flags);
-        STAMR3Deregister(pVM, &pPatchRec->patch.nrJumpRecs);
-        STAMR3Deregister(pVM, &pPatchRec->patch.nrFixups);
-        STAMR3Deregister(pVM, &pPatchRec->patch.opcode);
-        STAMR3Deregister(pVM, &pPatchRec->patch.uState);
-        STAMR3Deregister(pVM, &pPatchRec->patch.uOldState);
-        STAMR3Deregister(pVM, &pPatchRec->patch.uOpMode);
-#endif
+        STAMR3DeregisterF(pVM->pUVM, "/PATM/Stats/Patch/0x%RRv", pPatchRec->patch.pPrivInstrGC);
+        STAMR3DeregisterF(pVM->pUVM, "/PATM/Stats/PatchBD/0x%RRv*", pPatchRec->patch.pPrivInstrGC);
     }
 #endif
@@ -5749,31 +5734,16 @@
     }
 
-    /** Note: quite ugly to enable/disable/remove/insert old and new patches, but there's no easy way around it. */
+    /* Note: quite ugly to enable/disable/remove/insert old and new patches, but there's no easy way around it. */
 
     rc = PATMR3DisablePatch(pVM, pInstrGC);
     AssertRC(rc);
 
-    /** Kick it out of the lookup tree to make sure PATMR3InstallPatch doesn't fail (hack alert) */
+    /* Kick it out of the lookup tree to make sure PATMR3InstallPatch doesn't fail (hack alert) */
     RTAvloU32Remove(&pVM->patm.s.PatchLookupTreeHC->PatchTree, pPatchRec->Core.Key);
 #ifdef VBOX_WITH_STATISTICS
     if (PATM_STAT_INDEX_IS_VALID(pPatchRec->patch.uPatchIdx))
     {
-        STAMR3Deregister(pVM, &pPatchRec->patch);
-#ifndef DEBUG_sandervl
-        STAMR3Deregister(pVM, &pVM->patm.s.pStatsHC[pPatchRec->patch.uPatchIdx]);
-        STAMR3Deregister(pVM, &pPatchRec->patch.cbPatchBlockSize);
-        STAMR3Deregister(pVM, &pPatchRec->patch.cbPatchJump);
-        STAMR3Deregister(pVM, &pPatchRec->patch.cbPrivInstr);
-        STAMR3Deregister(pVM, &pPatchRec->patch.cCodeWrites);
-        STAMR3Deregister(pVM, &pPatchRec->patch.cInvalidWrites);
-        STAMR3Deregister(pVM, &pPatchRec->patch.cTraps);
-        STAMR3Deregister(pVM, &pPatchRec->patch.flags);
-        STAMR3Deregister(pVM, &pPatchRec->patch.nrJumpRecs);
-        STAMR3Deregister(pVM, &pPatchRec->patch.nrFixups);
-        STAMR3Deregister(pVM, &pPatchRec->patch.opcode);
-        STAMR3Deregister(pVM, &pPatchRec->patch.uState);
-        STAMR3Deregister(pVM, &pPatchRec->patch.uOldState);
-        STAMR3Deregister(pVM, &pPatchRec->patch.uOpMode);
-#endif
+        STAMR3DeregisterF(pVM->pUVM, "/PATM/Stats/Patch/0x%RRv", pPatchRec->patch.pPrivInstrGC);
+        STAMR3DeregisterF(pVM->pUVM, "/PATM/Stats/PatchBD/0x%RRv*", pPatchRec->patch.pPrivInstrGC);
     }
 #endif
Index: /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp	(revision 46492)
+++ /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp	(revision 46493)
@@ -1049,6 +1049,5 @@
     pEndpoint->tsIntervalStartMs = RTTimeMilliTS();
 
-    for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesNs); i++)
-    {
+    for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesNs) && RT_SUCCESS(rc); i++)
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesNs[i], STAMTYPE_COUNTER,
                              STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
@@ -1056,52 +1055,27 @@
                              "/PDM/AsyncCompletion/File/%s/TaskRun1Ns-%u-%u",
                              RTPathFilename(pEndpoint->pszUri), i*100, i*100+100-1);
-        if (RT_FAILURE(rc))
-            break;
-    }
-
-    if (RT_SUCCESS(rc))
-    {
-        for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesUs); i++)
-        {
-            rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesUs[i], STAMTYPE_COUNTER,
-                                 STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
-                                 "Microsecond resolution runtime statistics",
-                                 "/PDM/AsyncCompletion/File/%s/TaskRun2MicroSec-%u-%u",
-                                 RTPathFilename(pEndpoint->pszUri), i*100, i*100+100-1);
-            if (RT_FAILURE(rc))
-                break;
-        }
-    }
-
-    if (RT_SUCCESS(rc))
-    {
-        for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++)
-        {
-            rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesMs[i], STAMTYPE_COUNTER,
-                                 STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
-                                 "Milliseconds resolution runtime statistics",
-                                 "/PDM/AsyncCompletion/File/%s/TaskRun3Ms-%u-%u",
-                                 RTPathFilename(pEndpoint->pszUri), i*100, i*100+100-1);
-            if (RT_FAILURE(rc))
-                break;
-        }
-    }
-
-    if (RT_SUCCESS(rc))
-    {
-        for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++)
-        {
-            rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesSec[i], STAMTYPE_COUNTER,
-                                 STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
-                                 "Second resolution runtime statistics",
-                                 "/PDM/AsyncCompletion/File/%s/TaskRun4Sec-%u-%u",
-                                 RTPathFilename(pEndpoint->pszUri), i*10, i*10+10-1);
-            if (RT_FAILURE(rc))
-                break;
-        }
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesUs) && RT_SUCCESS(rc); i++)
+        rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesUs[i], STAMTYPE_COUNTER,
+                             STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
+                             "Microsecond resolution runtime statistics",
+                             "/PDM/AsyncCompletion/File/%s/TaskRun2MicroSec-%u-%u",
+                             RTPathFilename(pEndpoint->pszUri), i*100, i*100+100-1);
+
+    for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs) && RT_SUCCESS(rc); i++)
+        rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesMs[i], STAMTYPE_COUNTER,
+                             STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
+                             "Milliseconds resolution runtime statistics",
+                             "/PDM/AsyncCompletion/File/%s/TaskRun3Ms-%u-%u",
+                             RTPathFilename(pEndpoint->pszUri), i*100, i*100+100-1);
+
+    for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs) && RT_SUCCESS(rc); i++)
+        rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesSec[i], STAMTYPE_COUNTER,
+                             STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
+                             "Second resolution runtime statistics",
+                             "/PDM/AsyncCompletion/File/%s/TaskRun4Sec-%u-%u",
+                             RTPathFilename(pEndpoint->pszUri), i*10, i*10+10-1);
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunOver100Sec, STAMTYPE_COUNTER,
                              STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
@@ -1109,8 +1083,6 @@
                              "/PDM/AsyncCompletion/File/%s/TaskRunSecGreater100Sec",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatIoOpsPerSec, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1118,8 +1090,6 @@
                              "/PDM/AsyncCompletion/File/%s/IoOpsPerSec",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatIoOpsStarted, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1127,8 +1097,6 @@
                              "/PDM/AsyncCompletion/File/%s/IoOpsStarted",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatIoOpsCompleted, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1136,8 +1104,6 @@
                              "/PDM/AsyncCompletion/File/%s/IoOpsCompleted",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSizeSmaller512, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1145,8 +1111,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqSizeSmaller512",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize512To1K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1154,8 +1118,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqSize512To1K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize1KTo2K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1163,8 +1125,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqSize1KTo2K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize2KTo4K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1172,8 +1132,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqSize2KTo4K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize4KTo8K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1181,8 +1139,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqSize4KTo8K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize8KTo16K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1190,8 +1146,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqSize8KTo16K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize16KTo32K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1199,8 +1153,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqSize16KTo32K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize32KTo64K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1208,8 +1160,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqSize32KTo64K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize64KTo128K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1217,8 +1167,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqSize64KTo128K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize128KTo256K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1226,8 +1174,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqSize128KTo256K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSize256KTo512K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1235,8 +1181,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqSize256KTo512K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqSizeOver512K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1244,8 +1188,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqSizeOver512K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqsUnaligned512, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1253,8 +1195,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqsUnaligned512",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqsUnaligned4K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1262,8 +1202,6 @@
                              "/PDM/AsyncCompletion/File/%s/ReqsUnaligned4K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
-
-    if (RT_SUCCESS(rc))
-    {
+
+    if (RT_SUCCESS(rc))
         rc = STAMR3RegisterF(pVM, &pEndpoint->StatReqsUnaligned8K, STAMTYPE_COUNTER,
                              STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
@@ -1271,5 +1209,4 @@
                              "/PDM/AsyncCompletion/File/%s/ReqsUnaligned8K",
                              RTPathFilename(pEndpoint->pszUri));
-    }
 
     return rc;
@@ -1285,35 +1222,6 @@
 static void pdmR3AsyncCompletionStatisticsDeregister(PPDMASYNCCOMPLETIONENDPOINT pEndpoint)
 {
-    PVM pVM = pEndpoint->pEpClass->pVM;
-
-    for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesNs); i++)
-        STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesNs[i]);
-    for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesUs); i++)
-        STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesUs[i]);
-    for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++)
-        STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesMs[i]);
-    for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++)
-        STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesSec[i]);
-
-    STAMR3Deregister(pVM, &pEndpoint->StatTaskRunOver100Sec);
-    STAMR3Deregister(pVM, &pEndpoint->StatIoOpsPerSec);
-    STAMR3Deregister(pVM, &pEndpoint->StatIoOpsStarted);
-    STAMR3Deregister(pVM, &pEndpoint->StatIoOpsCompleted);
-
-    STAMR3Deregister(pVM, &pEndpoint->StatReqSizeSmaller512);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqSize512To1K);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqSize1KTo2K);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqSize2KTo4K);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqSize4KTo8K);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqSize8KTo16K);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqSize16KTo32K);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqSize32KTo64K);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqSize64KTo128K);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqSize128KTo256K);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqSize256KTo512K);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqSizeOver512K);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqsUnaligned512);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqsUnaligned4K);
-    STAMR3Deregister(pVM, &pEndpoint->StatReqsUnaligned8K);
+    /* I hope this doesn't remove too much... */
+    STAMR3DeregisterF(pEndpoint->pEpClass->pVM->pUVM, "/PDM/AsyncCompletion/File/%s/*", RTPathFilename(pEndpoint->pszUri));
 }
 
Index: /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp	(revision 46492)
+++ /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp	(revision 46493)
@@ -1154,6 +1154,6 @@
 
 #ifdef VBOX_WITH_STATISTICS
-    STAMR3Deregister(pEpClassFile->Core.pVM, &pEpFile->StatRead);
-    STAMR3Deregister(pEpClassFile->Core.pVM, &pEpFile->StatWrite);
+    /* Not sure if this might be unnecessary because of similar statement in pdmR3AsyncCompletionStatisticsDeregister? */
+    STAMR3DeregisterF(pEpClassFile->Core.pVM->pUVM, "/PDM/AsyncCompletion/File/%s/*", RTPathFilename(pEpFile->Core.pszUri));
 #endif
 
Index: /trunk/src/VBox/VMM/VMMR3/PDMBlkCache.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMBlkCache.cpp	(revision 46492)
+++ /trunk/src/VBox/VMM/VMMR3/PDMBlkCache.cpp	(revision 46493)
@@ -1242,7 +1242,6 @@
                         return VINF_SUCCESS;
                     }
-                    else
-                        rc = VERR_NO_MEMORY;
-
+
+                    rc = VERR_NO_MEMORY;
                     RTSemRWDestroy(pBlkCache->SemRWEntries);
                 }
@@ -1446,5 +1445,5 @@
 
 #ifdef VBOX_WITH_STATISTICS
-    STAMR3Deregister(pCache->pVM, &pBlkCache->StatWriteDeferred);
+    STAMR3DeregisterF(pCache->pVM->pUVM, "/PDM/BlkCache/%s/Cache/DeferredWrites", pBlkCache->pszId);
 #endif
 
Index: /trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp	(revision 46492)
+++ /trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp	(revision 46493)
@@ -525,15 +525,8 @@
     pCritSect->pVMR0   = NIL_RTR0PTR;
     pCritSect->pVMRC   = NIL_RTRCPTR;
+    if (!fFinal)
+        STAMR3DeregisterF(pVM->pUVM, "/PDM/CritSects/%s/*", pCritSect->pszName);
     RTStrFree((char *)pCritSect->pszName);
     pCritSect->pszName = NULL;
-    if (!fFinal)
-    {
-        STAMR3Deregister(pVM, &pCritSect->StatContentionRZLock);
-        STAMR3Deregister(pVM, &pCritSect->StatContentionRZUnlock);
-        STAMR3Deregister(pVM, &pCritSect->StatContentionR3);
-#ifdef VBOX_WITH_STATISTICS
-        STAMR3Deregister(pVM, &pCritSect->StatLocked);
-#endif
-    }
     return rc;
 }
@@ -602,22 +595,8 @@
     pCritSect->pVMR0   = NIL_RTR0PTR;
     pCritSect->pVMRC   = NIL_RTRCPTR;
+    if (!fFinal)
+        STAMR3DeregisterF(pVM->pUVM, "/PDM/CritSectsRw/%s/*", pCritSect->pszName);
     RTStrFree((char *)pCritSect->pszName);
     pCritSect->pszName = NULL;
-    if (!fFinal)
-    {
-        STAMR3Deregister(pVM, &pCritSect->StatContentionRZEnterExcl);
-        STAMR3Deregister(pVM, &pCritSect->StatContentionRZLeaveExcl);
-        STAMR3Deregister(pVM, &pCritSect->StatContentionRZEnterShared);
-        STAMR3Deregister(pVM, &pCritSect->StatContentionRZLeaveShared);
-        STAMR3Deregister(pVM, &pCritSect->StatRZEnterExcl);
-        STAMR3Deregister(pVM, &pCritSect->StatRZEnterShared);
-        STAMR3Deregister(pVM, &pCritSect->StatContentionR3EnterExcl);
-        STAMR3Deregister(pVM, &pCritSect->StatContentionR3EnterShared);
-        STAMR3Deregister(pVM, &pCritSect->StatR3EnterExcl);
-        STAMR3Deregister(pVM, &pCritSect->StatR3EnterShared);
-#ifdef VBOX_WITH_STATISTICS
-        STAMR3Deregister(pVM, &pCritSect->StatWriteLocked);
-#endif
-    }
 
     return RT_SUCCESS(rc1) ? rc2 : rc1;
Index: /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp	(revision 46492)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp	(revision 46493)
@@ -1427,5 +1427,5 @@
     VM_ASSERT_EMT(pDrvIns->Internal.s.pVMR3);
 
-    int rc = STAMR3DeregisterU(pDrvIns->Internal.s.pVMR3->pUVM, pvSample);
+    int rc = STAMR3DeregisterByAddr(pDrvIns->Internal.s.pVMR3->pUVM, pvSample);
     AssertRC(rc);
     return rc;
Index: /trunk/src/VBox/VMM/VMMR3/PDMQueue.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMQueue.cpp	(revision 46492)
+++ /trunk/src/VBox/VMM/VMMR3/PDMQueue.cpp	(revision 46493)
@@ -446,14 +446,5 @@
      * Deregister statistics.
      */
-    STAMR3Deregister(pVM, &pQueue->cbItem);
-    STAMR3Deregister(pVM, &pQueue->cbItem);
-    STAMR3Deregister(pVM, &pQueue->StatAllocFailures);
-    STAMR3Deregister(pVM, &pQueue->StatInsert);
-    STAMR3Deregister(pVM, &pQueue->StatFlush);
-    STAMR3Deregister(pVM, &pQueue->StatFlushLeftovers);
-#ifdef VBOX_WITH_STATISTICS
-    STAMR3Deregister(pVM, &pQueue->StatFlushPrf);
-    STAMR3Deregister(pVM, (void *)&pQueue->cStatPending);
-#endif
+    STAMR3DeregisterF(pVM->pUVM, "/PDM/Queue/%s/cbItem", pQueue->pszName);
 
     /*
Index: /trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp	(revision 46492)
+++ /trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp	(revision 46493)
@@ -411,7 +411,6 @@
 
 #ifdef VBOX_WITH_STATISTICS
-        char szPath[256];
-        RTStrPrintf(szPath, sizeof(szPath), "/PGM/VirtHandler/Calls/%RGv-%RGv", pNew->Core.Key, pNew->Core.KeyLast);
-        rc = STAMR3Register(pVM, &pNew->Stat, STAMTYPE_PROFILE, STAMVISIBILITY_USED, szPath, STAMUNIT_TICKS_PER_CALL, pszDesc);
+        rc = STAMR3RegisterF(pVM, &pNew->Stat, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, pszDesc,
+                             "/PGM/VirtHandler/Calls/%RGv-%RGv", pNew->Core.Key, pNew->Core.KeyLast);
         AssertRC(rc);
 #endif
@@ -509,5 +508,7 @@
     pgmUnlock(pVM);
 
-    STAM_DEREG(pVM, &pCur->Stat);
+#ifdef VBOX_WITH_STATISTICS
+    STAMR3DeregisterF(pVM->pUVM, "/PGM/VirtHandler/Calls/%RGv-%RGv", pCur->Core.Key, pCur->Core.KeyLast);
+#endif
     MMHyperFree(pVM, pCur);
 
Index: /trunk/src/VBox/VMM/VMMR3/STAM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/STAM.cpp	(revision 46492)
+++ /trunk/src/VBox/VMM/VMMR3/STAM.cpp	(revision 46493)
@@ -62,4 +62,11 @@
 #include <iprt/stream.h>
 #include <iprt/string.h>
+
+
+/*******************************************************************************
+*   Defined Constants And Macros                                               *
+*******************************************************************************/
+/** The maximum name length excluding the terminator. */
+#define STAM_MAX_NAME_LEN   239
 
 
@@ -487,12 +494,9 @@
     AssertReturn(enmType != STAMTYPE_CALLBACK, VERR_INVALID_PARAMETER);
 
-    char *pszFormattedName;
-    RTStrAPrintfV(&pszFormattedName, pszName, args);
-    if (!pszFormattedName)
-        return VERR_NO_MEMORY;
-
-    int rc = STAMR3RegisterU(pUVM, pvSample, enmType, enmVisibility, pszFormattedName, enmUnit, pszDesc);
-    RTStrFree(pszFormattedName);
-    return rc;
+    char   szFormattedName[STAM_MAX_NAME_LEN + 8];
+    size_t cch = RTStrPrintfV(szFormattedName, sizeof(szFormattedName), pszName, args);
+    AssertReturn(cch <= STAM_MAX_NAME_LEN, VERR_OUT_OF_RANGE);
+
+    return STAMR3RegisterU(pUVM, pvSample, enmType, enmVisibility, szFormattedName, enmUnit, pszDesc);
 }
 
@@ -1254,5 +1258,5 @@
     AssertReturn(pszName[1] != '/' && pszName[1], VERR_INVALID_NAME);
     uint32_t const cchName = (uint32_t)strlen(pszName);
-    AssertReturn(cchName < 256, VERR_OUT_OF_RANGE);
+    AssertReturn(cchName <= STAM_MAX_NAME_LEN, VERR_OUT_OF_RANGE);
     AssertReturn(pszName[cchName - 1] != '/', VERR_INVALID_NAME);
     AssertReturn(memchr(pszName, '\\', cchName) == NULL, VERR_INVALID_NAME);
@@ -1437,5 +1441,27 @@
 
 /**
- * Deregisters a sample previously registered by STAR3Register().
+ * Destroys the statistics descriptor, unlinking it and freeing all resources.
+ *
+ * @returns VINF_SUCCESS
+ * @param   pUVM        Pointer to the user mode VM structure.
+ * @param   pCur        The descriptor to destroy.
+ */
+static int stamR3DestroyDesc(PUVM pUVM, PSTAMDESC pCur)
+{
+    RTListNodeRemove(&pCur->ListEntry);
+#ifdef STAM_WITH_LOOKUP_TREE
+    pCur->pLookup->pDesc = NULL; /** @todo free lookup nodes once it's working. */
+    stamR3LookupDecUsage(pCur->pLookup);
+    stamR3LookupMaybeFree(pCur->pLookup);
+#endif
+    RTMemFree(pCur);
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Deregisters a sample previously registered by STAR3Register() given its
+ * address.
  *
  * This is intended used for devices which can be unplugged and for
@@ -1446,7 +1472,12 @@
  * @param   pvSample    Pointer to the sample registered with STAMR3Register().
  */
-VMMR3DECL(int)  STAMR3DeregisterU(PUVM pUVM, void *pvSample)
+VMMR3DECL(int)  STAMR3DeregisterByAddr(PUVM pUVM, void *pvSample)
 {
     UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
+
+    /* This is a complete waste of time when shutting down. */
+    VMSTATE enmState = VMR3GetStateU(pUVM);
+    if (enmState >= VMSTATE_DESTROYING)
+        return VINF_SUCCESS;
 
     STAM_LOCK_WR(pUVM);
@@ -1460,14 +1491,5 @@
     {
         if (pCur->u.pv == pvSample)
-        {
-            RTListNodeRemove(&pCur->ListEntry);
-#ifdef STAM_WITH_LOOKUP_TREE
-            pCur->pLookup->pDesc = NULL; /** @todo free lookup nodes once it's working. */
-            stamR3LookupDecUsage(pCur->pLookup);
-            stamR3LookupMaybeFree(pCur->pLookup);
-#endif
-            RTMemFree(pCur);
-            rc = VINF_SUCCESS;
-        }
+            rc = stamR3DestroyDesc(pUVM, pCur);
     }
 
@@ -1478,16 +1500,111 @@
 
 /**
- * Deregisters a sample previously registered by STAR3Register().
- *
- * This is intended used for devices which can be unplugged and for
- * temporary samples.
+ * Worker for STAMR3Deregister, STAMR3DeregisterV and STAMR3DeregisterF.
+ *
+ * @returns VBox status code.
+ * @retval  VWRN_NOT_FOUND if no matching names found.
+ *
+ * @param   pUVM        Pointer to the user mode VM structure.
+ * @param   pszPat      The name pattern.
+ */
+static int stamR3DeregisterByPattern(PUVM pUVM, const char *pszPat)
+{
+    Assert(!strchr(pszPat, '|')); /* single pattern! */
+
+    int rc = VWRN_NOT_FOUND;
+    STAM_LOCK_WR(pUVM);
+
+    PSTAMDESC pLast;
+    PSTAMDESC pCur = stamR3LookupFindPatternDescRange(pUVM->stam.s.pRoot, &pUVM->stam.s.List, pszPat, &pLast);
+    if (pCur)
+    {
+        for (;;)
+        {
+            PSTAMDESC pNext = RTListNodeGetNext(&pCur->ListEntry, STAMDESC, ListEntry);
+
+            if (RTStrSimplePatternMatch(pszPat, pCur->pszName))
+                rc = stamR3DestroyDesc(pUVM, pCur);
+
+            /* advance. */
+            if (pCur == pLast)
+                break;
+            pCur = pNext;
+        }
+        Assert(pLast);
+    }
+    else
+        Assert(!pLast);
+
+    STAM_UNLOCK_WR(pUVM);
+    return rc;
+}
+
+
+/**
+ * Deregister zero or more samples given a (single) pattern matching their
+ * names.
  *
  * @returns VBox status.
- * @param   pVM         Pointer to the VM.
- * @param   pvSample    Pointer to the sample registered with STAMR3Register().
- */
-VMMR3DECL(int)  STAMR3Deregister(PVM pVM, void *pvSample)
-{
-    return STAMR3DeregisterU(pVM->pUVM, pvSample);
+ * @param   pUVM        Pointer to the user mode VM structure.
+ * @param   pszPat      The name pattern.
+ * @sa      STAMR3DeregisterF, STAMR3DeregisterV
+ */
+VMMR3DECL(int)  STAMR3Deregister(PUVM pUVM, const char *pszPat)
+{
+    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
+
+    /* This is a complete waste of time when shutting down. */
+    VMSTATE enmState = VMR3GetStateU(pUVM);
+    if (enmState >= VMSTATE_DESTROYING)
+        return VINF_SUCCESS;
+
+    return stamR3DeregisterByPattern(pUVM, pszPat);
+}
+
+
+/**
+ * Deregister zero or more samples given a (single) pattern matching their
+ * names.
+ *
+ * @returns VBox status.
+ * @param   pUVM        Pointer to the user mode VM structure.
+ * @param   pszPatFmt   The name pattern format string.
+ * @param   ...         Format string arguments.
+ * @sa      STAMR3Deregister, STAMR3DeregisterV
+ */
+VMMR3DECL(int)  STAMR3DeregisterF(PUVM pUVM, const char *pszPatFmt, ...)
+{
+    va_list va;
+    va_start(va, pszPatFmt);
+    int rc = STAMR3DeregisterV(pUVM, pszPatFmt, va);
+    va_end(va);
+    return rc;
+}
+
+
+/**
+ * Deregister zero or more samples given a (single) pattern matching their
+ * names.
+ *
+ * @returns VBox status.
+ * @param   pUVM        Pointer to the user mode VM structure.
+ * @param   pszPatFmt   The name pattern format string.
+ * @param   va          Format string arguments.
+ * @sa      STAMR3Deregister, STAMR3DeregisterF
+ */
+VMMR3DECL(int)  STAMR3DeregisterV(PUVM pUVM, const char *pszPatFmt, va_list va)
+{
+    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
+
+    /* This is a complete waste of time when shutting down. */
+    VMSTATE enmState = VMR3GetStateU(pUVM);
+    if (enmState >= VMSTATE_DESTROYING)
+        return VINF_SUCCESS;
+
+    char   szPat[STAM_MAX_NAME_LEN + 8];
+    size_t cchPat = RTStrPrintfV(szPat, sizeof(szPat), pszPatFmt, va);
+    AssertReturn(cchPat <= STAM_MAX_NAME_LEN, VERR_OUT_OF_RANGE);
+
+    return stamR3DeregisterByPattern(pUVM, szPat);
 }
 
Index: /trunk/src/recompiler/VBoxREMWrapper.cpp
===================================================================
--- /trunk/src/recompiler/VBoxREMWrapper.cpp	(revision 46492)
+++ /trunk/src/recompiler/VBoxREMWrapper.cpp	(revision 46493)
@@ -1021,5 +1021,5 @@
 {
     { REMPARMDESC_FLAGS_INT,        sizeof(PVM),                NULL },
-    { REMPARMDESC_FLAGS_INT,        sizeof(void *),             NULL },
+    { REMPARMDESC_FLAGS_INT,        sizeof(const char *),       NULL },
 };
 static const REMPARMDESC g_aArgsTRPMAssertTrap[] =
Index: /trunk/src/recompiler/VBoxRecompiler.c
===================================================================
--- /trunk/src/recompiler/VBoxRecompiler.c	(revision 46492)
+++ /trunk/src/recompiler/VBoxRecompiler.c	(revision 46493)
@@ -550,65 +550,9 @@
 REMR3DECL(int) REMR3Term(PVM pVM)
 {
-#ifdef VBOX_WITH_STATISTICS
     /*
      * Statistics.
      */
-    STAM_DEREG(pVM, &gStatExecuteSingleInstr);
-    STAM_DEREG(pVM, &gStatCompilationQEmu);
-    STAM_DEREG(pVM, &gStatRunCodeQEmu);
-    STAM_DEREG(pVM, &gStatTotalTimeQEmu);
-    STAM_DEREG(pVM, &gStatTimers);
-    STAM_DEREG(pVM, &gStatTBLookup);
-    STAM_DEREG(pVM, &gStatIRQ);
-    STAM_DEREG(pVM, &gStatRawCheck);
-    STAM_DEREG(pVM, &gStatMemRead);
-    STAM_DEREG(pVM, &gStatMemWrite);
-    STAM_DEREG(pVM, &gStatGCPhys2HCVirt);
-
-    STAM_DEREG(pVM, &gStatCpuGetTSC);
-
-    STAM_DEREG(pVM, &gStatRefuseTFInhibit);
-    STAM_DEREG(pVM, &gStatRefuseVM86);
-    STAM_DEREG(pVM, &gStatRefusePaging);
-    STAM_DEREG(pVM, &gStatRefusePAE);
-    STAM_DEREG(pVM, &gStatRefuseIOPLNot0);
-    STAM_DEREG(pVM, &gStatRefuseIF0);
-    STAM_DEREG(pVM, &gStatRefuseCode16);
-    STAM_DEREG(pVM, &gStatRefuseWP0);
-    STAM_DEREG(pVM, &gStatRefuseRing1or2);
-    STAM_DEREG(pVM, &gStatRefuseCanExecute);
-    STAM_DEREG(pVM, &gaStatRefuseStale[0]);
-    STAM_DEREG(pVM, &gaStatRefuseStale[1]);
-    STAM_DEREG(pVM, &gaStatRefuseStale[2]);
-    STAM_DEREG(pVM, &gaStatRefuseStale[3]);
-    STAM_DEREG(pVM, &gaStatRefuseStale[4]);
-    STAM_DEREG(pVM, &gaStatRefuseStale[5]);
-    STAM_DEREG(pVM, &gStatFlushTBs);
-
-    STAM_DEREG(pVM, &gStatREMGDTChange);
-    STAM_DEREG(pVM, &gStatREMLDTRChange);
-    STAM_DEREG(pVM, &gStatREMIDTChange);
-    STAM_DEREG(pVM, &gStatREMTRChange);
-
-    STAM_DEREG(pVM, &gStatSelOutOfSync[0]);
-    STAM_DEREG(pVM, &gStatSelOutOfSync[1]);
-    STAM_DEREG(pVM, &gStatSelOutOfSync[2]);
-    STAM_DEREG(pVM, &gStatSelOutOfSync[3]);
-    STAM_DEREG(pVM, &gStatSelOutOfSync[4]);
-    STAM_DEREG(pVM, &gStatSelOutOfSync[5]);
-
-    STAM_DEREG(pVM, &gStatSelOutOfSyncStateBack[0]);
-    STAM_DEREG(pVM, &gStatSelOutOfSyncStateBack[1]);
-    STAM_DEREG(pVM, &gStatSelOutOfSyncStateBack[2]);
-    STAM_DEREG(pVM, &gStatSelOutOfSyncStateBack[3]);
-    STAM_DEREG(pVM, &gStatSelOutOfSyncStateBack[4]);
-    STAM_DEREG(pVM, &gStatSelOutOfSyncStateBack[5]);
-
-    STAM_DEREG(pVM, &pVM->rem.s.Env.StatTbFlush);
-#endif /* VBOX_WITH_STATISTICS */
-
-    STAM_REL_DEREG(pVM, &tb_flush_count);
-    STAM_REL_DEREG(pVM, &tb_phys_invalidate_count);
-    STAM_REL_DEREG(pVM, &tlb_flush_count);
+    STAMR3Deregister(pVM->pUVM, "/PROF/REM/*");
+    STAMR3Deregister(pVM->pUVM, "/REM/*");
 
     return VINF_SUCCESS;
