|
Articles Index
public class Benchmark {
public static void main(
String[] arg) {
long before =
System.currentTimeMillis();
int sum = 0;
for (int index = 0; index <
10*1000*1000; index += 1) {
sum += index;
}
long after =
System.currentTimeMillis();
System.out.println("Elapsed time: " +
Long.toString(after - before) +
" milliseconds");
}
}
|
The inner loop could be anything. "sum += index" is just
one operation that someone might try to measure. The method begins
interpreting, but on every backward branch (corresponding to the closing brace
of the loop), a counter associated with the method is incremented. When it goes
past a threshold (currently 10,000 in Java HotSpot version 1.0) then the method
is compiled.
The timeline is:
-
Interpreter starts interpreting
main() method.
-
Counter hits 10,000, and compilation begins, but still interpreting
main().
-
Compilation finishes, still interpreting
main().
-
main() finishes.
Because the main method is never reentered, the compiled version
will never be executed. That's where on-stack replacement comes in. A special
version of the method is compiled that allows execution to continue from the
middle of the loop.
With on-stack replacement in place, our timeline is now:
- Interpreter starts interpreting
main() method
- Counter hits 10,000, and compilation begins, but still interpreting
main()
- Compilation finishes, still interpreting
main()
- Counter hits 14,000 (in HotSpot 1.0), and interpreting stopstime
for OSR!
main() is compiled a second time via OSR to allow entry in
the middle of the loop
- main() resumes in the compiled code
- main() finishes
Return to main article
|
|