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.
11 // gcRoot is a single GC root: a variable plus a ptrmask.
13 decl unsafe
.Pointer
// Pointer to variable.
14 size
uintptr // Size of variable.
15 ptrdata
uintptr // Length of gcdata.
16 gcdata
*uint8 // Pointer mask.
19 // gcRootList is the set of GC roots for a package.
20 // The next field is used to put this all into a linked list.
21 // count gives the real length of the array.
22 type gcRootList
struct {
28 // roots is the list of GC roots for the program.
29 // The compiler keeps this variable itself off the list.
30 var gcRoots
*gcRootList
32 // registerGCRoots is called by compiler-generated code.
33 //go:linkname registerGCRoots runtime.registerGCRoots
35 // registerGCRoots is called by init functions to register the GC
36 // roots for a package. The init functions are run sequentially at
37 // the start of the program, so no locking is needed.
38 func registerGCRoots(r
*gcRootList
) {
43 // checkPreempt is called when the preempt field in the running G is true.
44 // It preempts the goroutine if it is safe to do so.
45 // If preemptscan is true, this scans the stack for the garbage collector
49 if !gp
.preempt || gp
!= gp
.m
.curg || gp
.m
.locks
!= 0 || gp
.m
.mallocing
!= 0 || gp
.m
.preemptoff
!= "" {
53 // Synchronize with scang.
54 gp
.scanningself
= true
55 casgstatus(gp
, _Grunning
, _Gwaiting
)
57 for !castogscanstatus(gp
, _Gwaiting
, _Gscanwaiting
) {
58 // Likely to be racing with the GC as
59 // it sees a _Gwaiting and does the
60 // stack scan. If so, gcworkdone will
61 // be set and gcphasework will simply
66 gcw
:= &gp
.m
.p
.ptr().gcw
68 if gcBlackenPromptly
{
74 gp
.preemptscan
= false
76 casfrom_Gscanstatus(gp
, _Gscanwaiting
, _Gwaiting
)
77 // This clears gcscanvalid.
78 casgstatus(gp
, _Gwaiting
, _Grunning
)
79 gp
.scanningself
= false
83 // Act like goroutine called runtime.Gosched.
84 casgstatus(gp
, _Gwaiting
, _Grunning
)
85 gp
.scanningself
= false