Moves the content (including header) of an object around in memory
NOTE: Memory locations may overlap!
+ NOTE: The size of the object can change by moving it around (hashcode)!
IN:
old......Old Location of the object before compaction
new......New Location of the object after compaction
size.....Size of the object in bytes
+ OUT:
+ New size of the object after moving it
+
*******************************************************************************/
-void compact_move(u1 *old, u1 *new, u4 size)
+u4 compact_move(u1 *old, u1 *new, u4 size)
{
+ s4 hashcode;
+ u4 new_size;
GC_ASSERT(new < old);
MMOVE(new, old, u1, size);
}
+
+ new_size = size;
+
+ /* check if we need to attach the hashcode to the object */
+ if (GC_TEST_FLAGS((java_objectheader *) new, HDRFLAG_HASH_TAKEN)) {
+
+ /* change the flags accordingly */
+ GC_CLEAR_FLAGS((java_objectheader *) new, HDRFLAG_HASH_TAKEN);
+ GC_SET_FLAGS((java_objectheader *) new, HDRFLAG_HASH_ATTACHED);
+
+ /* attach the hashcode at the end of the object */
+ new_size += SIZEOF_VOID_P;
+ hashcode = (s4) (ptrint) old;
+ *( (s4 *) (new + new_size - SIZEOF_VOID_P) ) = hashcode; /* TODO: clean this up */
+
+ GC_ASSERT(new + SIZEOF_VOID_P < old);
+ GC_LOG( printf("Hash attached: %d (0x%08x) to new object at %p\n", hashcode, hashcode, new); );
+
+ }
+
+ return new_size;
}
u1 *ptr_new;
java_objectheader *o;
u4 o_size;
+ u4 o_size_new;
u4 used;
GC_LOG( dolog("GC: Compaction Phase 1 started ..."); );
/* object survives, place next object behind it */
ptr_new += o_size;
+
+ /* size might change because of attached hashcode */
+ if (GC_TEST_FLAGS(o, HDRFLAG_HASH_TAKEN))
+ ptr_new += SIZEOF_VOID_P;
}
/* skip to next object */
/* unmark the object */
GC_CLEAR_MARKED(o);
- /* move the object */
- compact_move(ptr, ptr_new, o_size);
+ /* move the object (size can change) */
+ o_size_new = compact_move(ptr, ptr_new, o_size);
/* object survives, place next object behind it */
- ptr_new += o_size;
- used += o_size;
+ ptr_new += o_size_new;
+ used += o_size_new;
}
/* skip to next object */
/* align the size */
/* TODO */
- /* set the hash bits in the header */
- /* TODO: improve this!!! */
- GC_SET_HASH(o, (s4) o);
-
/* calculate the wordcount as stored in the header */
/* TODO: improve this to save wordcount and without header bytes */
if ((bytelength & 0x03) == 0) {
if (!o)
return 0;
- /* TODO: improve this heavily! */
- hashcode = GC_GET_HASH(o);
+ /* TODO: we need to lock the object here i think!!! */
+
+ /* check if there is a hash attached to this object */
+ if (GC_TEST_FLAGS(o, HDRFLAG_HASH_ATTACHED)) {
+
+ hashcode = *( (s4 *) ( ((u1 *) o) + get_object_size(o) - SIZEOF_VOID_P ) ); /* TODO: clean this up!!! */
+ GC_LOG( printf("Hash re-taken: %d (0x%08x)\n", hashcode, hashcode); );
+
+ } else {
- /*GC_LOG( printf("Hash taken: %d (0x%08x)\n", hashcode, hashcode); );*/
+ GC_SET_FLAGS(o, HDRFLAG_HASH_TAKEN);
+
+ hashcode = (s4) (ptrint) o;
+ GC_LOG( printf("Hash taken: %d (0x%08x)\n", hashcode, hashcode); );
+
+ }
return hashcode;
}
#if !defined(NDEBUG)
void heap_print_object_flags(java_objectheader *o)
{
- printf("0x%02x 0x%08x [%s%s%s]",
- GC_GET_SIZE(o), GC_GET_HASH(o),
+ printf("0x%02x [%s%s%s%s%s]",
+ GC_GET_SIZE(o),
GC_TEST_FLAGS(o, GC_FLAG_FINALIZER) ? "F" : " ",
+ GC_TEST_FLAGS(o, HDRFLAG_HASH_ATTACHED) ? "A" : " ",
+ GC_TEST_FLAGS(o, HDRFLAG_HASH_TAKEN) ? "T" : " ",
GC_TEST_FLAGS(o, GC_FLAG_UNCOLLECTABLE) ? "U" : " ",
GC_TEST_FLAGS(o, GC_FLAG_MARKED) ? "M" : " ");
}
/* align the size */
o_size = GC_ALIGN(o_size, GC_ALIGN_SIZE);
+ /* the hashcode attached to this object might increase the size */
+ if (GC_TEST_FLAGS(o, HDRFLAG_HASH_ATTACHED))
+ o_size += SIZEOF_VOID_P;
+
return o_size;
}
/* TODO: maybe move this to global.h */
-#define GC_FLAG_FINALIZER 0x10
+#define GC_FLAG_FINALIZER 0x40
#define GC_FLAG_UNCOLLECTABLE HDRFLAG_UNCOLLECTABLE
#define GC_FLAG_MARKED (HDRFLAG_MARK1 | HDRFLAG_MARK2)
#if SIZEOF_VOID_P == 8
# define GC_GET_SIZE(obj) ((u4) (((obj)->hdrflags >> 56) & 0xff))
# define GC_SET_SIZE(obj, size) ((obj)->hdrflags |= ((u8) ((size) & 0xff)) << 56)
-# define GC_GET_HASH(obj) ((obj)->hdrflags)
#else
# define GC_GET_SIZE(obj) ((u4) (((obj)->hdrflags >> 24) & 0xff))
# define GC_SET_SIZE(obj, size) ((obj)->hdrflags |= ((u4) ((size) & 0xff)) << 24)
-# define GC_GET_HASH(obj) ((obj)->hdrflags)
-# define GC_SET_HASH(obj, hash) ((obj)->hdrflags |= ((hash) << 8) & 0x00ffff00)
#endif
Joseph Wenninger
Christian Thalinger
- $Id: global.h 7397 2007-02-23 23:11:41Z michi $
+ $Id: global.h 7400 2007-02-24 01:00:08Z michi $
*/
#define HDRFLAG_MARK1 0x02
#define HDRFLAG_MARK2 0x04
#define HDRFLAG_UNCOLLECTABLE 0x08
+#define HDRFLAG_HASH_TAKEN 0x10
+#define HDRFLAG_HASH_ATTACHED 0x20
struct java_objectheader { /* header for all objects */
struct _vftbl *vftbl; /* pointer to virtual function table */