The GCJ Projects List
What follows is a list of projects that the GCJ community would love
to see someone pick up and run with. If you're interested in any of
these, be sure to send a note with your questions, ideas or intentions
to the java-discuss
mailing list. Similarly, if you would like to see a project listed
here that isn't, send a patch for this HTML file to the java-patches list.
Modify gcj to obey the constraints layed out by the jar file
manifest file.
Mozilla is open-source web browser,
designed for standards compliance, performance and portability. The
Open JVM Integration project
(OJI) is a Mozilla sub-project, and is working to extend the browser
to allow Java virtual machines to be plugged into Mozilla. A gij
based plugin would be very nice indeed (gijzilla?).
Measuring performance is tricky business. We currently do all our
performance measurements in an ad hoc manner. What is needed is some
infrastructure we can use to track performance regressions and
identify opportunities for improvement.
Bryce McKinlay has put
together a list of some benchmarks that run on
GCJ. IBM has also recently released a set of "micro benchmarks"
called jMocha. Building
some infrastructure around these would be incredibly useful.
There are a few concrete performance improvements that we already know
we want:
If an object or array is allocated in static code that is
executed at most once (i.e. not in a loop or in a non-private
method), then we have the option of pre-allocating the object
or array in the static data or bss segment. This is most
obviously the right thing to do when the expression is an array
brace initializer whose elements are compile-time constants, since
then we can initialize the array statically. (This is already
implemented.) It also makes sense for array elements that
are initialized to link-time constants, such as references
to other statically allocated objects, as you might get
from a multi-dimensional array brace-initializer.
It may also make sense to pre-allocate a non-array object.
It makes most sense when the object constructor is inlined,
especially if it turns out that most or all of the fields get
initialized to constants. Even if the constructor is not inlined,
it may still make sense to pre-allocate the object if it is
being assigned to a static final field: The tradeoff is that
you save the space needed for the call to allocate the object, but
you use more space if it turns out the class is never initialized.
Note that if a statically allocated object contains
pointer fields then the gc has to know about the object.
The cleanest way is to make sure the object header has
appropriate flags so that the gc recognizes that the object is
static but has pointer fields. There is no need to register the
static object with the gc, since if it is live, it will get
traversed anyway (typically via the fields table of the declaring
class).
- We'd like gcj to do tree-level inlining like the C++
compiler. We're most of the way there (when compiling
from Java source code), since gcj already represents
entire functions as trees.
- Once we have tree-level inlining, we can use it to
sometimes eliminate unnecessary synchronizations.
Combined with a simple "no escape" flag, this could also
let us further optimize string concatenation without
having to introduce a new class in the runtime.
- When compiling from bytecode, GCJ generates tree nodes
as long as it is within a single "statement" - i.e. no branching
or side effects. However, any branching or other complications
causes RTL to be emitted. This is similar to the historical
way the C and C++ front-ends were implemented. Gcc now has support
for representing an entire method body as a tree node, and g++
has been converted to do that, because it makes certain
optimizations more practical. Gcj already represents an entire
method body as a single tree structure when compiling from
Java source; we should do the same
when compiling from bytecode. To begin with, we can represent
control flow using
GOTO_EXPR . However, if would
be better if we can deduce higher-level structure. I.e. it is
easy to generate
(COND_EXPR TEST (GOTO_EXPR L1) (GOTO_EXPR L2)) , but it
would be better though harder to simplify that to a
COND_EXPR that does not use GOTO_EXPR .
The simplification is probably best done after we have generated
a correct but GOTO -based tree representation.
For example, if a label is only used once, we can move its code
to where the unique GOTO is.
- Add hooks to gcj and g++ to generate write barriers.
This would let us write a precise collector.
- Do escape analysis to detect method-local and
thread-local objects. This can yield a significant
performance improvement in some cases.
- Extend the existing null-pointer patch (for PR 2) to
optionally enable it for all method calls and field
dereferences. This will let gcj-compiled code work
correctly on systems without an MMU.
- The structure of
expand_byte_code in
expr.c uses macros in a way that in retrospect
looks like a mistake. It should be re-written to be a simple
switch statement based on the structure of
verify_jvm_instructions in verify.c .
(There are actually two switch statements using the magic macros
in expr.c - look for the includes of
"javaop.def" . They should both be re-written, but
second one is higher priority.)
- Write a program to convert existing locale data into a
format we can use.
|
|