Patchwork libgo patch committed: Ignore stacks when deciding when to GC

login
register
mail settings
Submitter Ian Taylor
Date April 20, 2012, 4:58 a.m.
Message ID <mcrobqnatj0.fsf@dhcp-172-18-216-180.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/153929/
State New
Headers show

Comments

Ian Taylor - April 20, 2012, 4:58 a.m.
This patch to libgo ignores space allocated for goroutine stacks when
deciding when to next run the garbage collector.  On systems that
support split stacks this does nothing, as on those systems the stacks
are allocated by the split stack code.  On systems that do not support
split stacks this doesn't let the large amount of memory allocated for
stacks cause the system to delay GC unreasonably.

This patch also does a couple of other minor things.  The heap bitmap
bits are allocated in page size units.  This fixes a problem on PPC
GNU/Linux which uses a larger page size than x86.

Also this clears the ucontext_t field in the G structure when it is put
on the free list.  This prevents the GC from thinking that old register
values, now meaningless, are valid pointers requiring data to be kept in
memory.

Bootstrapped on x86_64-unknown-linux-gnu and
powerpc64-unknown-linux-gnu.  Committed to mainline and 4.7 branch.

Ian

Patch

diff -r c8d973732b42 libgo/runtime/malloc.goc
--- a/libgo/runtime/malloc.goc	Thu Apr 19 21:46:43 2012 -0700
+++ b/libgo/runtime/malloc.goc	Thu Apr 19 21:50:27 2012 -0700
@@ -72,7 +72,7 @@ 
 		npages = size >> PageShift;
 		if((size & PageMask) != 0)
 			npages++;
-		s = runtime_MHeap_Alloc(&runtime_mheap, npages, 0, !(flag & FlagNoGC));
+		s = runtime_MHeap_Alloc(&runtime_mheap, npages, 0, 1);
 		if(s == nil)
 			runtime_throw("out of memory");
 		size = npages<<PageShift;
diff -r c8d973732b42 libgo/runtime/mgc0.c
--- a/libgo/runtime/mgc0.c	Thu Apr 19 21:46:43 2012 -0700
+++ b/libgo/runtime/mgc0.c	Thu Apr 19 21:50:27 2012 -0700
@@ -4,6 +4,8 @@ 
 
 // Garbage collector.
 
+#include <unistd.h>
+
 #include "runtime.h"
 #include "arch.h"
 #include "malloc.h"
@@ -918,7 +920,7 @@ 
 	uint64 stacks_sys;
 
 	stacks_inuse = 0;
-	stacks_sys = 0;
+	stacks_sys = runtime_stacks_sys;
 	for(m=runtime_allm; m; m=m->alllink) {
 		runtime_purgecachedstats(m);
 		// stacks_inuse += m->stackalloc->inuse;
@@ -1020,7 +1022,7 @@ 
 	stealcache();
 	cachestats();
 
-	mstats.next_gc = mstats.heap_alloc+mstats.heap_alloc*gcpercent/100;
+	mstats.next_gc = mstats.heap_alloc+(mstats.heap_alloc-runtime_stacks_sys)*gcpercent/100;
 	m->gcing = 0;
 
 	m->locks++;	// disable gc during the mallocs in newproc
@@ -1329,6 +1331,8 @@ 
 void
 runtime_MHeap_MapBits(MHeap *h)
 {
+	size_t page_size;
+
 	// Caller has added extra mappings to the arena.
 	// Add extra mappings of bitmap words as needed.
 	// We allocate extra bitmap pieces in chunks of bitmapChunk.
@@ -1342,6 +1346,9 @@ 
 	if(h->bitmap_mapped >= n)
 		return;
 
+	page_size = getpagesize();
+	n = (n+page_size-1) & ~(page_size-1);
+
 	runtime_SysMap(h->arena_start - n, n - h->bitmap_mapped);
 	h->bitmap_mapped = n;
 }
diff -r c8d973732b42 libgo/runtime/proc.c
--- a/libgo/runtime/proc.c	Thu Apr 19 21:46:43 2012 -0700
+++ b/libgo/runtime/proc.c	Thu Apr 19 21:50:27 2012 -0700
@@ -46,6 +46,8 @@ 
 # define StackMin 2 * 1024 * 1024
 #endif
 
+uintptr runtime_stacks_sys;
+
 static void schedule(G*);
 
 typedef struct Sched Sched;
@@ -1091,6 +1093,7 @@ 
 				m->lockedg = nil;
 			}
 			gp->idlem = nil;
+			runtime_memclr(&gp->context, sizeof gp->context);
 			gfput(gp);
 			if(--runtime_sched.gcount == 0)
 				runtime_exit(0);
@@ -1288,6 +1291,7 @@ 
 		*ret_stacksize = stacksize;
 		newg->gcinitial_sp = *ret_stack;
 		newg->gcstack_size = stacksize;
+		runtime_xadd(&runtime_stacks_sys, stacksize);
 #endif
 	}
 	return newg;
diff -r c8d973732b42 libgo/runtime/runtime.h
--- a/libgo/runtime/runtime.h	Thu Apr 19 21:46:43 2012 -0700
+++ b/libgo/runtime/runtime.h	Thu Apr 19 21:50:27 2012 -0700
@@ -463,3 +463,8 @@ 
 };
 
 void	__go_register_gc_roots(struct root_list*);
+
+// Size of stack space allocated using Go's allocator.
+// This will be 0 when using split stacks, as in that case
+// the stacks are allocated by the splitstack library.
+extern uintptr runtime_stacks_sys;