Index: /trunk/src/VBox/VMM/VMMAll/TMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 82332)
+++ /trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 82333)
@@ -1250,4 +1250,5 @@
 {
     PVMCC pVM = pTimer->CTX_SUFF(pVM);
+    STAM_COUNTER_INC(&pTimer->StatSetAbsolute);
 
     /* Treat virtual sync timers specially. */
@@ -1556,4 +1557,5 @@
 {
     PVMCC pVM = pTimer->CTX_SUFF(pVM);
+    STAM_COUNTER_INC(&pTimer->StatSetRelative);
 
     /* Treat virtual sync timers specially. */
@@ -1878,4 +1880,5 @@
 {
     PVMCC pVM = pTimer->CTX_SUFF(pVM);
+    STAM_COUNTER_INC(&pTimer->StatStop);
 
     /* Treat virtual sync timers specially. */
@@ -1985,4 +1988,5 @@
 {
     PVMCC pVM = pTimer->CTX_SUFF(pVM);
+    STAM_COUNTER_INC(&pTimer->StatGet);
 
     uint64_t u64;
Index: /trunk/src/VBox/VMM/VMMR3/TM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 82332)
+++ /trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 82333)
@@ -1486,4 +1486,20 @@
 }
 
+#ifdef VBOX_WITH_STATISTICS
+/** Names the clock of the timer.   */
+static const char *tmR3TimerClockName(PTMTIMERR3 pTimer)
+{
+    switch (pTimer->enmClock)
+    {
+        case TMCLOCK_VIRTUAL:       return "virtual";
+        case TMCLOCK_VIRTUAL_SYNC:  return "virtual-sync";
+        case TMCLOCK_REAL:          return "real";
+        case TMCLOCK_TSC:           return "tsc";
+        case TMCLOCK_MAX:           break;
+    }
+    return "corrupt clock value";
+}
+#endif
+
 
 /**
@@ -1546,4 +1562,23 @@
 #endif
     TM_UNLOCK_TIMERS(pVM);
+
+    /*
+     * Register statistics.
+     */
+#ifdef VBOX_WITH_STATISTICS
+
+    STAMR3RegisterF(pVM, &pTimer->StatTimer,        STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
+                    tmR3TimerClockName(pTimer), "/TM/Timers/%s", pszDesc);
+    STAMR3RegisterF(pVM, &pTimer->StatCritSectEnter, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
+                    "", "/TM/Timers/%s/CritSectEnter", pszDesc);
+    STAMR3RegisterF(pVM, &pTimer->StatGet,          STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS,
+                    "", "/TM/Timers/%s/Get", pszDesc);
+    STAMR3RegisterF(pVM, &pTimer->StatSetAbsolute,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS,
+                    "", "/TM/Timers/%s/SetAbsolute", pszDesc);
+    STAMR3RegisterF(pVM, &pTimer->StatSetRelative,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS,
+                    "", "/TM/Timers/%s/SetRelative", pszDesc);
+    STAMR3RegisterF(pVM, &pTimer->StatStop,         STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS,
+                    "", "/TM/Timers/%s/Stop", pszDesc);
+#endif
 
     *ppTimer = pTimer;
@@ -1872,5 +1907,14 @@
 
     /*
-     * Read to move the timer from the created list and onto the free list.
+     * Deregister statistics.
+     */
+#ifdef VBOX_WITH_STATISTICS
+    char szPrefix[128];
+    RTStrPrintf(szPrefix, sizeof(szPrefix), "/TM/Timers/%s", pTimer->pszDesc);
+    STAMR3DeregisterByPrefix(pVM->pUVM, szPrefix);
+#endif
+
+    /*
+     * Ready to move the timer from the created list and onto the free list.
      */
     Assert(!pTimer->offNext); Assert(!pTimer->offPrev); Assert(!pTimer->offScheduleNext);
@@ -2229,5 +2273,9 @@
         PPDMCRITSECT    pCritSect = pTimer->pCritSect;
         if (pCritSect)
+        {
+            STAM_PROFILE_START(&pTimer->StatCritSectEnter, Locking);
             PDMCritSectEnter(pCritSect, VERR_IGNORED);
+            STAM_PROFILE_STOP(&pTimer->StatCritSectEnter, Locking);
+        }
         Log2(("tmR3TimerQueueRun: %p:{.enmState=%s, .enmClock=%d, .enmType=%d, u64Expire=%llx (now=%llx) .pszDesc=%s}\n",
               pTimer, tmTimerState(pTimer->enmState), pTimer->enmClock, pTimer->enmType, pTimer->u64Expire, u64Now, pTimer->pszDesc));
@@ -2254,4 +2302,5 @@
             /* fire */
             TM_SET_STATE(pTimer, TMTIMERSTATE_EXPIRED_DELIVER);
+            STAM_PROFILE_START(&pTimer->StatTimer, PrfTimer);
             switch (pTimer->enmType)
             {
@@ -2265,4 +2314,5 @@
                     break;
             }
+            STAM_PROFILE_STOP(&pTimer->StatTimer, PrfTimer);
 
             /* change the state if it wasn't changed already in the handler. */
@@ -2416,5 +2466,9 @@
         PPDMCRITSECT pCritSect = pTimer->pCritSect;
         if (pCritSect)
+        {
+            STAM_PROFILE_START(&pTimer->StatCritSectEnter, Locking);
             PDMCritSectEnter(pCritSect, VERR_IGNORED);
+            STAM_PROFILE_STOP(&pTimer->StatCritSectEnter, Locking);
+        }
 
         Log2(("tmR3TimerQueueRun: %p:{.enmState=%s, .enmClock=%d, .enmType=%d, u64Expire=%llx (now=%llx) .pszDesc=%s}\n",
@@ -2433,4 +2487,5 @@
         tmTimerQueueUnlinkActive(pQueue, pTimer);
         TM_SET_STATE(pTimer, TMTIMERSTATE_EXPIRED_DELIVER);
+        STAM_PROFILE_START(&pTimer->StatTimer, PrfTimer);
         switch (pTimer->enmType)
         {
@@ -2444,4 +2499,5 @@
                 break;
         }
+        STAM_PROFILE_STOP(&pTimer->StatTimer, PrfTimer);
 
         /* Change the state if it wasn't changed already in the handler.
Index: /trunk/src/VBox/VMM/include/TMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/TMInternal.h	(revision 82332)
+++ /trunk/src/VBox/VMM/include/TMInternal.h	(revision 82333)
@@ -205,4 +205,12 @@
 #if HC_ARCH_BITS == 32
     uint32_t                padding0; /**< pad structure to multiple of 8 bytes. */
+#endif
+#ifdef VBOX_WITH_STATISTICS
+    STAMPROFILE             StatTimer;
+    STAMPROFILE             StatCritSectEnter;
+    STAMCOUNTER             StatGet;
+    STAMCOUNTER             StatSetAbsolute;
+    STAMCOUNTER             StatSetRelative;
+    STAMCOUNTER             StatStop;
 #endif
 } TMTIMER;
