aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mgcmark.go
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2024-04-04 04:50:13 +0000
committerGopher Robot <gobot@golang.org>2024-04-18 21:25:11 +0000
commitdfc86e922cd033155339c22aff64e109f6c8cc89 (patch)
treede0ed468258f04af1eaa6b60c16a13dd4698347e /src/runtime/mgcmark.go
parentfa470f6245191b3c2f0b715194edf7cdf951af48 (diff)
downloadgo-dfc86e922cd033155339c22aff64e109f6c8cc89.tar.xz
internal/weak: add package implementing weak pointers
This change adds the internal/weak package, which exposes GC-supported weak pointers to the standard library. This is for the upcoming weak package, but may be useful for other future constructs. For #62483. Change-Id: I4aa8fa9400110ad5ea022a43c094051699ccab9d Reviewed-on: https://go-review.googlesource.com/c/go/+/576297 Auto-Submit: Michael Knyszek <mknyszek@google.com> Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/runtime/mgcmark.go')
-rw-r--r--src/runtime/mgcmark.go43
1 files changed, 27 insertions, 16 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index a42912e1ca..61e917df41 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -328,6 +328,13 @@ func markrootSpans(gcw *gcWork, shard int) {
// 2) Finalizer specials (which are not in the garbage
// collected heap) are roots. In practice, this means the fn
// field must be scanned.
+ //
+ // Objects with weak handles have only one invariant related
+ // to this function: weak handle specials (which are not in the
+ // garbage collected heap) are roots. In practice, this means
+ // the handle field must be scanned. Note that the value the
+ // handle pointer referenced does *not* need to be scanned. See
+ // the definition of specialWeakHandle for details.
sg := mheap_.sweepgen
// Find the arena and page index into that arena for this shard.
@@ -373,24 +380,28 @@ func markrootSpans(gcw *gcWork, shard int) {
// removed from the list while we're traversing it.
lock(&s.speciallock)
for sp := s.specials; sp != nil; sp = sp.next {
- if sp.kind != _KindSpecialFinalizer {
- continue
- }
- // don't mark finalized object, but scan it so we
- // retain everything it points to.
- spf := (*specialfinalizer)(unsafe.Pointer(sp))
- // A finalizer can be set for an inner byte of an object, find object beginning.
- p := s.base() + uintptr(spf.special.offset)/s.elemsize*s.elemsize
+ switch sp.kind {
+ case _KindSpecialFinalizer:
+ // don't mark finalized object, but scan it so we
+ // retain everything it points to.
+ spf := (*specialfinalizer)(unsafe.Pointer(sp))
+ // A finalizer can be set for an inner byte of an object, find object beginning.
+ p := s.base() + uintptr(spf.special.offset)/s.elemsize*s.elemsize
- // Mark everything that can be reached from
- // the object (but *not* the object itself or
- // we'll never collect it).
- if !s.spanclass.noscan() {
- scanobject(p, gcw)
- }
+ // Mark everything that can be reached from
+ // the object (but *not* the object itself or
+ // we'll never collect it).
+ if !s.spanclass.noscan() {
+ scanobject(p, gcw)
+ }
- // The special itself is a root.
- scanblock(uintptr(unsafe.Pointer(&spf.fn)), goarch.PtrSize, &oneptrmask[0], gcw, nil)
+ // The special itself is a root.
+ scanblock(uintptr(unsafe.Pointer(&spf.fn)), goarch.PtrSize, &oneptrmask[0], gcw, nil)
+ case _KindSpecialWeakHandle:
+ // The special itself is a root.
+ spw := (*specialWeakHandle)(unsafe.Pointer(sp))
+ scanblock(uintptr(unsafe.Pointer(&spw.handle)), goarch.PtrSize, &oneptrmask[0], gcw, nil)
+ }
}
unlock(&s.speciallock)
}