Home | History | Annotate | Download | only in runtime
      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 
      7 package runtime
      8 
      9 import (
     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
     23 type 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 
     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 / sys.PtrSize / 8]byte
     36 var fingwait bool
     37 var fingwake bool
     38 var allfin *finblock // list of all blocks
     39 
     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 	nret uintptr        // bytes of return values from fn
     45 	fint *_type         // type of first argument of fn
     46 	ot   *ptrtype       // type of ptr to object (may be a heap pointer)
     47 }
     48 
     49 var finalizer1 = [...]byte{
     50 	// Each Finalizer is 5 words, ptr ptr INT ptr ptr (INT = uintptr here)
     51 	// Each byte describes 8 words.
     52 	// Need 8 Finalizers described by 5 bytes before pattern repeats:
     53 	//	ptr ptr INT ptr ptr
     54 	//	ptr ptr INT ptr ptr
     55 	//	ptr ptr INT ptr ptr
     56 	//	ptr ptr INT ptr ptr
     57 	//	ptr ptr INT ptr ptr
     58 	//	ptr ptr INT ptr ptr
     59 	//	ptr ptr INT ptr ptr
     60 	//	ptr ptr INT ptr ptr
     61 	// aka
     62 	//
     63 	//	ptr ptr INT ptr ptr ptr ptr INT
     64 	//	ptr ptr ptr ptr INT ptr ptr ptr
     65 	//	ptr INT ptr ptr ptr ptr INT ptr
     66 	//	ptr ptr ptr INT ptr ptr ptr ptr
     67 	//	INT ptr ptr ptr ptr INT ptr ptr
     68 	//
     69 	// Assumptions about Finalizer layout checked below.
     70 	1<<0 | 1<<1 | 0<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 0<<7,
     71 	1<<0 | 1<<1 | 1<<2 | 1<<3 | 0<<4 | 1<<5 | 1<<6 | 1<<7,
     72 	1<<0 | 0<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 0<<6 | 1<<7,
     73 	1<<0 | 1<<1 | 1<<2 | 0<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7,
     74 	0<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 0<<5 | 1<<6 | 1<<7,
     75 }
     76 
     77 func queuefinalizer(p unsafe.Pointer, fn *funcval, nret uintptr, fint *_type, ot *ptrtype) {
     78 	if gcphase != _GCoff {
     79 		// Currently we assume that the finalizer queue won't
     80 		// grow during marking so we don't have to rescan it
     81 		// during mark termination. If we ever need to lift
     82 		// this assumption, we can do it by adding the
     83 		// necessary barriers to queuefinalizer (which it may
     84 		// have automatically).
     85 		throw("queuefinalizer during GC")
     86 	}
     87 
     88 	lock(&finlock)
     89 	if finq == nil || finq.cnt == uint32(len(finq.fin)) {
     90 		if finc == nil {
     91 			finc = (*finblock)(persistentalloc(_FinBlockSize, 0, &memstats.gc_sys))
     92 			finc.alllink = allfin
     93 			allfin = finc
     94 			if finptrmask[0] == 0 {
     95 				// Build pointer mask for Finalizer array in block.
     96 				// Check assumptions made in finalizer1 array above.
     97 				if (unsafe.Sizeof(finalizer{}) != 5*sys.PtrSize ||
     98 					unsafe.Offsetof(finalizer{}.fn) != 0 ||
     99 					unsafe.Offsetof(finalizer{}.arg) != sys.PtrSize ||
    100 					unsafe.Offsetof(finalizer{}.nret) != 2*sys.PtrSize ||
    101 					unsafe.Offsetof(finalizer{}.fint) != 3*sys.PtrSize ||
    102 					unsafe.Offsetof(finalizer{}.ot) != 4*sys.PtrSize) {
    103 					throw("finalizer out of sync")
    104 				}
    105 				for i := range finptrmask {
    106 					finptrmask[i] = finalizer1[i%len(finalizer1)]
    107 				}
    108 			}
    109 		}
    110 		block := finc
    111 		finc = block.next
    112 		block.next = finq
    113 		finq = block
    114 	}
    115 	f := &finq.fin[finq.cnt]
    116 	atomic.Xadd(&finq.cnt, +1) // Sync with markroots
    117 	f.fn = fn
    118 	f.nret = nret
    119 	f.fint = fint
    120 	f.ot = ot
    121 	f.arg = p
    122 	fingwake = true
    123 	unlock(&finlock)
    124 }
    125 
    126 //go:nowritebarrier
    127 func iterate_finq(callback func(*funcval, unsafe.Pointer, uintptr, *_type, *ptrtype)) {
    128 	for fb := allfin; fb != nil; fb = fb.alllink {
    129 		for i := uint32(0); i < fb.cnt; i++ {
    130 			f := &fb.fin[i]
    131 			callback(f.fn, f.arg, f.nret, f.fint, f.ot)
    132 		}
    133 	}
    134 }
    135 
    136 func wakefing() *g {
    137 	var res *g
    138 	lock(&finlock)
    139 	if fingwait && fingwake {
    140 		fingwait = false
    141 		fingwake = false
    142 		res = fing
    143 	}
    144 	unlock(&finlock)
    145 	return res
    146 }
    147 
    148 var (
    149 	fingCreate  uint32
    150 	fingRunning bool
    151 )
    152 
    153 func createfing() {
    154 	// start the finalizer goroutine exactly once
    155 	if fingCreate == 0 && atomic.Cas(&fingCreate, 0, 1) {
    156 		go runfinq()
    157 	}
    158 }
    159 
    160 // This is the goroutine that runs all of the finalizers
    161 func runfinq() {
    162 	var (
    163 		frame    unsafe.Pointer
    164 		framecap uintptr
    165 	)
    166 
    167 	for {
    168 		lock(&finlock)
    169 		fb := finq
    170 		finq = nil
    171 		if fb == nil {
    172 			gp := getg()
    173 			fing = gp
    174 			fingwait = true
    175 			goparkunlock(&finlock, "finalizer wait", traceEvGoBlock, 1)
    176 			continue
    177 		}
    178 		unlock(&finlock)
    179 		if raceenabled {
    180 			racefingo()
    181 		}
    182 		for fb != nil {
    183 			for i := fb.cnt; i > 0; i-- {
    184 				f := &fb.fin[i-1]
    185 
    186 				framesz := unsafe.Sizeof((interface{})(nil)) + f.nret
    187 				if framecap < framesz {
    188 					// The frame does not contain pointers interesting for GC,
    189 					// all not yet finalized objects are stored in finq.
    190 					// If we do not mark it as FlagNoScan,
    191 					// the last finalized object is not collected.
    192 					frame = mallocgc(framesz, nil, true)
    193 					framecap = framesz
    194 				}
    195 
    196 				if f.fint == nil {
    197 					throw("missing type in runfinq")
    198 				}
    199 				// frame is effectively uninitialized
    200 				// memory. That means we have to clear
    201 				// it before writing to it to avoid
    202 				// confusing the write barrier.
    203 				*(*[2]uintptr)(frame) = [2]uintptr{}
    204 				switch f.fint.kind & kindMask {
    205 				case kindPtr:
    206 					// direct use of pointer
    207 					*(*unsafe.Pointer)(frame) = f.arg
    208 				case kindInterface:
    209 					ityp := (*interfacetype)(unsafe.Pointer(f.fint))
    210 					// set up with empty interface
    211 					(*eface)(frame)._type = &f.ot.typ
    212 					(*eface)(frame).data = f.arg
    213 					if len(ityp.mhdr) != 0 {
    214 						// convert to interface with methods
    215 						// this conversion is guaranteed to succeed - we checked in SetFinalizer
    216 						*(*iface)(frame) = assertE2I(ityp, *(*eface)(frame))
    217 					}
    218 				default:
    219 					throw("bad kind in runfinq")
    220 				}
    221 				fingRunning = true
    222 				reflectcall(nil, unsafe.Pointer(f.fn), frame, uint32(framesz), uint32(framesz))
    223 				fingRunning = false
    224 
    225 				// Drop finalizer queue heap references
    226 				// before hiding them from markroot.
    227 				// This also ensures these will be
    228 				// clear if we reuse the finalizer.
    229 				f.fn = nil
    230 				f.arg = nil
    231 				f.ot = nil
    232 				atomic.Store(&fb.cnt, i-1)
    233 			}
    234 			next := fb.next
    235 			lock(&finlock)
    236 			fb.next = finc
    237 			finc = fb
    238 			unlock(&finlock)
    239 			fb = next
    240 		}
    241 	}
    242 }
    243 
    244 // SetFinalizer sets the finalizer associated with obj to the provided
    245 // finalizer function. When the garbage collector finds an unreachable block
    246 // with an associated finalizer, it clears the association and runs
    247 // finalizer(obj) in a separate goroutine. This makes obj reachable again,
    248 // but now without an associated finalizer. Assuming that SetFinalizer
    249 // is not called again, the next time the garbage collector sees
    250 // that obj is unreachable, it will free obj.
    251 //
    252 // SetFinalizer(obj, nil) clears any finalizer associated with obj.
    253 //
    254 // The argument obj must be a pointer to an object allocated by calling
    255 // new, by taking the address of a composite literal, or by taking the
    256 // address of a local variable.
    257 // The argument finalizer must be a function that takes a single argument
    258 // to which obj's type can be assigned, and can have arbitrary ignored return
    259 // values. If either of these is not true, SetFinalizer may abort the
    260 // program.
    261 //
    262 // Finalizers are run in dependency order: if A points at B, both have
    263 // finalizers, and they are otherwise unreachable, only the finalizer
    264 // for A runs; once A is freed, the finalizer for B can run.
    265 // If a cyclic structure includes a block with a finalizer, that
    266 // cycle is not guaranteed to be garbage collected and the finalizer
    267 // is not guaranteed to run, because there is no ordering that
    268 // respects the dependencies.
    269 //
    270 // The finalizer for obj is scheduled to run at some arbitrary time after
    271 // obj becomes unreachable.
    272 // There is no guarantee that finalizers will run before a program exits,
    273 // so typically they are useful only for releasing non-memory resources
    274 // associated with an object during a long-running program.
    275 // For example, an os.File object could use a finalizer to close the
    276 // associated operating system file descriptor when a program discards
    277 // an os.File without calling Close, but it would be a mistake
    278 // to depend on a finalizer to flush an in-memory I/O buffer such as a
    279 // bufio.Writer, because the buffer would not be flushed at program exit.
    280 //
    281 // It is not guaranteed that a finalizer will run if the size of *obj is
    282 // zero bytes.
    283 //
    284 // It is not guaranteed that a finalizer will run for objects allocated
    285 // in initializers for package-level variables. Such objects may be
    286 // linker-allocated, not heap-allocated.
    287 //
    288 // A finalizer may run as soon as an object becomes unreachable.
    289 // In order to use finalizers correctly, the program must ensure that
    290 // the object is reachable until it is no longer required.
    291 // Objects stored in global variables, or that can be found by tracing
    292 // pointers from a global variable, are reachable. For other objects,
    293 // pass the object to a call of the KeepAlive function to mark the
    294 // last point in the function where the object must be reachable.
    295 //
    296 // For example, if p points to a struct that contains a file descriptor d,
    297 // and p has a finalizer that closes that file descriptor, and if the last
    298 // use of p in a function is a call to syscall.Write(p.d, buf, size), then
    299 // p may be unreachable as soon as the program enters syscall.Write. The
    300 // finalizer may run at that moment, closing p.d, causing syscall.Write
    301 // to fail because it is writing to a closed file descriptor (or, worse,
    302 // to an entirely different file descriptor opened by a different goroutine).
    303 // To avoid this problem, call runtime.KeepAlive(p) after the call to
    304 // syscall.Write.
    305 //
    306 // A single goroutine runs all finalizers for a program, sequentially.
    307 // If a finalizer must run for a long time, it should do so by starting
    308 // a new goroutine.
    309 func SetFinalizer(obj interface{}, finalizer interface{}) {
    310 	if debug.sbrk != 0 {
    311 		// debug.sbrk never frees memory, so no finalizers run
    312 		// (and we don't have the data structures to record them).
    313 		return
    314 	}
    315 	e := efaceOf(&obj)
    316 	etyp := e._type
    317 	if etyp == nil {
    318 		throw("runtime.SetFinalizer: first argument is nil")
    319 	}
    320 	if etyp.kind&kindMask != kindPtr {
    321 		throw("runtime.SetFinalizer: first argument is " + etyp.string() + ", not pointer")
    322 	}
    323 	ot := (*ptrtype)(unsafe.Pointer(etyp))
    324 	if ot.elem == nil {
    325 		throw("nil elem type!")
    326 	}
    327 
    328 	// find the containing object
    329 	_, base, _ := findObject(e.data)
    330 
    331 	if base == nil {
    332 		// 0-length objects are okay.
    333 		if e.data == unsafe.Pointer(&zerobase) {
    334 			return
    335 		}
    336 
    337 		// Global initializers might be linker-allocated.
    338 		//	var Foo = &Object{}
    339 		//	func main() {
    340 		//		runtime.SetFinalizer(Foo, nil)
    341 		//	}
    342 		// The relevant segments are: noptrdata, data, bss, noptrbss.
    343 		// We cannot assume they are in any order or even contiguous,
    344 		// due to external linking.
    345 		for datap := &firstmoduledata; datap != nil; datap = datap.next {
    346 			if datap.noptrdata <= uintptr(e.data) && uintptr(e.data) < datap.enoptrdata ||
    347 				datap.data <= uintptr(e.data) && uintptr(e.data) < datap.edata ||
    348 				datap.bss <= uintptr(e.data) && uintptr(e.data) < datap.ebss ||
    349 				datap.noptrbss <= uintptr(e.data) && uintptr(e.data) < datap.enoptrbss {
    350 				return
    351 			}
    352 		}
    353 		throw("runtime.SetFinalizer: pointer not in allocated block")
    354 	}
    355 
    356 	if e.data != base {
    357 		// As an implementation detail we allow to set finalizers for an inner byte
    358 		// of an object if it could come from tiny alloc (see mallocgc for details).
    359 		if ot.elem == nil || ot.elem.kind&kindNoPointers == 0 || ot.elem.size >= maxTinySize {
    360 			throw("runtime.SetFinalizer: pointer not at beginning of allocated block")
    361 		}
    362 	}
    363 
    364 	f := efaceOf(&finalizer)
    365 	ftyp := f._type
    366 	if ftyp == nil {
    367 		// switch to system stack and remove finalizer
    368 		systemstack(func() {
    369 			removefinalizer(e.data)
    370 		})
    371 		return
    372 	}
    373 
    374 	if ftyp.kind&kindMask != kindFunc {
    375 		throw("runtime.SetFinalizer: second argument is " + ftyp.string() + ", not a function")
    376 	}
    377 	ft := (*functype)(unsafe.Pointer(ftyp))
    378 	if ft.dotdotdot() {
    379 		throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string() + " because dotdotdot")
    380 	}
    381 	if ft.inCount != 1 {
    382 		throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string())
    383 	}
    384 	fint := ft.in()[0]
    385 	switch {
    386 	case fint == etyp:
    387 		// ok - same type
    388 		goto okarg
    389 	case fint.kind&kindMask == kindPtr:
    390 		if (fint.uncommon() == nil || etyp.uncommon() == nil) && (*ptrtype)(unsafe.Pointer(fint)).elem == ot.elem {
    391 			// ok - not same type, but both pointers,
    392 			// one or the other is unnamed, and same element type, so assignable.
    393 			goto okarg
    394 		}
    395 	case fint.kind&kindMask == kindInterface:
    396 		ityp := (*interfacetype)(unsafe.Pointer(fint))
    397 		if len(ityp.mhdr) == 0 {
    398 			// ok - satisfies empty interface
    399 			goto okarg
    400 		}
    401 		if _, ok := assertE2I2(ityp, *efaceOf(&obj)); ok {
    402 			goto okarg
    403 		}
    404 	}
    405 	throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string())
    406 okarg:
    407 	// compute size needed for return parameters
    408 	nret := uintptr(0)
    409 	for _, t := range ft.out() {
    410 		nret = round(nret, uintptr(t.align)) + uintptr(t.size)
    411 	}
    412 	nret = round(nret, sys.PtrSize)
    413 
    414 	// make sure we have a finalizer goroutine
    415 	createfing()
    416 
    417 	systemstack(func() {
    418 		if !addfinalizer(e.data, (*funcval)(f.data), nret, fint, ot) {
    419 			throw("runtime.SetFinalizer: finalizer already set")
    420 		}
    421 	})
    422 }
    423 
    424 // Look up pointer v in heap. Return the span containing the object,
    425 // the start of the object, and the size of the object. If the object
    426 // does not exist, return nil, nil, 0.
    427 func findObject(v unsafe.Pointer) (s *mspan, x unsafe.Pointer, n uintptr) {
    428 	c := gomcache()
    429 	c.local_nlookup++
    430 	if sys.PtrSize == 4 && c.local_nlookup >= 1<<30 {
    431 		// purge cache stats to prevent overflow
    432 		lock(&mheap_.lock)
    433 		purgecachedstats(c)
    434 		unlock(&mheap_.lock)
    435 	}
    436 
    437 	// find span
    438 	arena_start := mheap_.arena_start
    439 	arena_used := mheap_.arena_used
    440 	if uintptr(v) < arena_start || uintptr(v) >= arena_used {
    441 		return
    442 	}
    443 	p := uintptr(v) >> pageShift
    444 	q := p - arena_start>>pageShift
    445 	s = mheap_.spans[q]
    446 	if s == nil {
    447 		return
    448 	}
    449 	x = unsafe.Pointer(s.base())
    450 
    451 	if uintptr(v) < uintptr(x) || uintptr(v) >= uintptr(unsafe.Pointer(s.limit)) || s.state != mSpanInUse {
    452 		s = nil
    453 		x = nil
    454 		return
    455 	}
    456 
    457 	n = s.elemsize
    458 	if s.spanclass.sizeclass() != 0 {
    459 		x = add(x, (uintptr(v)-uintptr(x))/n*n)
    460 	}
    461 	return
    462 }
    463 
    464 // Mark KeepAlive as noinline so that it is easily detectable as an intrinsic.
    465 //go:noinline
    466 
    467 // KeepAlive marks its argument as currently reachable.
    468 // This ensures that the object is not freed, and its finalizer is not run,
    469 // before the point in the program where KeepAlive is called.
    470 //
    471 // A very simplified example showing where KeepAlive is required:
    472 // 	type File struct { d int }
    473 // 	d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0)
    474 // 	// ... do something if err != nil ...
    475 // 	p := &File{d}
    476 // 	runtime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) })
    477 // 	var buf [10]byte
    478 // 	n, err := syscall.Read(p.d, buf[:])
    479 // 	// Ensure p is not finalized until Read returns.
    480 // 	runtime.KeepAlive(p)
    481 // 	// No more uses of p after this point.
    482 //
    483 // Without the KeepAlive call, the finalizer could run at the start of
    484 // syscall.Read, closing the file descriptor before syscall.Read makes
    485 // the actual system call.
    486 func KeepAlive(x interface{}) {
    487 	// Introduce a use of x that the compiler can't eliminate.
    488 	// This makes sure x is alive on entry. We need x to be alive
    489 	// on entry for "defer runtime.KeepAlive(x)"; see issue 21402.
    490 	if cgoAlwaysFalse {
    491 		println(x)
    492 	}
    493 }
    494