1.1 --- a/jitcraft/Heap.h Wed Jul 04 19:54:53 2012 -0400
1.2 +++ b/jitcraft/Heap.h Fri Jul 06 09:45:21 2012 -0400
1.3 @@ -1,4 +1,5 @@
1.4 -/*
1.5 +/* vim: set ts=4 sw=4 tw=99 et:
1.6 + *
1.7 * Copyright (C) 2012 David Anderson
1.8 *
1.9 * This file is part of JITCraft.
1.10 @@ -28,13 +29,67 @@
1.11
1.12 class Zone;
1.13
1.14 -// Heap-allocated objects go here. Heaps are thread-local.
1.15 +// Heap-allocated objects go here. Heaps are thread-local. The heap contains
1.16 +// four spaces:
1.17 +//
1.18 +// LIFO Space: Used for objects that may be stack-allocated.
1.19 +// New Space: Used for objects that are expected to be short-lived.
1.20 +// Old Space: Used for objects that are expected to be long-lived, or that
1.21 +// survive one collection.
1.22 +// Large Space: Used for objects that are so large they should never be
1.23 +// moved between spaces.
1.24 +//
1.25 +// The garbage collector is both incremental and generational. Marking is
1.26 +// performed incrementally, interleaved with program execution. Minor
1.27 +// collections are also performed to mitigate the potential necessity of
1.28 +// major collections.
1.29 +//
1.30 +// MINOR COLLECTIONS (also called "scavenges") are usually performed when the
1.31 +// new space reaches maximum capacity. During a minor collection, all live
1.32 +// objects in the new space are moved into the old space. Then, the new space
1.33 +// is reset such that it is empty.
1.34 +//
1.35 +// The new is split into contiguous halves. When both halves reach maximum
1.36 +// capacity, a scavenge is performed on the older half. Thus, allocation is
1.37 +// only ever performed in one half at a time, to give newer objects a chance
1.38 +// to die.
1.39 +//
1.40 +// Scavenges are beneficial for two major reasons:
1.41 +// (1) Allocation from the new space is just a pointer bump.
1.42 +// (2) Only the root set and remembered sets need to visited.
1.43 +//
1.44 +// The "remembered set" is a list of all pointers that reach into the new
1.45 +// space, but come from the Old or Large spaces. The remembered set is
1.46 +// maintained via write barriers, and if it becomes full, entire chunks
1.47 +// are marked as requiring traversal.
1.48 +//
1.49 +// The root and remembered sets must be visited twice: once to determine
1.50 +// which objects in the new space are live, and again to update any
1.51 +// references after the new space has been reclaimed.
1.52 +//
1.53 +// Live objects in the LIFO space are always deeply traversed for pointers
1.54 +// into the new space, since it would be too difficult to maintain a working
1.55 +// remembered set.
1.56 +//
1.57 +// MAJOR COLLECTIONS are performed periodically, when either a given memory
1.58 +// threshold has been reached, or when requested by the host application.
1.59 +// They are also performed if no memory can be allocated.
1.60 +//
1.61 +// Major collections are extremely slow; they require full heap traversal,
1.62 +// which can take more than a second on very large heaps. However, they
1.63 +// have the greatest chance at reclaiming all syntactically dead objects.
1.64 +//
1.65 +// SWEEPING is performed after major collections. The free space in between
1.66 +// live objects is added to a free list. Tenured allocations are then
1.67 +// performed in the free space, if possible.
1.68 +//
1.69 class Heap
1.70 {
1.71 Zone *zone_;
1.72 HeapStack lifoSpace_;
1.73 OldSpace mapSpace_;
1.74 OldSpace oldSpace_;
1.75 + LargeObjectSpace largeSpace_;
1.76
1.77 Map *metaMap_;
1.78
1.79 @@ -54,7 +109,8 @@
1.80 };
1.81
1.82 private:
1.83 - Address newOldObject(size_t bytes);
1.84 + inline Address newLargeObject(size_t bytes);
1.85 + inline Address newOldObject(size_t bytes);
1.86 inline Address newStackObject(size_t bytes);
1.87 inline Address newObject(size_t bytes, Tenure pretenure);
1.88
1.89 @@ -74,6 +130,9 @@
1.90 inline void unwindLifo(Address to) {
1.91 lifoSpace_.unwind(to);
1.92 }
1.93 +
1.94 + // Perform a full garbage collection.
1.95 + void reclaim();
1.96 };
1.97
1.98 }