[kaffe] CVS kaffe (guilhem): Added unlimited heap support.

Kaffe CVS cvs-commits at kaffe.org
Wed Jul 13 06:36:30 PDT 2005


PatchSet 6726 
Date: 2005/07/13 13:31:07
Author: guilhem
Branch: HEAD
Tag: (none) 
Log:
Added unlimited heap support.

        * TODO: Added some TODO entries.

        * kaffe/kaffe/main.c
        (parseArgs): -Xmx may detect unlimited now.

        * kaffe/kaffe/version.c
        (printVersion): Kaffe reports unlimited if the internal default
        value is UNLIMITED_HEAP.

        * kaffe/kaffevm/gc.h
        (UNLIMITED_HEAP): New key value.

        * kaffe/kaffevm/kaffe-gc/gc-incremental.c
        (gcMalloc): Use directly KGC_invoke and adviseGC.

        * kaffe/kaffevm/kaffe-gc/gc-incremental.h: Removed unsed default
        values.

        * kaffe/kaffevm/kaffe-gc/gc-mem.c
        (gc_num_blocks, gc_num_live_pages): Moved from gc_block_alloc.
        (gc_block_alloc): Do not use gc_heap_limit anymore for computing the
        needed memory blocks.
        (gc_heap_grow): Only limit the heap if gc_heap_limit !=
        UNLIMITED_HEAP.

Members: 
	ChangeLog:1.4250->1.4251 
	TODO:1.8->1.9 
	kaffe/kaffe/main.c:1.88->1.89 
	kaffe/kaffe/version.c:1.13->1.14 
	kaffe/kaffevm/gc.h:1.33->1.34 
	kaffe/kaffevm/kaffe-gc/gc-incremental.c:1.30->1.31 
	kaffe/kaffevm/kaffe-gc/gc-incremental.h:1.8->1.9 
	kaffe/kaffevm/kaffe-gc/gc-mem.c:1.29->1.30 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4250 kaffe/ChangeLog:1.4251
--- kaffe/ChangeLog:1.4250	Tue Jul 12 23:50:48 2005
+++ kaffe/ChangeLog	Wed Jul 13 13:31:07 2005
@@ -1,3 +1,30 @@
+2004-07-13  Guilhem Lavaux  <guilhem at kaffe.org>
+
+	* TODO: Added some TODO entries.
+
+	* kaffe/kaffe/main.c
+	(parseArgs): -Xmx may detect unlimited now.
+
+	* kaffe/kaffe/version.c
+	(printVersion): Kaffe reports unlimited if the internal default
+	value is UNLIMITED_HEAP.
+
+	* kaffe/kaffevm/gc.h
+	(UNLIMITED_HEAP): New key value.
+
+	* kaffe/kaffevm/kaffe-gc/gc-incremental.c
+	(gcMalloc): Use directly KGC_invoke and adviseGC.
+
+	* kaffe/kaffevm/kaffe-gc/gc-incremental.h: Removed unsed default
+	values.
+	
+	* kaffe/kaffevm/kaffe-gc/gc-mem.c
+	(gc_num_blocks, gc_num_live_pages): Moved from gc_block_alloc.
+	(gc_block_alloc): Do not use gc_heap_limit anymore for computing the
+	needed memory blocks.
+	(gc_heap_grow): Only limit the heap if gc_heap_limit !=
+	UNLIMITED_HEAP.
+
 2005-07-13  Dalibor Topic  <robilad at kaffe.org>
 
 	* test/jni/Makefile.am: (check_PROGRAMS) Added jniWeakTest.
Index: kaffe/TODO
diff -u kaffe/TODO:1.8 kaffe/TODO:1.9
--- kaffe/TODO:1.8	Thu Mar 31 23:36:50 2005
+++ kaffe/TODO	Wed Jul 13 13:31:07 2005
@@ -3,7 +3,11 @@
  * writer.close() flushing the internal buffer on encoder(already fixed)
  * Calendar.getInstance().get(YEAR) returning non-zero
 
+* Engine changes:
+ * JIT must support thread concurrency. Variable must be in thread local storage and not globally visible.
+
 * Architectural changes:
+ * Kaffe-GC must be capable of running without heap limit.
  * Make threading model runtime selectable.
  * Make runtime engine runtime selectable
  * Make gc backend runtime selectable
Index: kaffe/kaffe/kaffe/main.c
diff -u kaffe/kaffe/kaffe/main.c:1.88 kaffe/kaffe/kaffe/main.c:1.89
--- kaffe/kaffe/kaffe/main.c:1.88	Fri Jul  8 02:04:45 2005
+++ kaffe/kaffe/kaffe/main.c	Wed Jul 13 13:31:12 2005
@@ -687,9 +687,15 @@
 					fprintf(stderr,  _("Error: No heap size found for -mx option.\n"));
 					exit(1);
 				}
-				vmargs.maxHeapSize = parseSize(argv[i]);
+				if (strcmp(argv[i], "unlimited") == 0)
+					vmargs.maxHeapSize = UNLIMITED_HEAP;
+				else
+					vmargs.maxHeapSize = parseSize(argv[i]);
 			} else {
-				vmargs.maxHeapSize = parseSize(&argv[i][j]);
+				if (strcmp(&argv[i][j], "unlimited") == 0)
+					vmargs.maxHeapSize = UNLIMITED_HEAP;
+				else
+					vmargs.maxHeapSize = parseSize(&argv[i][j]);
 			}
 		}
 		else if ((strncmp(argv[i], "-ms", (j=3)) == 0)
Index: kaffe/kaffe/kaffe/version.c
diff -u kaffe/kaffe/kaffe/version.c:1.13 kaffe/kaffe/kaffe/version.c:1.14
--- kaffe/kaffe/kaffe/version.c:1.13	Wed May 18 20:36:22 2005
+++ kaffe/kaffe/kaffe/version.c	Wed Jul 13 13:31:12 2005
@@ -53,8 +53,13 @@
 
 	fprintf(versionfd, _("Engine: %s   Version: %s   Java Version: %s\n"),
 		engine_name, PACKAGE_VERSION, JAVA_VERSION_STRING);
-	fprintf(versionfd, _("Heap defaults: minimum size: %d MB, maximum size: %d MB\n"),
-		MIN_HEAPSIZE / (1024*1024), MAX_HEAPSIZE / (1024*1024));
+	if (MAX_HEAPSIZE == UNLIMITED_HEAP) {
+		fprintf(versionfd, _("Heap defaults: minimum size: %d MB, maximum size: unlimited\n"),
+			MIN_HEAPSIZE / (1024*1024)); 
+	} else {
+		fprintf(versionfd, _("Heap defaults: minimum size: %d MB, maximum size: %d MB\n"),
+			MIN_HEAPSIZE / (1024*1024), MAX_HEAPSIZE / (1024*1024));
+	}
 	fprintf(versionfd, _("Stack default size: %d KB\n"), THREADSTACKSIZE / 1024);
 }
 
Index: kaffe/kaffe/kaffevm/gc.h
diff -u kaffe/kaffe/kaffevm/gc.h:1.33 kaffe/kaffe/kaffevm/gc.h:1.34
--- kaffe/kaffe/kaffevm/gc.h:1.33	Tue Jul  5 17:20:40 2005
+++ kaffe/kaffe/kaffevm/gc.h	Wed Jul 13 13:31:13 2005
@@ -17,8 +17,9 @@
 /*
  * Default values for initial and maximum heap size and heap increment.
  */
+#define UNLIMITED_HEAP  (-1)
 #define	MIN_HEAPSIZE	(5*1024*1024)
-#define	MAX_HEAPSIZE	(64*1024*1024)
+#define	MAX_HEAPSIZE	(UNLIMITED_HEAP)
 #define	ALLOC_HEAPSIZE	(1024*1024)
 
 /* 
Index: kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.c
diff -u kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.c:1.30 kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.c:1.31
--- kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.c:1.30	Mon May 30 00:14:18 2005
+++ kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.c	Wed Jul 13 13:31:15 2005
@@ -1048,7 +1048,7 @@
 
 static
 void*
-gcMalloc(Collector* gcif UNUSED, size_t size, gc_alloc_type_t fidx)
+gcMalloc(Collector* gcif, size_t size, gc_alloc_type_t fidx)
 {
 	gc_block* info;
 	gc_unit* unit;
@@ -1077,7 +1077,7 @@
 				/* Try invoking GC if it is available */
 				if (garbageman != 0) {
 					unlockStaticMutex(&gc_lock);
-					adviseGC();
+					KGC_invoke(gcif, 0);
 					lockStaticMutex(&gc_lock);
 				}
 				break;
Index: kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.h
diff -u kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.h:1.8 kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.h:1.9
--- kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.h:1.8	Sun Mar 13 12:57:24 2005
+++ kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.h	Wed Jul 13 13:31:15 2005
@@ -13,14 +13,6 @@
 #ifndef __gc_incremental_h
 #define __gc_incremental_h
 
-/*
- * Default values for initial and maximum heap size and heap increment.
- */
-#define	MIN_HEAPSIZE	(5*1024*1024)
-#define	MAX_HEAPSIZE	(64*1024*1024)
-#define	ALLOC_HEAPSIZE	(1024*1024)
-
-
 /* ------------------------------------------------------------------------ */
 
 /*
Index: kaffe/kaffe/kaffevm/kaffe-gc/gc-mem.c
diff -u kaffe/kaffe/kaffevm/kaffe-gc/gc-mem.c:1.29 kaffe/kaffe/kaffevm/kaffe-gc/gc-mem.c:1.30
--- kaffe/kaffe/kaffevm/kaffe-gc/gc-mem.c:1.29	Sat May  7 08:06:29 2005
+++ kaffe/kaffe/kaffevm/kaffe-gc/gc-mem.c	Wed Jul 13 13:31:15 2005
@@ -127,6 +127,8 @@
 #define	ROUNDUPPAGESIZE(V)	(((uintp)(V) + gc_pgsize - 1) & -gc_pgsize)
 
 static char * gc_block_base = NULL;
+static size_t gc_num_blocks = 0;
+static size_t gc_num_live_pages = 0;
 
 #define KGC_BLOCKS		((gc_block *) gc_block_base)
 
@@ -255,7 +257,7 @@
 	/*
 	 * Perform some sanity checks.
 	 */
-	if (gc_heap_initial_size > gc_heap_limit) {
+	if (gc_heap_initial_size > gc_heap_limit && gc_heap_limit != UNLIMITED_HEAP) {
 		dprintf(
 		    "Initial heap size (%dK) > Maximum heap size (%dK)\n",
 		    (int) (gc_heap_initial_size/1024), (int)(gc_heap_limit/1024));
@@ -1085,17 +1087,15 @@
 gc_block_alloc(size_t size)
 {
 	int size_pg = (size>>gc_pgbits);
-	static int n_live = 0;	/* number of pages in java heap */
-	static int nblocks;	/* number of gc_blocks in array */
 	uintp heap_addr;
 	static uintp last_addr;
 
 	if (!gc_block_base) {
-		nblocks = (gc_heap_limit+gc_pgsize-1)>>gc_pgbits;
+		gc_num_blocks = (size+gc_pgsize-1)>>gc_pgbits;
 
-		gc_block_base = malloc(nblocks * sizeof(gc_block));
+		gc_block_base = malloc(gc_num_blocks * sizeof(gc_block));
 		if (!gc_block_base) return NULL;
-		memset(gc_block_base, 0, nblocks * sizeof(gc_block));
+		memset(gc_block_base, 0, gc_num_blocks * sizeof(gc_block));
 	}
 
 	DBG(GCSYSALLOC, dprintf("pagealloc(%ld)", (long) size));
@@ -1109,10 +1109,10 @@
 	}
 
 	if (gc_mem2block((void *) (heap_addr + size))
-	    > ((gc_block *)gc_block_base) + nblocks
+	    > ((gc_block *)gc_block_base) + gc_num_blocks
 	    || heap_addr < gc_heap_base) {
 		char * old_blocks = gc_block_base;
-		int onb = nblocks;
+		int onb = gc_num_blocks;
 		int min_nb;	/* minimum size of array to hold heap_addr */
 #if defined(KAFFE_STATS)
 		static timespent growtime;
@@ -1127,29 +1127,41 @@
 		   currently fit in the gc_block array.  But, we must
 		   also make sure to allocate enough blocks to cover
 		   the current allocation */
-		nblocks = (nblocks * (gc_heap_limit >> gc_pgbits))
-			/ n_live;
+		gc_num_blocks = (gc_num_blocks * ((gc_heap_total + size) >> gc_pgbits))
+			/ gc_num_live_pages;
 		if (heap_addr < gc_heap_base) 
-			min_nb = nblocks
+			min_nb = gc_num_blocks
 			  + ((gc_heap_base - heap_addr) >> gc_pgbits);
 		else
 			min_nb = ((heap_addr + size) - gc_heap_base) >>
 			  gc_pgbits;
-		nblocks = MAX(nblocks, min_nb);
+		gc_num_blocks = MAX(gc_num_blocks, min_nb);
 		DBG(GCSYSALLOC,
 		    dprintf("growing block array from %d to %d elements\n",
-			    onb, nblocks));
+			    onb, gc_num_blocks));
 
 		KTHREAD(spinon)(NULL);
 		gc_block_base = realloc(old_blocks,
-						nblocks * sizeof(gc_block));
+					gc_num_blocks * sizeof(gc_block));
 		if (!gc_block_base) {
-			/* roll back this call */
-			pagefree(heap_addr, size);
-			gc_block_base = old_blocks;
-			nblocks = onb;
-			KTHREAD(spinoff)(NULL);
-			return NULL;
+			/* In some implementations, realloc is not smart enough to acquire new block
+			 * in a non-contiguous region. Even if internally it calls some malloc procedure
+			 * it fails evenly. A countermeasure is to use slow real malloc if realloc fails
+			 * and only if that call also fails we put throw a OOM.
+			 */
+			DBG(GCSYSALLOC, dprintf("realloc has failed. Trying malloc.\n"));
+			gc_block_base = malloc(gc_num_blocks * sizeof(gc_block));
+			if (!gc_block_base) {
+				/* roll back this call */
+				DBG(GCSYSALLOC, dprintf("failed to grow the block list\n"));
+				pagefree(heap_addr, size);
+				gc_block_base = old_blocks;
+				gc_num_blocks = onb;
+				KTHREAD(spinoff)(NULL);
+				return NULL;
+			}
+			memcpy(gc_block_base, old_blocks, onb * sizeof(gc_block));
+			free(old_blocks);
 		}
 
 		DBG(GCSYSALLOC, dprintf("old block_base = %p, new block_base = %p\n", old_blocks, gc_block_base));
@@ -1177,7 +1189,7 @@
 			  }
 
 			memset(b + onb, 0,
-			       (nblocks - onb) * sizeof(gc_block));
+			       (gc_num_blocks - onb) * sizeof(gc_block));
 
 			for (i = 0; i<=KGC_PRIM_LIST_COUNT; i++)
 				R(gc_block, gc_prim_freelist[i]);
@@ -1191,7 +1203,7 @@
 		KTHREAD(spinoff)(NULL);
 		stopTiming(&growtime);
 	}
-	n_live += size_pg;
+	gc_num_live_pages += size_pg;
 	last_addr = MAX(last_addr, heap_addr + size);
 	gc_heap_range = last_addr - gc_heap_base;
 	DBG(GCSYSALLOC, dprintf("%ld unused bytes in heap addr range\n",
@@ -1231,7 +1243,7 @@
 	if (gc_heap_total == gc_heap_limit) {
 		unlockStaticMutex(&gc_heap_lock);
 		return (NULL);
-	} else if (gc_heap_total + sz > gc_heap_limit) {
+	} else if (gc_heap_total + sz > gc_heap_limit && gc_heap_limit != UNLIMITED_HEAP) {
 		/* take as much memory as we can */
 		sz = gc_heap_limit - gc_heap_total;
 		assert(sz % gc_pgsize == 0);
@@ -1252,7 +1264,7 @@
 	}
 
 	gc_heap_total += sz;
-	assert(gc_heap_total <= gc_heap_limit);
+	assert(gc_heap_total <= gc_heap_limit || gc_heap_limit == UNLIMITED_HEAP);
 
 	/* Place block into the freelist for subsequent use */
 	DBG(GCDIAG, gc_set_magic_marker(blk));



More information about the kaffe mailing list