diff options
Diffstat (limited to 'libgo/go/runtime/mfinal.go')
-rw-r--r-- | libgo/go/runtime/mfinal.go | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/libgo/go/runtime/mfinal.go b/libgo/go/runtime/mfinal.go index 229ccb5..4353ee5 100644 --- a/libgo/go/runtime/mfinal.go +++ b/libgo/go/runtime/mfinal.go @@ -12,8 +12,12 @@ import ( "unsafe" ) +// finblock is an array of finalizers to be executed. finblocks are +// arranged in a linked list for the finalizer queue. +// // finblock is allocated from non-GC'd memory, so any heap pointers -// must be specially handled. +// must be specially handled. GC currently assumes that the finalizer +// queue does not grow during marking (but it can shrink). // //go:notinheap type finblock struct { @@ -42,6 +46,16 @@ type finalizer struct { } func queuefinalizer(p unsafe.Pointer, fn *funcval, ft *functype, ot *ptrtype) { + if gcphase != _GCoff { + // Currently we assume that the finalizer queue won't + // grow during marking so we don't have to rescan it + // during mark termination. If we ever need to lift + // this assumption, we can do it by adding the + // necessary barriers to queuefinalizer (which it may + // have automatically). + throw("queuefinalizer during GC") + } + lock(&finlock) if finq == nil || finq.cnt == uint32(len(finq.fin)) { if finc == nil { @@ -399,7 +413,7 @@ func findObject(v unsafe.Pointer) (s *mspan, x unsafe.Pointer, n uintptr) { } n = s.elemsize - if s.sizeclass != 0 { + if s.spanclass.sizeclass() != 0 { x = add(x, (uintptr(v)-uintptr(x))/n*n) } return |