]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Use a very fast in-line allocator. This improves its performance by
authorJulian Seward <jseward@acm.org>
Wed, 23 Nov 2005 04:25:07 +0000 (04:25 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 23 Nov 2005 04:25:07 +0000 (04:25 +0000)
up to 10% on a P4.

git-svn-id: svn://svn.valgrind.org/vex/trunk@1469

VEX/priv/main/vex_main.c
VEX/priv/main/vex_util.c
VEX/priv/main/vex_util.h
VEX/pub/libvex.h

index 085093e58180a5bba5205641955b333c731b69c9..26cdcc2f08feb10519aafdf875c7c16c983b0e1a 100644 (file)
@@ -263,8 +263,8 @@ VexTranslateResult LibVEX_Translate (
    vex_traceflags = traceflags;
 
    vassert(vex_initdone);
-   vexClearTEMP();
-
+   vexSetAllocModeTEMP_and_clear();
+   vexAllocSanityCheck();
 
    /* First off, check that the guest and host insn sets
       are supported. */
@@ -406,6 +406,8 @@ VexTranslateResult LibVEX_Translate (
       vassert(archinfo_guest->subarch == archinfo_host->subarch);
    }
 
+   vexAllocSanityCheck();
+
    if (vex_traceflags & VEX_TRACE_FE)
       vex_printf("\n------------------------" 
                    " Front end "
@@ -423,9 +425,11 @@ VexTranslateResult LibVEX_Translate (
                      offB_TISTART,
                      offB_TILEN );
 
+   vexAllocSanityCheck();
+
    if (irbb == NULL) {
       /* Access failure. */
-      vexClearTEMP();
+      vexSetAllocModeTEMP_and_clear();
       vex_traceflags = 0;
       return VexTransAccessFail;
    }
@@ -455,6 +459,8 @@ VexTranslateResult LibVEX_Translate (
    sanityCheckIRBB( irbb, "initial IR", 
                     False/*can be non-flat*/, guest_word_type );
 
+   vexAllocSanityCheck();
+
    /* Clean it up, hopefully a lot. */
    irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn, 
                               guest_bytes_addr );
@@ -469,11 +475,15 @@ VexTranslateResult LibVEX_Translate (
       vex_printf("\n");
    }
 
+   vexAllocSanityCheck();
+
    /* Get the thing instrumented. */
    if (instrument1)
       irbb = (*instrument1)(irbb, guest_layout, 
                             guest_bytes_addr_noredir, guest_extents,
                             guest_word_type, host_word_type);
+   vexAllocSanityCheck();
+
    if (instrument2)
       irbb = (*instrument2)(irbb, guest_layout,
                             guest_bytes_addr_noredir, guest_extents,
@@ -500,6 +510,8 @@ VexTranslateResult LibVEX_Translate (
                        True/*must be flat*/, guest_word_type );
    }
 
+   vexAllocSanityCheck();
+
    if (vex_traceflags & VEX_TRACE_OPT2) {
       vex_printf("\n------------------------" 
                    " After post-instr IR optimisation "
@@ -512,6 +524,8 @@ VexTranslateResult LibVEX_Translate (
    do_deadcode_BB( irbb );
    do_treebuild_BB( irbb );
 
+   vexAllocSanityCheck();
+
    if (vex_traceflags & VEX_TRACE_TREES) {
       vex_printf("\n------------------------" 
                    "  After tree-building "
@@ -531,6 +545,8 @@ VexTranslateResult LibVEX_Translate (
 
    vcode = iselBB ( irbb, archinfo_host );
 
+   vexAllocSanityCheck();
+
    if (vex_traceflags & VEX_TRACE_VCODE)
       vex_printf("\n");
 
@@ -550,6 +566,8 @@ VexTranslateResult LibVEX_Translate (
                                   genSpill, genReload, guest_sizeB,
                                   ppInstr, ppReg );
 
+   vexAllocSanityCheck();
+
    if (vex_traceflags & VEX_TRACE_RCODE) {
       vex_printf("\n------------------------" 
                    " Register-allocated code "
@@ -589,7 +607,7 @@ VexTranslateResult LibVEX_Translate (
          vex_printf("\n\n");
       }
       if (out_used + j > host_bytes_size) {
-         vexClearTEMP();
+         vexSetAllocModeTEMP_and_clear();
          vex_traceflags = 0;
          return VexTransOutputFull;
       }
@@ -601,7 +619,9 @@ VexTranslateResult LibVEX_Translate (
    }
    *host_bytes_used = out_used;
 
-   vexClearTEMP();
+   vexAllocSanityCheck();
+
+   vexSetAllocModeTEMP_and_clear();
 
    vex_traceflags = 0;
    return VexTransOK;
index 370e582a2db5bf4d7488888e5dcbb9357739e42b..0436e8ffa8641b6d0e9c1a419223e5c584096972 100644 (file)
 */
 #define N_TEMPORARY_BYTES 2400000
 
-static Char temporary[N_TEMPORARY_BYTES];
-static Int  temporary_used = 0;
+static HChar  temporary[N_TEMPORARY_BYTES];
+static HChar* temporary_first = &temporary[0];
+static HChar* temporary_curr  = &temporary[0];
+static HChar* temporary_last  = &temporary[N_TEMPORARY_BYTES-1];
 
-#define N_PERMANENT_BYTES 1000
+static ULong  temporary_bytes_allocd_TOT = 0;
 
-static Char permanent[N_TEMPORARY_BYTES];
-static Int  permanent_used = 0;
+#define N_PERMANENT_BYTES 1000
 
+static HChar  permanent[N_TEMPORARY_BYTES];
+static HChar* permanent_first = &permanent[0];
+static HChar* permanent_curr  = &permanent[0];
+static HChar* permanent_last  = &permanent[N_TEMPORARY_BYTES-1];
 
-/* Gather statistics. */
-static Int temporary_bytes_allocd = 0;
-static Int temporary_count_allocs = 0;
+static VexAllocMode mode = VexAllocModeTEMP;
 
-static ULong temporary_bytes_allocd_TOT = 0;
-static ULong temporary_count_allocs_TOT = 0;
+void vexAllocSanityCheck ( void )
+{
+   vassert(temporary_first == &temporary[0]);
+   vassert(temporary_last  == &temporary[N_TEMPORARY_BYTES-1]);
+   vassert(permanent_first == &permanent[0]);
+   vassert(permanent_last  == &permanent[N_TEMPORARY_BYTES-1]);
+   vassert(temporary_first <= temporary_curr);
+   vassert(temporary_curr  <= temporary_last);
+   vassert(permanent_first <= permanent_curr);
+   vassert(permanent_curr  <= permanent_last);
+   vassert(private_LibVEX_alloc_first <= private_LibVEX_alloc_curr);
+   vassert(private_LibVEX_alloc_curr  <= private_LibVEX_alloc_last);
+   if (mode == VexAllocModeTEMP){
+      vassert(private_LibVEX_alloc_first == temporary_first);
+      vassert(private_LibVEX_alloc_last  == temporary_last);
+   } 
+   else
+   if (mode == VexAllocModePERM) {
+      vassert(private_LibVEX_alloc_first == permanent_first);
+      vassert(private_LibVEX_alloc_last  == permanent_last);
+   }
+   else 
+      vassert(0);
+
+#  define IS_WORD_ALIGNED(p)   (0 == (((HWord)p) & (sizeof(HWord)-1)))
+   vassert(sizeof(HWord) == 4 || sizeof(HWord) == 8);
+   vassert(IS_WORD_ALIGNED(temporary_first));
+   vassert(IS_WORD_ALIGNED(temporary_curr));
+   vassert(IS_WORD_ALIGNED(temporary_last+1));
+   vassert(IS_WORD_ALIGNED(permanent_first));
+   vassert(IS_WORD_ALIGNED(permanent_curr));
+   vassert(IS_WORD_ALIGNED(permanent_last+1));
+   vassert(IS_WORD_ALIGNED(private_LibVEX_alloc_first));
+   vassert(IS_WORD_ALIGNED(private_LibVEX_alloc_curr));
+   vassert(IS_WORD_ALIGNED(private_LibVEX_alloc_last+1));
+#  undef IS_WORD_ALIGNED
+}
 
 /* The current allocation mode. */
-static VexAllocMode mode = VexAllocModeTEMP;
-
 
 void vexSetAllocMode ( VexAllocMode m )
 {
+   vexAllocSanityCheck();
+
+   /* Save away the current allocation point .. */
+   if (mode == VexAllocModeTEMP){
+      temporary_curr = private_LibVEX_alloc_curr;
+   } 
+   else
+   if (mode == VexAllocModePERM) {
+      permanent_curr = private_LibVEX_alloc_curr;
+   }
+   else 
+      vassert(0);
+
+   /* Did that screw anything up? */
+   vexAllocSanityCheck();
+
+   if (m == VexAllocModeTEMP){
+      private_LibVEX_alloc_first = temporary_first;
+      private_LibVEX_alloc_curr  = temporary_curr;
+      private_LibVEX_alloc_last  = temporary_last;
+   } 
+   else
+   if (m == VexAllocModePERM) {
+      private_LibVEX_alloc_first = permanent_first;
+      private_LibVEX_alloc_curr  = permanent_curr;
+      private_LibVEX_alloc_last  = permanent_last;
+   }
+   else 
+      vassert(0);
+
    mode = m;
 }
 
@@ -94,48 +160,39 @@ VexAllocMode vexGetAllocMode ( void )
    return mode;
 }
 
-/* Exported to library client. */
+/* Visible to library client, unfortunately. */
 
-void* LibVEX_Alloc ( Int nbytes ) 
+HChar* private_LibVEX_alloc_first = &temporary[0];
+HChar* private_LibVEX_alloc_curr  = &temporary[0];
+HChar* private_LibVEX_alloc_last  = &temporary[N_TEMPORARY_BYTES-1];
+
+__attribute__((noreturn))
+void private_LibVEX_alloc_OOM(void)
 {
-   /* 3 or 7 depending on host word size. */
-#  define ALIGN (sizeof(void*)-1)
-   vassert(vex_initdone);
-   vassert(nbytes >= 0);
-   if (0 && vex_valgrind_support) {
-      /* ugly hack -- do not remove */
-      //extern void* malloc ( int );
-      //return malloc(nbytes);
-      return NULL;
-   } else {
-      nbytes = (nbytes + ALIGN) & ~ALIGN;
-      if (mode == VexAllocModeTEMP) {
-         if (temporary_used + nbytes > N_TEMPORARY_BYTES)
-            vpanic("VEX temporary storage exhausted.\n"
-                   "Increase N_TEMPORARY_BYTES and recompile.");
-         temporary_count_allocs++;
-         temporary_bytes_allocd += nbytes;
-         temporary_used += nbytes;
-         return (void*)(&temporary[temporary_used - nbytes]);
-      } else {
-         if (permanent_used + nbytes > N_PERMANENT_BYTES)
-            vpanic("VEX permanent storage exhausted.\n"
-                   "Increase N_PERMANENT_BYTES and recompile.");
-         permanent_used += nbytes;
-         return (void*)(&permanent[permanent_used - nbytes]);
-      }
-   }
-#  undef ALIGN
+   HChar* pool = "???";
+   if (private_LibVEX_alloc_first == &temporary[0]) pool = "TEMP";
+   if (private_LibVEX_alloc_first == &permanent[0]) pool = "PERM";
+   vex_printf("VEX temporary storage exhausted.\n");
+   vex_printf("Pool = %s,  start %p curr %p end %p (size %d)\n",
+              pool, 
+              private_LibVEX_alloc_first,
+              private_LibVEX_alloc_curr,
+              private_LibVEX_alloc_last,
+              private_LibVEX_alloc_last - private_LibVEX_alloc_first);
+   vpanic("VEX temporary storage exhausted.\n"
+          "Increase N_{TEMPORARY,PERMANENT}_BYTES and recompile.");
 }
 
-void vexClearTEMP ( void )
+void vexSetAllocModeTEMP_and_clear ( void )
 {
    /* vassert(vex_initdone); */ /* causes infinite assert loops */
-   temporary_bytes_allocd_TOT += (ULong)temporary_bytes_allocd;
-   temporary_count_allocs_TOT += (ULong)temporary_count_allocs;
-   temporary_used = 0;
-   temporary_bytes_allocd = 0;
-   temporary_count_allocs = 0;
+   temporary_bytes_allocd_TOT 
+      += (ULong)( private_LibVEX_alloc_curr - private_LibVEX_alloc_first);
+
+   mode = VexAllocModeTEMP;
+   temporary_curr            = &temporary[0];
+   private_LibVEX_alloc_curr = &temporary[0];
+   vexAllocSanityCheck();
 }
 
 
@@ -143,11 +200,8 @@ void vexClearTEMP ( void )
 
 void LibVEX_ShowAllocStats ( void )
 {
-   vex_printf("vex storage:  P %d,  T total %lld (%lld),  T curr %d (%d)\n",
-              permanent_used,
-              (Long)temporary_bytes_allocd_TOT, 
-              (Long)temporary_count_allocs_TOT,
-              temporary_bytes_allocd, temporary_count_allocs );
+   vex_printf("vex storage: T total %lld bytes allocated\n",
+              (Long)temporary_bytes_allocd_TOT );
 }
 
 
index afe94c8727c7eaa71f7a2fd5d4a82f91f2d2320e..6ec1e7a9cf02e61d648ca89745c2bd659d4a0476 100644 (file)
@@ -101,9 +101,9 @@ typedef
 
 extern void         vexSetAllocMode ( VexAllocMode );
 extern VexAllocMode vexGetAllocMode ( void );
+extern void         vexAllocSanityCheck ( void );
 
-extern void vexClearTEMP ( void );
-
+extern void vexSetAllocModeTEMP_and_clear ( void );
 
 #endif /* ndef __VEX_UTIL_H */
 
index 361981b5dbab3218484f77caca3c4179b1558ceb..5541dbd86ea0785ee5d8eb5ecd2cd00eeb8013c9 100644 (file)
@@ -168,7 +168,30 @@ extern const HChar* LibVEX_Version ( void );
    LibVEX_Translate.  The storage allocated will only stay alive until
    translation of the current basic block is complete.
  */
-extern void* LibVEX_Alloc ( Int nbytes );
+extern HChar* private_LibVEX_alloc_first;
+extern HChar* private_LibVEX_alloc_curr;
+extern HChar* private_LibVEX_alloc_last;
+extern void   private_LibVEX_alloc_OOM(void) __attribute__((noreturn));
+
+static inline void* LibVEX_Alloc ( Int nbytes )
+{
+#if 0
+  /* Nasty debugging hack, do not use. */
+  return malloc(nbytes);
+#else
+   HChar* curr;
+   HChar* next;
+   Int    ALIGN;
+   ALIGN  = sizeof(void*)-1;
+   nbytes = (nbytes + ALIGN) & ~ALIGN;
+   curr   = private_LibVEX_alloc_curr;
+   next   = curr + nbytes;
+   if (next >= private_LibVEX_alloc_last)
+      private_LibVEX_alloc_OOM();
+   private_LibVEX_alloc_curr = next;
+   return curr;
+#endif
+}
 
 /* Show Vex allocation statistics. */
 extern void LibVEX_ShowAllocStats ( void );