Name: rmT116609 Date: 02/18/2003
DESCRIPTION OF THE PROBLEM :
The Java language lacks "structs".
The lack of structs gives rise to serious code complexity
when dealing with external systems, and serious performance
implications for code that performs a large amount of I/O
with external systems.
Because of the way Java and Objects are intertwined it would
probably not be entirely practical to insist on the same
struct semantics that are found in C. In particular the lack
of pointers and pass-by-value semantics for a trivial
implementation of structs makes an apples-to-apples theft
from the C language impossible.
However, as the particular problem I am trying to crack is
dealing with high-performance I/O operations (in fact,
OpenGL graphics rendering in this case), I believe there is
an elegant solution based on NIO buffers which should
provide wonderful syntax, high performance, and 100% robust
operation with minimal impact.
The solution I propose is to associate a "struct" with a
Buffer. The buffer's primitive type then becomes the struct,
i.e a position(n) command on the buffer moves the buffer to
access the nth struct in a buffer of these structs.
A struct should syntactically accessed the same as a normal
object, ie. passed by reference, and so on. Struct field
assignments and reads take place directly to and from memory
with no intermediate copy.
A struct should be defined in Java using simple C-like
syntax, and generate a .class file like any other Java class
construct. The difference is that the fields may only be
primitive Java types or themselves structs. Each field is
not stored in an instance of the object itself; instead they
are mapped to offsets in memory from a Buffer. A struct
therefore must have a reference to its parent Buffer to
prevent the buffer from being garbage collected and structs
being allowed to access unmanaged memory.
public struct Vertex {
private float x, y, z, nx, ny, nz;
private byte r, g, b, a;
void normalize() {
//etc
}
};
A struct descends from the class javax.nio.Struct, which has
a package-visible constructor which takes the parent
StructBuffer as a parameter:
public abstract class Struct {
private final Buffer buffer;
private final int position;
Struct(Buffer buffer) {
this.buffer = buffer;
}
}
The usage of the new "struct" keyword, which is
syntactically similar to "class" and "interface", instructs
the runtime not to reserve space for the structs' fields
because they will instead be referenced directly from a
buffer at the specified position.
Then a buffer of this struct should be initialized, perhaps
using the new generics feature to simplify the syntax:
// Allocates a struct buffer with 10 structs in it at the
specified address, which can be a long
StructBuffer<Vertex> buf = new StructBuffer<Vertex>(10,
address);
// or from a ByteBuffer, which will check that the
bytebuffer's capacity is an exact multiple of the struct's size
StructBuffer<Vertex> buf = new StructBuffer(byteBuf);
Then values from the buffer can be referenced directly as
Vertexes:
Vertex v0 = buf.get(0);
v0.normalize();
Vertex v1 = buf.get(1, v1); // Constructs v1 if necessary
The underlying implementation in Java should be identical in
speed to C for the common case (with bounds check
elimination and native byte ordering), yet because a struct
can only be constructed by an existing StructBuffer, it will
have all the safety of bounds-checking and garbage
collection which will prevent illegal writes to memory.
The two problems solved by this RFE would be the sheer
complexity of maintaining multiple buffers to access
different parts of a struct with different primitive types;
and the massive increase in performance afforded by being
able to reference memory directly and bracket accesses to
members of a struct with one bounds check.
You will understand if you do graphics programming; it is a
key requirement of games programmers to have greatly
simplified and efficient access to these operations or the
benefits of C++ simply outweigh the extra complexity and
overhead inherent in Java.
(Review ID: 181371)
======================================================================