Binary compatibility and finding compiled classes
Jakob Praher
jpraher@yahoo.de
Sun Oct 10 19:46:00 GMT 2004
hi,
Am Don, den 07.10.2004 schrieb Tom Tromey um 19:58:
> One thing we'd like to be able to do with the new binary compatibility
> code is compile a .jar to a .so, drop it somewhere, and then have the
> application pick it up without excessive configuration.
this would be a great idea.
>> There have been a few different proposals, and implementations, of
> this idea. I think it would be useful to clear some of this up now,
> before the next release, so we can at least be clear about what is
> supported and what is experimental; maybe we can also remove anything
> we know we don't want.
>
some things that come to my mind:
* the location of the jar file may not be writeable (for instance
/usr/share/java /usr/share/jars ... )
* jar URLS should work too.
* jar files may have the same name, but different content
* jar files may have the same name, but different versions
* FQCNs are not unique (though should be)
* as you said the location of any given Class file is denoted by the
CodeSource of the Class file.
why not this simple approach:
create a /var/cache/gcj/socache directory or whatever u call it.
with the the md5 of the CodeSource or full qualified name of the jar
file as the entry for the sos.
for instance
file:///usr/share/java/xalan-2.5.jar
would get either
/var/cache/gcj/socache/40948f9e35193eb44b7a597aec45f3c5.so
or better
/var/cache/gcj/socache/a58141db08e6011e558d4dfa411a3081/libXalan-2.5.so
so when a class gets loaded it is searched whether a cache entry exists.
package gnu.gcj.runtime;
class SoCache {
....
final class SoEntry {
final URL jarPath;
final File libPath;
boolean isValid( ) { ... }
int hashCode( ) { ... }
}
...
}
Let's concider this naive approach, which is just something I stupidly
put together while thinking about it:
Class ClassLoader.loadClass( String fqcn ) {
ClassLoader cl = ?
String fqcnPath = fqcn.replace( '.', '/' ) + ".class";
URL classLoc = cl.getResource( fqcn );
SoCache.Entry entry = gnu.gcj.runtime.SoCache.findSoCacheEntry( classLoc
);
if (entry == null || ! entry.isValid( ) ) {
// construct it and put it in cache
}
SharedLibLoader sl = gnu.gcj.runtime.SoCache.getLoader( entry );
return sl.defineClass( fqcn );
}
if a Class is once loaded by the cached so, it has its Classloader set
to that SharedLibLoader. Classes used by that class will go over that
SharedLibLoader.loadClass and thus, if contained in the parents class
laoder or that classloader will get satisified. One problem could be
that if in the time between two classes are loaded from the same
location and the jar file changes in between, there will be a new
SharedLibLoader constructed, which could be a problem given that those 2
classes then have a different defining class loader, but .... just have
to think about that ().
by using URL as the jar location also ensures that this works for any
remote jar file that gets loaded.
I would place this mechanism as was one of your suggestions into the
root class laoder (java::lang::natClassLoader), so that all jars (if it
is enabled) could be cached. The cache should be validated with a
timestamp of the mtime of the local file, or one could put a md5 over
the jar itself in the directory under
/var/cache/gcj/socache/{md5}/jar.md5. Perhaps the file size would also
be enough to detect changes in the jar file.
Regarding HTTP based jars, one could query the files change date via a
modified-since request and then also only download it, if the
modification date is different.
> Finally let me say that the BC ABI has been a huge success so far. It
> has already turned precompiling Eclipse 2 from a multi-month effort to
> something that is essentially trivial. We should all shower praise on
> Andrew and Bryce.
yeah its great. So at least for me -findirect-dispatch is my favorite
gcc switch. Kudos to you all!
I very much enjoyed reading through the assembler output of
$ gcj -S -findirect-dispatch Foo.java
I would be very interested in a build environment (makefiles and so on)
that works with -findirect-dispatch and eclipse2 .... :-)
Ahh and did you look at making a Inline Cache of indirection table
lookups? I've read a university presentation by Lars Bak (now at OOVM,
but former implementor of the java hotspot vm), that said one could do
this sort of stuff not only for hash table lookups (like smalltalk
selectors, but also for vtable results). The only question is, how this
could be done using native code. Perhaps the objective C performance
tuning stuff can be reused here. At least I've once come over an
interesting web page, that disassembled the objective C caching
mechanisms.
>> Tom
More information about the Java
mailing list