Source file src/weak/pointer.go
1 // Copyright 2024 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package weak 6 7 import ( 8 "internal/abi" 9 "runtime" 10 "unsafe" 11 ) 12 13 // Pointer is a weak pointer to a value of type T. 14 // 15 // Just like regular pointers, Pointer may reference any part of an 16 // object, such as a field of a struct or an element of an array. 17 // Objects that are only pointed to by weak pointers are not considered 18 // reachable, and once the object becomes unreachable, [Pointer.Value] 19 // may return nil. 20 // 21 // The primary use-cases for weak pointers are for implementing caches, 22 // canonicalization maps (like the unique package), and for tying together 23 // the lifetimes of separate values (for example, through a map with weak 24 // keys). 25 // 26 // Two Pointer values always compare equal if the pointers from which they were 27 // created compare equal. This property is retained even after the 28 // object referenced by the pointer used to create a weak reference is 29 // reclaimed. 30 // If multiple weak pointers are made to different offsets within the same object 31 // (for example, pointers to different fields of the same struct), those pointers 32 // will not compare equal. 33 // If a weak pointer is created from an object that becomes unreachable, but is 34 // then resurrected due to a finalizer, that weak pointer will not compare equal 35 // with weak pointers created after the resurrection. 36 // 37 // Calling [Make] with a nil pointer returns a weak pointer whose [Pointer.Value] 38 // always returns nil. The zero value of a Pointer behaves as if it were created 39 // by passing nil to [Make] and compares equal with such pointers. 40 // 41 // [Pointer.Value] is not guaranteed to eventually return nil. 42 // [Pointer.Value] may return nil as soon as the object becomes 43 // unreachable. 44 // Values stored in global variables, or that can be found by tracing 45 // pointers from a global variable, are reachable. A function argument or 46 // receiver may become unreachable at the last point where the function 47 // mentions it. To ensure [Pointer.Value] does not return nil, 48 // pass a pointer to the object to the [runtime.KeepAlive] function after 49 // the last point where the object must remain reachable. 50 // 51 // Note that because [Pointer.Value] is not guaranteed to eventually return 52 // nil, even after an object is no longer referenced, the runtime is allowed to 53 // perform a space-saving optimization that batches objects together in a single 54 // allocation slot. The weak pointer for an unreferenced object in such an 55 // allocation may never become nil if it always exists in the same batch as a 56 // referenced object. Typically, this batching only happens for tiny 57 // (on the order of 16 bytes or less) and pointer-free objects. 58 type Pointer[T any] struct { 59 u unsafe.Pointer 60 } 61 62 // Make creates a weak pointer from a pointer to some value of type T. 63 func Make[T any](ptr *T) Pointer[T] { 64 // Explicitly force ptr to escape to the heap. 65 ptr = abi.Escape(ptr) 66 67 var u unsafe.Pointer 68 if ptr != nil { 69 u = runtime_registerWeakPointer(unsafe.Pointer(ptr)) 70 } 71 runtime.KeepAlive(ptr) 72 return Pointer[T]{u} 73 } 74 75 // Value returns the original pointer used to create the weak pointer. 76 // It returns nil if the value pointed to by the original pointer was reclaimed by 77 // the garbage collector. 78 // If a weak pointer points to an object with a finalizer, then Value will 79 // return nil as soon as the object's finalizer is queued for execution. 80 func (p Pointer[T]) Value() *T { 81 if p.u == nil { 82 return nil 83 } 84 return (*T)(runtime_makeStrongFromWeak(p.u)) 85 } 86 87 // Implemented in runtime. 88 89 //go:linkname runtime_registerWeakPointer 90 func runtime_registerWeakPointer(unsafe.Pointer) unsafe.Pointer 91 92 //go:linkname runtime_makeStrongFromWeak 93 func runtime_makeStrongFromWeak(unsafe.Pointer) unsafe.Pointer 94