1 // Copyright 2016 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 // gccgo-specific support for GC.
10 "runtime/internal/sys"
14 // For gccgo, use go:linkname to export compiler-called functions.
16 //go:linkname gcWriteBarrier
18 // gcRoot is a single GC root: a variable plus a ptrmask.
21 decl unsafe.Pointer // Pointer to variable.
22 size uintptr // Size of variable.
23 ptrdata uintptr // Length of gcdata.
24 gcdata *uint8 // Pointer mask.
27 // gcRootList is the set of GC roots for a package.
28 // The next field is used to put this all into a linked list.
29 // count gives the real length of the array.
30 type gcRootList struct {
36 // roots is the list of GC roots for the program.
37 // The compiler keeps this variable itself off the list.
38 var gcRoots *gcRootList
40 // Slice containing pointers to all reachable gcRoot's sorted by
41 // starting address (generated at init time from 'gcRoots').
42 // The compiler also keeps this variable itself off the list.
43 // The storage backing this slice is allocated via persistentalloc(), the
44 // idea being that we don't want to treat the slice itself as a global
45 // variable, since it points to things that don't need to be scanned
47 var gcRootsIndex []*gcRoot
49 // rootradixsort performs an in-place radix sort of the 'arr' rootptr slice.
50 // Note: not a stable sort, however we expect it to be called only on slices
51 // with no duplicate entries, so this should not matter.
52 func rootradixsort(arr []*gcRoot, lo, hi int, bit uint) {
53 // Partition the array into two bins based on the values at the
54 // specified bit position: 0's bin (grown from the left) and and
55 // 1's bin (grown from the right). We keep two boundary markers,
56 // the 0's boundary "zbb" (which grows to the right) and the 1's
57 // boundary "obb" (which grows to the left). At each step we
58 // examine the bit for the right-of-ZBB element: if it is zero, we
59 // leave it in place and move the ZBB to the right. If the bit is
60 // not zero, then we swap the ZBB and OBB elements and move the
61 // OBB to the left. When this is done, the two partitions are then
62 // sorted using the next lower bit.
64 // 0's bin boundary, initially set to before the first element
66 // 1's bin boundary, set to just beyond the last element
68 // mask to pick up bit of interest
69 bmask := uintptr(1) << bit
72 zbbval := uintptr(arr[zbb+1].decl) & bmask
74 // Move zbb one to the right
77 // Move obb one to the left and swap
78 arr[obb-1], arr[zbb+1] = arr[zbb+1], arr[obb-1]
84 // NB: in most cases there is just a single partition to visit
85 // so if we wanted to reduce stack space we could check for this
86 // and insert a goto back up to the top.
88 rootradixsort(arr, lo, zbb, bit-1)
91 rootradixsort(arr, obb, hi, bit-1)
97 func createGcRootsIndex() {
106 // Construct the gcRootsIndex slice. Use non-heap storage for the array
107 // backing the slice.
108 sp := (*notInHeapSlice)(unsafe.Pointer(&gcRootsIndex))
109 sp.array = (*notInHeap)(persistentalloc1(sys.PtrSize*uintptr(nroots), sys.PtrSize, &memstats.other_sys))
111 throw("runtime: cannot allocate memory")
116 // Populate the roots index slice
120 for i := 0; i < gcr.count; i++ {
121 gcRootsIndex[k] = &gcr.roots[i]
127 // Sort it by starting address.
128 rootradixsort(gcRootsIndex, 0, nroots-1, sys.PtrSize*8-1)
131 // registerGCRoots is called by compiler-generated code.
132 //go:linkname registerGCRoots
134 // registerGCRoots is called by init functions to register the GC
135 // roots for a package. The init functions are run sequentially at
136 // the start of the program, so no locking is needed.
137 func registerGCRoots(r *gcRootList) {
142 // checkPreempt is called when the preempt field in the running G is true.
143 // It preempts the goroutine if it is safe to do so.
144 // If preemptscan is true, this scans the stack for the garbage collector
146 func checkPreempt() {
148 if !gp.preempt || gp != gp.m.curg || !canPreemptM(gp.m) {
156 // Act like goroutine called runtime.Gosched.
160 // gcWriteBarrier implements a write barrier. This is implemented in
161 // assembly in the gc library, but there is no special advantage to
162 // doing so with gccgo.
165 func gcWriteBarrier(dst *uintptr, src uintptr) {
166 buf := &getg().m.p.ptr().wbBuf
167 if !buf.putFast(src, *dst) {