-
Feature Request
-
Resolution: Done
-
Major
-
1.4.0
-
None
In order to support injection down class hierarchies (i.e. implement the ^ prefix to the class/interface name in the CLASS/INTERFACE clause) the Byteman agent transformer has to do extra work when it is passed a class/interface for transformation. It must always check if there is a rule in the rule base which mentions the target class by name or mentions one of its interfaces by name. However, it also has to iterate over the superclasses list and see if there is an overriding injection rule mentioning a superclass or one of the superclass's interfaces. In the latter case the overriding injection rule must be injected into the class being transformed (yes, it's counter-intuitive until you think about it but injecting a rule down the hierarchy requires looking at classes further up the hierarchy when deciding whether a rule applies to a given class).
This makes overriding injection actually quite costly to implement, especially because it is sometimes necessary to deal with the situation where a subclass is loaded before its superclass which requires loading the superclass bytecode (once) as a resource. Since the agent gets handed every class loaded by the JVM avoiding this cost is well worthwhile. An admittedly rather finger in the air test on my notebook shows that it adds about 3-4 seconds to the current AS 6 boot time of 35 seconds. With the supers check explicitly disabled the agent adds about 1 second.
Clearly, the supers check is only necessary if there are actually rules in the rule base which use overriding injection. Currently a system property must be set to disable overriding injection. If instead the agent were to track and count overriding rules as they are loaded and unloaded it could identify the situation where there were no overriding rules very cheaply and automatically avoid this overhead whenever it is appropriate.