Commit 09ea3b51 authored by Sébastien Paolacci's avatar Sébastien Paolacci Committed by Russ Cox

runtime: earlier detection of unused spans.

Mark candidate spans one GC pass earlier.

Move scavenger's code out from mgc0 and constrain it into mheap (where it belongs).

R=rsc, dvyukov, minux.ma
CC=golang-dev
https://golang.org/cl/7002049
parent a8e0a757
...@@ -1159,10 +1159,6 @@ sweepspan(ParFor *desc, uint32 idx) ...@@ -1159,10 +1159,6 @@ sweepspan(ParFor *desc, uint32 idx)
USED(&desc); USED(&desc);
s = runtime·mheap.allspans[idx]; s = runtime·mheap.allspans[idx];
// Stamp newly unused spans. The scavenger will use that
// info to potentially give back some pages to the OS.
if(s->state == MSpanFree && s->unusedsince == 0)
s->unusedsince = runtime·nanotime();
if(s->state != MSpanInUse) if(s->state != MSpanInUse)
return; return;
arena_start = runtime·mheap.arena_start; arena_start = runtime·mheap.arena_start;
......
...@@ -138,7 +138,9 @@ HaveSpan: ...@@ -138,7 +138,9 @@ HaveSpan:
*(uintptr*)(t->start<<PageShift) = *(uintptr*)(s->start<<PageShift); // copy "needs zeroing" mark *(uintptr*)(t->start<<PageShift) = *(uintptr*)(s->start<<PageShift); // copy "needs zeroing" mark
t->state = MSpanInUse; t->state = MSpanInUse;
MHeap_FreeLocked(h, t); MHeap_FreeLocked(h, t);
t->unusedsince = s->unusedsince; // preserve age
} }
s->unusedsince = 0;
// Record span info, because gc needs to be // Record span info, because gc needs to be
// able to map interior pointer to containing span. // able to map interior pointer to containing span.
...@@ -300,10 +302,12 @@ MHeap_FreeLocked(MHeap *h, MSpan *s) ...@@ -300,10 +302,12 @@ MHeap_FreeLocked(MHeap *h, MSpan *s)
} }
mstats.heap_idle += s->npages<<PageShift; mstats.heap_idle += s->npages<<PageShift;
s->state = MSpanFree; s->state = MSpanFree;
s->unusedsince = 0;
s->npreleased = 0;
runtime·MSpanList_Remove(s); runtime·MSpanList_Remove(s);
sp = (uintptr*)(s->start<<PageShift); sp = (uintptr*)(s->start<<PageShift);
// Stamp newly unused spans. The scavenger will use that
// info to potentially give back some pages to the OS.
s->unusedsince = runtime·nanotime();
s->npreleased = 0;
// Coalesce with earlier, later spans. // Coalesce with earlier, later spans.
p = s->start; p = s->start;
...@@ -401,10 +405,10 @@ runtime·MHeap_Scavenger(void) ...@@ -401,10 +405,10 @@ runtime·MHeap_Scavenger(void)
runtime·entersyscall(); runtime·entersyscall();
runtime·notesleep(&note); runtime·notesleep(&note);
runtime·exitsyscall(); runtime·exitsyscall();
if(trace)
runtime·printf("scvg%d: GC forced\n", k);
runtime·lock(h); runtime·lock(h);
now = runtime·nanotime(); now = runtime·nanotime();
if (trace)
runtime·printf("scvg%d: GC forced\n", k);
} }
sumreleased = 0; sumreleased = 0;
for(i=0; i < nelem(h->free)+1; i++) { for(i=0; i < nelem(h->free)+1; i++) {
...@@ -415,7 +419,7 @@ runtime·MHeap_Scavenger(void) ...@@ -415,7 +419,7 @@ runtime·MHeap_Scavenger(void)
if(runtime·MSpanList_IsEmpty(list)) if(runtime·MSpanList_IsEmpty(list))
continue; continue;
for(s=list->next; s != list; s=s->next) { for(s=list->next; s != list; s=s->next) {
if(s->unusedsince != 0 && (now - s->unusedsince) > limit) { if((now - s->unusedsince) > limit) {
released = (s->npages - s->npreleased) << PageShift; released = (s->npages - s->npreleased) << PageShift;
mstats.heap_released += released; mstats.heap_released += released;
sumreleased += released; sumreleased += released;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment