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