binary compatibility ABI (was: Re: [boehm-gc] Import 6.3 alpha 1)

Andrew Haley aph@redhat.com
Tue Sep 9 15:17:00 GMT 2003


I've been giving this some thought.

It seems to me that the right way to handle access to fields is
automatically to generate access methods for them.  Unlike the
traditional Java access methods getFoo() and putFoo(), these methods
will return the address [Footnote 1] of a field rather than access the
contents of a field.

So, for

class Body
{
    public long idNum;
}

we'll generate (C++)

class Body
{
  private:
    jlong idNum$;
  public:
    jlong *idNum() __attribute__((pure));
}

[Footote 2]

jlong *Body::idNum()
{
    return &idNum$;
}

The symbol that is the name of a static field will no longer need to
be exported; all CNI code will use the access methods to get at static
fields.  That way we will get full binary compatibility for CNI code,
and we don't have to touch the C++ compiler.

[Footote 3,4]

Of course, this means that CNI will change, but we don't necessarily
have to have a flag day.  If we make the name of the access method
different from the name of the field, for an intermediate time we can
continue to support CNI code that uses the "old" technique of binding
to a global symbol.

Also, we can dispense with the call to initialize the class that
contains a static data member:

class Body
{
    static public int count;
}

we'll generate (C++ish)

jint *Body::count() __attribute__((pure));
jint *Body::count()
{
    _Jv_InitClass (&class$);
    return &count$;
}

By removing all external access to fields, we reduce the problem of
binary compatibility to that of ensuring that -findirect-dispatch
works correctly.

Footnotes:

[1] It might be better to make the return type of the access methods a
C++ reference rather than a pointer.  Or, perhaps better still, a C++
smart pointer.

[2] "__attribute__((pure))" ensures that the optimizer knows that for
any particular object the address of a field won't change.

[3] I am assuming that a client may want to stash the address of a
field somewhere, so it doesn't need to call idNum() more than once.
However, that is entirely an optimization issue, and doesn't affect
the ABI in any way.

[4] With whole-program optimization and inlining, these access methods
will disappear.  This overcomes any objection that this technique will
be inefficient when statically compiling an executable.

Andrew.



More information about the Java mailing list