// obj is the start of an object with mark mbits.
// If it isn't already marked, mark it and enqueue into workbuf.
// Return possibly new workbuf to use.
+// base and off are for debugging only and could be removed.
//go:nowritebarrier
-func greyobject(obj uintptr, mbits *markbits, wbuf *workbuf) *workbuf {
+func greyobject(obj uintptr, base, off uintptr, mbits *markbits, wbuf *workbuf) *workbuf {
// obj should be start of allocation, and so must be at least pointer-aligned.
if obj&(ptrSize-1) != 0 {
throw("greyobject: obj not pointer-aligned")
if checkmark {
if !ismarked(mbits) {
print("runtime:greyobject: checkmarks finds unexpected unmarked object obj=", hex(obj), ", mbits->bits=", hex(mbits.bits), " *mbits->bitp=", hex(*mbits.bitp), "\n")
+ print("runtime: found obj at *(", hex(base), "+", hex(off), ")\n")
k := obj >> _PageShift
x := k
if obj == 0 {
continue
}
- wbuf = greyobject(obj, &mbits, wbuf)
+ wbuf = greyobject(obj, b, i, &mbits, wbuf)
}
return wbuf
}
keepworking := b == 0
+ if gcphase != _GCmark && gcphase != _GCmarktermination {
+ println("gcphase", gcphase)
+ throw("scanblock phase")
+ }
+
// ptrmask can have 2 possible values:
// 1. nil - obtain pointer mask from GC bitmap.
// 2. pointer to a compact mask (for stacks and data).
var mbits markbits
obj := objectstart(b, &mbits)
if obj != 0 {
- wbuf = greyobject(obj, &mbits, wbuf) // augments the wbuf
+ wbuf = greyobject(obj, 0, 0, &mbits, wbuf) // augments the wbuf
}
putpartial(wbuf)
}
checkmark = true
clearcheckmarkbits() // Converts BitsDead to BitsScalar.
- gc_m(startTime, eagersweep) // turns off checkmark
- // Work done, fixed up the GC bitmap to remove the checkmark bits.
- clearcheckmarkbits()
+ gc_m(startTime, eagersweep) // turns off checkmark + calls clearcheckmarkbits
}
//go:nowritebarrier
// by placing it onto a scanenqueue state and then calling
// runtimeĀ·restartg(mastergp) to make it Grunnable.
// At the bottom we will want to return this p back to the scheduler.
- oldphase := gcphase
// Prepare flag indicating that the scan has not been completed.
lock(&allglock)
work.nwait = 0
work.ndone = 0
work.nproc = 1 // For now do not do this in parallel.
- gcphase = _GCscan
// ackgcphase is not needed since we are not scanning running goroutines.
parforsetup(work.markfor, work.nproc, uint32(_RootCount+local_allglen), nil, false, markroot)
parfordo(work.markfor)
}
unlock(&allglock)
- gcphase = oldphase
casgstatus(mastergp, _Gwaiting, _Grunning)
// Let the g that called us continue to run.
}
return
}
checkmark = false // done checking marks
+ clearcheckmarkbits()
}
// Cache the current array for sweeping.