[boehm-gc] Import 6.3 alpha 1

Bryce McKinlay bryce@mckinlay.net.nz
Sat Aug 2 04:05:00 GMT 2003


On Friday, Aug 1, 2003, at 17:02 Pacific/Auckland, Jeff Sturm wrote:

> This code was easy to fix.  On the one hand I'm happy that gcj alerted  
> me
> to the dependency.  On the other it ought to have worked anyway (at  
> least
> until this line of code was executed, at which time  
> NoClassDefFoundError
> or something is thrown).


With the binary-compatibility ABI, thats precisely what will happen:  
you'll get a NoClassDefFoundError at the point where the first attempt  
to initialize "FakeDriver" is made. The runtime would have discovered  
the FakeDriver didn't exist while the class containing this code was  
being linked, and linked it against a stub Class object with a flag  
indicating that the classes implementation/definition was not  
available. JvInitClass would see this flag and throw the exception.

The only sort of code I can imagine that would cause problems is if you  
did something like:

void loadFakeDriver()
{
    
dynamically_create_bytecode_for_FakeDriver_and_put_it_into_the_classpath 
();
   FakeDriver.run();
}

This can't work because the link tables are immutable once they are  
created: allowing them to be updated once they are already being used  
would complicate everything way too much. But this code will have  
unspecified results according to the JLS, it isn't valid java source  
without a FakeDriver.class present, and it could be made to work  
perfectly well using Class.forName().

In some cases it could certainly be desirable to know about missing  
dependencies in your compiled application without having to exercise  
all possible code paths. To get this we can add a runtime flag to make  
libgcj issue warnings about missing classes at link time.

> Native-code compilation with gcj works as though every class explicity
> named in the source code is loaded at build time, though class
> linkage/initialization is deferred to run time.  It sometimes goes too
> far.  I realize -fno-assume-compiled=... makes it easier, but support  
> for
> that is incomplete.

With the current ABI, much of what constitutes linkage (in the Java  
sense) is _not_ deferred until runtime, and therein lies the problem.  
With the binary-compatible ABI, it would become far easier to build  
3rd-party projects, especially for bytecode->native compilation.

A major problem currently is that many projects ship .jars with  
dependencies against 3rd party classes that are not actually required  
to run the application, because the application checks for the  
existence of those classes before running the code that requires them.  
With a VM thats fine, but with GCJ currently you must also compile all  
those dependencies to native code, and then carefully link them all  
against your binary. A total pain! The binary compatibility ABI fixes  
that.

For example, assuming valid bytecode and no GCJ bugs, a command like

gcj --main=Ant ant.jar -o ant

will always produce a binary regardless of what the classes in ant.jar  
depend against. This is possible because class files already contain  
all the type information needed for classes that they refer to  
(assuming runtime symbolic linking). Of course, if ant really does  
require some other class that isn't present in its .jar (or libgcj),  
then you'll get an exception when trying to run it. But thats not so  
bad - you'll be able to add bytecode for that class to the classpath,  
or LD_PRELOAD a shared library, to get it running without even  
recompiling the original .jar! And of course, as a bonus your ant  
binary will continue to work against future versions of libgcj without  
recompilation!

> I'd be happy if there were some gcj flags that work 99% of the time  
> when
> doing a naive compilation of third party sources or jar archives to  
> native
> code, even if not the default flags.  Maybe finishing  
> -fno-assume-compiled
> will be good enough.

Sounds like -fno-assume-compiled and the binary compatibility ABI are  
two different means to the same end. I'm confident that, if the  
compiler is made smart enough, the performance impact of the new ABI  
would be negligible enough, and other benefits like ease-of-use, faster  
link and load times, and smaller binaries significant enough, to make  
it the default ABI.

Regards

Bryce.



More information about the Java mailing list