Our final optimization is to note that if we're running with thread-private caches (i.e. with the -thread_private option to DynamoRIO) we can use absolute addressing on the per-thread counters instead of indirecting via TLS which should greatly speed things up. The downside to -thread_private is that on applications with many threads memory use can get quite high, potentially enough to impact performance of the system.
#include <stddef.h>
#ifdef WINDOWS
# define DISPLAY_STRING(msg) dr_messagebox(msg)
#else
# define DISPLAY_STRING(msg) dr_printf("%s\n", msg)
#endif
#define TESTALL(mask, var) (((mask) & (var)) == (mask))
#define TESTANY(mask, var) (((mask) & (var)) != 0)
typedef struct bb_counts {
uint64 blocks;
uint64 total_size;
} bb_counts;
static bb_counts counts_as_built;
void *as_built_lock;
static bb_counts counts_dynamic;
void *count_lock;
static uint64 bbs_eflags_saved;
static void
event_exit(void);
event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
bool for_trace, bool translating);
static void
event_thread_init(void *drcontext);
static void
event_thread_exit(void *drcontext);
DR_EXPORT void
{
}
static void
event_exit(void)
{
char msg[512];
int len;
len = snprintf(msg, sizeof(msg)/sizeof(msg[0]),
"Number of blocks built : %"UINT64_FORMAT_CODE"\n"
" Average size : %5.2lf instructions\n"
" Num saved eflags : %"UINT64_FORMAT_CODE"\n"
"Number of blocks executed : %"UINT64_FORMAT_CODE"\n"
" Average weighted size : %5.2lf instructions\n",
counts_as_built.blocks,
counts_as_built.total_size / (double)counts_as_built.blocks,
bbs_eflags_saved,
counts_dynamic.blocks,
counts_dynamic.total_size / (double)counts_dynamic.blocks);
msg[sizeof(msg)/sizeof(msg[0])-1] = '\0';
DISPLAY_STRING(msg);
}
static void
event_thread_init(void *drcontext)
{
bb_counts *counts = (bb_counts *)
dr_thread_alloc(drcontext,
sizeof(bb_counts));
memset(counts, 0, sizeof(bb_counts));
}
static void
event_thread_exit(void *drcontext)
{
counts_dynamic.blocks += counts->blocks;
counts_dynamic.total_size += counts->total_size;
}
event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
bool for_trace, bool translating)
{
uint num_instructions = 0;
bool eflags_saved = true;
where = instr;
eflags_saved = false;
}
num_instructions++;
}
counts_as_built.blocks++;
counts_as_built.total_size += num_instructions;
if (eflags_saved)
bbs_eflags_saved++;
if (eflags_saved) {
}
+
+ }
#ifdef X86_32
INSTR_CREATE_add(drcontext,
INSTR_CREATE_adc(drcontext,
INSTR_CREATE_add(drcontext,
INSTR_CREATE_adc(drcontext,
#else
INSTR_CREATE_add(drcontext,
#endif
+ }
if (eflags_saved) {
}
}