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 // gcRoot is a single GC root: a variable plus a ptrmask.
16 decl unsafe
.Pointer
// Pointer to variable.
17 size
uintptr // Size of variable.
18 ptrdata
uintptr // Length of gcdata.
19 gcdata
*uint8 // Pointer mask.
22 // gcRootList is the set of GC roots for a package.
23 // The next field is used to put this all into a linked list.
24 // count gives the real length of the array.
25 type gcRootList
struct {
31 // roots is the list of GC roots for the program.
32 // The compiler keeps this variable itself off the list.
33 var gcRoots
*gcRootList
35 // registerGCRoots is called by compiler-generated code.
36 //go:linkname registerGCRoots runtime.registerGCRoots
38 // registerGCRoots is called by init functions to register the GC
39 // roots for a package. The init functions are run sequentially at
40 // the start of the program, so no locking is needed.
41 func registerGCRoots(r
*gcRootList
) {
46 // checkPreempt is called when the preempt field in the running G is true.
47 // It preempts the goroutine if it is safe to do so.
48 // If preemptscan is true, this scans the stack for the garbage collector
52 if !gp
.preempt || gp
!= gp
.m
.curg || gp
.m
.locks
!= 0 || gp
.m
.mallocing
!= 0 || gp
.m
.preemptoff
!= "" {
56 // Synchronize with scang.
57 gp
.scanningself
= true
58 casgstatus(gp
, _Grunning
, _Gwaiting
)
60 for !castogscanstatus(gp
, _Gwaiting
, _Gscanwaiting
) {
61 // Likely to be racing with the GC as
62 // it sees a _Gwaiting and does the
63 // stack scan. If so, gcworkdone will
64 // be set and gcphasework will simply
69 gcw
:= &gp
.m
.p
.ptr().gcw
71 if gcBlackenPromptly
{
77 gp
.preemptscan
= false
79 casfrom_Gscanstatus(gp
, _Gscanwaiting
, _Gwaiting
)
80 // This clears gcscanvalid.
81 casgstatus(gp
, _Gwaiting
, _Grunning
)
82 gp
.scanningself
= false
86 // Act like goroutine called runtime.Gosched.
87 casgstatus(gp
, _Gwaiting
, _Grunning
)
88 gp
.scanningself
= false
92 // gcWriteBarrier implements a write barrier. This is implemented in
93 // assembly in the gc library, but there is no special advantage to
94 // doing so with gccgo.
97 func gcWriteBarrier(dst
*uintptr, src
uintptr) {
98 buf
:= &getg().m
.p
.ptr().wbBuf
100 np
:= next
+ 2*sys
.PtrSize
102 *(*uintptr)(unsafe
.Pointer(next
)) = src
103 *(*uintptr)(unsafe
.Pointer(next
+ sys
.PtrSize
)) = *dst