X hits on this document

PDF document

Program Transformations for Light-Weight CPU Accounting and Control in the Java Virtual Machine A ... - page 7 / 40





7 / 40


3.1. Bytecode Transformation Scheme

Our two main design goals for the bytecode rewriting schemes are to ensure portability (by following a strict adherence to the speci- fication of the Java language and virtual machine) and performance (i.e., minimal overhead due to the additional instructions inserted into the original classes). In this section we present a simple, unoptimized transformation scheme.

Each thread is permanently associated with a ThreadCPUAccount accounting object, of which the public interface is listed in Fig- ure 2. First, upon entering a method of a transformed component, it is necessary to determine the ThreadCPUAccount belonging to the currently executing thread: this is achieved through a call to get- CurrentAccount(). Then, as execution proceeds through the body of the method, the thread updates the consumption counter of its ThreadCPUAccount: this is the actual CPU accounting.

public final class ThreadCPUAccount { public static ThreadCPUAccount getCurrentAccount(); public int consumption; public void triggerConsume(); ...


Figure 2. Part of the ThreadCPUAccount API.

To prevent overflows of the consumption counter, which is a simple 32-bit integer,3 and, more fundamentally, to ensure the regular execu- tion of the shared management tasks, the counter has to be steadily checked against an adjustable granularity limit. More precisely, each thread invokes the triggerConsume() method of its ThreadCPU- Account, when the local consumption counter exceeds the limit defined by the granularity variable. In the following, we refer to this periodic check as polling.

There are dedicated JVM bytecode instructions for the compar- ison with zero. Hence, in order to optimize the comparison of the consumption counter to the granularity, the counter runs from

  • -

    granularity to zero, and when it equals or exceeds zero, the

triggerConsume() method is called. We use the iflt instruction, which branches if the value on top of the operand stack is smaller than zero, in order to skip the invocation of triggerConsume() in the preponderant case where consumption is below zero.

3 64-bit long integers unfortunately still impose a prohibitive runtime overhead in Java.

Document info
Document views43
Page views43
Page last viewedThu May 19 15:55:25 UTC 2016