例子中的注释写到: 执行动态优化,在不干扰目标应用程序行为的情况下, 只要有价值和可行, 就将 “inc” 指令转换为 “add 1”。 说明在 已知底层处理器时 最好的做法是 在运行时执行 微体系结构 特定优化。可见这个例子和上一个 div.c 的区别就是这次我们实实在在进行了代码替换和优化。
老规矩,先看 dr_client_main
DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
/* We only used drreg for liveness, not for spilling, so we need no slots. */
drreg_options_t ops = {
sizeof(ops), 0 /*no slots needed*/, false };
if (!drmgr_init() || drreg_init(&ops) != DRREG_SUCCESS)
DR_ASSERT(false);
/* Register for our events: process exit, and code transformation.
* We're changing the app's code, rather than just inserting observational
* instrumentation.
*/
dr_register_exit_event(event_exit);
if (!drmgr_register_bb_app2app_event(event_instruction_change, NULL))
DR_ASSERT(false);
/* Long ago, this optimization would target the Pentium 4 (identified via
* "proc_get_family() == FAMILY_PENTIUM_4"), where an add of 1 is faster
* than an inc. For illustration purposes we leave a boolean controlling it
* but we turn it on all the time in this sample and leave it for future
* work to determine whether to disable it on certain microarchitectures.
*/
enable = true;
/* Initialize our global variables. */
num_examined = 0;
num_converted = 0;
注释里说,这个优化是针对于 奔腾4 处理器的,不过我们是为了学习 DynamoRIO ,不用管这些。
drreg_options_t ops = { sizeof(ops), 0 /no slots needed/, false };
这一行代码是我们第一次遇见, drreg_options_t 用来初始化 drreg 扩展,可以看到后面的 drreg_init(&ops)。drreg 是一个辅佐 管理寄存器的扩展,我们可以利用它获得一个寄存器的使用权。 这里ops结构体里的第二个参数 0,用来表示需要的插槽数,因为本次我们不需要寄存器插槽,因此设为0。关于该扩展更多的细节我还没有弄明白,以后再说。
然后就是一堆初始化,把 drmgr 和 drreg 都初始化完成。
dr_register_exit_event(event_exit) 这里注册了结束回调函数。
drmgr_register_bb_app2app_event(event_instruction_change, NULL) 也是个关键,该函数的作用是为 在 basic block creation 细分化的4个阶段里的第一个阶段 “app2app" ,注册回调函数。这样在4个阶段之前会先调用 event_instruction_change函数。
剩下几个变量里,enable 用来表示决定 需要优化。
event_exit 退出回调函数
static void
event_exit(void)
{
char msg[256];
int len;
if (enable) {
len = dr_snprintf(msg, sizeof(msg) / sizeof(msg[0]),
"converted %d out of %d inc/dec to add/sub\n", num_converted,
num_examined);
} else {
len = dr_snprintf(msg, sizeof(msg) / sizeof(msg[0]),
"decided to keep all original inc/dec\n");
}
DR_ASSERT(len > 0);
msg[sizeof(msg) / sizeof(msg[0]) - 1] = '\0';
DISPLAY_STRING(msg);
if (!drmgr_unregister_bb_app2app_event(event_instruction_change) ||
drreg_exit() != DRREG_SUCCESS)
DR_ASSERT(false);
drmgr_exit()