summaryrefslogtreecommitdiff
path: root/libgo/go/runtime/mfinal.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/mfinal.go')
-rw-r--r--libgo/go/runtime/mfinal.go18
1 files changed, 16 insertions, 2 deletions
diff --git a/libgo/go/runtime/mfinal.go b/libgo/go/runtime/mfinal.go
index 229ccb55387..4353ee57569 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