Concerning limitations, the major hurdle of our approach is that it can- not account for the execution of native code. It is nevertheless possible to wrap expensive native operations, such as (de-)serialization and class loading, with libraries that deduce the approximate CPU consumption from the size and value of the arguments.
It should be noted that bytecode instruction counting and CPU time are distinct metrics for different purposes. While CPU account- ing based on bytecode instruction counting has many advantages as discussed in Section 2, more research is needed in order to assess to which extent and under what conditions it can be used as an accurate prediction of real CPU time for a concrete system. For this purpose, individual (sequences of) bytecode instructions may receive different weights according to their complexity. This weighting would be specific to a particular execution environment and may be generated by a cal- ibration mechanism. Therefore, such an approach would sacrifice the platform-independence of the accounting, but would still be applicable with on-the-fly rewriting, as promoted starting with JDK 1.5.0 (see discussion in next section on further deployment possibilities).
Security of our transformations (e.g. with respect to combination with other transformations or protection from tampering with CPU- consumption accounts, whether directly or indirectly by reflection) has not been addressed in this article. Nevertheless, it is fairly straight- forward to implement load-time bytecode verification algorithms to prevent applications from tampering with their own CPU consumption accounts. Moreover, the reflection methods of java.lang.Class (e.g., getFields(), getMethods(), etc.), can be patched in order to prevent access to the internals of our CPU accounting mechanism by untrusted code.
Another issue related to reflection is that our optimized program transformation scheme, which passes a ThreadCPUAccount instance as extra argument, may break existing code that relies on the reflection API. After introduction of wrapper methods, the arrays of reflection ob- jects returned by getConstructors(), getDeclaredConstructors(), getMethods(), and getDeclaredMethods() of java.lang.Class (i.e., instances of java.lang.reflect.Constructor respectively java.lang.reflect.Method) will contain both the wrapper methods (with the unmodified signatures) as well as methods with extended signatures. If an application selects a method from this array consid- ering only the method name (but not the signature), it may try to invoke a method with extended signature, but fail to provide the extra argument, resulting in an IllegalArgumentException. We solve this