|
From: Nicholas N. <nj...@cs...> - 2006-12-15 02:47:10
|
On Thu, 14 Dec 2006, Ben Liblit wrote: > I am creating a custom Valgrind tool that adds instrumentation code to > Ist_Exit instructions. However, the extra instrumentation is only > needed the first time each Ist_Exit instruction executes. After that, > I'd like to discard the instrumentation and leave the Ist_Exit > instruction exactly as it was in the uninstrumented basic block. > > When my instrumentor function sees an Ist_Exit instruction, it injects a > dirty call (via unsafeIRDirty_0_N). The call provides one argument: the > current code address as revealed by the closest preceding Ist_IMark > instruction. Call this "codeAddr". > > Inside the called dirty function, I use > VALGRIND_DISCARD_TRANSLATIONS(codeAddr, codeAddr + 1) to discard > Valgrind's translation of the instrumented Ist_Exit instruction. Some > bookkeeping on the side will let me notice that the *next* time the same > instruction is considered for instrumentation, I should just pass the > instruction along unchanged. > > Is it OK to use VALGRIND_DISCARD_TRANSLATIONS from within a dirty-called > function? Is it OK if the instrumented translation being discarded > includes the code which made the dirty call in the first place? (That > is, can instrumentation be self-removing in this manner?) > > Empirically, Valgrind doesn't explode or set my cat on fire when I make > this call. But it appears that the translation is not actually being > discarded either. The number of basic blocks my code is asked to > instrument is identical with or without the > VALGRIND_DISCARD_TRANSLATIONS call. That suggests that the translations > are not actually being discarded, because if they were, they would need > to be reinstrumented later when the code loops back to the same basic > block for a second time. > > Any tips on how to make this work would be much appreciated. I'm surprised what you're trying doesn't make Valgrind explode. Perhaps the code in the cache is marked as removed but not immediately overwritten. I have no idea why the code would not be genuinely discarded. First question: do you really need this optimisation? Does it make a big difference? I'd be interested to know what the tool does. If so, I'd probably use the support for conditional dirty calls -- create a boolean in memory for each Ist_Exit, set it initially, clear it once it's reached, and make the call conditional on it. It's a little slower at run-time, but avoid repeatedly JITting the block. Nick |