Confirmed users
329
edits
(Created page with "All garbage collection requires a way to find the set of objects that are currently reachable. This requires knowing about all pointers into the JS heap ("roots"), as well as ...") |
(minor fixups) |
||
| Line 22: | Line 22: | ||
beginning of an incremental collection, all roots (external pointers) into the | beginning of an incremental collection, all roots (external pointers) into the | ||
heap are recorded, then the main program is allowed to continue running but is | heap are recorded, then the main program is allowed to continue running but is | ||
interrupted periodically so the incremental collector can gradually | interrupted periodically so the incremental collector can gradually trace the | ||
whole heap graph. Because the graph can change during this sweep, any | whole heap graph. Because the graph can change during this sweep, any | ||
intra-heap reference that is deleted must be marked (treated as live): such | intra-heap reference that is deleted must be marked (treated as live): such | ||
references usually | references usually are either dead or reachable from somewhere else, but it's also possible that the main program | ||
moved a reference from a part of the heap that has not yet been scanned to a | moved a reference from a part of the heap that has not yet been scanned to a | ||
part that has already been scanned, and so it will not get marked during the | part that has already been scanned, and so it will not get marked during the | ||
rest of the incremental collection. This adds a required capability (3): a | rest of the incremental collection. This adds a required capability (3): a | ||
record of all pointers within the heap that were deleted while incremental GC | record of all pointers within the heap that were deleted while incremental GC | ||
was active. | was active. Note that this is actually accomplished by putting them on the same mark stack as is used to record the current state of the incremental GC. | ||
Capability #1 means that we need to be able to find and update all pointers | Capability #1 means that we need to be able to find and update all pointers | ||
from outside the JS heap into the JS heap. (Intra-heap pointers can be found | from outside the JS heap into the JS heap. (Intra-heap pointers can be found | ||
and updated by scanning, so they don't need any special handling.) | and updated by scanning, so they don't need any special handling.) The embedding uses APIs to register certain data structures as part of the root set, as well as callbacks to record other root pointers during the GC. For pointers on the stack, we use the Stack Rooting API; see js/public/RootingAPI.h. | ||
Capabilities #2 and #3 mean that we need "write barriers" for all JS heap | Capabilities #2 and #3 mean that we need "write barriers" for all JS heap | ||
pointers stored within the C++ heap, which is a fancy way of saying that if you | pointers stored within the C++ heap, which is a fancy way of saying that if you | ||
modify a pointer into the heap, you may need to do | modify a pointer into the heap, you may need to do something before and/or after | ||
the write to update bookkeeping information. Capability #2 requires a | the write to update bookkeeping information. Capability #2 requires a | ||
"post-barrier", an action taken after the write occurs, to store a record of | "post-barrier", an action taken after the write occurs (or at least, using the written value), to store a record of | ||
any new pointer value that points (or might point) into the nursery. Capability #3 | |||
requires a "pre-barrier", an action taken before the write occurs, so it can | requires a "pre-barrier", an action taken before the write occurs, so it can | ||
mark the overwritten value as live (before it is | mark the overwritten value as live (before it is lost from the | ||
graph). | graph). | ||
| Line 62: | Line 61: | ||
Pointers from the C++ heap to the JS heap must be findable and updatable, and | Pointers from the C++ heap to the JS heap must be findable and updatable, and | ||
writes must be barriered | writes must be barriered. Pointers from the C++ heap to the C++ heap don't matter to the GC. Pointers | ||
from the C++ heap to the stack are kind of funky but don't matter to the GC. | |||
from the C++ heap to the stack are kind of funky but don't matter. | |||
Pointers from the tenured area to anywhere in the JS heap are automatically | Pointers from the tenured area to anywhere in the JS heap are automatically | ||
| Line 74: | Line 72: | ||
Pointers from the nursery are the same as those from tenured, except it doesn't | Pointers from the nursery are the same as those from tenured, except it doesn't | ||
matter for GGC if a nursery pointer points to the nursery vs tenured. So the | matter for GGC if a nursery pointer points to the nursery vs tenured. So the | ||
post barrier is not needed. The pre barrier is not needed because incremental GC does a nursery collection before each slice. | |||
needed | |||