[kaffe] 1.1.0 on mips-linux - new JIT memory problem?
Helmer Krämer
hkraemer@freenet.de
Wed Jun 11 03:03:02 2003
This is a multi-part message in MIME format.
--Multipart_Wed__11_Jun_2003_12:06:04_+0200_0978ae60
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
On Wed, 11 Jun 2003 00:12:43 +0200
"Kevin D. Kissell" <kevink@mips.com> wrote:
> > could you do a
> >
> > kaffe -verbosegc -verbosemem at.dms.kjc.Main HelloWorldApp.java
> >
> > and put the memory stats up somewhere? It'd be interesting to see where the
> > leaks are coming from.
>
> Alas, all one gets is (after a long pause):
>
> [kevink@agena regression]$ kaffe -verbosegc -verbosemem at dms.kjc.Main HelloWorldApp.java
> Internal error: caught an unexpected exception.
> Please check your CLASSPATH and your installation.
> java/lang/OutOfMemoryError
> at java.util.HashMap.rehash(HashMap.java:236)
> at java.util.HashMap.put(HashMap.java:136)
> at java.util.Hashtable.put(Hashtable.java:109)
> at java.lang.System.initProperties(System.java:native)
> at java.lang.System.<clinit>(System.java:43)
> at java.lang.ClassLoader.<init>(ClassLoader.java:114)
> at java.security.SecureClassLoader.<init>(SecureClassLoader.java:20)
> at kaffe.lang.AppClassLoader.<init>(AppClassLoader.java:238)
> at kaffe.lang.AppClassLoader.<clinit>(AppClassLoader.java:37)
> Aborted (core dumped)
>
> and a 48MB core file.
Sounds like fun, doesn't it :o) ?
What happens if you run kaffe with -vmdebug GCDIAG,GCFREE,GCSYSALLOC
(should produce loads of output)? If you try it again with the attached
patch applied, does that make matters a lot worse?
Greetings,
Helmer
--Multipart_Wed__11_Jun_2003_12:06:04_+0200_0978ae60
Content-Type: text/plain;
name="gc-patch.diff"
Content-Disposition: attachment;
filename="gc-patch.diff"
Content-Transfer-Encoding: 7bit
Index: kaffe/kaffevm/mem/gc-incremental.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/mem/gc-incremental.c,v
retrieving revision 1.62
diff -u -r1.62 gc-incremental.c
--- kaffe/kaffevm/mem/gc-incremental.c 11 Mar 2003 08:00:18 -0000 1.62
+++ kaffe/kaffevm/mem/gc-incremental.c 11 Jun 2003 09:56:37 -0000
@@ -860,19 +860,51 @@
int i;
size_t bsz;
int iLockRoot;
+ int times = 0;
assert(gc_init != 0);
assert(fidx < nrTypes && size != 0);
- unit = gc_heap_malloc(size + sizeof(gc_unit));
+ lockStaticMutex(&gc_lock);
- /* keep pointer to object */
- mem = UTOMEM(unit);
- if (unit == 0) {
- return 0;
- }
+ for (unit=0; unit==0;) {
+ times++;
+ unit = gc_heap_malloc(size + sizeof(gc_unit));
+
+ /* keep pointer to object */
+ mem = UTOMEM(unit);
+ if (unit == 0) {
+ switch (times) {
+ case 1:
+ /* Try invoking GC if it is available */
+ if (garbageman != 0) {
+ unlockStaticMutex(&gc_lock);
+ adviseGC();
+ lockStaticMutex(&gc_lock);
+ }
+ break;
- lockStaticMutex(&gc_lock);
+ case 2:
+ /* Grow the heap */
+ gc_heap_grow(size);
+ break;
+
+ default:
+ if (DBGEXPR(CATCHOUTOFMEM, true, false)) {
+ /*
+ * If we ran out of memory, a OutOfMemoryException is
+ * thrown. If we fail to allocate memory for it, all
+ * is lost.
+ */
+ static int ranout;
+ assert (ranout++ == 0 || !!!"Ran out of memory!");
+ }
+ /* Guess we've really run out */
+ unlockStaticMutex(&gc_lock);
+ return (0);
+ }
+ }
+ }
info = GCMEM2BLOCK(mem);
i = GCMEM2IDX(info, unit);
Index: kaffe/kaffevm/mem/gc-mem.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/mem/gc-mem.c,v
retrieving revision 1.43
diff -u -r1.43 gc-mem.c
--- kaffe/kaffevm/mem/gc-mem.c 2 Jun 2003 14:15:47 -0000 1.43
+++ kaffe/kaffevm/mem/gc-mem.c 11 Jun 2003 09:56:37 -0000
@@ -280,11 +280,10 @@
gc_heap_initial_size = ROUNDUPPAGESIZE(gc_heap_initial_size);
/* allocate heap of initial size from system */
- gc_system_alloc(gc_heap_initial_size);
+ gc_heap_grow(gc_heap_initial_size);
}
-/*
- * gc_heap_malloc
+/**
* Allocate a piece of memory.
*/
void*
@@ -292,11 +291,10 @@
{
static int gc_heap_init = 0;
size_t lnr;
- gc_freeobj* mem;
+ gc_freeobj* mem = 0;
gc_block** mptr;
gc_block* blk;
size_t nsz;
- int times;
int iLockRoot;
/* Initialise GC heap first time in - we must assume single threaded
@@ -309,8 +307,6 @@
lockStaticMutex(&gc_heap_lock);
- times = 0;
-
DBG(SLACKANAL,
if (GC_SMALL_OBJECT(sz)) {
totalslack += (freelist[sztable[sz].list].sz - sz);
@@ -318,9 +314,6 @@
}
)
- rerun:;
- times++;
-
DBG(GCDIAG,
gc_heap_check();
)
@@ -342,8 +335,7 @@
else {
blk = gc_small_block(nsz);
if (blk == 0) {
- nsz = gc_pgsize;
- goto nospace;
+ goto out;
}
blk->next = *mptr;
*mptr = blk;
@@ -378,9 +370,7 @@
nsz = sz;
blk = gc_large_block(nsz);
if (blk == 0) {
- nsz = nsz + GCBLOCK_OVH + sizeof(gcFuncs*) + ROUNDUPALIGN(1);
- nsz = ROUNDUPPAGESIZE(nsz);
- goto nospace;
+ goto out;
}
mem = GCBLOCK2FREE(blk, 0);
GC_SET_STATE(blk, 0, GC_STATE_NORMAL);
@@ -395,60 +385,13 @@
assert(GC_OBJECT_SIZE(mem) >= sz);
+ out:
unlockStaticMutex(&gc_heap_lock);
return (mem);
-
- /* --------------------------------------------------------------- */
- nospace:;
-
- /* Failed to find space in any freelists. Must try to get the
- * memory from somewhere.
- */
-
- switch (times) {
- case 1:
- /* Try invoking GC if it is available */
- if (garbageman != 0) {
- /* The other caller of invokeGC, Runtime.gc() can't
- * give up this lock on its own, since it does not
- * hold this lock.
- */
- unlockStaticMutex(&gc_heap_lock);
- adviseGC();
- lockStaticMutex(&gc_heap_lock);
- }
- break;
-
- case 2:
- /* Get from the system */
- if (nsz < gc_heap_allocation_size) {
- nsz = gc_heap_allocation_size;
- }
- gc_system_alloc(nsz);
- break;
-
- default:
- if (DBGEXPR(CATCHOUTOFMEM, true, false))
- {
- /*
- * If we ran out of memory, a OutOfMemoryException is
- * thrown. If we fail to allocate memory for it, all
- * is lost.
- */
- static int ranout;
- assert (ranout++ == 0 || !!!"Ran out of memory!");
- }
- /* Guess we've really run out */
- unlockStaticMutex(&gc_heap_lock);
- return (0);
- }
-
- /* Try again */
- goto rerun;
}
-/*
+/**
* Free a piece of memory.
*/
void
@@ -1005,17 +948,33 @@
return GCMEM2BLOCK(heap_addr);
}
-static
-void*
-gc_system_alloc(size_t sz)
+/**
+ * Grows the heap.
+ *
+ * @param sz minimum number of bytes to grow.
+ * @return 0 in case of an error, otherwise != 0
+ */
+void *
+gc_heap_grow(size_t sz)
{
gc_block* blk;
+ if (GC_SMALL_OBJECT(sz)) {
+ sz = gc_pgsize;
+ } else {
+ sz = sz + GCBLOCK_OVH + sizeof(gcFuncs*) + ROUNDUPALIGN(1);
+ sz = ROUNDUPPAGESIZE(sz);
+ }
+
+ if (sz < gc_heap_allocation_size) {
+ sz = gc_heap_allocation_size;
+ }
+
assert(sz % gc_pgsize == 0);
if (gc_heap_total == gc_heap_limit) {
return (0);
- } else if (gc_heap_total + sz > gc_heap_limit) {
+ } else if (gc_heap_total + sz > gc_heap_limit) {
/* take as much memory as we can */
sz = gc_heap_limit - gc_heap_total;
assert(sz % gc_pgsize == 0);
@@ -1026,13 +985,14 @@
#endif
blk = gc_block_alloc(sz);
-
-DBG(GCSYSALLOC,
- dprintf("gc_system_alloc: %ld byte at %p\n", (long) sz, blk); )
+
+ DBG(GCSYSALLOC,
+ dprintf("gc_system_alloc: %ld byte at %p\n", (long) sz, blk); )
if (blk == 0) {
return (0);
}
+
gc_heap_total += sz;
assert(gc_heap_total <= gc_heap_limit);
Index: kaffe/kaffevm/mem/gc-mem.h
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/mem/gc-mem.h,v
retrieving revision 1.15
diff -u -r1.15 gc-mem.h
--- kaffe/kaffevm/mem/gc-mem.h 2 Jun 2003 14:15:47 -0000 1.15
+++ kaffe/kaffevm/mem/gc-mem.h 11 Jun 2003 09:56:38 -0000
@@ -69,6 +69,8 @@
extern void* gc_heap_malloc(size_t);
extern void gc_heap_free(void*);
+extern void* gc_heap_grow(size_t);
+
/**
* Evaluates to the size of the object that contains address @M.
*
--Multipart_Wed__11_Jun_2003_12:06:04_+0200_0978ae60--