[ARM] Fix typo in comment in arm_expand_prologue
[official-gcc.git] / libgo / go / runtime / mgc_gccgo.go
blobc1fa1547adc76a09766a0fabea124dbe04055301
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.
7 package runtime
9 import "unsafe"
11 // gcRoot is a single GC root: a variable plus a ptrmask.
12 type gcRoot struct {
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 {
23 next *gcRootList
24 count int
25 roots [1 << 26]gcRoot
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) {
39 r.next = gcRoots
40 gcRoots = r
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
46 // and carries on.
47 func checkPreempt() {
48 gp := getg()
49 if !gp.preempt || gp != gp.m.curg || gp.m.locks != 0 || gp.m.mallocing != 0 || gp.m.preemptoff != "" {
50 return
53 // Synchronize with scang.
54 gp.scanningself = true
55 casgstatus(gp, _Grunning, _Gwaiting)
56 if gp.preemptscan {
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
62 // return.
64 if !gp.gcscandone {
65 mp := acquirem()
66 gcw := &gp.m.p.ptr().gcw
67 scanstack(gp, gcw)
68 if gcBlackenPromptly {
69 gcw.dispose()
71 releasem(mp)
72 gp.gcscandone = true
74 gp.preemptscan = false
75 gp.preempt = false
76 casfrom_Gscanstatus(gp, _Gscanwaiting, _Gwaiting)
77 // This clears gcscanvalid.
78 casgstatus(gp, _Gwaiting, _Grunning)
79 gp.scanningself = false
80 return
83 // Act like goroutine called runtime.Gosched.
84 casgstatus(gp, _Gwaiting, _Grunning)
85 gp.scanningself = false
86 mcall(gopreempt_m)