summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/malloc.cgo
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-02-03 16:31:34 -0800
committerRuss Cox <rsc@golang.org>2010-02-03 16:31:34 -0800
commit3732daa8e7c635ba306dd923a4342650524320df (patch)
tree31d454f4c7a1d0189ddbd9b1e771c8716655dc72 /src/pkg/runtime/malloc.cgo
parent9c681e46bfdf7a2745d2df35412592e8c13e0fce (diff)
downloadgolang-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.cgo46
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);
+}