This is the mail archive of the java-discuss@sourceware.cygnus.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Patches for faster interface dispatch, type checking


Godmar Back wrote:

> > If a class claims to implement a given interface but doesn't (which
> > could happen if it was compiled against a different version of the
> > interface), this is detected when the idispatch tables are generated
> > (prior to class initialization) in _Jv_AppendPartialITable():
> >
>
> It's detected there, but you can't throw the exception at this point.
> You have to delay it until run-time.  After all, the call may never happen.
> The JLS is pretty clear on that.

Strictly speaking, I think you're right, of course. But its interesting that
the IBM JDK *will* refuse to load a class that claims to implement an
interface but doesn't have all its methods.

ie: given the code:

interface I
{
  void a();
}

public class Test implements I
{
  public static void main(String args[])
  {
    I i = new Test();
    i.a();
  }

  public void a()
  {
    System.out.println("a-ok");
  }
}

$ javac *.java
$ java Test
a-ok

Now, after adding a new prototype, "void b();" to I.

$ javac I.java
$ java Test
Can't find class Test

It looks like they have also ignored this part of the spec in the name of
runtime efficency.

Out of interest I added the extra check and measured the performance loss
incurred:

inline void *
_Jv_LookupInterfaceMethod0 (jclass klass, jclass iface, int method_idx)
{
  _Jv_IDispatchTable *cldt = klass->idt;
  int idx = iface->idt->iface.ioffsets[cldt->cls.iindex] + method_idx;
  void *ncode = cldt->cls.itable[idx];
  if (!ncode)
    JvThrow (new java::lang::NoSuchMethodError
      (_Jv_GetMethodString (klass, iface->methods[method_idx].name)));
  return ncode;
}

Time to make 10M interface calls:
Before, without check: 818ms [81ns / call]
After, with check: 1103ms [110ns / call]

So, we'd take a hit of about 25% doing it by-the-book. The method also maybe
becomes too long to realistically inline in most cases.

Doing the "correct" behaviour *might* be useful to maintain binary
compatability between, say, a library that changes the definition of an
interface that some application code implements. But its arguable how useful
that would really be, especially considering that such a change would break
source-level compatibility as well. I would tend to take the position that if
popular JDK implementations do it one way (which they do) then its fairly safe
to implement the same behaviour. On the other hand, the spec is
explicit: "Adding a member to an interface does not break compatibility with
pre-existing binaries."

Are there any other arguments in favour of this "lazy" method-existance
checking?

regards

  [ bryce ]



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]