Interface method calls are slow.

Jeff Sturm jsturm@sigma6.com
Wed Nov 17 08:00:00 GMT 1999


Per Bothner wrote:
> > > Also, inlining (final, static) methods across class boundaries does
> > > not yet seem to work.
> >
> > I don't know if that's fixable. The C++ compiler goes away with that
> > because inline methods are declared in file included by every
> > compilation unit that requires them -- I believe. I'll have to check
> > with the C++ team.
> 
> If we're talking about Java code, it doesn't really have anything
> to do with the C++ compiler.  If the classes whose methods we're
> calling are given from Java source, we just need to remember the
> trees for final/static methods we might want to inline, even if
> they are in other classes.  If the classes are available from
> bytecode, we need to make sure that inline rtl is generated and
> saved;  if that is not already happening, it is probably some
> simple thing that needs to be fixed.

The C++ compiler has an easier job than Java, since all inline
declarations appear in a single code stream (thanks to cpp) and are
already ordered (thanks to language rules).  So the C++ model isn't very
useful to us.

I investigated gcj inlining within two code examples.  The first
declares two classes in one source file:

    class A {
        static int swap(int i) {
            return ((i >>> 24) & 0xff) |
                ((i >>> 16) & 0xff) <<  8 |
                ((i >>>  8) & 0xff) << 16 |
                (i & 0xff) << 24;
        }
    }

    public class B {
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++) {
                System.out.println(i + ": " + A.swap(i));
            }
        }
    }

The code compiles without warnings, but `swap' is not inlined... the
frontend seems to discard the parse tree after A is compiled.

The other example references an external class (java.util.Vector):

    public class C {
        public void c(java.util.Vector v) {
            for (int i = 0; i < v.size(); i++) {
                System.out.println(v.elementAt(i));
            }
        }
    }

Compiling this emits warnings:

    [jsturm@toronto inline]$ gcj -O2 -Winline -S C.java
    C.java: In class `C':
    C.java: In method `c(java.util.Vector)':
    java/util/Vector.java:0: warning: can't inline call to `size()'
    C.java:3: warning: called from here
    java/util/Vector.java:0: warning: can't inline call to
`elementAt(int)'
    C.java:4: warning: called from here

The Vector.java source is parsed recursively in parse_source_file
(jcf-parse.c).  I think the parse tree is preserved, but
DECL_SAVED_INSNS is not set because rest_of_compilation is never called
since no code need be generated for the Vector class.  Consequently the
backend fails to inline the calls to size() and elementAt().

I worked on the problem for a while and gave up... admittedly I'm not
too familiar with the gcc backend.

-- 
Jeff Sturm
jsturm@sigma6.com


More information about the Java mailing list