I solved the problem of “uninstrumenting” calls to
Thread.* methods with a very high degree of code reuse: I applied the same instrumentor that changes calls to original an
Object.wait method to the wrapper method
Object.wait$$$Wrapper$$$, except this time the roles are reversed: It changes calls to the wrapper method
Thread.start into calls to the original method
Now code that was previously only used for global instrumentation is also used for local instrumentation, albeit only in the case where it needs to be “globally undone”. That might make it a bit more confusing, but generally it was the right thing to do. There wasn’t any point in rewriting what’s already there.
P.S.: Maybe locally vs. globally isn’t the right terminology. Locally vs. non-locally? Ugh…