1 // Copyright 2012 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.
9 // Called from C. Returns the Go type *m.
10 func gc_m_ptr(ret *interface{}) {
14 // Called from C. Returns the Go type *g.
15 func gc_g_ptr(ret *interface{}) {
19 // Called from C. Returns the Go type *itab.
20 func gc_itab_ptr(ret *interface{}) {
24 func gc_unixnanotime(now *int64) {
25 sec, nsec := timenow()
26 *now = sec*1e9 + int64(nsec)
30 gogc(2) // force GC and do eager sweep
31 systemstack(scavenge_m)
34 var poolcleanup func()
36 func registerPoolCleanup(f func()) {
42 if poolcleanup != nil {
46 for _, p := range &allp {
50 // clear tinyalloc pool
51 if c := p.mcache; c != nil {
57 for i := range p.deferpool {
65 getg().issystem = true
67 for gosweepone() != ^uintptr(0) {
73 // This can happen if a GC runs between
74 // gosweepone returning ^0 above
75 // and the lock being acquired.
80 goparkunlock(&gclock, "GC sweep wait")
85 _PoisonGC = 0xf969696969696969 & (1<<(8*ptrSize) - 1)
86 _PoisonStack = 0x6868686868686868 & (1<<(8*ptrSize) - 1)
89 // NOTE: Really dst *unsafe.Pointer, src unsafe.Pointer,
90 // but if we do that, Go inserts a write barrier on *dst = src.
92 func writebarrierptr(dst *uintptr, src uintptr) {
94 writebarrierptr_nostore(dst, src)
97 // Like writebarrierptr, but the store has already been applied.
100 func writebarrierptr_nostore(dst *uintptr, src uintptr) {
101 if getg() == nil { // very low-level startup
105 if src != 0 && (src < _PageSize || src == _PoisonGC || src == _PoisonStack) {
106 systemstack(func() { gothrow("bad pointer in write barrier") })
110 if mp.inwb || mp.dying > 0 {
123 func writebarrierstring(dst *[2]uintptr, src [2]uintptr) {
124 writebarrierptr(&dst[0], src[0])
129 func writebarrierslice(dst *[3]uintptr, src [3]uintptr) {
130 writebarrierptr(&dst[0], src[0])
136 func writebarrieriface(dst *[2]uintptr, src [2]uintptr) {
137 writebarrierptr(&dst[0], src[0])
138 writebarrierptr(&dst[1], src[1])
141 //go:generate go run wbfat_gen.go -- wbfat.go
143 // The above line generates multiword write barriers for
144 // all the combinations of ptr+scalar up to four words.
145 // The implementations are written to wbfat.go.
148 func writebarrierfat(typ *_type, dst, src unsafe.Pointer) {
149 mask := loadPtrMask(typ)
150 nptr := typ.size / ptrSize
151 for i := uintptr(0); i < nptr; i += 2 {
153 if (bits>>2)&_BitsMask == _BitsPointer {
154 writebarrierptr((*uintptr)(dst), *(*uintptr)(src))
156 *(*uintptr)(dst) = *(*uintptr)(src)
158 dst = add(dst, ptrSize)
159 src = add(src, ptrSize)
164 if (bits>>2)&_BitsMask == _BitsPointer {
165 writebarrierptr((*uintptr)(dst), *(*uintptr)(src))
167 *(*uintptr)(dst) = *(*uintptr)(src)
169 dst = add(dst, ptrSize)
170 src = add(src, ptrSize)
175 func writebarriercopy(typ *_type, dst, src slice) int {
183 dstp := unsafe.Pointer(dst.array)
184 srcp := unsafe.Pointer(src.array)
186 if uintptr(srcp) < uintptr(dstp) && uintptr(srcp)+uintptr(n)*typ.size > uintptr(dstp) {
187 // Overlap with src before dst.
188 // Copy backward, being careful not to move dstp/srcp
189 // out of the array they point into.
190 dstp = add(dstp, uintptr(n-1)*typ.size)
191 srcp = add(srcp, uintptr(n-1)*typ.size)
194 writebarrierfat(typ, dstp, srcp)
198 dstp = add(dstp, -typ.size)
199 srcp = add(srcp, -typ.size)
202 // Copy forward, being careful not to move dstp/srcp
203 // out of the array they point into.
206 writebarrierfat(typ, dstp, srcp)
210 dstp = add(dstp, typ.size)
211 srcp = add(srcp, typ.size)