diff options
| author | Russ Cox <rsc@golang.org> | 2010-02-03 16:31:34 -0800 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2010-02-03 16:31:34 -0800 |
| commit | 3732daa8e7c635ba306dd923a4342650524320df (patch) | |
| tree | 31d454f4c7a1d0189ddbd9b1e771c8716655dc72 /src/pkg/runtime/malloc.cgo | |
| parent | 9c681e46bfdf7a2745d2df35412592e8c13e0fce (diff) | |
| download | golang-3732daa8e7c635ba306dd923a4342650524320df.tar.gz | |
finalizers; merge package malloc into package runtime
R=r, cw
CC=golang-dev
http://codereview.appspot.com/198085
Diffstat (limited to 'src/pkg/runtime/malloc.cgo')
| -rw-r--r-- | src/pkg/runtime/malloc.cgo | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/src/pkg/runtime/malloc.cgo b/src/pkg/runtime/malloc.cgo index 6acbac2eb..d7e3e4151 100644 --- a/src/pkg/runtime/malloc.cgo +++ b/src/pkg/runtime/malloc.cgo @@ -6,10 +6,11 @@ // // TODO(rsc): double-check stats. -package malloc +package runtime #include "runtime.h" #include "malloc.h" #include "defs.h" +#include "type.h" MHeap mheap; MStats mstats; @@ -96,8 +97,10 @@ free(void *v) throw("malloc/free - deadlock"); m->mallocing = 1; - if(!mlookup(v, nil, nil, &ref)) + if(!mlookup(v, nil, nil, &ref)) { + printf("free %p: not an allocated block\n", v); throw("free mlookup"); + } *ref = RefFree; // Find size class for v. @@ -274,10 +277,41 @@ func Lookup(p *byte) (base *byte, size uintptr) { mlookup(p, &base, &size, nil); } -func GetStats() (s *MStats) { - s = &mstats; -} - func GC() { gc(1); } + +func SetFinalizer(obj Eface, finalizer Eface) { + byte *base; + uintptr size; + FuncType *ft; + + if(obj.type == nil) { + printf("runtime.SetFinalizer: first argument is nil interface\n"); + throw: + throw("runtime.SetFinalizer"); + } + if(obj.type->kind != KindPtr) { + printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *obj.type->string); + goto throw; + } + if(!mlookup(obj.data, &base, &size, nil) || obj.data != base) { + printf("runtime.SetFinalizer: pointer not at beginning of allocated block\n"); + goto throw; + } + if(finalizer.type != nil) { + if(finalizer.type->kind != KindFunc) { + badfunc: + printf("runtime.SetFinalizer: second argument is %S, not func(%S)\n", *finalizer.type->string, *obj.type->string); + goto throw; + } + ft = (FuncType*)finalizer.type; + if(ft->dotdotdot || ft->out.len != 0 || ft->in.len != 1 || *(Type**)ft->in.array != obj.type) + goto badfunc; + if(getfinalizer(obj.data, 0)) { + printf("runtime.SetFinalizer: finalizer already set"); + goto throw; + } + } + addfinalizer(obj.data, finalizer.data); +} |
