libbacktrace: use __has_attribute for fallthrough
[official-gcc.git] / libgo / go / runtime / mfinal.go
blob09fb064a95049602fa0e960e9918b89d373e235b
1 // Copyright 2009 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.
5 // Garbage collector: finalizers and block profiling.
7 package runtime
9 import (
10 "internal/goarch"
11 "runtime/internal/atomic"
12 "unsafe"
15 // finblock is an array of finalizers to be executed. finblocks are
16 // arranged in a linked list for the finalizer queue.
18 // finblock is allocated from non-GC'd memory, so any heap pointers
19 // must be specially handled. GC currently assumes that the finalizer
20 // queue does not grow during marking (but it can shrink).
22 //go:notinheap
23 type finblock struct {
24 alllink *finblock
25 next *finblock
26 cnt uint32
27 _ int32
28 fin [(_FinBlockSize - 2*goarch.PtrSize - 2*4) / unsafe.Sizeof(finalizer{})]finalizer
31 var finlock mutex // protects the following variables
32 var fing *g // goroutine that runs finalizers
33 var finq *finblock // list of finalizers that are to be executed
34 var finc *finblock // cache of free blocks
35 var finptrmask [_FinBlockSize / goarch.PtrSize / 8]byte
36 var fingwait bool
37 var fingwake bool
38 var allfin *finblock // list of all blocks
40 // NOTE: Layout known to queuefinalizer.
41 type finalizer struct {
42 fn *funcval // function to call (may be a heap pointer)
43 arg unsafe.Pointer // ptr to object (may be a heap pointer)
44 ft *functype // type of fn (unlikely, but may be a heap pointer)
45 ot *ptrtype // type of ptr to object (may be a heap pointer)
48 func queuefinalizer(p unsafe.Pointer, fn *funcval, ft *functype, ot *ptrtype) {
49 if gcphase != _GCoff {
50 // Currently we assume that the finalizer queue won't
51 // grow during marking so we don't have to rescan it
52 // during mark termination. If we ever need to lift
53 // this assumption, we can do it by adding the
54 // necessary barriers to queuefinalizer (which it may
55 // have automatically).
56 throw("queuefinalizer during GC")
59 lock(&finlock)
60 if finq == nil || finq.cnt == uint32(len(finq.fin)) {
61 if finc == nil {
62 finc = (*finblock)(persistentalloc(_FinBlockSize, 0, &memstats.gcMiscSys))
63 finc.alllink = allfin
64 allfin = finc
65 if finptrmask[0] == 0 {
66 // Build pointer mask for Finalizer array in block.
67 // We allocate values of type finalizer in
68 // finblock values. Since these values are
69 // allocated by persistentalloc, they require
70 // special scanning during GC. finptrmask is a
71 // pointer mask to use while scanning.
72 // Since all the values in finalizer are
73 // pointers, just turn all bits on.
74 for i := range finptrmask {
75 finptrmask[i] = 0xff
79 block := finc
80 finc = block.next
81 block.next = finq
82 finq = block
84 f := &finq.fin[finq.cnt]
85 atomic.Xadd(&finq.cnt, +1) // Sync with markroots
86 f.fn = fn
87 f.ft = ft
88 f.ot = ot
89 f.arg = p
90 fingwake = true
91 unlock(&finlock)
94 //go:nowritebarrier
95 func iterate_finq(callback func(*funcval, unsafe.Pointer, *functype, *ptrtype)) {
96 for fb := allfin; fb != nil; fb = fb.alllink {
97 for i := uint32(0); i < fb.cnt; i++ {
98 f := &fb.fin[i]
99 callback(f.fn, f.arg, f.ft, f.ot)
104 func wakefing() *g {
105 var res *g
106 lock(&finlock)
107 if fingwait && fingwake {
108 fingwait = false
109 fingwake = false
110 res = fing
112 unlock(&finlock)
113 return res
116 var (
117 fingCreate uint32
120 func createfing() {
121 // start the finalizer goroutine exactly once
122 if fingCreate == 0 && atomic.Cas(&fingCreate, 0, 1) {
123 expectSystemGoroutine()
124 go runfinq()
128 // This is the goroutine that runs all of the finalizers
129 func runfinq() {
130 setSystemGoroutine()
132 var (
133 ef eface
134 ifac iface
137 gp := getg()
138 gp.isFinalizerGoroutine = true
139 for {
140 lock(&finlock)
141 fb := finq
142 finq = nil
143 if fb == nil {
144 fing = gp
145 fingwait = true
146 goparkunlock(&finlock, waitReasonFinalizerWait, traceEvGoBlock, 1)
147 continue
149 unlock(&finlock)
150 for fb != nil {
151 for i := fb.cnt; i > 0; i-- {
152 f := &fb.fin[i-1]
154 if f.ft == nil {
155 throw("missing type in runfinq")
157 fint := f.ft.in[0]
158 var param unsafe.Pointer
159 switch fint.kind & kindMask {
160 case kindPtr:
161 // direct use of pointer
162 param = unsafe.Pointer(&f.arg)
163 case kindInterface:
164 ityp := (*interfacetype)(unsafe.Pointer(fint))
165 if len(ityp.methods) == 0 {
166 // set up with empty interface
167 ef._type = &f.ot.typ
168 ef.data = f.arg
169 param = unsafe.Pointer(&ef)
170 } else {
171 // convert to interface with methods
172 // this conversion is guaranteed to succeed - we checked in SetFinalizer
173 ifac.tab = getitab(fint, &f.ot.typ, true)
174 ifac.data = f.arg
175 param = unsafe.Pointer(&ifac)
177 default:
178 throw("bad kind in runfinq")
180 // This is not a system goroutine while
181 // running the actual finalizer.
182 // This matters because we want this
183 // goroutine to appear in a stack dump
184 // if the finalizer crashes.
185 // The gc toolchain handles this using
186 // a global variable fingRunning,
187 // but we don't need that.
188 gp.isSystemGoroutine = false
189 reflectcall(f.ft, f.fn, false, false, &param, nil)
190 gp.isSystemGoroutine = true
192 // Drop finalizer queue heap references
193 // before hiding them from markroot.
194 // This also ensures these will be
195 // clear if we reuse the finalizer.
196 f.fn = nil
197 f.arg = nil
198 f.ot = nil
199 atomic.Store(&fb.cnt, i-1)
201 next := fb.next
202 lock(&finlock)
203 fb.next = finc
204 finc = fb
205 unlock(&finlock)
206 fb = next
211 // SetFinalizer sets the finalizer associated with obj to the provided
212 // finalizer function. When the garbage collector finds an unreachable block
213 // with an associated finalizer, it clears the association and runs
214 // finalizer(obj) in a separate goroutine. This makes obj reachable again,
215 // but now without an associated finalizer. Assuming that SetFinalizer
216 // is not called again, the next time the garbage collector sees
217 // that obj is unreachable, it will free obj.
219 // SetFinalizer(obj, nil) clears any finalizer associated with obj.
221 // The argument obj must be a pointer to an object allocated by calling
222 // new, by taking the address of a composite literal, or by taking the
223 // address of a local variable.
224 // The argument finalizer must be a function that takes a single argument
225 // to which obj's type can be assigned, and can have arbitrary ignored return
226 // values. If either of these is not true, SetFinalizer may abort the
227 // program.
229 // Finalizers are run in dependency order: if A points at B, both have
230 // finalizers, and they are otherwise unreachable, only the finalizer
231 // for A runs; once A is freed, the finalizer for B can run.
232 // If a cyclic structure includes a block with a finalizer, that
233 // cycle is not guaranteed to be garbage collected and the finalizer
234 // is not guaranteed to run, because there is no ordering that
235 // respects the dependencies.
237 // The finalizer is scheduled to run at some arbitrary time after the
238 // program can no longer reach the object to which obj points.
239 // There is no guarantee that finalizers will run before a program exits,
240 // so typically they are useful only for releasing non-memory resources
241 // associated with an object during a long-running program.
242 // For example, an os.File object could use a finalizer to close the
243 // associated operating system file descriptor when a program discards
244 // an os.File without calling Close, but it would be a mistake
245 // to depend on a finalizer to flush an in-memory I/O buffer such as a
246 // bufio.Writer, because the buffer would not be flushed at program exit.
248 // It is not guaranteed that a finalizer will run if the size of *obj is
249 // zero bytes.
251 // It is not guaranteed that a finalizer will run for objects allocated
252 // in initializers for package-level variables. Such objects may be
253 // linker-allocated, not heap-allocated.
255 // A finalizer may run as soon as an object becomes unreachable.
256 // In order to use finalizers correctly, the program must ensure that
257 // the object is reachable until it is no longer required.
258 // Objects stored in global variables, or that can be found by tracing
259 // pointers from a global variable, are reachable. For other objects,
260 // pass the object to a call of the KeepAlive function to mark the
261 // last point in the function where the object must be reachable.
263 // For example, if p points to a struct, such as os.File, that contains
264 // a file descriptor d, and p has a finalizer that closes that file
265 // descriptor, and if the last use of p in a function is a call to
266 // syscall.Write(p.d, buf, size), then p may be unreachable as soon as
267 // the program enters syscall.Write. The finalizer may run at that moment,
268 // closing p.d, causing syscall.Write to fail because it is writing to
269 // a closed file descriptor (or, worse, to an entirely different
270 // file descriptor opened by a different goroutine). To avoid this problem,
271 // call runtime.KeepAlive(p) after the call to syscall.Write.
273 // A single goroutine runs all finalizers for a program, sequentially.
274 // If a finalizer must run for a long time, it should do so by starting
275 // a new goroutine.
276 func SetFinalizer(obj any, finalizer any) {
277 if debug.sbrk != 0 {
278 // debug.sbrk never frees memory, so no finalizers run
279 // (and we don't have the data structures to record them).
280 return
282 e := efaceOf(&obj)
283 etyp := e._type
284 if etyp == nil {
285 throw("runtime.SetFinalizer: first argument is nil")
287 if etyp.kind&kindMask != kindPtr {
288 throw("runtime.SetFinalizer: first argument is " + etyp.string() + ", not pointer")
290 ot := (*ptrtype)(unsafe.Pointer(etyp))
291 if ot.elem == nil {
292 throw("nil elem type!")
295 // find the containing object
296 base, _, _ := findObject(uintptr(e.data), 0, 0, false)
298 if base == 0 {
299 // 0-length objects are okay.
300 if e.data == unsafe.Pointer(&zerobase) {
301 return
304 // Global initializers might be linker-allocated.
305 // var Foo = &Object{}
306 // func main() {
307 // runtime.SetFinalizer(Foo, nil)
308 // }
309 // The relevant segments are: noptrdata, data, bss, noptrbss.
310 // We cannot assume they are in any order or even contiguous,
311 // due to external linking.
313 // For gccgo we have no reliable way to detect them,
314 // so we just return.
315 return
318 if uintptr(e.data) != base {
319 // As an implementation detail we allow to set finalizers for an inner byte
320 // of an object if it could come from tiny alloc (see mallocgc for details).
321 if ot.elem == nil || ot.elem.ptrdata != 0 || ot.elem.size >= maxTinySize {
322 throw("runtime.SetFinalizer: pointer not at beginning of allocated block")
326 f := efaceOf(&finalizer)
327 ftyp := f._type
328 if ftyp == nil {
329 // switch to system stack and remove finalizer
330 systemstack(func() {
331 removefinalizer(e.data)
333 return
336 if ftyp.kind&kindMask != kindFunc {
337 throw("runtime.SetFinalizer: second argument is " + ftyp.string() + ", not a function")
339 ft := (*functype)(unsafe.Pointer(ftyp))
340 if ft.dotdotdot {
341 throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string() + " because dotdotdot")
343 if len(ft.in) != 1 {
344 throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string())
346 fint := ft.in[0]
347 switch {
348 case fint == etyp:
349 // ok - same type
350 goto okarg
351 case fint.kind&kindMask == kindPtr:
352 if (fint.uncommontype == nil || etyp.uncommontype == nil) && (*ptrtype)(unsafe.Pointer(fint)).elem == ot.elem {
353 // ok - not same type, but both pointers,
354 // one or the other is unnamed, and same element type, so assignable.
355 goto okarg
357 case fint.kind&kindMask == kindInterface:
358 ityp := (*interfacetype)(unsafe.Pointer(fint))
359 if len(ityp.methods) == 0 {
360 // ok - satisfies empty interface
361 goto okarg
363 if getitab(fint, etyp, true) == nil {
364 goto okarg
367 throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string())
368 okarg:
369 // make sure we have a finalizer goroutine
370 createfing()
372 systemstack(func() {
373 data := f.data
374 if !isDirectIface(ftyp) {
375 data = *(*unsafe.Pointer)(data)
377 if !addfinalizer(e.data, (*funcval)(data), ft, ot) {
378 throw("runtime.SetFinalizer: finalizer already set")
383 // Mark KeepAlive as noinline so that it is easily detectable as an intrinsic.
384 //go:noinline
386 // KeepAlive marks its argument as currently reachable.
387 // This ensures that the object is not freed, and its finalizer is not run,
388 // before the point in the program where KeepAlive is called.
390 // A very simplified example showing where KeepAlive is required:
391 // type File struct { d int }
392 // d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0)
393 // // ... do something if err != nil ...
394 // p := &File{d}
395 // runtime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) })
396 // var buf [10]byte
397 // n, err := syscall.Read(p.d, buf[:])
398 // // Ensure p is not finalized until Read returns.
399 // runtime.KeepAlive(p)
400 // // No more uses of p after this point.
402 // Without the KeepAlive call, the finalizer could run at the start of
403 // syscall.Read, closing the file descriptor before syscall.Read makes
404 // the actual system call.
406 // Note: KeepAlive should only be used to prevent finalizers from
407 // running prematurely. In particular, when used with unsafe.Pointer,
408 // the rules for valid uses of unsafe.Pointer still apply.
409 func KeepAlive(x any) {
410 // Introduce a use of x that the compiler can't eliminate.
411 // This makes sure x is alive on entry. We need x to be alive
412 // on entry for "defer runtime.KeepAlive(x)"; see issue 21402.
413 if cgoAlwaysFalse {
414 println(x)