harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Egor Pasko <egor.pa...@gmail.com>
Subject [drlvm] interface call devirtualization
Date Mon, 10 Jul 2006 15:44:52 GMT

I looked through the list of TODO projects for JIT [1] and decided to write a
microbenchmark detecting how good interface call devirtualization works in JIT 
(see below)

Jitrino.OPT showed very-very slow (~2.5 times slower than JRockit (1.5/linux)).

I looked through the compile-time log of Jitrino.OPT (see below) and found the
reason: Jitrino.OPT did *not* hoist "interface vtable address load instruction
(ldintfcvt)" above the hottest loop. 

At the moment, I would wait a little before hacking load hoisting
since it looks more complicated than interface call
devirtualization. A strange thing, "interface call devirtualization"
would have boosted JRockit's performance too (I checked that with a
slightly changed benchmark).

So, that would be interesting to implement it!

Seems like the best choice is to start from a couple of easy heuristics:
* if there is only one loaded class to implement the interface, choose it
* if there are more, choose the one with it's method invoked earlier (compiled
  by some JIT, possibly, some other JIT), 
* if we have many candidate methods that are compiled, choose the most frequent
  one (need a method-entry profile, the feature is likely to stay untouched for
  a while, I guess)

4 questions for now:

0. Does anybody want to participate? :))) 
   I am always ready to help with implementation details.

1. Does anybody have some additional elegant ideas?

2. How do you like the benchmark?

3. Should I create a JIRA for the issue ASAP? :)


The benchmark:
import java.util.Date;

interface Intfc {
    public void reset();
    public void inc();
    public int getNum();

    static final long exercise = 1000000000;

class IntfcImpl implements Intfc {

    public IntfcImpl() { reset(); }

    private int num;

    public void inc() { num++; }

    public int getNum() { return num; }

    public void reset() { num = 0; }

class Runner {
    public Runner(Intfc o) { intfc_obj = o; }
    public void run()

        /* uncomment to test performance on a non-devirtualized version */
        //IntfcImpl impl_obj = (IntfcImpl) intfc_obj;

        for (long i = 0; i < Intfc.exercise; i++ ) {

            /* uncomment to test performance on a non-devirtualized version */

    public void measureTime()
        Date before, after;

        before = new Date();
        after = new Date();
        System.out.println("run: " + (after.getTime() - before.getTime()));

    private Intfc intfc_obj;

public class IntfcCaller {
    public static void main(String[] args) {
        IntfcImpl obj = new IntfcImpl();
        // use obj a little

        Runner runner = new Runner(obj);


        if ( obj.getNum() != Intfc.exercise ) {

to get the compile-time log of method Runner::run() I put an extra option:

-Xjit LOG=\"singlefile,root=all,method=run\"

A piece of loop body:
Block L5:
  Predecessors: L4
  Successors: L6 UNWIND
  I27:tauhastype      t18,cls:Intfc -) t20:tau
  I28:ldintfcvt t18,cls:Intfc ((t19)) -) t21:vtb:cls:Intfc
  I29:ldvfnslot [t21.Intfc::inc] ((t19)) -) t22:method:inc
  I31:callimem  [t22](t18) ((t19,t20)) -)

Even the highest optimization level (option -Xjit opt::skip=off) does not help

[1] http://mail-archives.apache.org/mod_mbox/incubator-harmony-dev/200606.mbox/%3Cuejxhim8n.fsf@gmail.com%3E

Egor Pasko, Intel Managed Runtime Division

Terms of use : http://incubator.apache.org/harmony/mailing.html
To unsubscribe, e-mail: harmony-dev-unsubscribe@incubator.apache.org
For additional commands, e-mail: harmony-dev-help@incubator.apache.org

View raw message