Index: trunk/src/VBox/VMM/include/IEMInline.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMInline.h	(revision 101121)
+++ trunk/src/VBox/VMM/include/IEMInline.h	(revision 101163)
@@ -332,4 +332,5 @@
 }
 
+#ifdef VBOX_INCLUDED_vmm_dbgf_h /* VM::dbgf.ro.cEnabledHwBreakpoints is only accessible if VBox/vmm/dbgf.h is included. */
 
 /**
@@ -392,8 +393,11 @@
 }
 
+#endif /* VBOX_INCLUDED_vmm_dbgf_h */
+
 
 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
 
 # if defined(VBOX_INCLUDED_vmm_dbgf_h) || defined(DOXYGEN_RUNNING) /* dbgf.ro.cEnabledHwBreakpoints */
+
 /**
  * Initializes the execution state.
@@ -458,8 +462,7 @@
 #  endif /* VBOX_STRICT */
 }
-# endif /* VBOX_INCLUDED_vmm_dbgf_h */
-
-
-# if defined(VBOX_WITH_NESTED_HWVIRT_SVM) || defined(VBOX_WITH_NESTED_HWVIRT_VMX)
+
+
+#  if defined(VBOX_WITH_NESTED_HWVIRT_SVM) || defined(VBOX_WITH_NESTED_HWVIRT_VMX)
 /**
  * Performs a minimal reinitialization of the execution state.
@@ -477,6 +480,7 @@
     iemOpcodeFlushHeavy(pVCpu, cbInstr);
 }
-# endif
-
+#  endif
+
+# endif /* VBOX_INCLUDED_vmm_dbgf_h || DOXYGEN_RUNNING */
 
 /**
@@ -3564,4 +3568,5 @@
 
 
+# ifdef XAPIC_OFF_END /* Requires VBox/apic.h to be included before IEMInline.h. */
 /**
  * Sets virtual-APIC write emulation as pending.
@@ -3588,4 +3593,5 @@
         VMCPU_FF_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE);
 }
+# endif /* XAPIC_OFF_END */
 
 #endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
Index: trunk/src/VBox/VMM/include/IEMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMInternal.h	(revision 101121)
+++ trunk/src/VBox/VMM/include/IEMInternal.h	(revision 101163)
@@ -742,4 +742,14 @@
 AssertCompile(!(IEM_F_MODE_X86_64BIT              & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK));
 
+/** Native instruction type for use with the native code generator.
+ * This is a byte (uint8_t) for x86 and amd64 and uint32_t for the other(s). */
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+typedef uint8_t IEMNATIVEINSTR;
+#else
+typedef uint32_t IEMNATIVEINSTR;
+#endif
+/** Pointer to a native instruction unit. */
+typedef IEMNATIVEINSTR *PIEMNATIVEINSTR;
+
 /**
  * A call for the threaded call table.
@@ -826,7 +836,8 @@
         struct
         {
-            uint8_t            *pbCode;
-            /** Amount of code that pbCode points to. */
-            uint32_t            cbAllocated;
+            /** The native instructions. */
+            PIEMNATIVEINSTR     paInstructions;
+            /** Number of instructions pointed to by paInstructions. */
+            uint32_t            cInstructions;
         } Native;
         /** Generic view for zeroing when freeing. */
@@ -974,4 +985,7 @@
     /** Statistics: Time spend pruning. */
     STAMPROFILE     StatPrune;
+
+    /** The delayed free list (see iemTbAlloctorScheduleForFree). */
+    PIEMTB          pDelayedFreeHead;
 
     /** Allocation chunks. */
@@ -1368,8 +1382,4 @@
      * This is allocated once with maxed-out sizes and re-used afterwards. */
     R3PTRTYPE(PIEMTB)       pThrdCompileTbR3;
-    /** Fixed TB used for native recompilation.
-     * This is allocated once and re-used afterwards, growing individual
-     * components as needed. */
-    R3PTRTYPE(PIEMTB)       pNativeCompileTbR3;
     /** Pointer to the ring-3 TB cache for this EMT. */
     R3PTRTYPE(PIEMTBCACHE)  pTbCacheR3;
@@ -1378,6 +1388,8 @@
      * RIP to opcode bytes stored in the TB (AMD-V / VT-x). */
     uint64_t                uCurTbStartPc;
-    /** Number of TBs executed. */
-    uint64_t                cTbExec;
+    /** Number of threaded TBs executed. */
+    uint64_t                cTbExecThreaded;
+    /** Number of native TBs executed. */
+    uint64_t                cTbExecNative;
     /** Whether we need to check the opcode bytes for the current instruction.
      * This is set by a previous instruction if it modified memory or similar.  */
@@ -1414,6 +1426,34 @@
     /** Pointer to the ring-3 TB allocator for this EMT. */
     R3PTRTYPE(PIEMTBALLOCATOR) pTbAllocatorR3;
-    /* Alignment. */
-    uint64_t                auAlignment10[7];
+    /** Pointer to the ring-3 executable memory allocator for this EMT. */
+    R3PTRTYPE(struct IEMEXECMEMALLOCATOR *) pExecMemAllocatorR3;
+
+    /** Native recompiler state for ring-3. */
+    struct IEMRECOMPILERSTATE
+    {
+        /** Size of the buffer that pbNativeRecompileBufR3 points to in
+         * IEMNATIVEINSTR units. */
+        uint32_t                            cInstrBufAlloc;
+        uint32_t                            uPadding; /* We don't keep track of this here... */
+        /** Fixed temporary code buffer for native recompilation. */
+        R3PTRTYPE(PIEMNATIVEINSTR)          pInstrBuf;
+
+        /** Actual number of labels in paLabels. */
+        uint32_t                            cLabels;
+        /** Max number of entries allowed in paLabels before reallocating it. */
+        uint32_t                            cLabelsAlloc;
+        /** Labels defined while recompiling (referenced by fixups). */
+        R3PTRTYPE(struct IEMNATIVELABEL *)  paLabels;
+
+        /** Actual number of fixups paFixups. */
+        uint32_t                            cFixups;
+        /** Max number of entries allowed in paFixups before reallocating it. */
+        uint32_t                            cFixupsAlloc;
+        /** Buffer used by the recompiler for recording fixups when generating code. */
+        R3PTRTYPE(struct IEMNATIVEFIXUP *)  paFixups;
+    } Native;
+
+//    /* Alignment. */
+//    uint64_t                auAlignment10[1];
     /** Statistics: Times TB execution was broken off before reaching the end. */
     STAMCOUNTER             StatTbExecBreaks;
@@ -1430,4 +1470,8 @@
     /** Threaded TB statistics: Number of calls per TB. */
     STAMPROFILE             StatTbThreadedCalls;
+    /** Native TB statistics: Native code size per TB. */
+    STAMPROFILE             StatTbNativeCode;
+    /** Native TB statistics: Profiling native recompilation. */
+    STAMPROFILE             StatNativeRecompilation;
     /** @} */
 
@@ -5290,6 +5334,9 @@
 extern const PFNIEMOP g_apfnIemThreadedRecompilerVecMap3[1024];
 
-DECLCALLBACK(int) iemTbInit(PVMCC pVM, uint32_t cInitialTbs, uint32_t cMaxTbs);
-void            iemThreadedTbObsolete(PVMCPUCC pVCpu, PIEMTB pTb);
+DECLCALLBACK(int)   iemTbInit(PVMCC pVM, uint32_t cInitialTbs, uint32_t cMaxTbs,
+                              uint64_t cbInitialExec, uint64_t cbMaxExec, uint32_t cbChunkExec);
+void                iemThreadedTbObsolete(PVMCPUCC pVCpu, PIEMTB pTb, bool fSafeToFree);
+void                iemTbAllocatorProcessDelayedFrees(PVMCPU pVCpu, PIEMTBALLOCATOR pTbAllocator);
+
 
 /** @todo FNIEMTHREADEDFUNC and friends may need more work... */
@@ -5348,4 +5395,9 @@
 bool iemThreadedCompileBeginEmitCallsComplications(PVMCPUCC pVCpu, PIEMTB pTb);
 
+/* Native recompiler public bits: */
+PIEMTB iemNativeRecompile(PVMCPUCC pVCpu, PIEMTB pTb);
+int    iemExecMemAllocatorInit(PVMCPU pVCpu, uint64_t cbMax, uint64_t cbInitial, uint32_t cbChunk);
+void   iemExecMemAllocatorFree(PVMCPU pVCpu, void *pv, size_t cb);
+
 
 /** @} */
