DynamoRIO
|
average_bb_size.p4
Now we add instrumentation to gather the dynamic counts. For the first pass we'll use a clean call to increment the counters from each block. However this approach is very slow since for each basic block execution a context switch out of the cache will occur. We'll look at other approaches next.
#include "dr_api.h"
#ifdef WINDOWS
# define DISPLAY_STRING(msg) dr_messagebox(msg)
#else
# define DISPLAY_STRING(msg) dr_printf("%s\n", msg)
#endif
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 void
event_exit(void);
static dr_emit_flags_t
bool for_trace, bool translating);
+ static void
+ clean_call(uint instruction_count);
DR_EXPORT void
{
/* register events */
dr_register_exit_event(event_exit);
dr_register_bb_event(event_basic_block);
/* initialize lock */
as_built_lock = dr_mutex_create();
+ count_lock = dr_mutex_create();
}
static void
event_exit(void)
{
/* Display results - we must first snpritnf the string as on windows
* dr_printf(), dr_messagebox() and dr_fprintf() can't print floats. */
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"
+ "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,
+ counts_dynamic.blocks,
+ counts_dynamic.total_size / (double)counts_dynamic.blocks);
DR_ASSERT(len > 0);
msg[sizeof(msg)/sizeof(msg[0])-1] = '\0';
DISPLAY_STRING(msg);
/* free mutex */
dr_mutex_destroy(as_built_lock);
+ dr_mutex_destroy(count_lock);
}
+ static void
+ clean_call(uint instruction_count)
+ {
+ dr_mutex_lock(count_lock);
+ counts_dynamic.blocks++;
+ counts_dynamic.total_size += instruction_count;
+ dr_mutex_unlock(count_lock);
+ }
static dr_emit_flags_t
bool for_trace, bool translating)
{
uint num_instructions = 0;
instr_t *instr;
/* count the number of instructions in this block */
num_instructions++;
}
/* update the as-built counts */
dr_mutex_lock(as_built_lock);
counts_as_built.blocks++;
counts_as_built.total_size += num_instructions;
dr_mutex_unlock(as_built_lock);
+ /* insert clean call */
+ false, 1, OPND_CREATE_INT32(num_instructions));
+
return DR_EMIT_DEFAULT;
}
DR_API void dr_mutex_lock(void *mutex)
DR_API instr_t * instrlist_first(instrlist_t *ilist)
Top-level include file for DynamoRIO API.
DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[])
DR_API void * dr_mutex_create(void)
DR_API INSTR_INLINE instr_t * instr_get_next(instr_t *instr)
DR_API void dr_mutex_unlock(void *mutex)
DR_API void dr_register_bb_event(dr_emit_flags_t(*func)(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating))
DR_API void dr_register_exit_event(void(*func)(void))
DR_API void dr_insert_clean_call(void *drcontext, instrlist_t *ilist, instr_t *where, void *callee, bool save_fpstate, uint num_args,...)
DR_API void dr_mutex_destroy(void *mutex)
Definition: dr_defines.h:378