[e-lang] E-on-Java works with recent gcj

Toby Murray toby.murray at dsto.defence.gov.au
Mon Aug 14 05:07:36 EDT 2006


Mark S. Miller wrote:

>Tyler recently told me about a useful java feature I didn't know. In a jar 
>file manifest, you can put a directive "Class-Path: ...". When the jar file 
>itself is launched, it will include the specified class on the class path. Is 
>there any corresponding way to build a gcj executable that knows what it's 
>supposed to use as a class path?
>
>  
>
Yes, it turns out that there is. I've now managed to get a binary up and 
running that requires no special tweaking of classpath etc. at runtime.
The binary also uses precompiled versions for classes (which are stored 
in a shared library) when loading them at runtime, which increases the 
start-time by about 10% over a version where everything has to be loaded 
from bytecode.

Here's a rough sketch how to get it up and running. (Step 2 isn't 
necessary but helps to prevent a Makefile rebuilding everthing each time 
because your dependency calculations get out of whack...)

1. Patch SWTRunner.java as before.
2. Patch methodCall.java (in org.erights.e.elang.tests, I think) so it 
has the correct package name.
3. Build the java sources to class files
e.g. gcj  -C -d BUILD/class <All .java files> -I<path to SWT JAR file>
4. Build the java sources to .o files. (I'm using one invocation of gcj 
for each .java file at the moment, although this is slow)
5. Build a static library of all .o files built from step 4
6. Build a JAR of all .class files built from step 3. Ensure that when 
building this JAR file, the paths to the .class files in the JAR match 
the package names etc.
(pretend that this JAR file is called e.jar for now)
7. Build a shared library from the JAR file
e.g. gcj -shared -findirect-dispatch -Wl,-Bsymbolic -fPIC -o e.jar.so e.jar
8. Build a classmap db file that maps .class files to their 
implementation in the shared library
e.g. gcj-dbtool -n classmap.db; gcj-dbtool -a classmap.db e.jar e.jar.so
9. Build a binary, telling the binary where it's classpath is and where 
to find the classmap db file
e.g. gcj --main=...MetaRune <static library name> -o e <flags to include 
SWT JAR and link against SWT library> 
-Djava.class.path=$PWD/bin/resources:$PWD/e.jar:$PWD/esrc 
-Dgnu.gcj.precompiled.db.path=$PWD/classmap.db

The 'e' binary built above should be able to use the precompiled 
versions of the classes in the e.jar.so at runtime.

The way this precompiled stuff works (I think) is that the classmap.db 
contains a mapping from "classname,checksum" -> somelibrary.so
At runtime, it checks the classpath for a needed class. If found, it 
calculates the checksum of the class. If this matches the checksum in 
the db then it loads the shared library and uses the precompiled version 
out of there rather than interpreting the bytecode of the class it found 
in the classpath.
This is why the binary still needs e.jar in its classpath. Although by 
having the classmap.db and e.jar.so, we get a slight performance 
increase of about 10%  for running a HelloWorld program ( println("Hello 
World!") )

I've attached a Makefile that I was using to build this stuff. I had to 
transcribe the Makefile from a hardcopy so it might have typos in it. 
Hopefully  there's enough context to allow someone to fix typos in it etc.
It *should* calculate the dependencies correctly so that once you've 
built it all, if you do another 'make' it won'tt ry to rebulid anything. 
(Although see Step 2. above).

You can test whereher your binary is loading precompiled classes from a 
shared library or whether its interpreting bytecode form the .jar file 
by doing an strace() on it anc cehcking for open()s of the classmap.db 
and the e.jar.so. (I'm presuming it won't open() e.jar.so unless it 
knows it wants to load a class from there, because it's already done the 
checksum and found that it matches).

Like I said above, using the precompiled version gets a startup time 
improvement of about 10%. Don't know how it goes in general though.

My "e" binary can be run like this:

e --rune <path to some file>.e

or

e --rune <path to some file>.e-awt

and has AWT working correctly etc.

-- 
Toby Murray
Advanced Computer Capabilities Group
Information Networks Division
DSTO, Australia

IMPORTANT: This e-mail remains the property of the Australian Defence
Organisation and is subject to the jurisdiction of section 70 of the
Crimes Act 1914. If you have received this e-mail in error, you are
requested to contact the sender and delete the e-mail.

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: Makefile.gcj.txt
Url: http://www.eros-os.org/pipermail/e-lang/attachments/20060814/377d37b9/attachment.txt 


More information about the e-lang mailing list