Commit 485b8d1a authored by Simon Marlow's avatar Simon Marlow
Browse files

Rework the block allocator

The main goal here is to reduce fragmentation, which turns out to be
the case of #743.  While I was here I found some opportunities to
improve performance too.  The code is rather more complex, but it also
contains a long comment describing the strategy, so please take a look
at that for the details.
parent d12cd2f2
......@@ -130,6 +130,11 @@ INLINE_HEADER bdescr *Bdescr(StgPtr p)
#define FIRST_BDESCR(m) \
((bdescr *)((FIRST_BLOCK_OFF>>(BLOCK_SHIFT-BDESCR_SHIFT)) + (W_)(m)))
/* Last real block descriptor in a megablock */
#define LAST_BDESCR(m) \
((bdescr *)(((MBLOCK_SIZE-BLOCK_SIZE)>>(BLOCK_SHIFT-BDESCR_SHIFT)) + (W_)(m)))
/* Number of usable blocks in a megablock */
#define BLOCKS_PER_MBLOCK ((MBLOCK_SIZE - FIRST_BLOCK_OFF) / BLOCK_SIZE)
......@@ -161,6 +166,45 @@ dbl_link_onto(bdescr *bd, bdescr **list)
*list = bd;
}
INLINE_HEADER void
dbl_link_remove(bdescr *bd, bdescr **list)
{
if (bd->u.back) {
bd->u.back->link = bd->link;
} else {
*list = bd->link;
}
if (bd->link) {
bd->link->u.back = bd->u.back;
}
}
INLINE_HEADER void
dbl_link_insert_after(bdescr *bd, bdescr *after)
{
bd->link = after->link;
bd->u.back = after;
if (after->link) {
after->link->u.back = bd;
}
after->link = bd;
}
INLINE_HEADER void
dbl_link_replace(bdescr *new, bdescr *old, bdescr **list)
{
new->link = old->link;
new->u.back = old->u.back;
if (old->link) {
old->link->u.back = new;
}
if (old->u.back) {
old->u.back->link = new;
} else {
*list = new;
}
}
/* Initialisation ---------------------------------------------------------- */
extern void initBlockAllocator(void);
......
This diff is collapsed.
......@@ -1049,14 +1049,7 @@ void freeExec (void *addr)
// the head of the queue.
if (bd->gen_no == 0 && bd != exec_block) {
debugTrace(DEBUG_gc, "free exec block %p", bd->start);
if (bd->u.back) {
bd->u.back->link = bd->link;
} else {
exec_block = bd->link;
}
if (bd->link) {
bd->link->u.back = bd->u.back;
}
dbl_link_remove(bd, &exec_block);
setExecutable(bd->start, bd->blocks * BLOCK_SIZE, rtsFalse);
freeGroup(bd);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment