I’ve been sick for a while, so I haven’t done very much. I fixed a few small bugs, though, and ran some tests.
One test involved finding out if the class loader can be run in parallel to other Java code. It is fairly clear that this has to be possible, but I still wanted to know this for sure. The answer, of course, is “yes, it can run in parallel”. That, of course, means that the class loader can modify thread timing. Our class loader and the entire framework should be invisible, though.
Right now I’m trying to figure out how much of an impact that has. The changes to the class files themselves are relatively small, so they don’t matter at a larger scale. The order of two instructions in threads might change, but it doesn’t have any effect on atomic blocks. Once I get rid of all the other problems that are still there (\*puke\*), I should be safe with classes instrumented offline.
Online instrumentation should produce identical files (it does) and identical events (it doesn’t). There are actually two problems:
- A short stub program (
CUnitRun) has to be run to install the custom class loader. This program already generates events that do not appear if the program is run by itself.
- The instrumenting class loader will intervene whenever a class needs to be loaded. While the classes of the class loader itself have been instrumented in a way so that they do not generate events, they make use of Java API classes that do generate events.
It probably makes sense to ignore any events that occur before the slave’s
main method is entered or after it has been exited. The programmer doesn’t have any influence on them, and they may be assumed to be correct. In the case of the
CUnitRun stub program, the events generated therein are ignored as well. It’s the
main method of the actual slave program that counts.
Removing the events generated by the class loader is much more difficult. Right now I’m thinking about setting a “do not record” flag when the class loader is entered, and resetting it when it is exited. That would prevent the API classes used in the class loader from recording events. This flag must be set on a per-thread basis: Only events occurring in the thread that currently runs the class loader should be ignored. I really have to stress that because it just occurred to me :)
I’m not exactly sure how this needs to work with other class loaders that the instrumenting class loader needs to cooperate with, but that’s a topic for a more thorough inquiry anyway. I also do not know how it must work with Java’s default class loader, though. Without the instrumenting class loader, the Java class loader probably does generate events. With the instrumenting class loader, most or even all events may be removed. For a first shot, it might be ok to also exclude class loaders and assume them to be correct, though.
I’ve been thinking about the “do not record” flag a bit more. It would have to be implemented in a way that’s thread-safe and that doesn’t disturb the rest of the system, i.e. it should probably has to be lockfree. That’s going to be hard. Another option is to not filter them out in the slave but in the master. To do that, the slave would have to enqueue additional “thread x entered class loader” and “thread x exited class loader” events. This should involve less logic on the slave side.