summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/mgc0.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/mgc0.c')
-rw-r--r--src/pkg/runtime/mgc0.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/src/pkg/runtime/mgc0.c b/src/pkg/runtime/mgc0.c
index 83d217320..bd5d2e25a 100644
--- a/src/pkg/runtime/mgc0.c
+++ b/src/pkg/runtime/mgc0.c
@@ -23,9 +23,17 @@ extern byte data[];
extern byte etext[];
extern byte end[];
-static void *finq[128]; // finalizer queue - two elements per entry
-static void **pfinq = finq;
-static void **efinq = finq+nelem(finq);
+typedef struct Finq Finq;
+struct Finq
+{
+ void (*fn)(void*);
+ void *p;
+ int32 nret;
+};
+
+static Finq finq[128]; // finalizer queue - two elements per entry
+static Finq *pfinq = finq;
+static Finq *efinq = finq+nelem(finq);
static void sweepblock(byte*, int64, uint32*, int32);
@@ -172,7 +180,7 @@ sweepblock(byte *p, int64 n, uint32 *gcrefp, int32 pass)
break;
case RefNone:
case RefNone|RefNoPointers:
- if(pass == 0 && getfinalizer(p, 0)) {
+ if(pass == 0 && getfinalizer(p, 0, nil)) {
// Tentatively mark as finalizable.
// Make sure anything it points at will not be collected.
if(Debug > 0)
@@ -192,8 +200,12 @@ sweepblock(byte *p, int64 n, uint32 *gcrefp, int32 pass)
if(pfinq < efinq) {
if(Debug > 0)
printf("finalize %p+%D\n", p, n);
- *pfinq++ = getfinalizer(p, 1);
- *pfinq++ = p;
+ pfinq->p = p;
+ pfinq->nret = 0;
+ pfinq->fn = getfinalizer(p, 1, &pfinq->nret);
+ if(pfinq->fn == nil)
+ throw("getfinalizer inconsistency");
+ pfinq++;
}
// Reset for next mark+sweep.
*gcrefp = RefNone | (gcref&RefNoPointers);
@@ -242,7 +254,7 @@ gc(int32 force)
{
int64 t0, t1;
byte *p;
- void **fp;
+ Finq *fp;
// The gc is turned off (via enablegc) until
// the bootstrap has completed.
@@ -283,10 +295,10 @@ gc(int32 force)
// kick off goroutines to run queued finalizers
m->locks++; // disable gc during the mallocs in newproc
- for(fp=finq; fp<pfinq; fp+=2) {
- ·newproc(sizeof(void*), fp[0], fp[1]);
- fp[0] = nil;
- fp[1] = nil;
+ for(fp=finq; fp<pfinq; fp++) {
+ newproc1((byte*)fp->fn, (byte*)&fp->p, sizeof(fp->p), fp->nret);
+ fp->fn = nil;
+ fp->p = nil;
}
pfinq = finq;
m->locks--;