compacting meta-data
Per Bothner
per@bothner.com
Thu May 6 04:33:00 GMT 2004
Assume we rely on compile-time (rather than link-time)
duplicate delimination of names (_Jv_Utf8Consts).
Then we can mix _Jv_Utf8Consts and other metadata in
the same compact constant pointer-free section.
Assume each compilation unit has a big "meta-data"
section, which we can model as:
static const unsigned char[] __metadata = { ... };
All classes compiled in the same unit (.o file) share
the same __metadata section, and each class contain a
pointer to this buffer. This one pointer needs relocation,
but other references can be relative offsets into
__metadata, which don't need relocation. Thus:
class java::lang::Class
{
/* Pointer to this unit's __metadata buffer. */
const char* metadata;
/* An offset into metadata. I.e. old cls->name becomes
* (_Jv_Utf8Const*) (cls->metadata+cls->name_off). */
int name_off;
/* An offset into metadata. I.e. old cls->fields becomes
* (_Jv_Field*) (cls->metadata+cls->fields_off). */
int fields_off;
...
};
Furthermore, relative offsets can use variable-width encodings,
so they can use as little as one byte for a "pointer".
Assume we represent a non-negative integer as a '_Jv_VInt',
which uses a variable number of bytes. Values 0 to 127
use a single byte, while bigger numbers use 7 bits per byte,
with the high-order bit set in all but the last byte.
Thus a _Jv_Field is now variable-length.
class _Jv_Field
{
/* pseudo-code follows:
// a variable-length relative offset to this field's name.
// the offset is negated; the compiler emits _Jv_Ut8Const
// for each field into __metadata, if need be, so when
// the _Jv_Field is emitted it can point back to the name.
// _Jv_VarInt name;
// offset - if a non-static field
_Jv_VarInt boffset;
... flags, type etc
*/
_Jv_Utf8Const * getNameUtf8Const ()
{
const char *ptr = this;
int name_off = DECODE_VAR_INT(&ptr);
return (_Jv_Utf8Const*) ((const char*) this - name_off);
}
jint getBOffset ()
{
const char *ptr = this;
int name = DECODE_VAR_INT(&ptr);
int offset = DECODE_VAR_INT(&ptr);
return offset;
}
}
... and so on.
Of course this is a lot slower than currently. We assume the
metedata for a class is traversed once as needed during class
initialization. We also assume that a java.lang.reflect.Field
has all the meta-data unpacked. Furthermore, a JNI jfieldID
is changed so it no longer points to the packed _Jv_Field,
but rather to an unpacked java.lang.reflect.Field.
I'm not volunteering to do this of course ...
--
--Per Bothner
per@bothner.com http://per.bothner.com/
More information about the Java
mailing list