diff options
| author | Keith Randall <khr@golang.org> | 2014-01-07 13:45:50 -0800 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2014-01-07 13:45:50 -0800 |
| commit | 020b39c3f3d3826d02c735c29d1dae7282aeb3f7 (patch) | |
| tree | b84e0d2dd661a351233b6eed20a7f4466ec4dfe3 /src/pkg/runtime/malloc.goc | |
| parent | affab3f3128558dd808247f01abfee4b2bfee712 (diff) | |
| download | go-020b39c3f3d3826d02c735c29d1dae7282aeb3f7.tar.xz | |
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
Diffstat (limited to 'src/pkg/runtime/malloc.goc')
| -rw-r--r-- | src/pkg/runtime/malloc.goc | 23 |
1 files changed, 11 insertions, 12 deletions
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; i<ft->out.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; |
