Index: /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 104955)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 104956)
@@ -936,6 +936,6 @@
         {
             /* likely when executing lots of code, otherwise unlikely */
-# ifdef VBOX_WITH_STATISTICS
-            pVCpu->iem.s.CodeTlb.cTlbHits++;
+# ifdef IEM_WITH_TLB_STATISTICS
+            pVCpu->iem.s.CodeTlb.cTlbCoreHits++;
 # endif
             Assert(!(pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_ACCESSED));
@@ -973,5 +973,5 @@
         else
         {
-            pVCpu->iem.s.CodeTlb.cTlbMisses++;
+            pVCpu->iem.s.CodeTlb.cTlbCoreMisses++;
 
             /* This page table walking will set A bits as required by the access while performing the walk.
@@ -1105,5 +1105,5 @@
         else
         {
-            pVCpu->iem.s.CodeTlb.cTlbSlowReadPath++;
+            pVCpu->iem.s.CodeTlb.cTlbSlowCodeReadPath++;
 
             /* Check instruction length. */
@@ -6342,5 +6342,7 @@
         && !(pTlbe->fFlagsAndPhysRev & (IEMTLBE_F_PT_NO_ACCESSED | (fAccess & IEM_ACCESS_TYPE_WRITE ? IEMTLBE_F_PT_NO_DIRTY : 0))) )
     {
-        STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+# ifdef IEM_WITH_TLB_STATISTICS
+        pVCpu->iem.s.DataTlb.cTlbCoreHits++;
+#endif
 
         /* If the page is either supervisor only or non-writable, we need to do
@@ -6394,5 +6396,5 @@
     else
     {
-        pVCpu->iem.s.DataTlb.cTlbMisses++;
+        pVCpu->iem.s.DataTlb.cTlbCoreMisses++;
 
         /* This page table walking will set A bits as required by the access while performing the walk.
@@ -6618,7 +6620,11 @@
  *                            IEM_MEMMAP_F_ALIGN_GP_OR_AC.
  *                      Pass zero to skip alignment.
- */
-void *iemMemMapJmp(PVMCPUCC pVCpu, uint8_t *pbUnmapInfo, size_t cbMem, uint8_t iSegReg, RTGCPTR GCPtrMem, uint32_t fAccess,
-                   uint32_t uAlignCtl) IEM_NOEXCEPT_MAY_LONGJMP
+ * @tparam  a_fSafe     Whether this is a call from "safe" fallback function in
+ *                      IEMAllMemRWTmpl.cpp.h (@c true) or a generic one that
+ *                      needs counting as such in the statistics.
+ */
+template<bool a_fSafeCall = false>
+static void *iemMemMapJmp(PVMCPUCC pVCpu, uint8_t *pbUnmapInfo, size_t cbMem, uint8_t iSegReg, RTGCPTR GCPtrMem,
+                          uint32_t fAccess, uint32_t uAlignCtl) IEM_NOEXCEPT_MAY_LONGJMP
 {
     STAM_COUNTER_INC(&pVCpu->iem.s.StatMemMapJmp);
@@ -6739,8 +6745,18 @@
     if (   pTlbe->uTag == uTag
         && !(pTlbe->fFlagsAndPhysRev & (IEMTLBE_F_PT_NO_ACCESSED | (fNoWriteNoDirty & IEMTLBE_F_PT_NO_DIRTY))) )
-        STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+    {
+# ifdef IEM_WITH_TLB_STATISTICS
+        if (a_fSafeCall)
+            pVCpu->iem.s.DataTlb.cTlbSafeHits++;
+        else
+            pVCpu->iem.s.DataTlb.cTlbCoreHits++;
+# endif
+    }
     else
     {
-        pVCpu->iem.s.DataTlb.cTlbMisses++;
+        if (a_fSafeCall)
+            pVCpu->iem.s.DataTlb.cTlbSafeMisses++;
+        else
+            pVCpu->iem.s.DataTlb.cTlbCoreMisses++;
 
         /* This page table walking will set A and D bits as required by the
@@ -6941,4 +6957,12 @@
     *pbUnmapInfo = iMemMap | 0x08 | ((fAccess & IEM_ACCESS_TYPE_MASK) << 4);
     return pvMem;
+}
+
+
+/** @see iemMemMapJmp */
+static void *iemMemMapSafeJmp(PVMCPUCC pVCpu, uint8_t *pbUnmapInfo, size_t cbMem, uint8_t iSegReg, RTGCPTR GCPtrMem,
+                              uint32_t fAccess, uint32_t uAlignCtl) IEM_NOEXCEPT_MAY_LONGJMP
+{
+    return iemMemMapJmp<true /*a_fSafeCall*/>(pVCpu, pbUnmapInfo, cbMem, iSegReg, GCPtrMem, fAccess, uAlignCtl);
 }
 
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmpl.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmpl.cpp.h	(revision 104955)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmpl.cpp.h	(revision 104956)
@@ -84,6 +84,6 @@
 #  endif
     uint8_t              bUnmapInfo;
-    TMPL_MEM_TYPE const *pSrc = (TMPL_MEM_TYPE const *)iemMemMapJmp(pVCpu, &bUnmapInfo, sizeof(*pSrc), iSegReg, GCPtrMem,
-                                                                    IEM_ACCESS_DATA_R, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
+    TMPL_MEM_TYPE const *pSrc = (TMPL_MEM_TYPE const *)iemMemMapSafeJmp(pVCpu, &bUnmapInfo, sizeof(*pSrc), iSegReg, GCPtrMem,
+                                                                        IEM_ACCESS_DATA_R, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
     *pDst = *pSrc;
     iemMemCommitAndUnmapJmp(pVCpu, bUnmapInfo);
@@ -98,6 +98,6 @@
 #  endif
     uint8_t              bUnmapInfo;
-    TMPL_MEM_TYPE const *puSrc = (TMPL_MEM_TYPE const *)iemMemMapJmp(pVCpu, &bUnmapInfo, sizeof(*puSrc), iSegReg, GCPtrMem,
-                                                                     IEM_ACCESS_DATA_R, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
+    TMPL_MEM_TYPE const *puSrc = (TMPL_MEM_TYPE const *)iemMemMapSafeJmp(pVCpu, &bUnmapInfo, sizeof(*puSrc), iSegReg, GCPtrMem,
+                                                                         IEM_ACCESS_DATA_R, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
     TMPL_MEM_TYPE const  uRet = *puSrc;
     iemMemCommitAndUnmapJmp(pVCpu, bUnmapInfo);
@@ -172,6 +172,6 @@
 #endif
     uint8_t        bUnmapInfo;
-    TMPL_MEM_TYPE *puDst = (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, &bUnmapInfo, sizeof(*puDst), iSegReg, GCPtrMem,
-                                                         IEM_ACCESS_DATA_W, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
+    TMPL_MEM_TYPE *puDst = (TMPL_MEM_TYPE *)iemMemMapSafeJmp(pVCpu, &bUnmapInfo, sizeof(*puDst), iSegReg, GCPtrMem,
+                                                             IEM_ACCESS_DATA_W, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
 #ifdef TMPL_MEM_BY_REF
     *puDst = *pValue;
@@ -205,6 +205,6 @@
     Log8(("IEM AT/map " TMPL_MEM_FMT_DESC " %d|%RGv\n", iSegReg, GCPtrMem));
     *pbUnmapInfo = 1 | ((IEM_ACCESS_TYPE_READ  | IEM_ACCESS_TYPE_WRITE) << 4); /* zero is for the TLB hit */
-    return (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, pbUnmapInfo, sizeof(TMPL_MEM_TYPE), iSegReg, GCPtrMem,
-                                         IEM_ACCESS_DATA_ATOMIC, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
+    return (TMPL_MEM_TYPE *)iemMemMapSafeJmp(pVCpu, pbUnmapInfo, sizeof(TMPL_MEM_TYPE), iSegReg, GCPtrMem,
+                                             IEM_ACCESS_DATA_ATOMIC, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
 }
 
@@ -229,6 +229,6 @@
     Log8(("IEM RW/map " TMPL_MEM_FMT_DESC " %d|%RGv\n", iSegReg, GCPtrMem));
     *pbUnmapInfo = 1 | ((IEM_ACCESS_TYPE_READ  | IEM_ACCESS_TYPE_WRITE) << 4); /* zero is for the TLB hit */
-    return (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, pbUnmapInfo, sizeof(TMPL_MEM_TYPE), iSegReg, GCPtrMem,
-                                         IEM_ACCESS_DATA_RW, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
+    return (TMPL_MEM_TYPE *)iemMemMapSafeJmp(pVCpu, pbUnmapInfo, sizeof(TMPL_MEM_TYPE), iSegReg, GCPtrMem,
+                                             IEM_ACCESS_DATA_RW, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
 }
 
@@ -253,6 +253,6 @@
     Log8(("IEM WO/map " TMPL_MEM_FMT_DESC " %d|%RGv\n", iSegReg, GCPtrMem));
     *pbUnmapInfo = 1 | (IEM_ACCESS_TYPE_WRITE << 4); /* zero is for the TLB hit */
-    return (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, pbUnmapInfo, sizeof(TMPL_MEM_TYPE), iSegReg, GCPtrMem,
-                                         IEM_ACCESS_DATA_W, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
+    return (TMPL_MEM_TYPE *)iemMemMapSafeJmp(pVCpu, pbUnmapInfo, sizeof(TMPL_MEM_TYPE), iSegReg, GCPtrMem,
+                                             IEM_ACCESS_DATA_W, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
 }
 
@@ -277,6 +277,6 @@
     Log4(("IEM RO/map " TMPL_MEM_FMT_DESC " %d|%RGv\n", iSegReg, GCPtrMem));
     *pbUnmapInfo = 1 | (IEM_ACCESS_TYPE_READ << 4); /* zero is for the TLB hit */
-    return (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, pbUnmapInfo, sizeof(TMPL_MEM_TYPE), iSegReg, GCPtrMem,
-                                         IEM_ACCESS_DATA_R, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
+    return (TMPL_MEM_TYPE *)iemMemMapSafeJmp(pVCpu, pbUnmapInfo, sizeof(TMPL_MEM_TYPE), iSegReg, GCPtrMem,
+                                             IEM_ACCESS_DATA_R, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
 }
 
@@ -496,6 +496,6 @@
 
     uint8_t        bUnmapInfo;
-    TMPL_MEM_TYPE *puDst = (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, &bUnmapInfo, sizeof(TMPL_MEM_TYPE), X86_SREG_SS, GCPtrMem,
-                                                         IEM_ACCESS_STACK_W, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
+    TMPL_MEM_TYPE *puDst = (TMPL_MEM_TYPE *)iemMemMapSafeJmp(pVCpu, &bUnmapInfo, sizeof(TMPL_MEM_TYPE), X86_SREG_SS, GCPtrMem,
+                                                             IEM_ACCESS_STACK_W, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
     *puDst = uValue;
     iemMemCommitAndUnmapJmp(pVCpu, bUnmapInfo);
@@ -529,6 +529,6 @@
         {
             /* WORD per intel specs. */
-            uint16_t *puDst = (uint16_t *)iemMemMapJmp(pVCpu, &bUnmapInfo, sizeof(uint16_t), X86_SREG_SS, GCPtrMem,
-                                                       IEM_ACCESS_STACK_W, (sizeof(uint16_t) - 1) | TMPL_MEM_MAP_FLAGS_ADD); /** @todo 2 or 4 alignment check for PUSH SS? */
+            uint16_t *puDst = (uint16_t *)iemMemMapSafeJmp(pVCpu, &bUnmapInfo, sizeof(uint16_t), X86_SREG_SS, GCPtrMem,
+                                                           IEM_ACCESS_STACK_W, (sizeof(uint16_t) - 1) | TMPL_MEM_MAP_FLAGS_ADD); /** @todo 2 or 4 alignment check for PUSH SS? */
             *puDst = (uint16_t)uValue;
             iemMemCommitAndUnmapJmp(pVCpu, bUnmapInfo);
@@ -541,6 +541,6 @@
              *        than FS (which all that bs3-cpu-weird-1 does atm).  (Maybe this is
              *        something for the CPU profile... Hope not.) */
-            uint32_t *puDst = (uint32_t *)iemMemMapJmp(pVCpu, &bUnmapInfo, sizeof(uint32_t), X86_SREG_SS, GCPtrMem,
-                                                       IEM_ACCESS_STACK_W, (sizeof(uint32_t) - 1) | TMPL_MEM_MAP_FLAGS_ADD);
+            uint32_t *puDst = (uint32_t *)iemMemMapSafeJmp(pVCpu, &bUnmapInfo, sizeof(uint32_t), X86_SREG_SS, GCPtrMem,
+                                                           IEM_ACCESS_STACK_W, (sizeof(uint32_t) - 1) | TMPL_MEM_MAP_FLAGS_ADD);
             *puDst = (uint16_t)uValue | (pVCpu->cpum.GstCtx.eflags.u & (UINT32_C(0xffff0000) & ~X86_EFL_RAZ_MASK));
             iemMemCommitAndUnmapJmp(pVCpu, bUnmapInfo);
@@ -551,6 +551,6 @@
     {
         /* DWORD per spec. */
-        uint32_t *puDst = (uint32_t *)iemMemMapJmp(pVCpu, &bUnmapInfo, sizeof(uint32_t), X86_SREG_SS, GCPtrMem,
-                                                   IEM_ACCESS_STACK_W, (sizeof(uint32_t) - 1) | TMPL_MEM_MAP_FLAGS_ADD);
+        uint32_t *puDst = (uint32_t *)iemMemMapSafeJmp(pVCpu, &bUnmapInfo, sizeof(uint32_t), X86_SREG_SS, GCPtrMem,
+                                                       IEM_ACCESS_STACK_W, (sizeof(uint32_t) - 1) | TMPL_MEM_MAP_FLAGS_ADD);
         *puDst = uValue;
         iemMemCommitAndUnmapJmp(pVCpu, bUnmapInfo);
@@ -572,6 +572,6 @@
     /* Read the data. */
     uint8_t              bUnmapInfo;
-    TMPL_MEM_TYPE const *puSrc = (TMPL_MEM_TYPE const *)iemMemMapJmp(pVCpu, &bUnmapInfo, sizeof(TMPL_MEM_TYPE), X86_SREG_SS,
-                                                                     GCPtrMem, IEM_ACCESS_STACK_R, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
+    TMPL_MEM_TYPE const *puSrc = (TMPL_MEM_TYPE const *)iemMemMapSafeJmp(pVCpu, &bUnmapInfo, sizeof(TMPL_MEM_TYPE), X86_SREG_SS,
+                                                                         GCPtrMem, IEM_ACCESS_STACK_R, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
     TMPL_MEM_TYPE const  uValue = *puSrc;
     iemMemCommitAndUnmapJmp(pVCpu, bUnmapInfo);
@@ -598,6 +598,6 @@
     /* Write the data. */
     uint8_t        bUnmapInfo;
-    TMPL_MEM_TYPE *puDst = (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, &bUnmapInfo, sizeof(TMPL_MEM_TYPE), X86_SREG_SS, GCPtrTop,
-                                                         IEM_ACCESS_STACK_W, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
+    TMPL_MEM_TYPE *puDst = (TMPL_MEM_TYPE *)iemMemMapSafeJmp(pVCpu, &bUnmapInfo, sizeof(TMPL_MEM_TYPE), X86_SREG_SS, GCPtrTop,
+                                                             IEM_ACCESS_STACK_W, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
     *puDst = uValue;
     iemMemCommitAndUnmapJmp(pVCpu, bUnmapInfo);
@@ -625,6 +625,6 @@
     /* Read the data. */
     uint8_t              bUnmapInfo;
-    TMPL_MEM_TYPE const *puSrc = (TMPL_MEM_TYPE const *)iemMemMapJmp(pVCpu, &bUnmapInfo, sizeof(TMPL_MEM_TYPE), X86_SREG_SS,
-                                                                     GCPtrTop, IEM_ACCESS_STACK_R, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
+    TMPL_MEM_TYPE const *puSrc = (TMPL_MEM_TYPE const *)iemMemMapSafeJmp(pVCpu, &bUnmapInfo, sizeof(TMPL_MEM_TYPE), X86_SREG_SS,
+                                                                         GCPtrTop, IEM_ACCESS_STACK_R, TMPL_MEM_TYPE_ALIGN | TMPL_MEM_MAP_FLAGS_ADD);
     TMPL_MEM_TYPE const  uValue = *puSrc;
     iemMemCommitAndUnmapJmp(pVCpu, bUnmapInfo);
@@ -666,6 +666,6 @@
      * ancient hardware when it actually did change. */
     uint8_t   bUnmapInfo;
-    uint16_t *puDst = (uint16_t *)iemMemMapJmp(pVCpu, &bUnmapInfo, sizeof(uint16_t), X86_SREG_SS, GCPtrTop,
-                                               IEM_ACCESS_STACK_W, (sizeof(uint16_t) - 1) | TMPL_MEM_MAP_FLAGS_ADD); /** @todo 2 or 4 alignment check for PUSH SS? */
+    uint16_t *puDst = (uint16_t *)iemMemMapSafeJmp(pVCpu, &bUnmapInfo, sizeof(uint16_t), X86_SREG_SS, GCPtrTop,
+                                                   IEM_ACCESS_STACK_W, (sizeof(uint16_t) - 1) | TMPL_MEM_MAP_FLAGS_ADD); /** @todo 2 or 4 alignment check for PUSH SS? */
     *puDst = (uint16_t)uValue;
     iemMemCommitAndUnmapJmp(pVCpu, bUnmapInfo);
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h	(revision 104955)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h	(revision 104956)
@@ -127,5 +127,7 @@
                  * Fetch and return the data.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#  ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#  endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -198,5 +200,7 @@
                  * Fetch and return the dword
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#  ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#  endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -274,5 +278,7 @@
                  * Store the value and return.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#   ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#   endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -345,5 +351,7 @@
                  * Store the value and return.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#   ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#   endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -419,5 +427,7 @@
                  * Return the address.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#   ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#   endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -476,5 +486,7 @@
                  * Return the address.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#   ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#   endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -535,5 +547,7 @@
                  * Return the address.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#   ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#   endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -592,5 +606,7 @@
                  * Return the address.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#   ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#   endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -649,5 +665,7 @@
                  * Return the address.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#   ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#   endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -704,5 +722,7 @@
                  * Return the address.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#   ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#   endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -759,5 +779,7 @@
                  * Return the address.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#   ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#   endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -813,5 +835,7 @@
                  * Return the address.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#  ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#  endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -882,5 +906,7 @@
                  * Do the store and return.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#   ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#   endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -943,5 +969,7 @@
                  * Do the push and return.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#      ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#      endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -1004,5 +1032,7 @@
                  * Do the push and return.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#    ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#    endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -1061,5 +1091,7 @@
                  * Do the push and return.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#     ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#     endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -1117,5 +1149,7 @@
                  * Do the pop.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#   ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#   endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -1169,5 +1203,7 @@
                  * Do the pop.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#    ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#    endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -1226,5 +1262,7 @@
                  * Do the push and return.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#   ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#   endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -1286,5 +1324,7 @@
                  * Do the pop.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#  ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#  endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -1322,5 +1362,5 @@
 RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,SRegJmp)(PVMCPUCC pVCpu, TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
 {
-#  if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3) && !defined(TMPL_MEM_NO_INLINE)
+#    if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3) && !defined(TMPL_MEM_NO_INLINE)
     /* See fallback for details on this weirdness: */
     bool const    fIsIntel = IEM_IS_GUEST_CPU_INTEL(pVCpu);
@@ -1334,10 +1374,10 @@
     RTGCPTR const GCPtrTop = iemRegGetRspForPush(pVCpu, sizeof(TMPL_MEM_TYPE), &uNewRsp);
     RTGCPTR const GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, X86_SREG_SS, cbAccess, GCPtrTop);
-#  if TMPL_MEM_TYPE_SIZE > 1
+#     if TMPL_MEM_TYPE_SIZE > 1
     if (RT_LIKELY(   !(GCPtrEff & (cbAccess - 1U))
                   || (   cbAccess == sizeof(uint16_t)
                       ? TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, uint16_t)
                       : TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ) ))
-#  endif
+#    endif
     {
         /*
@@ -1362,5 +1402,7 @@
                  * Do the push and return.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#    ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#    endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -1395,5 +1437,5 @@
        outdated page pointer, or other troubles.  (This will do a TLB load.) */
     Log12Ex(LOG_GROUP_IEM_MEM,(LOG_FN_FMT ": %RGv falling back\n", LOG_FN_NAME, GCPtrEff));
-#  endif
+#    endif
     RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,SRegSafeJmp)(pVCpu, uValue);
 }
@@ -1412,12 +1454,12 @@
            && pVCpu->cpum.GstCtx.ss.u32Limit == UINT32_MAX
            && pVCpu->cpum.GstCtx.ss.u64Base == 0);
-#  if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3) && !defined(TMPL_MEM_NO_INLINE)
+#    if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3) && !defined(TMPL_MEM_NO_INLINE)
     /*
      * Calculate the new stack pointer and check that the item doesn't cross a page boundrary.
      */
     uint32_t const uNewEsp = pVCpu->cpum.GstCtx.esp - sizeof(TMPL_MEM_TYPE);
-#  if TMPL_MEM_TYPE_SIZE > 1
+#     if TMPL_MEM_TYPE_SIZE > 1
     if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(uNewEsp)))
-#  endif
+#     endif
     {
         /*
@@ -1442,5 +1484,7 @@
                  * Do the push and return.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#     ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#     endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -1457,5 +1501,5 @@
        outdated page pointer, or other troubles.  (This will do a TLB load.) */
     Log12Ex(LOG_GROUP_IEM_MEM,(LOG_FN_FMT ": %RX32 falling back\n", LOG_FN_NAME, uNewEsp));
-#  endif
+#    endif
     RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, uValue);
 }
@@ -1469,12 +1513,12 @@
 {
     Assert(iGReg < 16);
-#  if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3) && !defined(TMPL_MEM_NO_INLINE)
+#    if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3) && !defined(TMPL_MEM_NO_INLINE)
     /*
      * Calculate the new stack pointer and check that the item doesn't cross a page boundrary.
      */
     uint32_t const uOldEsp = pVCpu->cpum.GstCtx.esp;
-#   if TMPL_MEM_TYPE_SIZE > 1
+#     if TMPL_MEM_TYPE_SIZE > 1
     if (RT_LIKELY(TMPL_MEM_ALIGN_CHECK(uOldEsp)))
-#   endif
+#     endif
     {
         /*
@@ -1498,16 +1542,18 @@
                  * Do the pop and update the register values.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#     ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#     endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
                 TMPL_MEM_TYPE const uValue = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[uOldEsp & GUEST_PAGE_OFFSET_MASK];
                 pVCpu->cpum.GstCtx.rsp = uOldEsp + sizeof(TMPL_MEM_TYPE); /* must be first for 16-bit */
-#   if TMPL_MEM_TYPE_SIZE == 2
+#     if TMPL_MEM_TYPE_SIZE == 2
                 pVCpu->cpum.GstCtx.aGRegs[iGReg].u16 = uValue;
-#   elif TMPL_MEM_TYPE_SIZE == 4
+#     elif TMPL_MEM_TYPE_SIZE == 4
                 pVCpu->cpum.GstCtx.aGRegs[iGReg].u   = uValue;
-#   else
-#    error "TMPL_MEM_TYPE_SIZE"
-#   endif
+#     else
+#      error "TMPL_MEM_TYPE_SIZE"
+#     endif
                 Log9Ex(LOG_GROUP_IEM_MEM,("IEM RD " TMPL_MEM_FMT_DESC " SS|%RX32 (->%RX32): " TMPL_MEM_FMT_TYPE " (r%u)\n",
                                           uOldEsp, uOldEsp + sizeof(TMPL_MEM_TYPE), uValue, iGReg));
@@ -1520,5 +1566,5 @@
        outdated page pointer, or other troubles.  (This will do a TLB load.) */
     Log10Ex(LOG_GROUP_IEM_MEM,(LOG_FN_FMT ": %RX32 falling back\n", LOG_FN_NAME, uOldEsp));
-#  endif
+#    endif
     RT_CONCAT3(iemMemStackPopGReg,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, iGReg);
 }
@@ -1536,5 +1582,5 @@
 RT_CONCAT3(iemMemFlat32StackPush,TMPL_MEM_FN_SUFF,SRegJmp)(PVMCPUCC pVCpu, TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
 {
-#  if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3) && !defined(TMPL_MEM_NO_INLINE)
+#    if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3) && !defined(TMPL_MEM_NO_INLINE)
     /* See fallback for details on this weirdness: */
     bool const    fIsIntel = IEM_IS_GUEST_CPU_INTEL(pVCpu);
@@ -1571,5 +1617,7 @@
                  * Do the push and return.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#     ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#     endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -1604,5 +1652,5 @@
        outdated page pointer, or other troubles.  (This will do a TLB load.) */
     Log12Ex(LOG_GROUP_IEM_MEM,(LOG_FN_FMT ": %RX32 falling back\n", LOG_FN_NAME, uNewEsp));
-#  endif
+#    endif
     RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,SRegSafeJmp)(pVCpu, uValue);
 }
@@ -1647,5 +1695,7 @@
                  * Do the push and return.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#     ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#     endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
@@ -1703,5 +1753,7 @@
                  * Do the push and return.
                  */
-                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
+#     ifdef IEM_WITH_TLB_STATISTICS
+                pVCpu->iem.s.DataTlb.cTlbInlineCodeHits++;
+#     endif
                 Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
                 Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompBltIn.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompBltIn.cpp	(revision 104955)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompBltIn.cpp	(revision 104956)
@@ -1306,5 +1306,5 @@
                                             idxLabelTlbLookup, idxLabelTlbMiss, idxRegGCPhys, offInstr);
 
-# ifdef VBOX_WITH_STATISTICS
+# ifdef IEM_WITH_TLB_STATISTICS
         off = iemNativeEmitIncStamCounterInVCpu(pReNative, off, TlbState.idxReg1, TlbState.idxReg2,
                                                 RT_UOFFSETOF(VMCPUCC, iem.s.StatNativeCodeTlbHitsForNewPageWithOffset));
@@ -1600,5 +1600,5 @@
                                                   idxLabelTlbLookup, idxLabelTlbMiss, idxRegDummy);
 
-# ifdef VBOX_WITH_STATISTICS
+# ifdef IEM_WITH_TLB_STATISTICS
         off = iemNativeEmitIncStamCounterInVCpu(pReNative, off, TlbState.idxReg1, TlbState.idxReg2,
                                                 RT_UOFFSETOF(VMCPUCC, iem.s.StatNativeCodeTlbHitsForNewPage));
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h	(revision 104955)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h	(revision 104956)
@@ -1164,5 +1164,5 @@
          */
         PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 64);
-# ifdef VBOX_WITH_STATISTICS
+# ifdef IEM_WITH_TLB_STATISTICS
         off = iemNativeEmitIncStamCounterInVCpuEx(pCodeBuf, off, TlbState.idxReg1, TlbState.idxReg2,
                                                   RT_UOFFSETOF(VMCPUCC, iem.s.StatNativeTlbHitsForStack));
@@ -1847,5 +1847,5 @@
          */
         PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 32);
-# ifdef VBOX_WITH_STATISTICS
+# ifdef IEM_WITH_TLB_STATISTICS
         off = iemNativeEmitIncStamCounterInVCpuEx(pCodeBuf, off, TlbState.idxReg1, TlbState.idxReg2,
                                                   RT_UOFFSETOF(VMCPUCC, iem.s.StatNativeTlbHitsForStack));
@@ -6678,5 +6678,5 @@
          */
         PIEMNATIVEINSTR pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 64);
-# ifdef VBOX_WITH_STATISTICS
+# ifdef IEM_WITH_TLB_STATISTICS
         off = iemNativeEmitIncStamCounterInVCpuEx(pCodeBuf, off, TlbState.idxReg1, TlbState.idxReg2,
                                                   enmOp == kIemNativeEmitMemOp_Store
@@ -7565,5 +7565,5 @@
          */
         PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 64);
-# ifdef VBOX_WITH_STATISTICS
+# ifdef IEM_WITH_TLB_STATISTICS
         off = iemNativeEmitIncStamCounterInVCpuEx(pCodeBuf, off, TlbState.idxReg1, TlbState.idxReg2,
                                                   RT_UOFFSETOF(VMCPUCC, iem.s.StatNativeTlbHitsForStack));
@@ -7912,5 +7912,5 @@
          */
         PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 32);
-# ifdef VBOX_WITH_STATISTICS
+# ifdef IEM_WITH_TLB_STATISTICS
         off = iemNativeEmitIncStamCounterInVCpuEx(pCodeBuf, off, TlbState.idxReg1, TlbState.idxReg2,
                                                   RT_UOFFSETOF(VMCPUCC, iem.s.StatNativeTlbHitsForStack));
@@ -8497,5 +8497,5 @@
         off = iemNativeEmitTlbLookup<true>(pReNative, off, &TlbState, iSegReg, cbMem, fAlignMask, fAccess,
                                            idxLabelTlbLookup, idxLabelTlbMiss, idxRegMemResult);
-# ifdef VBOX_WITH_STATISTICS
+# ifdef IEM_WITH_TLB_STATISTICS
         off = iemNativeEmitIncStamCounterInVCpu(pReNative, off, TlbState.idxReg1, TlbState.idxReg2,
                                                 RT_UOFFSETOF(VMCPUCC,  iem.s.StatNativeTlbHitsForMapped));
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp	(revision 104955)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp	(revision 104956)
@@ -8609,9 +8609,20 @@
         ENTRY(iem.s.DataTlb.uTlbRevision),
         ENTRY(iem.s.DataTlb.uTlbPhysRev),
-        ENTRY(iem.s.DataTlb.cTlbHits),
+        ENTRY(iem.s.DataTlb.cTlbCoreHits),
+        ENTRY(iem.s.DataTlb.cTlbInlineCodeHits),
+        ENTRY(iem.s.DataTlb.cTlbNativeMissTag),
+        ENTRY(iem.s.DataTlb.cTlbNativeMissFlagsAndPhysRev),
+        ENTRY(iem.s.DataTlb.cTlbNativeMissAlignment),
+        ENTRY(iem.s.DataTlb.cTlbNativeMissCrossPage),
+        ENTRY(iem.s.DataTlb.cTlbNativeMissNonCanonical),
         ENTRY(iem.s.DataTlb.aEntries),
         ENTRY(iem.s.CodeTlb.uTlbRevision),
         ENTRY(iem.s.CodeTlb.uTlbPhysRev),
-        ENTRY(iem.s.CodeTlb.cTlbHits),
+        ENTRY(iem.s.CodeTlb.cTlbCoreHits),
+        ENTRY(iem.s.CodeTlb.cTlbNativeMissTag),
+        ENTRY(iem.s.CodeTlb.cTlbNativeMissFlagsAndPhysRev),
+        ENTRY(iem.s.CodeTlb.cTlbNativeMissAlignment),
+        ENTRY(iem.s.CodeTlb.cTlbNativeMissCrossPage),
+        ENTRY(iem.s.CodeTlb.cTlbNativeMissNonCanonical),
         ENTRY(iem.s.CodeTlb.aEntries),
         ENTRY(pVMR3),
Index: /trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/IEMR3.cpp	(revision 104955)
+++ /trunk/src/VBox/VMM/VMMR3/IEMR3.cpp	(revision 104956)
@@ -297,4 +297,6 @@
         char   szPat[128];
         RT_NOREF_PV(szPat); /* lazy bird */
+        char   szVal[128];
+        RT_NOREF_PV(szVal); /* lazy bird */
 
         STAMR3RegisterF(pVM, &pVCpu->iem.s.cInstructions,               STAMTYPE_U32,       STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
@@ -319,63 +321,150 @@
                         "Number of misaligned (for the host) atomic instructions", "/IEM/CPU%u/cMisalignedAtomics", idCpu);
 
-        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbMisses,          STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Code TLB misses",                          "/IEM/CPU%u/CodeTlb-Misses", idCpu);
+        /* Code TLB: */
         STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.uTlbRevision,        STAMTYPE_X64,       STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
-                        "Code TLB revision",                        "/IEM/CPU%u/CodeTlb-Revision", idCpu);
+                        "Code TLB revision",                            "/IEM/CPU%u/Tlb/Code/Revision", idCpu);
         STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.CodeTlb.uTlbPhysRev, STAMTYPE_X64,       STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
-                        "Code TLB physical revision",               "/IEM/CPU%u/CodeTlb-PhysRev", idCpu);
-        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbSlowReadPath,    STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Code TLB slow read path",                  "/IEM/CPU%u/CodeTlb-SlowReads", idCpu);
-
-        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbMisses,          STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Data TLB misses",                          "/IEM/CPU%u/DataTlb-Misses", idCpu);
-        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbSafeReadPath,    STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Data TLB safe read path",                  "/IEM/CPU%u/DataTlb-SafeReads", idCpu);
-        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbSafeWritePath,   STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Data TLB safe write path",                 "/IEM/CPU%u/DataTlb-SafeWrites", idCpu);
+                        "Code TLB physical revision",                   "/IEM/CPU%u/Tlb/Code/RevisionPhysical", idCpu);
+
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbCoreMisses,      STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Code TLB misses",                              "/IEM/CPU%u/Tlb/Code/Misses", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbSlowCodeReadPath, STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Code TLB slow read path",                      "/IEM/CPU%u/Tlb/Code/SlowReads", idCpu);
+# ifdef IEM_WITH_TLB_STATISTICS
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbCoreHits,        STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Code TLB hits (non-native)",                   "/IEM/CPU%u/Tlb/Code/Hits/Other", idCpu);
+#  if defined(VBOX_WITH_IEM_NATIVE_RECOMPILER)
+        STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeCodeTlbHitsForNewPage, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Code TLB native hits on new page",             "/IEM/CPU%u/Tlb/Code/Hits/New-Page", idCpu);
+        STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeCodeTlbHitsForNewPageWithOffset, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Code TLB native hits on new page /w offset",   "/IEM/CPU%u/Tlb/Code/Hits/New-Page-With-Offset", idCpu);
+#  endif
+
+        RTStrPrintf(szPat, sizeof(szPat), "/IEM/CPU%u/Tlb/Code/Hits/*", idCpu);
+        STAMR3RegisterSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, szPat, "Code TLB hits",
+                          "/IEM/CPU%u/Tlb/Code/Hits", idCpu);
+
+        RTStrPrintf(szVal, sizeof(szVal), "/IEM/CPU%u/Tlb/Code/Misses", idCpu);
+        RTStrPrintf(szPat, sizeof(szPat), "/IEM/CPU%u/Tlb/Code/Hits", idCpu);
+        STAMR3RegisterPctOfSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, STAMUNIT_PPM, szVal, true, szPat,
+                               "Code TLB actual miss rate",             "/IEM/CPU%u/Tlb/Code/RateMisses", idCpu);
+
+#  if defined(VBOX_WITH_IEM_NATIVE_RECOMPILER)
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbNativeMissTag,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Code TLB misses in native code: Tag mismatch [not directly included grand parent sum]",
+                        "/IEM/CPU%u/Tlb/Code/Misses/NativeBreakdown/Tag", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbNativeMissFlagsAndPhysRev,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Code TLB misses in native code: Flags or physical revision mistmatch [not directly included grand parent sum]",
+                        "/IEM/CPU%u/Tlb/Code/Misses/NativeBreakdown/FlagsAndPhysRev", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbNativeMissAlignment,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Code TLB misses in native code: Alignment [not directly included grand parent sum]",
+                        "/IEM/CPU%u/Tlb/Code/Misses/NativeBreakdown/Alignment", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbNativeMissCrossPage,  STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Code TLB misses in native code: Cross page [not directly included grand parent sum]",
+                        "/IEM/CPU%u/Tlb/Code/Misses/NativeBreakdown/CrossPage", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbNativeMissNonCanonical,  STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Code TLB misses in native code: Non-canonical [not directly included grand parent sum]",
+                        "/IEM/CPU%u/Tlb/Code/Misses/NativeBreakdown/NonCanonical", idCpu);
+
+        STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeCodeTlbMissesNewPage, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Code TLB native misses on new page",
+                        "/IEM/CPU%u/Tlb/Code/Misses/NativeBreakdown2/New-Page", idCpu);
+        STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeCodeTlbMissesNewPageWithOffset, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Code TLB native misses on new page w/ offset",
+                        "/IEM/CPU%u/Tlb/Code/Misses/NativeBreakdown2/New-Page-With-Offset", idCpu);
+#  endif
+# endif /* IEM_WITH_TLB_STATISTICS */
+
+        /* Data TLB organized as best we can... */
         STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.uTlbRevision,        STAMTYPE_X64,       STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
-                        "Data TLB revision",                        "/IEM/CPU%u/DataTlb-Revision", idCpu);
+                        "Data TLB revision",                            "/IEM/CPU%u/Tlb/Data/Revision", idCpu);
         STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.DataTlb.uTlbPhysRev, STAMTYPE_X64,       STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
-                        "Data TLB physical revision",               "/IEM/CPU%u/DataTlb-PhysRev", idCpu);
-
-# ifdef VBOX_WITH_STATISTICS
-        STAMR3RegisterF(pVM, &pVCpu->iem.s.CodeTlb.cTlbHits,            STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Code TLB hits",                            "/IEM/CPU%u/CodeTlb-Hits", idCpu);
-        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbHits,            STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Data TLB hits",                            "/IEM/CPU%u/DataTlb-Hits-Other", idCpu);
+                        "Data TLB physical revision",                   "/IEM/CPU%u/Tlb/Data/RevisionPhysical", idCpu);
+
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbCoreMisses,      STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Data TLB core misses (iemMemMap, direct iemMemMapJmp (not safe path))",
+                        "/IEM/CPU%u/Tlb/Data/Misses/Core", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbSafeReadPath,    STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Data TLB safe read path (inline/native misses going to iemMemMapJmp)",
+                        "/IEM/CPU%u/Tlb/Data/Misses/Safe/Reads", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbSafeWritePath,   STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Data TLB safe write path (inline/native misses going to iemMemMapJmp)",
+                        "/IEM/CPU%u/Tlb/Data/Misses/Safe/Writes", idCpu);
+        RTStrPrintf(szPat, sizeof(szPat), "/IEM/CPU%u/Tlb/Data/Misses/*", idCpu);
+        STAMR3RegisterSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, szPat, "Data TLB misses",
+                          "/IEM/CPU%u/Tlb/Data/Misses", idCpu);
+
+        RTStrPrintf(szPat, sizeof(szPat), "/IEM/CPU%u/Tlb/Data/Misses/Safe/*", idCpu);
+        STAMR3RegisterSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, szPat, "Data TLB actual safe path calls (read + write)",
+                          "/IEM/CPU%u/Tlb/Data/Misses/Safe", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbSafeHits,        STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Data TLB hits in iemMemMapJmp - not part of safe-path total",
+                        "/IEM/CPU%u/Tlb/Data/Misses/Safe/SubPartHits", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbSafeMisses,      STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Data TLB misses in iemMemMapJmp - not part of safe-path total",
+                        "/IEM/CPU%u/Tlb/Data/Misses/Safe/SubPartMisses", idCpu);
+
+# ifdef IEM_WITH_TLB_STATISTICS
+#  ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbNativeMissTag,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Data TLB misses in native code: Tag mismatch [not directly included grand parent sum]",
+                        "/IEM/CPU%u/Tlb/Data/Misses/NativeBreakdown/Tag", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbNativeMissFlagsAndPhysRev,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Data TLB misses in native code: Flags or physical revision mistmatch [not directly included grand parent sum]",
+                        "/IEM/CPU%u/Tlb/Data/Misses/NativeBreakdown/FlagsAndPhysRev", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbNativeMissAlignment,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Data TLB misses in native code: Alignment [not directly included grand parent sum]",
+                        "/IEM/CPU%u/Tlb/Data/Misses/NativeBreakdown/Alignment", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbNativeMissCrossPage,  STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Data TLB misses in native code: Cross page [not directly included grand parent sum]",
+                        "/IEM/CPU%u/Tlb/Data/Misses/NativeBreakdown/CrossPage", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbNativeMissNonCanonical,  STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Data TLB misses in native code: Non-canonical [not directly included grand parent sum]",
+                        "/IEM/CPU%u/Tlb/Data/Misses/NativeBreakdown/NonCanonical", idCpu);
+#  endif
+# endif
+
+# ifdef IEM_WITH_TLB_STATISTICS
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbCoreHits,        STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Data TLB core hits (iemMemMap, direct iemMemMapJmp (not safe path))",
+                        "/IEM/CPU%u/Tlb/Data/Hits/Core", idCpu);
+        STAMR3RegisterF(pVM, &pVCpu->iem.s.DataTlb.cTlbInlineCodeHits,  STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
+                        "Data TLB hits in IEMAllMemRWTmplInline.cpp.h",
+                        "/IEM/CPU%u/Tlb/Data/Hits/Inline", idCpu);
 #  ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER
         STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeTlbHitsForStack, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Data TLB native stack access hits",        "/IEM/CPU%u/DataTlb-Hits-Native-Stack", idCpu);
+                        "Data TLB native stack access hits",
+                        "/IEM/CPU%u/Tlb/Data/Hits/Native/Stack", idCpu);
         STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeTlbHitsForFetch, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Data TLB native data fetch hits",          "/IEM/CPU%u/DataTlb-Hits-Native-Fetch", idCpu);
+                        "Data TLB native data fetch hits",
+                        "/IEM/CPU%u/Tlb/Data/Hits/Native/Fetch", idCpu);
         STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeTlbHitsForStore, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Data TLB native data store hits",          "/IEM/CPU%u/DataTlb-Hits-Native-Store", idCpu);
+                        "Data TLB native data store hits",
+                        "/IEM/CPU%u/Tlb/Data/Hits/Native/Store", idCpu);
         STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeTlbHitsForMapped, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Data TLB native mapped data hits",         "/IEM/CPU%u/DataTlb-Hits-Native-Mapped", idCpu);
+                        "Data TLB native mapped data hits",
+                        "/IEM/CPU%u/Tlb/Data/Hits/Native/Mapped", idCpu);
 #  endif
-        RTStrPrintf(szPat, sizeof(szPat), "/IEM/CPU%u/DataTlb-Hits-*", idCpu);
-        STAMR3RegisterSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, szPat,
-                          "Data TLB hits total",                    "/IEM/CPU%u/DataTlb-Hits", idCpu);
-
-        RTStrPrintf(szPat, sizeof(szPat), "/IEM/CPU%u/DataTlb-Safe*", idCpu);
-        STAMR3RegisterSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, szPat,
-                          "Data TLB actual misses",                 "/IEM/CPU%u/DataTlb-SafeTotal", idCpu);
-        char szVal[128];
-        RTStrPrintf(szVal, sizeof(szVal), "/IEM/CPU%u/DataTlb-SafeTotal", idCpu);
-        RTStrPrintf(szPat, sizeof(szPat), "/IEM/CPU%u/DataTlb-Hits-*", idCpu);
+        RTStrPrintf(szPat, sizeof(szPat), "/IEM/CPU%u/Tlb/Data/Hits/*", idCpu);
+        STAMR3RegisterSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, szPat, "Data TLB hits",
+                          "/IEM/CPU%u/Tlb/Data/Hits", idCpu);
+
+#  ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER
+        RTStrPrintf(szPat, sizeof(szPat), "/IEM/CPU%u/Tlb/Data/Hits/Native/*", idCpu);
+        STAMR3RegisterSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, szPat, "Data TLB hits from native code",
+                          "/IEM/CPU%u/Tlb/Data/Hits/Native", idCpu);
+#  endif
+
+        RTStrPrintf(szVal, sizeof(szVal), "/IEM/CPU%u/Tlb/Data/Hits|/IEM/CPU%u/Tlb/Data/Misses", idCpu, idCpu);
+        STAMR3RegisterSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, szPat, "Data TLB lookups (sum of hits and misses)",
+                          "/IEM/CPU%u/Tlb/Data/Hits/AllLookups", idCpu);
+
+        RTStrPrintf(szVal, sizeof(szVal), "/IEM/CPU%u/Tlb/Data/Misses", idCpu);
+        RTStrPrintf(szPat, sizeof(szPat), "/IEM/CPU%u/Tlb/Data/Hits", idCpu);
         STAMR3RegisterPctOfSum(pVM->pUVM, STAMVISIBILITY_ALWAYS, STAMUNIT_PPM, szVal, true, szPat,
-                               "Data TLB actual miss rate",         "/IEM/CPU%u/DataTlb-SafeRate", idCpu);
-
-#  ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER
-        STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeCodeTlbMissesNewPage, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Code TLB native misses on new page",           "/IEM/CPU%u/CodeTlb-Misses-New-Page", idCpu);
-        STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeCodeTlbMissesNewPageWithOffset, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Code TLB native misses on new page w/ offset", "/IEM/CPU%u/CodeTlb-Misses-New-Page-With-Offset", idCpu);
-        STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeCodeTlbHitsForNewPage, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Code TLB native hits on new page",   "/IEM/CPU%u/CodeTlb-Hits-New-Page", idCpu);
-        STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeCodeTlbHitsForNewPageWithOffset, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
-                        "Code TLB native hits on new page /w offset",   "/IEM/CPU%u/CodeTlb-Hits-New-Page-With-Offset", idCpu);
-#  endif
-# endif
+                               "Data TLB actual miss rate",             "/IEM/CPU%u/Tlb/Data/RateMisses", idCpu);
+
+# endif /* IEM_WITH_TLB_STATISTICS */
+
 
 #ifdef VBOX_WITH_IEM_RECOMPILER
Index: /trunk/src/VBox/VMM/include/IEMInternal-armv8.h
===================================================================
--- /trunk/src/VBox/VMM/include/IEMInternal-armv8.h	(revision 104955)
+++ /trunk/src/VBox/VMM/include/IEMInternal-armv8.h	(revision 104956)
@@ -336,5 +336,5 @@
     uint32_t            cTlbMisses;
     /** Slow read path.  */
-    uint32_t            cTlbSlowReadPath;
+    uint32_t            cTlbSlowCodeReadPath;
 #if 0
     /** TLB misses because of tag mismatch. */
Index: /trunk/src/VBox/VMM/include/IEMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/IEMInternal.h	(revision 104955)
+++ /trunk/src/VBox/VMM/include/IEMInternal.h	(revision 104956)
@@ -111,4 +111,10 @@
  * Delay the writeback or dirty registers as long as possible. */
 # define IEMNATIVE_WITH_DELAYED_REGISTER_WRITEBACK
+#endif
+
+/** @def IEM_WITH_TLB_STATISTICS
+ * Enables all TLB statistics. */
+#if defined(VBOX_WITH_STATISTICS) || defined(DOXYGEN_RUNNING)
+# define IEM_WITH_TLB_STATISTICS
 #endif
 
@@ -552,30 +558,48 @@
     /* Statistics: */
 
-    /** TLB hits (VBOX_WITH_STATISTICS only). */
-    uint64_t            cTlbHits;
-    /** TLB misses. */
-    uint32_t            cTlbMisses;
-    /** Slow read path.  */
-    uint32_t            cTlbSlowReadPath;
-    /** Safe read path.  */
-    uint32_t            cTlbSafeReadPath;
-    /** Safe write path.  */
-    uint32_t            cTlbSafeWritePath;
-#if 0
-    /** TLB misses because of tag mismatch. */
-    uint32_t            cTlbMissesTag;
-    /** TLB misses because of virtual access violation. */
-    uint32_t            cTlbMissesVirtAccess;
-    /** TLB misses because of dirty bit. */
-    uint32_t            cTlbMissesDirty;
-    /** TLB misses because of MMIO */
-    uint32_t            cTlbMissesMmio;
-    /** TLB misses because of write access handlers. */
-    uint32_t            cTlbMissesWriteHandler;
-    /** TLB misses because no r3(/r0) mapping. */
-    uint32_t            cTlbMissesMapping;
-#endif
+    /** TLB hits in IEMAll.cpp code (IEM_WITH_TLB_STATISTICS only; both).
+     * @note For the data TLB this is only used in iemMemMap and and for direct (i.e.
+     *       not via safe read/write path) calls to iemMemMapJmp. */
+    uint64_t            cTlbCoreHits;
+    /** Safe read/write TLB hits in iemMemMapJmp (IEM_WITH_TLB_STATISTICS
+     *  only; data tlb only). */
+    uint64_t            cTlbSafeHits;
+    /** TLB hits in IEMAllMemRWTmplInline.cpp.h (data + IEM_WITH_TLB_STATISTICS only). */
+    uint64_t            cTlbInlineCodeHits;
+
+    /** TLB misses in IEMAll.cpp code (both).
+     * @note For the data TLB this is only used in iemMemMap and for direct (i.e.
+     *       not via safe read/write path) calls to iemMemMapJmp. So,
+     *       for the data TLB this more like 'other misses', while for the code
+     *       TLB is all misses. */
+    uint64_t            cTlbCoreMisses;
+    /** Safe read/write TLB misses in iemMemMapJmp (so data only). */
+    uint64_t            cTlbSafeMisses;
+    /** Safe read path taken (data only).  */
+    uint64_t            cTlbSafeReadPath;
+    /** Safe write path taken (data only).  */
+    uint64_t            cTlbSafeWritePath;
+
+    /** @name Details for native code TLB misses.
+     * @note These counts are included in the above counters (cTlbSafeReadPath,
+     *       cTlbSafeWritePath, cTlbInlineCodeHits).
+     * @{ */
+    /** TLB misses in native code due to tag mismatch.   */
+    STAMCOUNTER         cTlbNativeMissTag;
+    /** TLB misses in native code due to flags or physical revision mismatch. */
+    STAMCOUNTER         cTlbNativeMissFlagsAndPhysRev;
+    /** TLB misses in native code due to misaligned access. */
+    STAMCOUNTER         cTlbNativeMissAlignment;
+    /** TLB misses in native code due to cross page access. */
+    uint32_t            cTlbNativeMissCrossPage;
+    /** TLB misses in native code due to non-canonical address. */
+    uint32_t            cTlbNativeMissNonCanonical;
+    /** @} */
+
+    /** Slow read path (code only).  */
+    uint32_t            cTlbSlowCodeReadPath;
+
     /** Alignment padding. */
-    uint32_t            au32Padding[6];
+    uint32_t            au32Padding[5];
 
     /** The TLB entries. */
Index: /trunk/src/VBox/VMM/include/IEMN8veRecompilerTlbLookup.h
===================================================================
--- /trunk/src/VBox/VMM/include/IEMN8veRecompilerTlbLookup.h	(revision 104955)
+++ /trunk/src/VBox/VMM/include/IEMN8veRecompilerTlbLookup.h	(revision 104956)
@@ -545,6 +545,16 @@
         /* test regflat, fAlignMask */
         off = iemNativeEmitTestAnyBitsInGpr8Ex(pCodeBuf, off, idxRegFlatPtr, fAlignMask);
+#ifndef IEM_WITH_TLB_STATISTICS
         /* jnz tlbmiss */
         off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss, kIemNativeInstrCond_ne);
+#else
+        /* jz  1F; inc stat; jmp tlbmiss */
+        uint32_t const offFixup1 = off;
+        off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 16, kIemNativeInstrCond_e);
+        off = iemNativeEmitIncStamCounterInVCpuEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2,
+                                                  offVCpuTlb + RT_UOFFSETOF(IEMTLB, cTlbNativeMissAlignment));
+        off = iemNativeEmitJmpToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss);
+        iemNativeFixupFixedJump(pReNative, offFixup1, off);
+#endif
     }
 
@@ -559,6 +569,16 @@
         /* cmp reg1, GUEST_PAGE_SIZE - cbMem */
         off = iemNativeEmitCmpGpr32WithImmEx(pCodeBuf, off, pTlbState->idxReg1, GUEST_PAGE_SIZE);
+#ifndef IEM_WITH_TLB_STATISTICS
         /* ja  tlbmiss */
         off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss, kIemNativeInstrCond_nbe);
+#else
+        /* jbe 1F; inc stat; jmp tlbmiss */
+        uint32_t const offFixup1 = off;
+        off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 16, kIemNativeInstrCond_be);
+        off = iemNativeEmitIncU32CounterInVCpuEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2,
+                                                 offVCpuTlb + RT_UOFFSETOF(IEMTLB, cTlbNativeMissCrossPage));
+        off = iemNativeEmitJmpToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss);
+        iemNativeFixupFixedJump(pReNative, offFixup1, off);
+#endif
     }
 
@@ -590,6 +610,16 @@
         pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 7, pTlbState->idxReg1 & 7);
         pCodeBuf[off++] = 1;
+#  ifndef IEM_WITH_TLB_STATISTICS
         /* ja  tlbmiss */
         off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss, kIemNativeInstrCond_nbe);
+#  else
+        /* jbe 1F; inc stat; jmp tlbmiss */
+        uint32_t const offFixup1 = off;
+        off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 16, kIemNativeInstrCond_be);
+        off = iemNativeEmitIncU32CounterInVCpuEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2,
+                                                 offVCpuTlb + RT_UOFFSETOF(IEMTLB, cTlbNativeMissNonCanonical));
+        off = iemNativeEmitJmpToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss);
+        iemNativeFixupFixedJump(pReNative, offFixup1, off);
+#  endif
         /* shr reg1, 16 + GUEST_PAGE_SHIFT */
         off = iemNativeEmitShiftGprRightEx(pCodeBuf, off, pTlbState->idxReg1, 16 + GUEST_PAGE_SHIFT);
@@ -603,6 +633,16 @@
         Assert(Armv8A64ConvertImmRImmS2Mask32(14, 31) == 0xfffe);
         pCodeBuf[off++] = Armv8A64MkInstrTstImm(pTlbState->idxReg1, 14, 31, false /*f64Bit*/);
-        /* b.nq tlbmiss */
+#  ifndef IEM_WITH_TLB_STATISTICS
+        /* b.ne tlbmiss */
         off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss, kIemNativeInstrCond_ne);
+#  else
+        /* b.eq 1F; inc stat; jmp tlbmiss */
+        uint32_t const offFixup1 = off;
+        off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 16, kIemNativeInstrCond_e);
+        off = iemNativeEmitIncU32CounterInVCpuEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2,
+                                                 offVCpuTlb + RT_UOFFSETOF(IEMTLB, cTlbNativeMissNonCanonical));
+        off = iemNativeEmitJmpToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss);
+        iemNativeFixupFixedJump(pReNative, offFixup1, off);
+#  endif
 
         /* ubfx reg1, regflat, #12, #36 */
@@ -720,6 +760,16 @@
 #  error "Port me"
 # endif
+# ifndef IEM_WITH_TLB_STATISTICS
     /* jne tlbmiss */
     off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss, kIemNativeInstrCond_ne);
+# else
+    /* je  1F; inc stat; jmp tlbmiss */
+    uint32_t const offFixup1 = off;
+    off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 16, kIemNativeInstrCond_e);
+    off = iemNativeEmitIncStamCounterInVCpuEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2,
+                                              offVCpuTlb + RT_UOFFSETOF(IEMTLB, cTlbNativeMissTag));
+    off = iemNativeEmitJmpToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss);
+    iemNativeFixupFixedJump(pReNative, offFixup1, off);
+# endif
 
     /*
@@ -764,6 +814,16 @@
 #  error "Port me"
 # endif
+# ifndef IEM_WITH_TLB_STATISTICS
     /* jne tlbmiss */
     off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss, kIemNativeInstrCond_ne);
+# else
+    /* je  2F; inc stat; jmp tlbmiss */
+    uint32_t const offFixup2 = off;
+    off = iemNativeEmitJccToFixedEx(pCodeBuf, off, off + 16, kIemNativeInstrCond_e);
+    off = iemNativeEmitIncStamCounterInVCpuEx(pCodeBuf, off, pTlbState->idxReg1, pTlbState->idxReg2,
+                                              offVCpuTlb + RT_UOFFSETOF(IEMTLB, cTlbNativeMissFlagsAndPhysRev));
+    off = iemNativeEmitJmpToLabelEx(pReNative, pCodeBuf, off, idxLabelTlbMiss);
+    iemNativeFixupFixedJump(pReNative, offFixup2, off);
+# endif
 
     /*
