From 020b39c3f3d3826d02c735c29d1dae7282aeb3f7 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Tue, 7 Jan 2014 13:45:50 -0800 Subject: runtime: use special records hung off the MSpan to record finalizers and heap profile info. Enables removing the special bit from the heap bitmap. Also provides a generic mechanism for annotating occasional heap objects. finalizers overhead per obj old 680 B 80 B avg new 16 B/span 48 B profile overhead per obj old 32KB 24 B + hash tables new 16 B/span 24 B R=cshapiro, khr, dvyukov, gobot CC=golang-codereviews https://golang.org/cl/13314053 --- src/pkg/runtime/malloc.goc | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'src/pkg/runtime/malloc.goc') diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc index eb044384b5..81cda75dfd 100644 --- a/src/pkg/runtime/malloc.goc +++ b/src/pkg/runtime/malloc.goc @@ -139,7 +139,6 @@ runtime·mallocgc(uintptr size, uintptr typ, uint32 flag) rate = 0x3fffffff; m->mcache->next_sample = runtime·fastrand1() % (2*rate); profile: - runtime·setblockspecial(v, true); runtime·MProf_Malloc(v, size, typ); } } @@ -165,7 +164,6 @@ runtime·free(void *v) int32 sizeclass; MSpan *s; MCache *c; - uint32 prof; uintptr size; if(v == nil) @@ -182,7 +180,6 @@ runtime·free(void *v) runtime·printf("free %p: not an allocated block\n", v); runtime·throw("free runtime·mlookup"); } - prof = runtime·blockspecial(v); if(raceenabled) runtime·racefree(v); @@ -216,8 +213,8 @@ runtime·free(void *v) c->local_nsmallfree[sizeclass]++; runtime·MCache_Free(c, v, sizeclass, size); } - if(prof) - runtime·MProf_Free(v, size); + if(s->specials != nil) + runtime·freeallspecials(s, v, size); m->mallocing = 0; } @@ -770,8 +767,6 @@ func SetFinalizer(obj Eface, finalizer Eface) { runtime·printf("runtime.SetFinalizer: pointer not at beginning of allocated block\n"); goto throw; } - nret = 0; - fint = nil; if(finalizer.type != nil) { if(finalizer.type->kind != KindFunc) goto badfunc; @@ -792,16 +787,20 @@ func SetFinalizer(obj Eface, finalizer Eface) { goto badfunc; // compute size needed for return parameters + nret = 0; for(i=0; iout.len; i++) { t = ((Type**)ft->out.array)[i]; nret = ROUND(nret, t->align) + t->size; } nret = ROUND(nret, sizeof(void*)); - } - - if(!runtime·addfinalizer(obj.data, finalizer.data, nret, fint, ot)) { - runtime·printf("runtime.SetFinalizer: finalizer already set\n"); - goto throw; + ot = (PtrType*)obj.type; + if(!runtime·addfinalizer(obj.data, finalizer.data, nret, fint, ot)) { + runtime·printf("runtime.SetFinalizer: finalizer already set\n"); + goto throw; + } + } else { + // NOTE: asking to remove a finalizer when there currently isn't one set is OK. + runtime·removefinalizer(obj.data); } return; -- cgit v1.3-5-g9baa