|
From: <sv...@va...> - 2005-11-23 04:25:10
|
Author: sewardj
Date: 2005-11-23 04:25:07 +0000 (Wed, 23 Nov 2005)
New Revision: 1469
Log:
Use a very fast in-line allocator. This improves its performance by
up to 10% on a P4.
Modified:
trunk/priv/main/vex_main.c
trunk/priv/main/vex_util.c
trunk/priv/main/vex_util.h
trunk/pub/libvex.h
Modified: trunk/priv/main/vex_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/main/vex_main.c 2005-11-23 03:54:48 UTC (rev 1468)
+++ trunk/priv/main/vex_main.c 2005-11-23 04:25:07 UTC (rev 1469)
@@ -263,9 +263,9 @@
vex_traceflags =3D traceflags;
=20
vassert(vex_initdone);
- vexClearTEMP();
+ vexSetAllocModeTEMP_and_clear();
+ vexAllocSanityCheck();
=20
-
/* First off, check that the guest and host insn sets
are supported. */
=20
@@ -406,6 +406,8 @@
vassert(archinfo_guest->subarch =3D=3D archinfo_host->subarch);
}
=20
+ vexAllocSanityCheck();
+
if (vex_traceflags & VEX_TRACE_FE)
vex_printf("\n------------------------"=20
" Front end "
@@ -423,9 +425,11 @@
offB_TISTART,
offB_TILEN );
=20
+ vexAllocSanityCheck();
+
if (irbb =3D=3D NULL) {
/* Access failure. */
- vexClearTEMP();
+ vexSetAllocModeTEMP_and_clear();
vex_traceflags =3D 0;
return VexTransAccessFail;
}
@@ -455,6 +459,8 @@
sanityCheckIRBB( irbb, "initial IR",=20
False/*can be non-flat*/, guest_word_type );
=20
+ vexAllocSanityCheck();
+
/* Clean it up, hopefully a lot. */
irbb =3D do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,=20
guest_bytes_addr );
@@ -469,11 +475,15 @@
vex_printf("\n");
}
=20
+ vexAllocSanityCheck();
+
/* Get the thing instrumented. */
if (instrument1)
irbb =3D (*instrument1)(irbb, guest_layout,=20
guest_bytes_addr_noredir, guest_extents,
guest_word_type, host_word_type);
+ vexAllocSanityCheck();
+
if (instrument2)
irbb =3D (*instrument2)(irbb, guest_layout,
guest_bytes_addr_noredir, guest_extents,
@@ -500,6 +510,8 @@
True/*must be flat*/, guest_word_type );
}
=20
+ vexAllocSanityCheck();
+
if (vex_traceflags & VEX_TRACE_OPT2) {
vex_printf("\n------------------------"=20
" After post-instr IR optimisation "
@@ -512,6 +524,8 @@
do_deadcode_BB( irbb );
do_treebuild_BB( irbb );
=20
+ vexAllocSanityCheck();
+
if (vex_traceflags & VEX_TRACE_TREES) {
vex_printf("\n------------------------"=20
" After tree-building "
@@ -531,6 +545,8 @@
=20
vcode =3D iselBB ( irbb, archinfo_host );
=20
+ vexAllocSanityCheck();
+
if (vex_traceflags & VEX_TRACE_VCODE)
vex_printf("\n");
=20
@@ -550,6 +566,8 @@
genSpill, genReload, guest_sizeB,
ppInstr, ppReg );
=20
+ vexAllocSanityCheck();
+
if (vex_traceflags & VEX_TRACE_RCODE) {
vex_printf("\n------------------------"=20
" Register-allocated code "
@@ -589,7 +607,7 @@
vex_printf("\n\n");
}
if (out_used + j > host_bytes_size) {
- vexClearTEMP();
+ vexSetAllocModeTEMP_and_clear();
vex_traceflags =3D 0;
return VexTransOutputFull;
}
@@ -601,8 +619,10 @@
}
*host_bytes_used =3D out_used;
=20
- vexClearTEMP();
+ vexAllocSanityCheck();
=20
+ vexSetAllocModeTEMP_and_clear();
+
vex_traceflags =3D 0;
return VexTransOK;
}
Modified: trunk/priv/main/vex_util.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/main/vex_util.c 2005-11-23 03:54:48 UTC (rev 1468)
+++ trunk/priv/main/vex_util.c 2005-11-23 04:25:07 UTC (rev 1469)
@@ -64,28 +64,94 @@
*/
#define N_TEMPORARY_BYTES 2400000
=20
-static Char temporary[N_TEMPORARY_BYTES];
-static Int temporary_used =3D 0;
+static HChar temporary[N_TEMPORARY_BYTES];
+static HChar* temporary_first =3D &temporary[0];
+static HChar* temporary_curr =3D &temporary[0];
+static HChar* temporary_last =3D &temporary[N_TEMPORARY_BYTES-1];
=20
+static ULong temporary_bytes_allocd_TOT =3D 0;
+
#define N_PERMANENT_BYTES 1000
=20
-static Char permanent[N_TEMPORARY_BYTES];
-static Int permanent_used =3D 0;
+static HChar permanent[N_TEMPORARY_BYTES];
+static HChar* permanent_first =3D &permanent[0];
+static HChar* permanent_curr =3D &permanent[0];
+static HChar* permanent_last =3D &permanent[N_TEMPORARY_BYTES-1];
=20
+static VexAllocMode mode =3D VexAllocModeTEMP;
=20
-/* Gather statistics. */
-static Int temporary_bytes_allocd =3D 0;
-static Int temporary_count_allocs =3D 0;
+void vexAllocSanityCheck ( void )
+{
+ vassert(temporary_first =3D=3D &temporary[0]);
+ vassert(temporary_last =3D=3D &temporary[N_TEMPORARY_BYTES-1]);
+ vassert(permanent_first =3D=3D &permanent[0]);
+ vassert(permanent_last =3D=3D &permanent[N_TEMPORARY_BYTES-1]);
+ vassert(temporary_first <=3D temporary_curr);
+ vassert(temporary_curr <=3D temporary_last);
+ vassert(permanent_first <=3D permanent_curr);
+ vassert(permanent_curr <=3D permanent_last);
+ vassert(private_LibVEX_alloc_first <=3D private_LibVEX_alloc_curr);
+ vassert(private_LibVEX_alloc_curr <=3D private_LibVEX_alloc_last);
+ if (mode =3D=3D VexAllocModeTEMP){
+ vassert(private_LibVEX_alloc_first =3D=3D temporary_first);
+ vassert(private_LibVEX_alloc_last =3D=3D temporary_last);
+ }=20
+ else
+ if (mode =3D=3D VexAllocModePERM) {
+ vassert(private_LibVEX_alloc_first =3D=3D permanent_first);
+ vassert(private_LibVEX_alloc_last =3D=3D permanent_last);
+ }
+ else=20
+ vassert(0);
=20
-static ULong temporary_bytes_allocd_TOT =3D 0;
-static ULong temporary_count_allocs_TOT =3D 0;
+# define IS_WORD_ALIGNED(p) (0 =3D=3D (((HWord)p) & (sizeof(HWord)-1)=
))
+ vassert(sizeof(HWord) =3D=3D 4 || sizeof(HWord) =3D=3D 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
+}
=20
/* The current allocation mode. */
-static VexAllocMode mode =3D VexAllocModeTEMP;
=20
-
void vexSetAllocMode ( VexAllocMode m )
{
+ vexAllocSanityCheck();
+
+ /* Save away the current allocation point .. */
+ if (mode =3D=3D VexAllocModeTEMP){
+ temporary_curr =3D private_LibVEX_alloc_curr;
+ }=20
+ else
+ if (mode =3D=3D VexAllocModePERM) {
+ permanent_curr =3D private_LibVEX_alloc_curr;
+ }
+ else=20
+ vassert(0);
+
+ /* Did that screw anything up? */
+ vexAllocSanityCheck();
+
+ if (m =3D=3D VexAllocModeTEMP){
+ private_LibVEX_alloc_first =3D temporary_first;
+ private_LibVEX_alloc_curr =3D temporary_curr;
+ private_LibVEX_alloc_last =3D temporary_last;
+ }=20
+ else
+ if (m =3D=3D VexAllocModePERM) {
+ private_LibVEX_alloc_first =3D permanent_first;
+ private_LibVEX_alloc_curr =3D permanent_curr;
+ private_LibVEX_alloc_last =3D permanent_last;
+ }
+ else=20
+ vassert(0);
+
mode =3D m;
}
=20
@@ -94,48 +160,39 @@
return mode;
}
=20
-/* Exported to library client. */
+/* Visible to library client, unfortunately. */
=20
-void* LibVEX_Alloc ( Int nbytes )=20
+HChar* private_LibVEX_alloc_first =3D &temporary[0];
+HChar* private_LibVEX_alloc_curr =3D &temporary[0];
+HChar* private_LibVEX_alloc_last =3D &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 >=3D 0);
- if (0 && vex_valgrind_support) {
- /* ugly hack -- do not remove */
- //extern void* malloc ( int );
- //return malloc(nbytes);
- return NULL;
- } else {
- nbytes =3D (nbytes + ALIGN) & ~ALIGN;
- if (mode =3D=3D 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 +=3D nbytes;
- temporary_used +=3D 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 +=3D nbytes;
- return (void*)(&permanent[permanent_used - nbytes]);
- }
- }
-# undef ALIGN
+ HChar* pool =3D "???";
+ if (private_LibVEX_alloc_first =3D=3D &temporary[0]) pool =3D "TEMP";
+ if (private_LibVEX_alloc_first =3D=3D &permanent[0]) pool =3D "PERM";
+ vex_printf("VEX temporary storage exhausted.\n");
+ vex_printf("Pool =3D %s, start %p curr %p end %p (size %d)\n",
+ pool,=20
+ 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.");
}
=20
-void vexClearTEMP ( void )
+void vexSetAllocModeTEMP_and_clear ( void )
{
/* vassert(vex_initdone); */ /* causes infinite assert loops */
- temporary_bytes_allocd_TOT +=3D (ULong)temporary_bytes_allocd;
- temporary_count_allocs_TOT +=3D (ULong)temporary_count_allocs;
- temporary_used =3D 0;
- temporary_bytes_allocd =3D 0;
- temporary_count_allocs =3D 0;
+ temporary_bytes_allocd_TOT=20
+ +=3D (ULong)( private_LibVEX_alloc_curr - private_LibVEX_alloc_fir=
st);
+
+ mode =3D VexAllocModeTEMP;
+ temporary_curr =3D &temporary[0];
+ private_LibVEX_alloc_curr =3D &temporary[0];
+ vexAllocSanityCheck();
}
=20
=20
@@ -143,11 +200,8 @@
=20
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,=20
- (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 );
}
=20
=20
Modified: trunk/priv/main/vex_util.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/main/vex_util.h 2005-11-23 03:54:48 UTC (rev 1468)
+++ trunk/priv/main/vex_util.h 2005-11-23 04:25:07 UTC (rev 1469)
@@ -101,10 +101,10 @@
=20
extern void vexSetAllocMode ( VexAllocMode );
extern VexAllocMode vexGetAllocMode ( void );
+extern void vexAllocSanityCheck ( void );
=20
-extern void vexClearTEMP ( void );
+extern void vexSetAllocModeTEMP_and_clear ( void );
=20
-
#endif /* ndef __VEX_UTIL_H */
=20
/*---------------------------------------------------------------*/
Modified: trunk/pub/libvex.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/pub/libvex.h 2005-11-23 03:54:48 UTC (rev 1468)
+++ trunk/pub/libvex.h 2005-11-23 04:25:07 UTC (rev 1469)
@@ -168,8 +168,31 @@
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));
=20
+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 =3D sizeof(void*)-1;
+ nbytes =3D (nbytes + ALIGN) & ~ALIGN;
+ curr =3D private_LibVEX_alloc_curr;
+ next =3D curr + nbytes;
+ if (next >=3D private_LibVEX_alloc_last)
+ private_LibVEX_alloc_OOM();
+ private_LibVEX_alloc_curr =3D next;
+ return curr;
+#endif
+}
+
/* Show Vex allocation statistics. */
extern void LibVEX_ShowAllocStats ( void );
=20
|