jitcraft/Heap.h
changeset 49 a92afa7484fd
parent 28 a9665857cfd5
child 51 fb324242a675
     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  }