Index: /trunk/src/VBox/VMM/VMMAll/TMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 87812)
+++ /trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 87813)
@@ -1147,8 +1147,6 @@
 VMMDECL(int) TMTimerLock(PVMCC pVM, TMTIMERHANDLE hTimer, int rcBusy)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
-    AssertPtr(pTimer);
-    AssertReturn(pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC, VERR_NOT_SUPPORTED);
+    TMTIMER_HANDLE_TO_VARS_RETURN(pVM, hTimer); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    AssertReturn(idxQueue == TMCLOCK_VIRTUAL_SYNC, VERR_NOT_SUPPORTED);
     return PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, rcBusy);
 }
@@ -1163,7 +1161,6 @@
 VMMDECL(void) TMTimerUnlock(PVMCC pVM, TMTIMERHANDLE hTimer)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN_VOID(pVM, hTimer, pTimer);
-    AssertReturnVoid(pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC);
+    TMTIMER_HANDLE_TO_VARS_RETURN_VOID(pVM, hTimer); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    AssertReturnVoid(idxQueue == TMCLOCK_VIRTUAL_SYNC);
     PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
 }
@@ -1179,8 +1176,6 @@
 VMMDECL(bool) TMTimerIsLockOwner(PVMCC pVM, TMTIMERHANDLE hTimer)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, false, pTimer);
-    AssertPtr(pTimer);
-    AssertReturn(pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC, false);
+    TMTIMER_HANDLE_TO_VARS_RETURN_EX(pVM, hTimer, false); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    AssertReturn(idxQueue == TMCLOCK_VIRTUAL_SYNC, false);
     return PDMCritSectIsOwner(&pVM->tm.s.VirtualSyncLock);
 }
@@ -1196,7 +1191,7 @@
  * @param   u64Expire       The new expire time.
  * @param   pQueue          Pointer to the shared timer queue data.
- * @param   enmClock        The sanitized clock.
- */
-static int tmTimerSetOptimizedStart(PVMCC pVM, PTMTIMER pTimer, uint64_t u64Expire, PTMTIMERQUEUE pQueue, TMCLOCK enmClock)
+ * @param   idxQueue        The queue index.
+ */
+static int tmTimerSetOptimizedStart(PVMCC pVM, PTMTIMER pTimer, uint64_t u64Expire, PTMTIMERQUEUE pQueue, uint32_t idxQueue)
 {
     Assert(pTimer->idxPrev == UINT32_MAX);
@@ -1207,5 +1202,5 @@
      * Calculate and set the expiration time.
      */
-    if (enmClock == TMCLOCK_VIRTUAL_SYNC)
+    if (idxQueue == TMCLOCK_VIRTUAL_SYNC)
     {
         uint64_t u64Last = ASMAtomicReadU64(&pVM->tm.s.u64VirtualSync);
@@ -1220,5 +1215,5 @@
      * Link the timer into the active list.
      */
-    tmTimerQueueLinkActive(pVM, TM_GET_TIMER_QUEUE_CC(pVM, enmClock, pQueue), pQueue, pTimer, u64Expire);
+    tmTimerQueueLinkActive(pVM, TM_GET_TIMER_QUEUE_CC(pVM, idxQueue, pQueue), pQueue, pTimer, u64Expire);
 
     STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetOpt);
@@ -1309,10 +1304,9 @@
 VMMDECL(int) TMTimerSet(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t u64Expire)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
+    TMTIMER_HANDLE_TO_VARS_RETURN(pVM, hTimer); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
     STAM_COUNTER_INC(&pTimer->StatSetAbsolute);
 
     /* Treat virtual sync timers specially. */
-    if (pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC)
+    if (idxQueue == TMCLOCK_VIRTUAL_SYNC)
         return tmTimerVirtualSyncSet(pVM, pTimer, u64Expire);
 
@@ -1341,9 +1335,9 @@
 #endif
 
+#if 1
     /*
      * The most common case is setting the timer again during the callback.
      * The second most common case is starting a timer at some other time.
      */
-#if 1
     TMTIMERSTATE enmState1 = pTimer->enmState;
     if (    enmState1 == TMTIMERSTATE_EXPIRED_DELIVER
@@ -1352,8 +1346,4 @@
     {
         /* Try take the TM lock and check the state again. */
-        TMCLOCK const       enmClock = pTimer->enmClock;
-        AssertReturn((unsigned)enmClock < TMCLOCK_MAX, VERR_TM_IPE_2);
-        PTMTIMERQUEUE const pQueue   = &pVM->tm.s.aTimerQueues[enmClock];
-
         int rc = PDMCritSectTryEnter(&pQueue->TimerLock);
         if (RT_SUCCESS_NP(rc))
@@ -1361,5 +1351,5 @@
             if (RT_LIKELY(tmTimerTry(pTimer, TMTIMERSTATE_ACTIVE, enmState1)))
             {
-                tmTimerSetOptimizedStart(pVM, pTimer, u64Expire, pQueue, enmClock);
+                tmTimerSetOptimizedStart(pVM, pTimer, u64Expire, pQueue, idxQueue);
                 STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatTimerSet), a);
                 PDMCritSectLeave(&pQueue->TimerLock);
@@ -1509,8 +1499,8 @@
  *                          Optional.
  * @param   pQueue          Pointer to the shared timer queue data.
- * @param   enmClock        The sanitized clock.
+ * @param   idxQueue        The queue index.
  */
 static int tmTimerSetRelativeOptimizedStart(PVMCC pVM, PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t *pu64Now,
-                                            PTMTIMERQUEUE pQueue, TMCLOCK enmClock)
+                                            PTMTIMERQUEUE pQueue, uint32_t idxQueue)
 {
     Assert(pTimer->idxPrev == UINT32_MAX);
@@ -1521,5 +1511,5 @@
      * Calculate and set the expiration time.
      */
-    uint64_t const  u64Expire = cTicksToNext + tmTimerSetRelativeNowWorker(pVM, enmClock, pu64Now);
+    uint64_t const  u64Expire = cTicksToNext + tmTimerSetRelativeNowWorker(pVM, pQueue->enmClock, pu64Now);
     pTimer->u64Expire         = u64Expire;
     Log2(("tmTimerSetRelativeOptimizedStart: %p:{.pszDesc='%s', .u64Expire=%'RU64} cTicksToNext=%'RU64\n", pTimer, pTimer->szName, u64Expire, cTicksToNext));
@@ -1529,7 +1519,8 @@
      */
     DBGFTRACE_U64_TAG2(pVM, u64Expire, "tmTimerSetRelativeOptimizedStart", pTimer->szName);
-    tmTimerQueueLinkActive(pVM, TM_GET_TIMER_QUEUE_CC(pVM, enmClock, pQueue), pQueue, pTimer, u64Expire);
+    tmTimerQueueLinkActive(pVM, TM_GET_TIMER_QUEUE_CC(pVM, idxQueue, pQueue), pQueue, pTimer, u64Expire);
 
     STAM_COUNTER_INC(&pVM->tm.s.StatTimerSetRelativeOpt);
+    RT_NOREF(idxQueue);
     return VINF_SUCCESS;
 }
@@ -1624,13 +1615,12 @@
  *                          Optional.
  */
-static int tmTimerSetRelative(PVMCC pVM, PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
+static int tmTimerSetRelative(PVMCC pVM, PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t *pu64Now,
+                              PTMTIMERQUEUE pQueue, uint32_t idxQueue)
 {
     STAM_COUNTER_INC(&pTimer->StatSetRelative);
 
     /* Treat virtual sync timers specially. */
-    TMCLOCK enmClock = pTimer->enmClock;
-    if (enmClock == TMCLOCK_VIRTUAL_SYNC)
+    if (idxQueue == TMCLOCK_VIRTUAL_SYNC)
         return tmTimerVirtualSyncSetRelative(pVM, pTimer, cTicksToNext, pu64Now);
-    AssertReturn((unsigned)enmClock < (unsigned)TMCLOCK_MAX, VERR_TM_IPE_2);
 
     STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatTimerSetRelative), a);
@@ -1668,8 +1658,7 @@
      * longer as this isn't supported for any timers, critsect or not.)
      *
-     * Note! Lock ordering doesn't apply when we only tries to
+     * Note! Lock ordering doesn't apply when we only _try_ to
      *       get the innermost locks.
      */
-    PTMTIMERQUEUE pQueue = &pVM->tm.s.aTimerQueues[enmClock];
     bool fOwnTMLock = RT_SUCCESS_NP(PDMCritSectTryEnter(&pQueue->TimerLock));
 #if 1
@@ -1682,5 +1671,5 @@
                       && tmTimerTry(pTimer, TMTIMERSTATE_ACTIVE, enmState)))
         {
-            tmTimerSetRelativeOptimizedStart(pVM, pTimer, cTicksToNext, pu64Now, pQueue, enmClock);
+            tmTimerSetRelativeOptimizedStart(pVM, pTimer, cTicksToNext, pu64Now, pQueue, idxQueue);
             STAM_PROFILE_STOP(&pVM->tm.s.CTX_SUFF_Z(StatTimerSetRelative), a);
             PDMCritSectLeave(&pQueue->TimerLock);
@@ -1705,5 +1694,5 @@
         {
             case TMTIMERSTATE_STOPPED:
-                if (enmClock == TMCLOCK_VIRTUAL_SYNC)
+                if (pQueue->enmClock == TMCLOCK_VIRTUAL_SYNC)
                 {
                     /** @todo To fix assertion in tmR3TimerQueueRunVirtualSync:
@@ -1719,5 +1708,5 @@
                     Assert(pTimer->idxPrev == UINT32_MAX);
                     Assert(pTimer->idxNext == UINT32_MAX);
-                    pTimer->u64Expire = cTicksToNext + tmTimerSetRelativeNowWorker(pVM, enmClock, pu64Now);
+                    pTimer->u64Expire = cTicksToNext + tmTimerSetRelativeNowWorker(pVM, pQueue->enmClock, pu64Now);
                     Log2(("TMTimerSetRelative: %p:{.enmState=%s, .pszDesc='%s', .u64Expire=%'RU64} cRetries=%d [EXP/STOP]\n",
                           pTimer, tmTimerState(enmState), pTimer->szName, pTimer->u64Expire, cRetries));
@@ -1734,5 +1723,5 @@
                 if (tmTimerTry(pTimer, TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE, enmState))
                 {
-                    pTimer->u64Expire = cTicksToNext + tmTimerSetRelativeNowWorker(pVM, enmClock, pu64Now);
+                    pTimer->u64Expire = cTicksToNext + tmTimerSetRelativeNowWorker(pVM, pQueue->enmClock, pu64Now);
                     Log2(("TMTimerSetRelative: %p:{.enmState=%s, .pszDesc='%s', .u64Expire=%'RU64} cRetries=%d [PEND_SCHED]\n",
                           pTimer, tmTimerState(enmState), pTimer->szName, pTimer->u64Expire, cRetries));
@@ -1749,5 +1738,5 @@
                 if (tmTimerTryWithLink(pVM, pTimer, TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE, enmState))
                 {
-                    pTimer->u64Expire = cTicksToNext + tmTimerSetRelativeNowWorker(pVM, enmClock, pu64Now);
+                    pTimer->u64Expire = cTicksToNext + tmTimerSetRelativeNowWorker(pVM, pQueue->enmClock, pu64Now);
                     Log2(("TMTimerSetRelative: %p:{.enmState=%s, .pszDesc='%s', .u64Expire=%'RU64} cRetries=%d [ACTIVE]\n",
                           pTimer, tmTimerState(enmState), pTimer->szName, pTimer->u64Expire, cRetries));
@@ -1764,5 +1753,5 @@
                 if (tmTimerTry(pTimer, TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE, enmState))
                 {
-                    pTimer->u64Expire = cTicksToNext + tmTimerSetRelativeNowWorker(pVM, enmClock, pu64Now);
+                    pTimer->u64Expire = cTicksToNext + tmTimerSetRelativeNowWorker(pVM, pQueue->enmClock, pu64Now);
                     Log2(("TMTimerSetRelative: %p:{.enmState=%s, .pszDesc='%s', .u64Expire=%'RU64} cRetries=%d [PEND_RESCH/STOP]\n",
                           pTimer, tmTimerState(enmState), pTimer->szName, pTimer->u64Expire, cRetries));
@@ -1809,5 +1798,5 @@
         if (rc != VERR_TRY_AGAIN)
         {
-            tmTimerSetRelativeNowWorker(pVM, enmClock, pu64Now);
+            tmTimerSetRelativeNowWorker(pVM, pQueue->enmClock, pu64Now);
             break;
         }
@@ -1816,5 +1805,5 @@
             AssertMsgFailed(("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, pTimer->szName));
             rc = VERR_TM_TIMER_UNSTABLE_STATE;
-            tmTimerSetRelativeNowWorker(pVM, enmClock, pu64Now);
+            tmTimerSetRelativeNowWorker(pVM, pQueue->enmClock, pu64Now);
             break;
         }
@@ -1851,7 +1840,6 @@
 VMMDECL(int) TMTimerSetRelative(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
-    return tmTimerSetRelative(pVM, pTimer, cTicksToNext, pu64Now);
+    TMTIMER_HANDLE_TO_VARS_RETURN(pVM, hTimer); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    return tmTimerSetRelative(pVM, pTimer, cTicksToNext, pu64Now, pQueue, idxQueue);
 }
 
@@ -2083,10 +2071,9 @@
 VMMDECL(uint64_t) TMTimerGet(PVMCC pVM, TMTIMERHANDLE hTimer)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, UINT64_MAX, pTimer);
+    TMTIMER_HANDLE_TO_VARS_RETURN_EX(pVM, hTimer, 0); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
     STAM_COUNTER_INC(&pTimer->StatGet);
 
     uint64_t u64;
-    switch (pTimer->enmClock)
+    switch (pQueue->enmClock)
     {
         case TMCLOCK_VIRTUAL:
@@ -2100,5 +2087,5 @@
             break;
         default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            AssertMsgFailed(("Invalid enmClock=%d\n", pQueue->enmClock));
             return UINT64_MAX;
     }
@@ -2118,7 +2105,6 @@
 VMMDECL(uint64_t) TMTimerGetFreq(PVMCC pVM, TMTIMERHANDLE hTimer)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
-    switch (pTimer->enmClock)
+    TMTIMER_HANDLE_TO_VARS_RETURN_EX(pVM, hTimer, 0); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    switch (pQueue->enmClock)
     {
         case TMCLOCK_VIRTUAL:
@@ -2130,5 +2116,5 @@
 
         default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            AssertMsgFailed(("Invalid enmClock=%d\n", pQueue->enmClock));
             return 0;
     }
@@ -2146,11 +2132,10 @@
 VMMDECL(uint64_t) TMTimerGetExpire(PVMCC pVM, TMTIMERHANDLE hTimer)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, UINT64_MAX, pTimer);
+    TMTIMER_HANDLE_TO_VARS_RETURN_EX(pVM, hTimer, UINT64_MAX); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
     TMTIMER_ASSERT_CRITSECT(pVM, pTimer);
     int cRetries = 1000;
     do
     {
-        TMTIMERSTATE    enmState = pTimer->enmState;
+        TMTIMERSTATE enmState = pTimer->enmState;
         switch (enmState)
         {
@@ -2211,6 +2196,5 @@
 VMMDECL(bool) TMTimerIsActive(PVMCC pVM, TMTIMERHANDLE hTimer)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, false, pTimer);
+    TMTIMER_HANDLE_TO_VARS_RETURN_EX(pVM, hTimer, false); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
     TMTIMERSTATE enmState = pTimer->enmState;
     switch (enmState)
@@ -2263,22 +2247,21 @@
 VMMDECL(int) TMTimerSetMillies(PVMCC pVM, TMTIMERHANDLE hTimer, uint32_t cMilliesToNext)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
-    switch (pTimer->enmClock)
+    TMTIMER_HANDLE_TO_VARS_RETURN(pVM, hTimer); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    switch (pQueue->enmClock)
     {
         case TMCLOCK_VIRTUAL:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return tmTimerSetRelative(pVM, pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
+            return tmTimerSetRelative(pVM, pTimer, cMilliesToNext * UINT64_C(1000000), NULL, pQueue, idxQueue);
 
         case TMCLOCK_VIRTUAL_SYNC:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return tmTimerSetRelative(pVM, pTimer, cMilliesToNext * UINT64_C(1000000), NULL);
+            return tmTimerSetRelative(pVM, pTimer, cMilliesToNext * UINT64_C(1000000), NULL, pQueue, idxQueue);
 
         case TMCLOCK_REAL:
             AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return tmTimerSetRelative(pVM, pTimer, cMilliesToNext, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cMilliesToNext, NULL, pQueue, idxQueue);
 
         default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            AssertMsgFailed(("Invalid enmClock=%d\n", pQueue->enmClock));
             return VERR_TM_TIMER_BAD_CLOCK;
     }
@@ -2296,22 +2279,21 @@
 VMMDECL(int) TMTimerSetMicro(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
-    switch (pTimer->enmClock)
+    TMTIMER_HANDLE_TO_VARS_RETURN(pVM, hTimer); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    switch (pQueue->enmClock)
     {
         case TMCLOCK_VIRTUAL:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return tmTimerSetRelative(pVM, pTimer, cMicrosToNext * 1000, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cMicrosToNext * 1000, NULL, pQueue, idxQueue);
 
         case TMCLOCK_VIRTUAL_SYNC:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return tmTimerSetRelative(pVM, pTimer, cMicrosToNext * 1000, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cMicrosToNext * 1000, NULL, pQueue, idxQueue);
 
         case TMCLOCK_REAL:
             AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return tmTimerSetRelative(pVM, pTimer, cMicrosToNext / 1000, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cMicrosToNext / 1000, NULL, pQueue, idxQueue);
 
         default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            AssertMsgFailed(("Invalid enmClock=%d\n", pQueue->enmClock));
             return VERR_TM_TIMER_BAD_CLOCK;
     }
@@ -2329,19 +2311,18 @@
 VMMDECL(int) TMTimerSetNano(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cNanosToNext)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
+    TMTIMER_HANDLE_TO_VARS_RETURN(pVM, hTimer); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
     switch (pTimer->enmClock)
     {
         case TMCLOCK_VIRTUAL:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return tmTimerSetRelative(pVM, pTimer, cNanosToNext, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cNanosToNext, NULL, pQueue, idxQueue);
 
         case TMCLOCK_VIRTUAL_SYNC:
             AssertCompile(TMCLOCK_FREQ_VIRTUAL == 1000000000);
-            return tmTimerSetRelative(pVM, pTimer, cNanosToNext, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cNanosToNext, NULL, pQueue, idxQueue);
 
         case TMCLOCK_REAL:
             AssertCompile(TMCLOCK_FREQ_REAL == 1000);
-            return tmTimerSetRelative(pVM, pTimer, cNanosToNext / 1000000, NULL);
+            return tmTimerSetRelative(pVM, pTimer, cNanosToNext / 1000000, NULL, pQueue, idxQueue);
 
         default:
@@ -2403,7 +2384,6 @@
 VMMDECL(uint64_t) TMTimerToNano(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cTicks)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
-    switch (pTimer->enmClock)
+    TMTIMER_HANDLE_TO_VARS_RETURN_EX(pVM, hTimer, 0); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    switch (pQueue->enmClock)
     {
         case TMCLOCK_VIRTUAL:
@@ -2417,5 +2397,5 @@
 
         default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            AssertMsgFailed(("Invalid enmClock=%d\n", pQueue->enmClock));
             return 0;
     }
@@ -2435,7 +2415,6 @@
 VMMDECL(uint64_t) TMTimerToMicro(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cTicks)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
-    switch (pTimer->enmClock)
+    TMTIMER_HANDLE_TO_VARS_RETURN_EX(pVM, hTimer, 0); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    switch (pQueue->enmClock)
     {
         case TMCLOCK_VIRTUAL:
@@ -2449,5 +2428,5 @@
 
         default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            AssertMsgFailed(("Invalid enmClock=%d\n", pQueue->enmClock));
             return 0;
     }
@@ -2467,7 +2446,6 @@
 VMMDECL(uint64_t) TMTimerToMilli(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cTicks)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
-    switch (pTimer->enmClock)
+    TMTIMER_HANDLE_TO_VARS_RETURN_EX(pVM, hTimer, 0); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    switch (pQueue->enmClock)
     {
         case TMCLOCK_VIRTUAL:
@@ -2481,5 +2459,5 @@
 
         default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            AssertMsgFailed(("Invalid enmClock=%d\n", pQueue->enmClock));
             return 0;
     }
@@ -2498,7 +2476,6 @@
 VMMDECL(uint64_t) TMTimerFromNano(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cNanoSecs)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
-    switch (pTimer->enmClock)
+    TMTIMER_HANDLE_TO_VARS_RETURN_EX(pVM, hTimer, 0); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    switch (pQueue->enmClock)
     {
         case TMCLOCK_VIRTUAL:
@@ -2512,5 +2489,5 @@
 
         default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            AssertMsgFailed(("Invalid enmClock=%d\n", pQueue->enmClock));
             return 0;
     }
@@ -2529,7 +2506,6 @@
 VMMDECL(uint64_t) TMTimerFromMicro(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cMicroSecs)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
-    switch (pTimer->enmClock)
+    TMTIMER_HANDLE_TO_VARS_RETURN_EX(pVM, hTimer, 0); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    switch (pQueue->enmClock)
     {
         case TMCLOCK_VIRTUAL:
@@ -2543,5 +2519,5 @@
 
         default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            AssertMsgFailed(("Invalid enmClock=%d\n", pQueue->enmClock));
             return 0;
     }
@@ -2560,7 +2536,6 @@
 VMMDECL(uint64_t) TMTimerFromMilli(PVMCC pVM, TMTIMERHANDLE hTimer, uint64_t cMilliSecs)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN_EX(pVM, hTimer, 0, pTimer);
-    switch (pTimer->enmClock)
+    TMTIMER_HANDLE_TO_VARS_RETURN_EX(pVM, hTimer, 0); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    switch (pQueue->enmClock)
     {
         case TMCLOCK_VIRTUAL:
@@ -2574,5 +2549,5 @@
 
         default:
-            AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
+            AssertMsgFailed(("Invalid enmClock=%d\n", pQueue->enmClock));
             return 0;
     }
Index: /trunk/src/VBox/VMM/VMMR3/TM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 87812)
+++ /trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 87813)
@@ -1883,13 +1883,11 @@
  * @returns VBox status code.
  * @param   pVM             The cross context VM structure.
+ * @param   pQueue          The queue the timer is on.
  * @param   pTimer          Timer handle as returned by one of the create functions.
  */
-static int tmR3TimerDestroy(PVMCC pVM, PTMTIMER pTimer)
-{
-    AssertReturn((unsigned)pTimer->enmClock < (unsigned)TMCLOCK_MAX, VERR_INTERNAL_ERROR_3);
-
-    PTMTIMERQUEUE   pQueue   = &pVM->tm.s.aTimerQueues[pTimer->enmClock];
-    bool            fActive  = false;
-    bool            fPending = false;
+static int tmR3TimerDestroy(PVMCC pVM, PTMTIMERQUEUE pQueue, PTMTIMER pTimer)
+{
+    bool fActive  = false;
+    bool fPending = false;
 
     AssertMsg(   !pTimer->pCritSect
@@ -2059,7 +2057,6 @@
     if (hTimer == NIL_TMTIMERHANDLE)
         return VINF_SUCCESS;
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
-    return tmR3TimerDestroy(pVM, pTimer);
+    TMTIMER_HANDLE_TO_VARS_RETURN(pVM, hTimer); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
+    return tmR3TimerDestroy(pVM, pQueue, pTimer);
 }
 
@@ -2092,5 +2089,5 @@
                 PDMCritSectRwLeaveShared(&pQueue->AllocLock);
 
-                int rc = tmR3TimerDestroy(pVM, pTimer);
+                int rc = tmR3TimerDestroy(pVM, pQueue, pTimer);
                 AssertRC(rc);
 
@@ -2133,5 +2130,5 @@
                 PDMCritSectRwLeaveShared(&pQueue->AllocLock);
 
-                int rc = tmR3TimerDestroy(pVM, pTimer);
+                int rc = tmR3TimerDestroy(pVM, pQueue, pTimer);
                 AssertRC(rc);
 
@@ -2174,5 +2171,5 @@
                 PDMCritSectRwLeaveShared(&pQueue->AllocLock);
 
-                int rc = tmR3TimerDestroy(pVM, pTimer);
+                int rc = tmR3TimerDestroy(pVM, pQueue, pTimer);
                 AssertRC(rc);
 
@@ -2883,6 +2880,5 @@
 {
     VM_ASSERT_EMT(pVM);
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
+    TMTIMER_HANDLE_TO_VARS_RETURN(pVM, hTimer); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
     LogFlow(("TMR3TimerSave: %p:{enmState=%s, .szName='%s'} pSSM=%p\n", pTimer, tmTimerState(pTimer->enmState), pTimer->szName, pSSM));
 
@@ -2931,6 +2927,5 @@
 {
     VM_ASSERT_EMT(pVM);
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
+    TMTIMER_HANDLE_TO_VARS_RETURN(pVM, hTimer); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
     Assert(pSSM);
     LogFlow(("TMR3TimerLoad: %p:{enmState=%s, .szName='%s'} pSSM=%p\n", pTimer, tmTimerState(pTimer->enmState), pTimer->szName, pSSM));
@@ -2957,5 +2952,5 @@
 
     /* Enter the critical sections to make TMTimerSet/Stop happy. */
-    if (pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC)
+    if (pQueue->enmClock == TMCLOCK_VIRTUAL_SYNC)
         PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_IGNORED);
     PPDMCRITSECT pCritSect = pTimer->pCritSect;
@@ -2990,5 +2985,5 @@
     if (pCritSect)
         PDMCritSectLeave(pCritSect);
-    if (pTimer->enmClock == TMCLOCK_VIRTUAL_SYNC)
+    if (pQueue->enmClock == TMCLOCK_VIRTUAL_SYNC)
         PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
 
@@ -3080,6 +3075,5 @@
 VMMR3DECL(int) TMR3TimerSetCritSect(PVM pVM, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
 {
-    PTMTIMER pTimer;
-    TMTIMER_HANDLE_TO_PTR_RETURN(pVM, hTimer, pTimer);
+    TMTIMER_HANDLE_TO_VARS_RETURN(pVM, hTimer); /* => pTimer, pQueueCC, pQueue, idxTimer, idxQueue */
     AssertPtrReturn(pCritSect, VERR_INVALID_PARAMETER);
     const char *pszName = PDMR3CritSectName(pCritSect); /* exploited for validation */
Index: /trunk/src/VBox/VMM/include/TMInline.h
===================================================================
--- /trunk/src/VBox/VMM/include/TMInline.h	(revision 87812)
+++ /trunk/src/VBox/VMM/include/TMInline.h	(revision 87813)
@@ -211,5 +211,4 @@
 #endif
 
-
 /** @def TMTIMER_HANDLE_TO_VARS_RETURN_EX
  * Converts a timer handle to a timer pointer, returning VERR_INVALID_HANDLE if
@@ -230,91 +229,50 @@
 #define TMTIMER_HANDLE_TO_VARS_RETURN(a_pVM, a_hTimer) TMTIMER_HANDLE_TO_VARS_RETURN_EX(a_pVM, a_hTimer, VERR_INVALID_HANDLE)
 
-
-/** @def TMTIMER_HANDLE_TO_PTR_RETURN_EX
- * Converts a timer handle to a timer pointer, returning @a a_rcRet if the
+/** @def TMTIMER_HANDLE_TO_VARS_RETURN_VOID
+ * Converts a timer handle to a timer pointer, returning void if the
  * handle is invalid.
  *
- * @param   a_pVM       The cross context VM structure.
- * @param   a_hTimer    The timer handle to translate.
- * @param   a_rcRet     What to return on failure.
- * @param   a_pTimerVar The timer variable to assign the resulting pointer to.
+ * This defines the following variables:
+ *      - idxQueue: The queue index.
+ *      - pQueueCC: Pointer to the context specific queue data.
+ *      - pTimer:   The timer pointer.
+ *      - idxTimer: The timer index.
+ *
+ * @param   a_pVM           The cross context VM structure.
+ * @param   a_hTimer        The timer handle to translate.
+ *
+ * @note    This macro has no scoping, so careful when using it around
+ *          conditional statements!
  */
 #ifdef IN_RING3
-# define TMTIMER_HANDLE_TO_PTR_RETURN_EX(a_pVM, a_hTimer, a_rcRet, a_pTimerVar) do { \
-        uintptr_t const idxQueue = (uintptr_t)((a_hTimer) >> TMTIMERHANDLE_QUEUE_IDX_SHIFT) \
-                                 & (uintptr_t)TMTIMERHANDLE_QUEUE_IDX_SMASK; \
-        AssertReturn(idxQueue < RT_ELEMENTS((a_pVM)->tm.s.aTimerQueues), a_rcRet); \
-        \
-        uintptr_t const idxTimer = (uintptr_t)((a_hTimer) & TMTIMERHANDLE_TIMER_IDX_MASK); \
-        AssertReturn(idxQueue < (a_pVM)->tm.s.aTimerQueues[idxQueue].cTimersAlloc, a_rcRet); \
-        \
-        (a_pTimerVar) = &(a_pVM)->tm.s.aTimerQueues[idxQueue].paTimers[idxTimer]; \
-        AssertReturn((a_pTimerVar)->hSelf == a_hTimer, a_rcRet); \
-    } while (0)
-#else
-# define TMTIMER_HANDLE_TO_PTR_RETURN_EX(a_pVM, a_hTimer, a_rcRet, a_pTimerVar) do { \
-        uintptr_t const idxQueue = (uintptr_t)((a_hTimer) >> TMTIMERHANDLE_QUEUE_IDX_SHIFT) \
-                                 & (uintptr_t)TMTIMERHANDLE_QUEUE_IDX_SMASK; \
-        AssertReturn(idxQueue < RT_ELEMENTS((a_pVM)->tm.s.aTimerQueues), a_rcRet); \
-        AssertCompile(RT_ELEMENTS((a_pVM)->tm.s.aTimerQueues) == RT_ELEMENTS((a_pVM)->tmr0.s.aTimerQueues)); \
-        \
-        uintptr_t const idxTimer = (uintptr_t)((a_hTimer) & TMTIMERHANDLE_TIMER_IDX_MASK); \
-        AssertReturn(idxQueue < (a_pVM)->tmr0.s.aTimerQueues[idxQueue].cTimersAlloc, a_rcRet); \
-        \
-        (a_pTimerVar) = &(a_pVM)->tmr0.s.aTimerQueues[idxQueue].paTimers[idxTimer]; \
-        AssertReturn((a_pTimerVar)->hSelf == a_hTimer, a_rcRet); \
-        Assert((a_pTimerVar)->fFlags & TMTIMER_FLAGS_RING0); \
-        Assert(VM_IS_EMT(pVM)); \
-    } while (0)
-#endif
-
-/** @def TMTIMER_HANDLE_TO_PTR_RETURN
- * Converts a timer handle to a timer pointer, returning VERR_INVALID_HANDLE if
- * invalid.
- *
- * @param   a_pVM       The cross context VM structure.
- * @param   a_hTimer    The timer handle to translate.
- * @param   a_pTimerVar The timer variable to assign the resulting pointer to.
- */
-#define TMTIMER_HANDLE_TO_PTR_RETURN(a_pVM, a_hTimer, a_pTimerVar) \
-        TMTIMER_HANDLE_TO_PTR_RETURN_EX(a_pVM, a_hTimer, VERR_INVALID_HANDLE, a_pTimerVar)
-
-/** @def TMTIMER_HANDLE_TO_PTR_RETURN_VOID
- * Converts a timer handle to a timer pointer, returning VERR_INVALID_HANDLE if
- * invalid.
- *
- * @param   a_pVM       The cross context VM structure.
- * @param   a_hTimer    The timer handle to translate.
- * @param   a_pTimerVar The timer variable to assign the resulting pointer to.
- */
-#ifdef IN_RING3
-# define TMTIMER_HANDLE_TO_PTR_RETURN_VOID(a_pVM, a_hTimer, a_pTimerVar) do { \
+# define TMTIMER_HANDLE_TO_VARS_RETURN_VOID(a_pVM, a_hTimer) \
         uintptr_t const idxQueue = (uintptr_t)((a_hTimer) >> TMTIMERHANDLE_QUEUE_IDX_SHIFT) \
                                  & (uintptr_t)TMTIMERHANDLE_QUEUE_IDX_SMASK; \
         AssertReturnVoid(idxQueue < RT_ELEMENTS((a_pVM)->tm.s.aTimerQueues)); \
-        \
-        uintptr_t const idxTimer = (uintptr_t)((a_hTimer) & TMTIMERHANDLE_TIMER_IDX_MASK); \
-        AssertReturnVoid(idxQueue < (a_pVM)->tm.s.aTimerQueues[idxQueue].cTimersAlloc); \
-        \
-        (a_pTimerVar) = &(a_pVM)->tm.s.aTimerQueues[idxQueue].paTimers[idxTimer]; \
-        AssertReturnVoid((a_pTimerVar)->hSelf == a_hTimer); \
-    } while (0)
-#else
-# define TMTIMER_HANDLE_TO_PTR_RETURN_VOID(a_pVM, a_hTimer, a_pTimerVar) do { \
+        PTMTIMERQUEUE const pQueue = &(a_pVM)->tm.s.aTimerQueues[idxQueue]; \
+        PTMTIMERQUEUE const pQueueCC = pQueue; RT_NOREF(pQueueCC); \
+        \
+        uintptr_t const idxTimer = (uintptr_t)((a_hTimer) & TMTIMERHANDLE_TIMER_IDX_MASK); \
+        AssertReturnVoid(idxQueue < pQueue->cTimersAlloc); \
+        \
+        PTMTIMER const pTimer = &pQueue->paTimers[idxTimer]; \
+        AssertReturnVoid(pTimer->hSelf == a_hTimer)
+#else
+# define TMTIMER_HANDLE_TO_VARS_RETURN_VOID(a_pVM, a_hTimer) \
         uintptr_t const idxQueue = (uintptr_t)((a_hTimer) >> TMTIMERHANDLE_QUEUE_IDX_SHIFT) \
                                  & (uintptr_t)TMTIMERHANDLE_QUEUE_IDX_SMASK; \
         AssertReturnVoid(idxQueue < RT_ELEMENTS((a_pVM)->tm.s.aTimerQueues)); \
         AssertCompile(RT_ELEMENTS((a_pVM)->tm.s.aTimerQueues) == RT_ELEMENTS((a_pVM)->tmr0.s.aTimerQueues)); \
-        \
-        uintptr_t const idxTimer = (uintptr_t)((a_hTimer) & TMTIMERHANDLE_TIMER_IDX_MASK); \
-        AssertReturnVoid(idxQueue < (a_pVM)->tmr0.s.aTimerQueues[idxQueue].cTimersAlloc); \
-        \
-        (a_pTimerVar) = &(a_pVM)->tmr0.s.aTimerQueues[idxQueue].paTimers[idxTimer]; \
-        AssertReturnVoid((a_pTimerVar)->hSelf == a_hTimer); \
-        Assert((a_pTimerVar)->fFlags & TMTIMER_FLAGS_RING0); \
-        Assert(VM_IS_EMT(pVM)); \
-    } while (0)
-#endif
-
+        PTMTIMERQUEUE const   pQueue   = &(a_pVM)->tm.s.aTimerQueues[idxQueue]; RT_NOREF(pQueue); \
+        PTMTIMERQUEUER0 const pQueueCC = &(a_pVM)->tmr0.s.aTimerQueues[idxQueue]; \
+        \
+        uintptr_t const idxTimer = (uintptr_t)((a_hTimer) & TMTIMERHANDLE_TIMER_IDX_MASK); \
+        AssertReturnVoid(idxQueue < pQueueCC->cTimersAlloc); \
+        \
+        PTMTIMER const pTimer = &pQueueCC->paTimers[idxTimer]; \
+        AssertReturnVoid(pTimer->hSelf == a_hTimer); \
+        Assert(pTimer->fFlags & TMTIMER_FLAGS_RING0); \
+        Assert(VM_IS_EMT(pVM))
+#endif
 
 #endif /* !VMM_INCLUDED_SRC_include_TMInline_h */
Index: /trunk/src/VBox/VMM/include/TMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/TMInternal.h	(revision 87812)
+++ /trunk/src/VBox/VMM/include/TMInternal.h	(revision 87813)
@@ -285,4 +285,5 @@
     /** Align on 64-byte boundrary. */
     bool                    afAlignment1[7];
+
     /** Time spent doing scheduling and timer callbacks. */
     STAMPROFILE             StatDo;
@@ -290,4 +291,5 @@
     uint32_t volatile       uMaxHzHint;
     uint32_t                u64Alignment2[7];
+
     /** Lock serializing the active timer list and associated work. */
     PDMCRITSECT             TimerLock;
