diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc index a593da486cf140660dbe224e63d21c87334fc719..76945a28d4d794746405c6417cbd926f934b72c3 100644 --- a/src/pkg/runtime/malloc.goc +++ b/src/pkg/runtime/malloc.goc @@ -19,6 +19,7 @@ package runtime // Mark mheap as 'no pointers', it does not contain interesting pointers but occupies ~45K. #pragma dataflag NOPTR MHeap runtime·mheap; +MStats mstats; int32 runtime·checking; @@ -417,7 +418,10 @@ runtime·purgecachedstats(MCache *c) } } -uintptr runtime·sizeof_C_MStats = sizeof(MStats); +// Size of the trailing by_size array differs between Go and C, +// NumSizeClasses was changed, but we can not change Go struct because of backward compatibility. +// sizeof_C_MStats is what C thinks about size of Go struct. +uintptr runtime·sizeof_C_MStats = sizeof(MStats) - (NumSizeClasses - 61) * sizeof(mstats.by_size[0]); #define MaxArena32 (2U<<30) diff --git a/src/pkg/runtime/malloc.h b/src/pkg/runtime/malloc.h index 52a23e391cf473cd823d15a758d27fb7789a4495..fc6c85e2c13314b562e9ac7903586f3611c0d202 100644 --- a/src/pkg/runtime/malloc.h +++ b/src/pkg/runtime/malloc.h @@ -90,7 +90,7 @@ typedef struct GCStats GCStats; enum { - PageShift = 12, + PageShift = 13, PageSize = 1<<PageShift, PageMask = PageSize - 1, }; @@ -103,7 +103,7 @@ enum // size classes. NumSizeClasses is that number. It's needed here // because there are static arrays of this length; when msize runs its // size choosing algorithm it double-checks that NumSizeClasses agrees. - NumSizeClasses = 61, + NumSizeClasses = 67, // Tunable constants. MaxSmallSize = 32<<10, @@ -259,7 +259,7 @@ struct MStats } by_size[NumSizeClasses]; }; -#define mstats runtime·memStats /* name shared with Go */ +#define mstats runtime·memStats extern MStats mstats; // Size classes. Computed and initialized by InitSizes. diff --git a/src/pkg/runtime/mem.go b/src/pkg/runtime/mem.go index dc735e4a629ad5c5badd0b88672e79e37d18942c..fa308b5d963916825b75659f8e4364a26814c9de 100644 --- a/src/pkg/runtime/mem.go +++ b/src/pkg/runtime/mem.go @@ -60,9 +60,8 @@ type MemStats struct { var sizeof_C_MStats uintptr // filled in by malloc.goc -var memStats MemStats - func init() { + var memStats MemStats if sizeof_C_MStats != unsafe.Sizeof(memStats) { println(sizeof_C_MStats, unsafe.Sizeof(memStats)) panic("MStats vs MemStatsType size mismatch") diff --git a/src/pkg/runtime/mgc0.c b/src/pkg/runtime/mgc0.c index e21ad286dae7d94e012adb016f54e3642a01f826..dc2a8a99bbd652624591132a845bc1f7d6a6bd8f 100644 --- a/src/pkg/runtime/mgc0.c +++ b/src/pkg/runtime/mgc0.c @@ -25,6 +25,10 @@ enum { wordsPerBitmapWord = sizeof(void*)*8/4, bitShift = sizeof(void*)*8/4, + WorkbufSize = 16*1024, + RootBlockSize = 4*1024, + FinBlockSize = 4*1024, + handoffThreshold = 4, IntermediateBufferCapacity = 64, @@ -154,11 +158,10 @@ struct Obj uintptr ti; // type info }; -// The size of Workbuf is N*PageSize. typedef struct Workbuf Workbuf; struct Workbuf { -#define SIZE (2*PageSize-sizeof(LFNode)-sizeof(uintptr)) +#define SIZE (WorkbufSize-sizeof(LFNode)-sizeof(uintptr)) LFNode node; // must be first uintptr nobj; Obj obj[SIZE/sizeof(Obj) - 1]; @@ -737,7 +740,7 @@ scanblock(Workbuf *wbuf, bool keepworking) ChanType *chantype; Obj *wp; - if(sizeof(Workbuf) % PageSize != 0) + if(sizeof(Workbuf) % WorkbufSize != 0) runtime·throw("scanblock: size of Workbuf is suboptimal"); // Memory arena parameters. @@ -1601,8 +1604,8 @@ runtime·queuefinalizer(byte *p, FuncVal *fn, uintptr nret, Type *fint, PtrType runtime·lock(&finlock); if(finq == nil || finq->cnt == finq->cap) { if(finc == nil) { - finc = runtime·persistentalloc(PageSize, 0, &mstats.gc_sys); - finc->cap = (PageSize - sizeof(FinBlock)) / sizeof(Finalizer) + 1; + finc = runtime·persistentalloc(FinBlockSize, 0, &mstats.gc_sys); + finc->cap = (FinBlockSize - sizeof(FinBlock)) / sizeof(Finalizer) + 1; finc->alllink = allfin; allfin = finc; } @@ -2233,6 +2236,8 @@ gc(struct gc_args *args) runtime·MProf_GC(); } +extern uintptr runtime·sizeof_C_MStats; + void runtime·ReadMemStats(MStats *stats) { @@ -2244,7 +2249,9 @@ runtime·ReadMemStats(MStats *stats) m->gcing = 1; runtime·stoptheworld(); updatememstats(nil); - *stats = mstats; + // Size of the trailing by_size array differs between Go and C, + // NumSizeClasses was changed, but we can not change Go struct because of backward compatibility. + runtime·memcopy(runtime·sizeof_C_MStats, stats, &mstats); m->gcing = 0; m->locks++; runtime·semrelease(&runtime·worldsema); diff --git a/src/pkg/runtime/netpoll.goc b/src/pkg/runtime/netpoll.goc index 2830f882d806123a431813444ef213bf4ee3b45a..81471dca5bb55f07c372701095490772c4908edd 100644 --- a/src/pkg/runtime/netpoll.goc +++ b/src/pkg/runtime/netpoll.goc @@ -34,6 +34,11 @@ package net #define READY ((G*)1) #define WAIT ((G*)2) +enum +{ + PollBlockSize = 4*1024, +}; + struct PollDesc { PollDesc* link; // in pollcache, protected by pollcache.Lock @@ -422,7 +427,7 @@ allocPollDesc(void) runtime·lock(&pollcache); if(pollcache.first == nil) { - n = PageSize/sizeof(*pd); + n = PollBlockSize/sizeof(*pd); if(n == 0) n = 1; // Must be in non-GC memory because can be referenced