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.
4
5// Garbage collector: finalizers and block profiling.
6
7package runtime
8
9import (
10	"runtime/internal/atomic"
11	"runtime/internal/sys"
12	"unsafe"
13)
14
15// finblock is an array of finalizers to be executed. finblocks are
16// arranged in a linked list for the finalizer queue.
17//
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).
21//
22//go:notinheap
23type finblock struct {
24	alllink *finblock
25	next    *finblock
26	cnt     uint32
27	_       int32
28	fin     [(_FinBlockSize - 2*sys.PtrSize - 2*4) / unsafe.Sizeof(finalizer{})]finalizer
29}
30
31var finlock mutex  // protects the following variables
32var fing *g        // goroutine that runs finalizers
33var finq *finblock // list of finalizers that are to be executed
34var finc *finblock // cache of free blocks
35var finptrmask [_FinBlockSize / sys.PtrSize / 8]byte
36var fingwait bool
37var fingwake bool
38var allfin *finblock // list of all blocks
39
40// NOTE: Layout known to queuefinalizer.
41type 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)
46}
47
48func 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")
57	}
58
59	lock(&finlock)
60	if finq == nil || finq.cnt == uint32(len(finq.fin)) {
61		if finc == nil {
62			finc = (*finblock)(persistentalloc(_FinBlockSize, 0, &memstats.gc_sys))
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
76				}
77			}
78		}
79		block := finc
80		finc = block.next
81		block.next = finq
82		finq = block
83	}
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)
92}
93
94//go:nowritebarrier
95func 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)
100		}
101	}
102}
103
104func wakefing() *g {
105	var res *g
106	lock(&finlock)
107	if fingwait && fingwake {
108		fingwait = false
109		fingwake = false
110		res = fing
111	}
112	unlock(&finlock)
113	return res
114}
115
116var (
117	fingCreate uint32
118)
119
120func createfing() {
121	// start the finalizer goroutine exactly once
122	if fingCreate == 0 && atomic.Cas(&fingCreate, 0, 1) {
123		expectSystemGoroutine()
124		go runfinq()
125	}
126}
127
128// This is the goroutine that runs all of the finalizers
129func runfinq() {
130	setSystemGoroutine()
131
132	var (
133		ef   eface
134		ifac iface
135	)
136
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
148		}
149		unlock(&finlock)
150		for fb != nil {
151			for i := fb.cnt; i > 0; i-- {
152				f := &fb.fin[i-1]
153
154				if f.ft == nil {
155					throw("missing type in runfinq")
156				}
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)
176					}
177				default:
178					throw("bad kind in runfinq")
179				}
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
191
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)
200			}
201			next := fb.next
202			lock(&finlock)
203			fb.next = finc
204			finc = fb
205			unlock(&finlock)
206			fb = next
207		}
208	}
209}
210
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.
218//
219// SetFinalizer(obj, nil) clears any finalizer associated with obj.
220//
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.
228//
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.
236//
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.
247//
248// It is not guaranteed that a finalizer will run if the size of *obj is
249// zero bytes.
250//
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.
254//
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.
262//
263// For example, if p points to a struct that contains a file descriptor d,
264// and p has a finalizer that closes that file descriptor, and if the last
265// use of p in a function is a call to syscall.Write(p.d, buf, size), then
266// p may be unreachable as soon as the program enters syscall.Write. The
267// finalizer may run at that moment, closing p.d, causing syscall.Write
268// to fail because it is writing to a closed file descriptor (or, worse,
269// to an entirely different file descriptor opened by a different goroutine).
270// To avoid this problem, call runtime.KeepAlive(p) after the call to
271// syscall.Write.
272//
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.
276func SetFinalizer(obj interface{}, finalizer interface{}) {
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
281	}
282	e := efaceOf(&obj)
283	etyp := e._type
284	if etyp == nil {
285		throw("runtime.SetFinalizer: first argument is nil")
286	}
287	if etyp.kind&kindMask != kindPtr {
288		throw("runtime.SetFinalizer: first argument is " + etyp.string() + ", not pointer")
289	}
290	ot := (*ptrtype)(unsafe.Pointer(etyp))
291	if ot.elem == nil {
292		throw("nil elem type!")
293	}
294
295	// find the containing object
296	base, _, _ := findObject(uintptr(e.data), 0, 0, false)
297
298	if base == 0 {
299		// 0-length objects are okay.
300		if e.data == unsafe.Pointer(&zerobase) {
301			return
302		}
303
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.
312		//
313		// For gccgo we have no reliable way to detect them,
314		// so we just return.
315		return
316	}
317
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")
323		}
324	}
325
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)
332		})
333		return
334	}
335
336	if ftyp.kind&kindMask != kindFunc {
337		throw("runtime.SetFinalizer: second argument is " + ftyp.string() + ", not a function")
338	}
339	ft := (*functype)(unsafe.Pointer(ftyp))
340	if ft.dotdotdot {
341		throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string() + " because dotdotdot")
342	}
343	if len(ft.in) != 1 {
344		throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string())
345	}
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
356		}
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
362		}
363		if getitab(fint, etyp, true) == nil {
364			goto okarg
365		}
366	}
367	throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string())
368okarg:
369	// make sure we have a finalizer goroutine
370	createfing()
371
372	systemstack(func() {
373		data := f.data
374		if !isDirectIface(ftyp) {
375			data = *(*unsafe.Pointer)(data)
376		}
377		if !addfinalizer(e.data, (*funcval)(data), ft, ot) {
378			throw("runtime.SetFinalizer: finalizer already set")
379		}
380	})
381}
382
383// Mark KeepAlive as noinline so that it is easily detectable as an intrinsic.
384//go:noinline
385
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.
389//
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.
401//
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.
405func KeepAlive(x interface{}) {
406	// Introduce a use of x that the compiler can't eliminate.
407	// This makes sure x is alive on entry. We need x to be alive
408	// on entry for "defer runtime.KeepAlive(x)"; see issue 21402.
409	if cgoAlwaysFalse {
410		println(x)
411	}
412}
413