[kaffe] 1.1.0 on mips-linux - new JIT memory problem?

Helmer Krämer hkraemer at freenet.de
Wed Jun 11 03:03:02 PDT 2003


On Wed, 11 Jun 2003 00:12:43 +0200
"Kevin D. Kissell" <kevink at 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 at 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
-------------- next part --------------
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.
  *


More information about the kaffe mailing list