#include <stddef.h>
#include "OSThreads.h"
+#include "SMP.h"
/* -----------------------------------------------------------------------------
* Generational GC
* ------------------------------------------------------------------------- */
typedef struct step_ {
- unsigned int no; /* step number */
- bdescr * blocks; /* blocks in this step */
- unsigned int n_blocks; /* number of blocks */
- struct step_ * to; /* destination step for live objects */
- struct generation_ * gen; /* generation this step belongs to */
- unsigned int gen_no; /* generation number (cached) */
- bdescr * large_objects; /* large objects (doubly linked) */
- unsigned int n_large_blocks; /* no. of blocks used by large objs */
- int is_compacted; /* compact this step? (old gen only) */
-
- /* During GC, if we are collecting this step, blocks and n_blocks
- * are copied into the following two fields. After GC, these blocks
- * are freed. */
- bdescr * old_blocks; /* bdescr of first from-space block */
- unsigned int n_old_blocks; /* number of blocks in from-space */
-
- /* temporary use during GC: */
- StgPtr hp; /* next free locn in to-space */
- StgPtr hpLim; /* end of current to-space block */
- bdescr * hp_bd; /* bdescr of current to-space block */
- StgPtr scavd_hp; /* ... same as above, but already */
- StgPtr scavd_hpLim; /* scavenged. */
- bdescr * scan_bd; /* block currently being scanned */
- StgPtr scan; /* scan pointer in current block */
- bdescr * new_large_objects; /* large objects collected so far */
- bdescr * scavenged_large_objects; /* live large objs after GC (d-link) */
- unsigned int n_scavenged_large_blocks;/* size of above */
- bdescr * bitmap; /* bitmap for compacting collection */
+ unsigned int no; // step number
+ int is_compacted; // compact this step? (old gen only)
+
+ struct generation_ * gen; // generation this step belongs to
+ unsigned int gen_no; // generation number (cached)
+
+ bdescr * blocks; // blocks in this step
+ unsigned int n_blocks; // number of blocks
+
+ struct step_ * to; // destination step for live objects
+
+ bdescr * large_objects; // large objects (doubly linked)
+ unsigned int n_large_blocks; // no. of blocks used by large objs
+
+ // ------------------------------------
+ // Fields below are used during GC only
+
+ // During GC, if we are collecting this step, blocks and n_blocks
+ // are copied into the following two fields. After GC, these blocks
+ // are freed.
+ bdescr * old_blocks; // bdescr of first from-space block
+ unsigned int n_old_blocks; // number of blocks in from-space
+
+ bdescr * todos; // blocks waiting to be scavenged
+ unsigned int n_todos; // count of above
+
+#if defined(THREADED_RTS)
+ SpinLock sync_todo; // lock for todos
+ SpinLock sync_large_objects; // lock for large_objects
+ // and scavenged_large_objects
+#endif
+
+ bdescr * scavenged_large_objects; // live large objs after GC (d-link)
+ unsigned int n_scavenged_large_blocks; // size (not count) of above
+
+ bdescr * bitmap; // bitmap for compacting collection
} step;
+
typedef struct generation_ {
- unsigned int no; /* generation number */
- step * steps; /* steps */
- unsigned int n_steps; /* number of steps */
- unsigned int max_blocks; /* max blocks in step 0 */
- bdescr *mut_list; /* mut objects in this gen (not G0)*/
-
- /* temporary use during GC: */
- bdescr *saved_mut_list;
-
- /* stats information */
- unsigned int collections;
- unsigned int failed_promotions;
+ unsigned int no; // generation number
+ step * steps; // steps
+ unsigned int n_steps; // number of steps
+ unsigned int max_blocks; // max blocks in step 0
+ bdescr *mut_list; // mut objects in this gen (not G0)
+
+ // stats information
+ unsigned int collections;
+ unsigned int failed_promotions;
+
+ // temporary use during GC:
+ bdescr *saved_mut_list;
} generation;
extern generation * RTS_VAR(generations);
'get_roots' is called to find all the
roots that the system knows about.
- StgClosure Called by get_roots on each root.
- MarkRoot(StgClosure *p) Returns the new location of the root.
+
-------------------------------------------------------------------------- */
extern void GarbageCollect(rtsBool force_major_gc);
#if defined(THREADED_RTS)
extern Mutex sm_mutex;
extern Mutex atomic_modify_mutvar_mutex;
+extern SpinLock recordMutableGen_sync;
#endif
#if defined(THREADED_RTS)
}
INLINE_HEADER void
+recordMutableGen_GC(StgClosure *p, generation *gen)
+{
+ ACQUIRE_SPIN_LOCK(&recordMutableGen_sync);
+ recordMutableGen(p,gen);
+ RELEASE_SPIN_LOCK(&recordMutableGen_sync);
+}
+
+INLINE_HEADER void
recordMutable(StgClosure *p)
{
bdescr *bd;
extern void threadPaused ( Capability *cap, StgTSO * );
extern StgClosure * isAlive ( StgClosure *p );
extern void markCAFs ( evac_fn evac );
+extern void GetRoots ( evac_fn evac );
/* -----------------------------------------------------------------------------
Stats 'n' DEBUG stuff