Concretely, to apply this CPU accounting scheme, each non-native and non-abstract Java method (respectively constructor) is rewritten in the following way:
1. Insert a call to getCurrentAccount() at the beginning of the method and save the result in a local variable (let us call it cpu).
as possible efficiently. The
order to conditional
“if (cpu.consumption >= 0) cpu.triggerConsume();” inserted in the following locations:
At the beginning of the method and before method termination (before a return or throw statement). This is to ensure that the conditional is regularly evaluated in presence of recursive methods and more generally of deeply nested call stacks. It is a form of call/return polling as described by Feeley .
At the beginning of each JVM subroutine and before return from the JVM subroutine. This ensures that the conditional is regularly evaluated in the (possibly nested) execution of JVM subroutines. Again, this is a form of call/return polling.
At the beginning of each exception handler. This is important for complete call/return polling, since a method may be termi- nated by an exception which was not thrown explicitly. E.g., a JVM invoke instruction may throw an exception, if the callee method throws an exception. In this case, the exception handler that catches the exception will perform the return polling.
At the beginning of each loop.
e) In each possible execution path (excluding backward jumps, since they are already taken care of as loops) after MAXPATH bytecode instructions, where MAXPATH is a global parameter passed to the bytecode rewriting tool. This means that the maximum number of instructions executed within one method before the conditional is evaluated is limited to MAXPATH. In order to avoid an overflow of the consumption counter,
MAXPATH should not exceed 215 explanation).
(see Section 3.5 for an
We omit superfluous call/return polling in leaf methods, i.e., in methods that do not invoke any other method (unless the invoca- tion is inside a structure that always requires polling, such as a loop, a subroutine or an exception handler). Furthermore, within the constraints cited above, we try to limit polling to the paths