summaryrefslogtreecommitdiff
path: root/rts/sm
diff options
context:
space:
mode:
Diffstat (limited to 'rts/sm')
-rw-r--r--rts/sm/BlockAlloc.c44
-rw-r--r--rts/sm/Compact.c12
-rw-r--r--rts/sm/Compact.h6
-rw-r--r--rts/sm/Evac.c6
-rw-r--r--rts/sm/Evac.h6
-rw-r--r--rts/sm/GC.c24
-rw-r--r--rts/sm/GC.h16
-rw-r--r--rts/sm/GCAux.c5
-rw-r--r--rts/sm/GCThread.h7
-rw-r--r--rts/sm/GCUtils.c5
-rw-r--r--rts/sm/GCUtils.h7
-rw-r--r--rts/sm/MBlock.c5
-rw-r--r--rts/sm/MBlock.h208
-rw-r--r--rts/sm/MarkWeak.c4
-rw-r--r--rts/sm/MarkWeak.h5
-rw-r--r--rts/sm/OSMem.h5
-rw-r--r--rts/sm/README11
-rw-r--r--rts/sm/Scav.c5
-rw-r--r--rts/sm/Scav.h6
-rw-r--r--rts/sm/Storage.c11
-rw-r--r--rts/sm/Storage.h169
-rw-r--r--rts/sm/Sweep.c4
-rw-r--r--rts/sm/Sweep.h7
23 files changed, 287 insertions, 291 deletions
diff --git a/rts/sm/BlockAlloc.c b/rts/sm/BlockAlloc.c
index 280ebfc7db..bf7a55e7a9 100644
--- a/rts/sm/BlockAlloc.c
+++ b/rts/sm/BlockAlloc.c
@@ -17,11 +17,10 @@
#include "PosixSource.h"
#include "Rts.h"
-#include "RtsFlags.h"
+
+#include "Storage.h"
#include "RtsUtils.h"
#include "BlockAlloc.h"
-#include "MBlock.h"
-#include "Storage.h"
#include <string.h>
@@ -284,7 +283,7 @@ alloc_mega_group (nat mblocks)
{
// we take our chunk off the end here.
nat best_mblocks = BLOCKS_TO_MBLOCKS(best->blocks);
- bd = FIRST_BDESCR(MBLOCK_ROUND_DOWN(best) +
+ bd = FIRST_BDESCR((StgWord8*)MBLOCK_ROUND_DOWN(best) +
(best_mblocks-mblocks)*MBLOCK_SIZE);
best->blocks = MBLOCK_GROUP_BLOCKS(best_mblocks - mblocks);
@@ -415,7 +414,8 @@ coalesce_mblocks (bdescr *p)
q = p->link;
if (q != NULL &&
MBLOCK_ROUND_DOWN(q) ==
- MBLOCK_ROUND_DOWN(p) + BLOCKS_TO_MBLOCKS(p->blocks) * MBLOCK_SIZE) {
+ (StgWord8*)MBLOCK_ROUND_DOWN(p) +
+ BLOCKS_TO_MBLOCKS(p->blocks) * MBLOCK_SIZE) {
// can coalesce
p->blocks = MBLOCK_GROUP_BLOCKS(BLOCKS_TO_MBLOCKS(p->blocks) +
BLOCKS_TO_MBLOCKS(q->blocks));
@@ -610,20 +610,21 @@ splitBlockGroup (bdescr *bd, nat blocks)
static void
initMBlock(void *mblock)
{
- bdescr *bd;
- void *block;
-
- /* the first few Bdescr's in a block are unused, so we don't want to
- * put them all on the free list.
- */
- block = FIRST_BLOCK(mblock);
- bd = FIRST_BDESCR(mblock);
-
- /* Initialise the start field of each block descriptor
- */
- for (; block <= LAST_BLOCK(mblock); bd += 1, block += BLOCK_SIZE) {
- bd->start = block;
- }
+ bdescr *bd;
+ StgWord8 *block;
+
+ /* the first few Bdescr's in a block are unused, so we don't want to
+ * put them all on the free list.
+ */
+ block = FIRST_BLOCK(mblock);
+ bd = FIRST_BDESCR(mblock);
+
+ /* Initialise the start field of each block descriptor
+ */
+ for (; block <= (StgWord8*)LAST_BLOCK(mblock); bd += 1,
+ block += BLOCK_SIZE) {
+ bd->start = (void*)block;
+ }
}
/* -----------------------------------------------------------------------------
@@ -708,7 +709,7 @@ checkFreeListSanity(void)
if (bd->link != NULL)
{
ASSERT (MBLOCK_ROUND_DOWN(bd->link) !=
- MBLOCK_ROUND_DOWN(bd) +
+ (StgWord8*)MBLOCK_ROUND_DOWN(bd) +
BLOCKS_TO_MBLOCKS(bd->blocks) * MBLOCK_SIZE);
}
}
@@ -758,7 +759,8 @@ reportUnmarkedBlocks (void)
debugBelch(" %p\n",bd);
}
if (bd->blocks >= BLOCKS_PER_MBLOCK) {
- mblock += (BLOCKS_TO_MBLOCKS(bd->blocks) - 1) * MBLOCK_SIZE;
+ mblock = (StgWord8*)mblock +
+ (BLOCKS_TO_MBLOCKS(bd->blocks) - 1) * MBLOCK_SIZE;
break;
} else {
bd += bd->blocks;
diff --git a/rts/sm/Compact.c b/rts/sm/Compact.c
index 9c13253c32..892364dfa5 100644
--- a/rts/sm/Compact.c
+++ b/rts/sm/Compact.c
@@ -13,16 +13,18 @@
#include "PosixSource.h"
#include "Rts.h"
+
+#include "Storage.h"
#include "RtsUtils.h"
-#include "RtsFlags.h"
-#include "OSThreads.h"
#include "BlockAlloc.h"
-#include "MBlock.h"
#include "GC.h"
#include "Compact.h"
#include "Schedule.h"
#include "Apply.h"
#include "Trace.h"
+#include "Weak.h"
+#include "MarkWeak.h"
+#include "Stable.h"
// Turn off inlining when debugging - it obfuscates things
#ifdef DEBUG
@@ -166,7 +168,7 @@ loop:
case 1:
{
StgWord r = *(StgPtr)(q-1);
- ASSERT(LOOKS_LIKE_INFO_PTR(UNTAG_CLOSURE((StgClosure *)r)));
+ ASSERT(LOOKS_LIKE_INFO_PTR((StgWord)UNTAG_CLOSURE((StgClosure *)r)));
return r;
}
case 2:
@@ -929,7 +931,7 @@ update_bkwd_compact( step *stp )
iptr = get_threaded_info(p);
unthread(p, (StgWord)free + GET_CLOSURE_TAG((StgClosure *)iptr));
- ASSERT(LOOKS_LIKE_INFO_PTR(((StgClosure *)p)->header.info));
+ ASSERT(LOOKS_LIKE_INFO_PTR((StgWord)((StgClosure *)p)->header.info));
info = get_itbl((StgClosure *)p);
size = closure_sizeW_((StgClosure *)p,info);
diff --git a/rts/sm/Compact.h b/rts/sm/Compact.h
index 40622c5682..7a237ac362 100644
--- a/rts/sm/Compact.h
+++ b/rts/sm/Compact.h
@@ -11,8 +11,8 @@
*
* ---------------------------------------------------------------------------*/
-#ifndef GCCOMPACT_H
-#define GCCOMPACT_H
+#ifndef SM_COMPACT_H
+#define SM_COMPACT_H
INLINE_HEADER rtsBool
mark_stack_empty(void)
@@ -76,4 +76,4 @@ is_marked(StgPtr p, bdescr *bd)
extern void compact (StgClosure *static_objects);
-#endif /* GCCOMPACT_H */
+#endif /* SM_COMPACT_H */
diff --git a/rts/sm/Evac.c b/rts/sm/Evac.c
index 5935f9069e..9e6d0f1783 100644
--- a/rts/sm/Evac.c
+++ b/rts/sm/Evac.c
@@ -11,16 +11,16 @@
*
* ---------------------------------------------------------------------------*/
+#include "PosixSource.h"
#include "Rts.h"
-#include "Storage.h"
-#include "MBlock.h"
+
#include "Evac.h"
+#include "Storage.h"
#include "GC.h"
#include "GCThread.h"
#include "GCUtils.h"
#include "Compact.h"
#include "Prelude.h"
-#include "LdvProfile.h"
#include "Trace.h"
#if defined(PROF_SPIN) && defined(THREADED_RTS) && defined(PARALLEL_GC)
diff --git a/rts/sm/Evac.h b/rts/sm/Evac.h
index e6ef02cfcc..78d024f3e9 100644
--- a/rts/sm/Evac.h
+++ b/rts/sm/Evac.h
@@ -11,6 +11,9 @@
*
* ---------------------------------------------------------------------------*/
+#ifndef SM_EVAC_H
+#define SM_EVAC_H
+
// Use a register argument for evacuate, if available.
// Earlier, the regparm attribute was used whenever __GNUC__ >= 2, but this
// generated warnings on PPC. So the use is restricted further.
@@ -31,3 +34,6 @@ REGPARM1 void evacuate (StgClosure **p);
REGPARM1 void evacuate1 (StgClosure **p);
extern lnat thunk_selector_depth;
+
+#endif /* SM_EVAC_H */
+
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index 88b11aae88..02fd6d9161 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -11,28 +11,23 @@
*
* ---------------------------------------------------------------------------*/
-// #include "PosixSource.h"
+#include "PosixSource.h"
#include "Rts.h"
-#include "RtsFlags.h"
+#include "HsFFI.h"
+
+#include "Storage.h"
#include "RtsUtils.h"
#include "Apply.h"
-#include "OSThreads.h"
-#include "LdvProfile.h"
#include "Updates.h"
#include "Stats.h"
#include "Schedule.h"
#include "Sanity.h"
#include "BlockAlloc.h"
-#include "MBlock.h"
#include "ProfHeap.h"
-#include "SchedAPI.h"
#include "Weak.h"
#include "Prelude.h"
-#include "ParTicky.h" // ToDo: move into Rts.h
#include "RtsSignals.h"
#include "STM.h"
-#include "HsFFI.h"
-#include "Linker.h"
#if defined(RTS_GTK_FRONTPANEL)
#include "FrontPanel.h"
#endif
@@ -40,6 +35,7 @@
#include "RetainerProfile.h"
#include "RaiseAsync.h"
#include "Papi.h"
+#include "Stable.h"
#include "GC.h"
#include "GCThread.h"
@@ -1112,10 +1108,11 @@ gcWorkerThread (Capability *cap)
#endif
+#if defined(THREADED_RTS)
+
void
waitForGcThreads (Capability *cap USED_IF_THREADS)
{
-#if defined(THREADED_RTS)
nat n_threads = RtsFlags.ParFlags.nNodes;
nat me = cap->no;
nat i, j;
@@ -1141,9 +1138,10 @@ waitForGcThreads (Capability *cap USED_IF_THREADS)
if (!retry) break;
}
}
-#endif
}
+#endif // THREADED_RTS
+
static void
start_gc_threads (void)
{
@@ -1185,10 +1183,10 @@ shutdown_gc_threads (nat n_threads USED_IF_THREADS, nat me USED_IF_THREADS)
#endif
}
+#if defined(THREADED_RTS)
void
releaseGCThreads (Capability *cap USED_IF_THREADS)
{
-#if defined(THREADED_RTS)
nat n_threads = RtsFlags.ParFlags.nNodes;
nat me = cap->no;
nat i;
@@ -1201,8 +1199,8 @@ releaseGCThreads (Capability *cap USED_IF_THREADS)
ACQUIRE_SPIN_LOCK(&gc_threads[i]->gc_spin);
RELEASE_SPIN_LOCK(&gc_threads[i]->mut_spin);
}
-#endif
}
+#endif
/* ----------------------------------------------------------------------------
Initialise a generation that is to be collected
diff --git a/rts/sm/GC.h b/rts/sm/GC.h
index fb4381dc0b..920b464bbb 100644
--- a/rts/sm/GC.h
+++ b/rts/sm/GC.h
@@ -11,8 +11,15 @@
*
* ---------------------------------------------------------------------------*/
-#ifndef GC_H
-#define GC_H
+#ifndef SM_GC_H
+#define SM_GC_H
+
+void GarbageCollect(rtsBool force_major_gc, nat gc_type, Capability *cap);
+
+typedef void (*evac_fn)(void *user, StgClosure **root);
+
+StgClosure * isAlive ( StgClosure *p );
+void markCAFs ( evac_fn evac, void *user );
extern nat N;
extern rtsBool major_gc;
@@ -45,9 +52,12 @@ extern StgWord64 whitehole_spin;
void gcWorkerThread (Capability *cap);
void initGcThreads (void);
void freeGcThreads (void);
+
+#if defined(THREADED_RTS)
void waitForGcThreads (Capability *cap);
void releaseGCThreads (Capability *cap);
+#endif
#define WORK_UNIT_WORDS 128
-#endif /* GC_H */
+#endif /* SM_GC_H */
diff --git a/rts/sm/GCAux.c b/rts/sm/GCAux.c
index c1ff54123d..404e9bbcbc 100644
--- a/rts/sm/GCAux.c
+++ b/rts/sm/GCAux.c
@@ -7,10 +7,11 @@
*
* ---------------------------------------------------------------------------*/
+#include "PosixSource.h"
#include "Rts.h"
-#include "Storage.h"
-#include "MBlock.h"
+
#include "GC.h"
+#include "Storage.h"
#include "Compact.h"
#include "Task.h"
#include "Capability.h"
diff --git a/rts/sm/GCThread.h b/rts/sm/GCThread.h
index f91092b7ea..9188a20a9a 100644
--- a/rts/sm/GCThread.h
+++ b/rts/sm/GCThread.h
@@ -11,10 +11,9 @@
*
* ---------------------------------------------------------------------------*/
-#ifndef GCTHREAD_H
-#define GCTHREAD_H
+#ifndef SM_GCTHREAD_H
+#define SM_GCTHREAD_H
-#include "OSThreads.h"
#include "WSDeque.h"
/* -----------------------------------------------------------------------------
@@ -271,5 +270,5 @@ extern StgWord8 the_gc_thread[];
#endif
-#endif // GCTHREAD_H
+#endif // SM_GCTHREAD_H
diff --git a/rts/sm/GCUtils.c b/rts/sm/GCUtils.c
index 57cede7d43..6c6f10e01f 100644
--- a/rts/sm/GCUtils.c
+++ b/rts/sm/GCUtils.c
@@ -11,8 +11,9 @@
*
* ---------------------------------------------------------------------------*/
+#include "PosixSource.h"
#include "Rts.h"
-#include "RtsFlags.h"
+
#include "Storage.h"
#include "GC.h"
#include "GCThread.h"
@@ -101,6 +102,7 @@ grab_local_todo_block (step_workspace *ws)
return NULL;
}
+#if defined(THREADED_RTS)
bdescr *
steal_todo_block (nat s)
{
@@ -117,6 +119,7 @@ steal_todo_block (nat s)
}
return NULL;
}
+#endif
void
push_scanned_block (bdescr *bd, step_workspace *ws)
diff --git a/rts/sm/GCUtils.h b/rts/sm/GCUtils.h
index e71f4374fb..d68ce7876f 100644
--- a/rts/sm/GCUtils.h
+++ b/rts/sm/GCUtils.h
@@ -11,7 +11,8 @@
*
* --------------------------------------------------------------------------*/
-#include "SMP.h"
+#ifndef SM_GCUTILS_H
+#define SM_GCUTILS_H
bdescr *allocBlock_sync(void);
void freeChain_sync(bdescr *bd);
@@ -21,7 +22,9 @@ StgPtr todo_block_full (nat size, step_workspace *ws);
StgPtr alloc_todo_block (step_workspace *ws, nat size);
bdescr *grab_local_todo_block (step_workspace *ws);
+#if defined(THREADED_RTS)
bdescr *steal_todo_block (nat s);
+#endif
// Returns true if a block is partially full. This predicate is used to try
// to re-use partial blocks wherever possible, and to reduce wastage.
@@ -55,3 +58,5 @@ recordMutableGen_GC (StgClosure *p, nat gen_no)
}
*bd->free++ = (StgWord)p;
}
+
+#endif /* SM_GCUTILS_H */
diff --git a/rts/sm/MBlock.c b/rts/sm/MBlock.c
index b3fa13b0bc..996b2c9ae9 100644
--- a/rts/sm/MBlock.c
+++ b/rts/sm/MBlock.c
@@ -9,10 +9,9 @@
* ---------------------------------------------------------------------------*/
#include "PosixSource.h"
-
#include "Rts.h"
+
#include "RtsUtils.h"
-#include "MBlock.h"
#include "BlockAlloc.h"
#include "Trace.h"
#include "OSMem.h"
@@ -235,7 +234,7 @@ getMBlocks(nat n)
// fill in the table
for (i = 0; i < n; i++) {
- markHeapAlloced( ret + i * MBLOCK_SIZE );
+ markHeapAlloced( (StgWord8*)ret + i * MBLOCK_SIZE );
}
mblocks_allocated += n;
diff --git a/rts/sm/MBlock.h b/rts/sm/MBlock.h
deleted file mode 100644
index f9dddc3138..0000000000
--- a/rts/sm/MBlock.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * (c) The GHC Team, 1998-2008
- *
- * MegaBlock Allocator interface.
- *
- * See wiki commentary at
- * http://hackage.haskell.org/trac/ghc/wiki/Commentary/HeapAlloced
- *
- * ---------------------------------------------------------------------------*/
-
-#ifndef MBLOCK_H
-#define MBLOCK_H
-
-#include "GC.h"
-
-extern lnat RTS_VAR(mblocks_allocated);
-
-extern void initMBlocks(void);
-extern void * getMBlock(void);
-extern void * getMBlocks(nat n);
-extern void freeAllMBlocks(void);
-
-#ifdef DEBUG
-extern void *getFirstMBlock(void);
-extern void *getNextMBlock(void *mblock);
-#endif
-
-/* -----------------------------------------------------------------------------
- The HEAP_ALLOCED() test.
-
- HEAP_ALLOCED is called FOR EVERY SINGLE CLOSURE during GC.
- It needs to be FAST.
-
- See wiki commentary at
- http://hackage.haskell.org/trac/ghc/wiki/Commentary/HeapAlloced
-
- Implementation of HEAP_ALLOCED
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Since heap is allocated in chunks of megablocks (MBLOCK_SIZE), we
- can just use a table to record which megablocks in the address
- space belong to the heap. On a 32-bit machine, with 1Mb
- megablocks, using 8 bits for each entry in the table, the table
- requires 4k. Lookups during GC will be fast, because the table
- will be quickly cached (indeed, performance measurements showed no
- measurable difference between doing the table lookup and using a
- constant comparison).
-
- On 64-bit machines, we cache one 12-bit block map that describes
- 4096 megablocks or 4GB of memory. If HEAP_ALLOCED is called for
- an address that is not in the cache, it calls slowIsHeapAlloced
- (see MBlock.c) which will find the block map for the 4GB block in
- question.
- -------------------------------------------------------------------------- */
-
-#if SIZEOF_VOID_P == 4
-extern StgWord8 mblock_map[];
-
-/* On a 32-bit machine a 4KB table is always sufficient */
-# define MBLOCK_MAP_SIZE 4096
-# define MBLOCK_MAP_ENTRY(p) ((StgWord)(p) >> MBLOCK_SHIFT)
-# define HEAP_ALLOCED(p) mblock_map[MBLOCK_MAP_ENTRY(p)]
-# define HEAP_ALLOCED_GC(p) HEAP_ALLOCED(p)
-
-/* -----------------------------------------------------------------------------
- HEAP_ALLOCED for 64-bit machines.
-
- Here are some cache layout options:
-
- [1]
- 16KB cache of 16-bit entries, 1MB lines (capacity 8GB)
- mblock size = 20 bits
- entries = 8192 13 bits
- line size = 0 bits (1 bit of value)
- tag size = 15 bits
- = 48 bits
-
- [2]
- 32KB cache of 16-bit entries, 4MB lines (capacity 32GB)
- mblock size = 20 bits
- entries = 16384 14 bits
- line size = 2 bits (4 bits of value)
- tag size = 12 bits
- = 48 bits
-
- [3]
- 16KB cache of 16-bit entries, 2MB lines (capacity 16GB)
- mblock size = 20 bits
- entries = 8192 13 bits
- line size = 1 bits (2 bits of value)
- tag size = 14 bits
- = 48 bits
-
- [4]
- 4KB cache of 32-bit entries, 16MB lines (capacity 16GB)
- mblock size = 20 bits
- entries = 1024 10 bits
- line size = 4 bits (16 bits of value)
- tag size = 14 bits
- = 48 bits
-
- [5]
- 4KB cache of 64-bit entries, 32MB lines (capacity 16GB)
- mblock size = 20 bits
- entries = 512 9 bits
- line size = 5 bits (32 bits of value)
- tag size = 14 bits
- = 48 bits
-
- We actually use none of the above. After much experimentation it was
- found that optimising the lookup is the most important factor,
- followed by reducing the number of misses. To that end, we use a
- variant of [1] in which each cache entry is ((mblock << 1) + value)
- where value is 0 for non-heap and 1 for heap. The cache entries can
- be 32 bits, since the mblock number is 48-20 = 28 bits, and we need
- 1 bit for the value. The cache can be as big as we like, but
- currently we use 8k entries, giving us 8GB capacity.
-
- ---------------------------------------------------------------------------- */
-
-#elif SIZEOF_VOID_P == 8
-
-#define MBC_LINE_BITS 0
-#define MBC_TAG_BITS 15
-typedef StgWord32 MbcCacheLine; // could use 16, but 32 was faster
-typedef StgWord8 MBlockMapLine;
-
-#define MBLOCK_MAP_LINE(p) (((StgWord)p & 0xffffffff) >> (MBLOCK_SHIFT + MBC_LINE_BITS))
-
-#define MBC_LINE_SIZE (1<<MBC_LINE_BITS)
-#define MBC_SHIFT (48 - MBLOCK_SHIFT - MBC_LINE_BITS - MBC_TAG_BITS)
-#define MBC_ENTRIES (1<<MBC_SHIFT)
-
-extern MbcCacheLine mblock_cache[];
-
-#define MBC_LINE(p) ((StgWord)p >> (MBLOCK_SHIFT + MBC_LINE_BITS))
-
-#define MBLOCK_MAP_ENTRIES (1 << (32 - MBLOCK_SHIFT - MBC_LINE_BITS))
-
-typedef struct {
- StgWord32 addrHigh32;
- MBlockMapLine lines[MBLOCK_MAP_ENTRIES];
-} MBlockMap;
-
-extern lnat mpc_misses;
-
-StgBool HEAP_ALLOCED_miss(StgWord mblock, void *p);
-
-INLINE_HEADER
-StgBool HEAP_ALLOCED(void *p)
-{
- StgWord mblock;
- nat entry_no;
- MbcCacheLine entry, value;
-
- mblock = (StgWord)p >> MBLOCK_SHIFT;
- entry_no = mblock & (MBC_ENTRIES-1);
- entry = mblock_cache[entry_no];
- value = entry ^ (mblock << 1);
- // this formulation coaxes gcc into prioritising the value==1
- // case, which we expect to be the most common.
- // __builtin_expect() didn't have any useful effect (gcc-4.3.0).
- if (value == 1) {
- return 1;
- } else if (value == 0) {
- return 0;
- } else {
- // putting the rest out of line turned out to be a slight
- // performance improvement:
- return HEAP_ALLOCED_miss(mblock,p);
- }
-}
-
-// In the parallel GC, the cache itself is safe to *read*, and can be
-// updated atomically, but we need to place a lock around operations
-// that touch the MBlock map.
-INLINE_HEADER
-StgBool HEAP_ALLOCED_GC(void *p)
-{
- StgWord mblock;
- nat entry_no;
- MbcCacheLine entry, value;
- StgBool b;
-
- mblock = (StgWord)p >> MBLOCK_SHIFT;
- entry_no = mblock & (MBC_ENTRIES-1);
- entry = mblock_cache[entry_no];
- value = entry ^ (mblock << 1);
- if (value == 1) {
- return 1;
- } else if (value == 0) {
- return 0;
- } else {
- // putting the rest out of line turned out to be a slight
- // performance improvement:
- ACQUIRE_SPIN_LOCK(&gc_alloc_block_sync);
- b = HEAP_ALLOCED_miss(mblock,p);
- RELEASE_SPIN_LOCK(&gc_alloc_block_sync);
- return b;
- }
-}
-
-#else
-# error HEAP_ALLOCED not defined
-#endif
-
-#endif /* MBLOCK_H */
diff --git a/rts/sm/MarkWeak.c b/rts/sm/MarkWeak.c
index 78c84ed77a..4f0a7a451b 100644
--- a/rts/sm/MarkWeak.c
+++ b/rts/sm/MarkWeak.c
@@ -11,14 +11,16 @@
*
* ---------------------------------------------------------------------------*/
+#include "PosixSource.h"
#include "Rts.h"
-#include "Storage.h"
+
#include "MarkWeak.h"
#include "GC.h"
#include "GCThread.h"
#include "Evac.h"
#include "Trace.h"
#include "Schedule.h"
+#include "Weak.h"
/* -----------------------------------------------------------------------------
Weak Pointers
diff --git a/rts/sm/MarkWeak.h b/rts/sm/MarkWeak.h
index 7b3a806857..2647a22eec 100644
--- a/rts/sm/MarkWeak.h
+++ b/rts/sm/MarkWeak.h
@@ -11,6 +11,9 @@
*
* ---------------------------------------------------------------------------*/
+#ifndef SM_MARKWEAK_H
+#define SM_MARKWEAK_H
+
extern StgWeak *old_weak_ptr_list;
extern StgTSO *resurrected_threads;
extern StgTSO *exception_threads;
@@ -19,3 +22,5 @@ void initWeakForGC ( void );
rtsBool traverseWeakPtrList ( void );
void markWeakPtrList ( void );
rtsBool traverseBlackholeQueue ( void );
+
+#endif /* SM_MARKWEAK_H */
diff --git a/rts/sm/OSMem.h b/rts/sm/OSMem.h
index dcf8eb73df..3dbca23d11 100644
--- a/rts/sm/OSMem.h
+++ b/rts/sm/OSMem.h
@@ -6,8 +6,13 @@
*
* ---------------------------------------------------------------------------*/
+#ifndef SM_OSMEM_H
+#define SM_OSMEM_H
+
void osMemInit(void);
void *osGetMBlocks(nat n);
void osFreeAllMBlocks(void);
lnat getPageSize (void);
void setExecutable (void *p, lnat len, rtsBool exec);
+
+#endif /* SM_OSMEM_H */
diff --git a/rts/sm/README b/rts/sm/README
deleted file mode 100644
index 61cb7d2c06..0000000000
--- a/rts/sm/README
+++ /dev/null
@@ -1,11 +0,0 @@
-The Storage Manager
-===================
-
-This directory contains the storage manager and garbage collector.
-The interfaces exported from here are:
-
- Storage.h (in ../includes)
- Block.h (in ../includes)
- GC.h
- Arena.h
- BlockAlloc.h
diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c
index b850423244..9ebd4c5597 100644
--- a/rts/sm/Scav.c
+++ b/rts/sm/Scav.c
@@ -11,10 +11,10 @@
*
* ---------------------------------------------------------------------------*/
+#include "PosixSource.h"
#include "Rts.h"
-#include "RtsFlags.h"
+
#include "Storage.h"
-#include "MBlock.h"
#include "GC.h"
#include "GCThread.h"
#include "GCUtils.h"
@@ -23,7 +23,6 @@
#include "Scav.h"
#include "Apply.h"
#include "Trace.h"
-#include "LdvProfile.h"
#include "Sanity.h"
#include "Capability.h"
diff --git a/rts/sm/Scav.h b/rts/sm/Scav.h
index df774cd63d..10b9ffde40 100644
--- a/rts/sm/Scav.h
+++ b/rts/sm/Scav.h
@@ -11,6 +11,9 @@
*
* ---------------------------------------------------------------------------*/
+#ifndef SM_SCAV_H
+#define SM_SCAV_H
+
void scavenge_loop (void);
void scavenge_mutable_list (bdescr *bd, generation *gen);
void scavenge_capability_mut_lists (Capability *cap);
@@ -20,3 +23,6 @@ void scavenge_loop1 (void);
void scavenge_mutable_list1 (bdescr *bd, generation *gen);
void scavenge_capability_mut_Lists1 (Capability *cap);
#endif
+
+#endif /* SM_SCAV_H */
+
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index d14e58856f..97615e9d1b 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -13,18 +13,15 @@
#include "PosixSource.h"
#include "Rts.h"
+
+#include "Storage.h"
#include "RtsUtils.h"
-#include "RtsFlags.h"
#include "Stats.h"
-#include "Hooks.h"
#include "BlockAlloc.h"
-#include "MBlock.h"
#include "Weak.h"
#include "Sanity.h"
#include "Arena.h"
-#include "OSThreads.h"
#include "Capability.h"
-#include "Storage.h"
#include "Schedule.h"
#include "RetainerProfile.h" // for counting memory blocks (memInventory)
#include "OSMem.h"
@@ -32,7 +29,6 @@
#include "GC.h"
#include "Evac.h"
-#include <stdlib.h>
#include <string.h>
#include "ffi.h"
@@ -71,6 +67,7 @@ step *nurseries = NULL; /* array of nurseries, >1 only if THREADED_RTS *
Mutex sm_mutex;
#endif
+static void allocNurseries ( void );
static void
initStep (step *stp, int g, int s)
@@ -440,7 +437,7 @@ assignNurseriesToCapabilities (void)
#endif
}
-void
+static void
allocNurseries( void )
{
nat i;
diff --git a/rts/sm/Storage.h b/rts/sm/Storage.h
new file mode 100644
index 0000000000..c6aa45e162
--- /dev/null
+++ b/rts/sm/Storage.h
@@ -0,0 +1,169 @@
+/* -----------------------------------------------------------------------------
+ *
+ * (c) The GHC Team, 1998-2009
+ *
+ * External Storage Manger Interface
+ *
+ * ---------------------------------------------------------------------------*/
+
+#ifndef SM_STORAGE_H
+#define SM_STORAGE_H
+
+/* -----------------------------------------------------------------------------
+ Initialisation / De-initialisation
+ -------------------------------------------------------------------------- */
+
+void initStorage(void);
+void exitStorage(void);
+void freeStorage(void);
+
+/* -----------------------------------------------------------------------------
+ Storage manager state
+ -------------------------------------------------------------------------- */
+
+extern bdescr * pinned_object_block;
+
+extern nat alloc_blocks;
+extern nat alloc_blocks_lim;
+
+INLINE_HEADER rtsBool
+doYouWantToGC( void )
+{
+ return (alloc_blocks >= alloc_blocks_lim);
+}
+
+/* for splitting blocks groups in two */
+bdescr * splitLargeBlock (bdescr *bd, nat blocks);
+
+/* -----------------------------------------------------------------------------
+ Generational garbage collection support
+
+ recordMutable(StgPtr p) Informs the garbage collector that a
+ previously immutable object has
+ become (permanently) mutable. Used
+ by thawArray and similar.
+
+ updateWithIndirection(p1,p2) Updates the object at p1 with an
+ indirection pointing to p2. This is
+ normally called for objects in an old
+ generation (>0) when they are updated.
+
+ updateWithPermIndirection(p1,p2) As above but uses a permanent indir.
+
+ -------------------------------------------------------------------------- */
+
+/*
+ * Storage manager mutex
+ */
+#if defined(THREADED_RTS)
+extern Mutex sm_mutex;
+#endif
+
+#if defined(THREADED_RTS)
+#define ACQUIRE_SM_LOCK ACQUIRE_LOCK(&sm_mutex);
+#define RELEASE_SM_LOCK RELEASE_LOCK(&sm_mutex);
+#define ASSERT_SM_LOCK() ASSERT_LOCK_HELD(&sm_mutex);
+#else
+#define ACQUIRE_SM_LOCK
+#define RELEASE_SM_LOCK
+#define ASSERT_SM_LOCK()
+#endif
+
+INLINE_HEADER void
+recordMutableGen(StgClosure *p, nat gen_no)
+{
+ bdescr *bd;
+
+ bd = generations[gen_no].mut_list;
+ if (bd->free >= bd->start + BLOCK_SIZE_W) {
+ bdescr *new_bd;
+ new_bd = allocBlock();
+ new_bd->link = bd;
+ bd = new_bd;
+ generations[gen_no].mut_list = bd;
+ }
+ *bd->free++ = (StgWord)p;
+
+}
+
+INLINE_HEADER void
+recordMutableGenLock(StgClosure *p, nat gen_no)
+{
+ ACQUIRE_SM_LOCK;
+ recordMutableGen(p,gen_no);
+ RELEASE_SM_LOCK;
+}
+
+INLINE_HEADER void
+recordMutable(StgClosure *p)
+{
+ bdescr *bd;
+ ASSERT(closure_MUTABLE(p));
+ bd = Bdescr((P_)p);
+ if (bd->gen_no > 0) recordMutableGen(p, bd->gen_no);
+}
+
+INLINE_HEADER void
+recordMutableLock(StgClosure *p)
+{
+ ACQUIRE_SM_LOCK;
+ recordMutable(p);
+ RELEASE_SM_LOCK;
+}
+
+/* -----------------------------------------------------------------------------
+ This is the write barrier for MUT_VARs, a.k.a. IORefs. A
+ MUT_VAR_CLEAN object is not on the mutable list; a MUT_VAR_DIRTY
+ is. When written to, a MUT_VAR_CLEAN turns into a MUT_VAR_DIRTY
+ and is put on the mutable list.
+ -------------------------------------------------------------------------- */
+
+void dirty_MUT_VAR(StgRegTable *reg, StgClosure *p);
+
+/* -----------------------------------------------------------------------------
+ Similarly, the write barrier for MVARs
+ -------------------------------------------------------------------------- */
+
+void dirty_MVAR(StgRegTable *reg, StgClosure *p);
+
+/* -----------------------------------------------------------------------------
+ Nursery manipulation
+ -------------------------------------------------------------------------- */
+
+void resetNurseries ( void );
+void resizeNurseries ( nat blocks );
+void resizeNurseriesFixed ( nat blocks );
+lnat countNurseryBlocks ( void );
+
+/* -----------------------------------------------------------------------------
+ Stats 'n' DEBUG stuff
+ -------------------------------------------------------------------------- */
+
+extern ullong total_allocated;
+
+lnat calcAllocated (void);
+lnat calcLiveBlocks (void);
+lnat calcLiveWords (void);
+lnat countOccupied (bdescr *bd);
+lnat calcNeeded (void);
+HsInt64 getAllocations (void);
+
+#if defined(DEBUG)
+void memInventory (rtsBool show);
+void checkSanity (void);
+nat countBlocks (bdescr *);
+void checkNurserySanity (step *stp);
+#endif
+
+/* ----------------------------------------------------------------------------
+ Storage manager internal APIs and globals
+ ------------------------------------------------------------------------- */
+
+#define END_OF_STATIC_LIST ((StgClosure*)1)
+
+void move_TSO (StgTSO *src, StgTSO *dest);
+
+extern StgClosure * caf_list;
+extern StgClosure * revertible_caf_list;
+
+#endif /* SM_STORAGE_H */
diff --git a/rts/sm/Sweep.c b/rts/sm/Sweep.c
index 444c3d5111..b6574024eb 100644
--- a/rts/sm/Sweep.c
+++ b/rts/sm/Sweep.c
@@ -11,9 +11,11 @@
*
* ---------------------------------------------------------------------------*/
+#include "PosixSource.h"
#include "Rts.h"
+
+#include "Storage.h"
#include "Sweep.h"
-#include "Block.h"
#include "Trace.h"
void
diff --git a/rts/sm/Sweep.h b/rts/sm/Sweep.h
index e7904a90a8..562a934faa 100644
--- a/rts/sm/Sweep.h
+++ b/rts/sm/Sweep.h
@@ -1,6 +1,6 @@
/* -----------------------------------------------------------------------------
*
- * (c) The GHC Team 2008
+ * (c) The GHC Team 2008
*
* Simple mark/sweep, collecting whole blocks.
*
@@ -11,4 +11,9 @@
*
* ---------------------------------------------------------------------------*/
+#ifndef SM_SWEEP_H
+#define SM_SWEEP_H
+
void sweep(step *gen);
+
+#endif /* SM_SWEEP_H */