|
@ -297,32 +297,36 @@ func GC() { |
|
|
markStack() |
|
|
markStack() |
|
|
markGlobals() |
|
|
markGlobals() |
|
|
|
|
|
|
|
|
// Channel operations in interrupts may move task pointers around while we are marking.
|
|
|
if baremetal && hasScheduler { |
|
|
// Therefore we need to scan the runqueue seperately.
|
|
|
// Channel operations in interrupts may move task pointers around while we are marking.
|
|
|
var markedTaskQueue task.Queue |
|
|
// Therefore we need to scan the runqueue seperately.
|
|
|
runqueueScan: |
|
|
var markedTaskQueue task.Queue |
|
|
for !runqueue.Empty() { |
|
|
runqueueScan: |
|
|
// Pop the next task off of the runqueue.
|
|
|
for !runqueue.Empty() { |
|
|
t := runqueue.Pop() |
|
|
// Pop the next task off of the runqueue.
|
|
|
|
|
|
t := runqueue.Pop() |
|
|
// Mark the task if it has not already been marked.
|
|
|
|
|
|
markRoot(uintptr(unsafe.Pointer(&runqueue)), uintptr(unsafe.Pointer(t))) |
|
|
// Mark the task if it has not already been marked.
|
|
|
|
|
|
markRoot(uintptr(unsafe.Pointer(&runqueue)), uintptr(unsafe.Pointer(t))) |
|
|
// Push the task onto our temporary queue.
|
|
|
|
|
|
markedTaskQueue.Push(t) |
|
|
// Push the task onto our temporary queue.
|
|
|
} |
|
|
markedTaskQueue.Push(t) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
finishMark() |
|
|
finishMark() |
|
|
|
|
|
|
|
|
// Restore the runqueue.
|
|
|
// Restore the runqueue.
|
|
|
i := interrupt.Disable() |
|
|
i := interrupt.Disable() |
|
|
if !runqueue.Empty() { |
|
|
if !runqueue.Empty() { |
|
|
// Something new came in while finishing the mark.
|
|
|
// Something new came in while finishing the mark.
|
|
|
|
|
|
interrupt.Restore(i) |
|
|
|
|
|
goto runqueueScan |
|
|
|
|
|
} |
|
|
|
|
|
runqueue = markedTaskQueue |
|
|
interrupt.Restore(i) |
|
|
interrupt.Restore(i) |
|
|
goto runqueueScan |
|
|
} else { |
|
|
|
|
|
finishMark() |
|
|
} |
|
|
} |
|
|
runqueue = markedTaskQueue |
|
|
|
|
|
interrupt.Restore(i) |
|
|
|
|
|
|
|
|
|
|
|
// Sweep phase: free all non-marked objects and unmark marked objects for
|
|
|
// Sweep phase: free all non-marked objects and unmark marked objects for
|
|
|
// the next collection cycle.
|
|
|
// the next collection cycle.
|
|
|