This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: [BC ABI] gcj-abi-2-dev-branch created
Tom Tromey wrote:
"Bryce" == Bryce McKinlay <mckinlay@redhat.com> writes:
Bryce> OK, you might be right. With the BC-ABI, the mangling isn't really all
Bryce> that important since the symbols will be private, the compiler could
Bryce> call them whatever it likes since the runtime can do all the
Bryce> linking. As for the standard ABI, instead of actually changing the
Bryce> mangling format I think it should be sufficient to add something like
Bryce> "$$return_type" to a method name in the cases where conflicts
Bryce> occur. This should allow us to keep generating .h files for CNI
Bryce> without having to dramatically alter either CNI or the C++ compiler.
I have a few questions about how CNI is going to continue to function.
One question is how CNI code will contribute to the otable. That
seems like a major problem.
For mangling, Andrew had the idea that we would emit static
initializers to register CNI methods with the runtime, basically akin
to JNI function registration. So perhaps that problem is
solved-enough.
Yeah, we will have to do something like that. One possibility I'm
considering is extending the use of the .jcr class registration
mechanism, so that it can register methods in addition to classes. We
need to find a way of registering method IPs that does not get messed up
by the PLT anyway (for the stack tracing code), so maybe this can solve
both problems.
The point you bring up is an important one. If CNI can contribute to
the otable, then we just need to teach g++ about our own weird
mangling (or add an attribute or something). That might work.
I don't think we need to change C++'s mangling at all. We'll just have
gcjh append something to the method names. For example:
package foo;
Object getFoo()
String getFoo()
becomes
foo::getFoo$$Object
foo::getFoo$$String
Another idea would be to declare that CNI can't work with BC code. \
IMO, this is not an option.
Bryce> As an aside, I'm not really sure that we need to keep the "covariant
Bryce> bridge methods" at all when generating .o output. I haven't discovered
Bryce> a situation yet where the bridge methods generated by the compiler do
Bryce> anything more than call the real method?
We talked about this on irc, but I thought I'd put the answer out to a
wider audience. The bridge methods are needed for runtime type
safety, and if you omit them, then at runtime you can perform invalid
unchecked casts.
The example:
class base<T> {
public T obj;
public void set (T x) { obj = x; }
}
case der extends base<String> {
public void set (String x) { x.something(); }
}
der foo;
base oops = foo; // this gets a compiler warning but is correct
oops.set (new Object ()); // remember we omitted the bridge, so
// no cast to String is performed
Ordinarily the compiler would generate a `der.set' that looks like:
public void set (Object x) { this.set((String) x); }
I remain unconvinced ;-). The bridge method which adds a cast check is
certainly neccessary in this case, however I have yet to see a case
where bridge methods with __covariant return types__ are used in this
way. As far as I can tell so far, the bridge methods for co-variant
returns are only inserted for VM compatibility.
For example, given:
class Foo
{
Foo get() {return new Foo();}
}
class Bar extends Foo
{
Bar get() {return new Bar();}
}
The compiler must insert a bridge method in Bar with declared type Foo.
The reason for this is that in order for Bar.get to override Foo.get in
the JVM, the signatures must match, and in a class file the return type
is part of the method signature. So the bridge method overrides
Foo.get() and does an invokevirtual to the real Bar.get(). There are no
type safety issues because the return type of Bar.get() must _always_ be
compatible with Foo.get().
I've been wrong about such things before though, so if anyone has a
counter example, I'd like to see it ;-)
Regards
Bryce