...

Source file src/runtime/mfinal.go

     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, waitReasonFinalizerWait, 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 is scheduled to run at some arbitrary time after the
   271	// program can no longer reach the object to which obj points.
   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(uintptr(e.data), 0, 0)
   330	
   331		if base == 0 {
   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 uintptr(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.ptrdata != 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	// Mark KeepAlive as noinline so that it is easily detectable as an intrinsic.
   425	//go:noinline
   426	
   427	// KeepAlive marks its argument as currently reachable.
   428	// This ensures that the object is not freed, and its finalizer is not run,
   429	// before the point in the program where KeepAlive is called.
   430	//
   431	// A very simplified example showing where KeepAlive is required:
   432	// 	type File struct { d int }
   433	// 	d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0)
   434	// 	// ... do something if err != nil ...
   435	// 	p := &File{d}
   436	// 	runtime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) })
   437	// 	var buf [10]byte
   438	// 	n, err := syscall.Read(p.d, buf[:])
   439	// 	// Ensure p is not finalized until Read returns.
   440	// 	runtime.KeepAlive(p)
   441	// 	// No more uses of p after this point.
   442	//
   443	// Without the KeepAlive call, the finalizer could run at the start of
   444	// syscall.Read, closing the file descriptor before syscall.Read makes
   445	// the actual system call.
   446	func KeepAlive(x interface{}) {
   447		// Introduce a use of x that the compiler can't eliminate.
   448		// This makes sure x is alive on entry. We need x to be alive
   449		// on entry for "defer runtime.KeepAlive(x)"; see issue 21402.
   450		if cgoAlwaysFalse {
   451			println(x)
   452		}
   453	}
   454	

View as plain text