Permalink
Browse files

Allow passing gct as a function paramater in the GC

This patch adds support for passing the gct variable as a
paramter in the garbage collector. The GC functions that
need access to the gct variable are declared with the
DECLARE_GCT_PARAM macro that will add the gct as an extra
argument. When calling these function use the GCT_PARAM
macro to automatically add the gct variable to the function
call.

The defintion of these two macros are controlled by the
PASS_GCT_AS_PARAM preprocessor variable. If this variable is
defined then the above macros are setup to do the parameter
passing, otherwise these macros will be suitably defined to
do nothing.

Currently we only pass the gct variable as a paramter when
using an llvm compiler C compiler such as clang or llvm-gcc.
  • Loading branch information...
dmpots committed Jul 5, 2011
1 parent b5a88e9 commit ed77af50f34a3aedcefe2f0dd624cc9e4010a2bc
Showing with 342 additions and 307 deletions.
  1. +50 −51 rts/sm/Evac.c
  2. +10 −0 rts/sm/Evac.h
  3. +27 −17 rts/sm/GC.c
  4. +24 −10 rts/sm/GCTDecl.h
  5. +2 −2 rts/sm/GCUtils.c
  6. +3 −3 rts/sm/GCUtils.h
  7. +10 −10 rts/sm/MarkWeak.c
  8. +4 −2 rts/sm/MarkWeak.h
  9. +206 −206 rts/sm/Scav.c
  10. +6 −6 rts/sm/Scav.h
View
@@ -36,23 +36,22 @@ StgWord64 whitehole_spin = 0;
#endif
#if !defined(PARALLEL_GC)
-#define copy_tag_nolock(p, info, src, size, stp, tag) \
- copy_tag(p, info, src, size, stp, tag)
+#define copy_tag_nolock(...) copy_tag(__VA_ARGS__)
#endif
/* Used to avoid long recursion due to selector thunks
*/
#define MAX_THUNK_SELECTOR_DEPTH 16
-static void eval_thunk_selector (StgClosure **q, StgSelector * p, rtsBool);
-STATIC_INLINE void evacuate_large(StgPtr p);
+static void eval_thunk_selector (DECLARE_GCT_PARAM(StgClosure **q, StgSelector * p, rtsBool));
+STATIC_INLINE void evacuate_large(DECLARE_GCT_PARAM(StgPtr p));
/* -----------------------------------------------------------------------------
Allocate some space in which to copy an object.
-------------------------------------------------------------------------- */
STATIC_INLINE StgPtr
-alloc_for_copy (nat size, nat gen_no)
+alloc_for_copy (DECLARE_GCT_PARAM(nat size, nat gen_no))
{
StgPtr to;
gen_workspace *ws;
@@ -78,7 +77,7 @@ alloc_for_copy (nat size, nat gen_no)
to = ws->todo_free;
ws->todo_free += size;
if (ws->todo_free > ws->todo_lim) {
- to = todo_block_full(size, ws);
+ to = todo_block_full(GCT_PARAM(size, ws));
}
ASSERT(ws->todo_free >= ws->todo_bd->free && ws->todo_free <= ws->todo_lim);
@@ -90,13 +89,13 @@ alloc_for_copy (nat size, nat gen_no)
-------------------------------------------------------------------------- */
STATIC_INLINE GNUC_ATTR_HOT void
-copy_tag(StgClosure **p, const StgInfoTable *info,
- StgClosure *src, nat size, nat gen_no, StgWord tag)
+copy_tag(DECLARE_GCT_PARAM(StgClosure **p, const StgInfoTable *info,
+ StgClosure *src, nat size, nat gen_no, StgWord tag))
{
StgPtr to, from;
nat i;
- to = alloc_for_copy(size,gen_no);
+ to = alloc_for_copy(GCT_PARAM(size,gen_no));
from = (StgPtr)src;
to[0] = (W_)info;
@@ -113,7 +112,7 @@ copy_tag(StgClosure **p, const StgInfoTable *info,
const StgInfoTable *new_info;
new_info = (const StgInfoTable *)cas((StgPtr)&src->header.info, (W_)info, MK_FORWARDING_PTR(to));
if (new_info != info) {
- return evacuate(p); // does the failed_to_evac stuff
+ return evacuate(GCT_PARAM(p)); // does the failed_to_evac stuff
} else {
*p = TAG_CLOSURE(tag,(StgClosure*)to);
}
@@ -132,13 +131,13 @@ copy_tag(StgClosure **p, const StgInfoTable *info,
#if defined(PARALLEL_GC)
STATIC_INLINE void
-copy_tag_nolock(StgClosure **p, const StgInfoTable *info,
- StgClosure *src, nat size, nat gen_no, StgWord tag)
+copy_tag_nolock(DECLARE_GCT_PARAM(StgClosure **p, const StgInfoTable *info,
+ StgClosure *src, nat size, nat gen_no, StgWord tag))
{
StgPtr to, from;
nat i;
- to = alloc_for_copy(size,gen_no);
+ to = alloc_for_copy(GCT_PARAM(size,gen_no));
from = (StgPtr)src;
to[0] = (W_)info;
@@ -169,8 +168,8 @@ copy_tag_nolock(StgClosure **p, const StgInfoTable *info,
* used to optimise evacuation of TSOs.
*/
static rtsBool
-copyPart(StgClosure **p, StgClosure *src, nat size_to_reserve,
- nat size_to_copy, nat gen_no)
+copyPart(DECLARE_GCT_PARAM(StgClosure **p, StgClosure *src, nat size_to_reserve,
+ nat size_to_copy, nat gen_no))
{
StgPtr to, from;
nat i;
@@ -187,14 +186,14 @@ copyPart(StgClosure **p, StgClosure *src, nat size_to_reserve,
}
if (IS_FORWARDING_PTR(info)) {
src->header.info = (const StgInfoTable *)info;
- evacuate(p); // does the failed_to_evac stuff
+ evacuate(GCT_PARAM(p)); // does the failed_to_evac stuff
return rtsFalse;
}
#else
info = (W_)src->header.info;
#endif
- to = alloc_for_copy(size_to_reserve, gen_no);
+ to = alloc_for_copy(GCT_PARAM(size_to_reserve, gen_no));
from = (StgPtr)src;
to[0] = info;
@@ -221,10 +220,10 @@ copyPart(StgClosure **p, StgClosure *src, nat size_to_reserve,
/* Copy wrappers that don't tag the closure after copying */
STATIC_INLINE GNUC_ATTR_HOT void
-copy(StgClosure **p, const StgInfoTable *info,
- StgClosure *src, nat size, nat gen_no)
+copy(DECLARE_GCT_PARAM(StgClosure **p, const StgInfoTable *info,
+ StgClosure *src, nat size, nat gen_no))
{
- copy_tag(p,info,src,size,gen_no,0);
+ copy_tag(GCT_PARAM(p,info,src,size,gen_no,0));
}
/* -----------------------------------------------------------------------------
@@ -239,7 +238,7 @@ copy(StgClosure **p, const StgInfoTable *info,
-------------------------------------------------------------------------- */
STATIC_INLINE void
-evacuate_large(StgPtr p)
+evacuate_large(DECLARE_GCT_PARAM(StgPtr p))
{
bdescr *bd;
generation *gen, *new_gen;
@@ -353,7 +352,7 @@ evacuate_large(StgPtr p)
------------------------------------------------------------------------- */
REGPARM1 GNUC_ATTR_HOT void
-evacuate(StgClosure **p)
+evacuate(DECLARE_GCT_PARAM(StgClosure **p))
{
bdescr *bd = NULL;
nat gen_no;
@@ -489,7 +488,7 @@ evacuate(StgClosure **p)
/* evacuate large objects by re-linking them onto a different list.
*/
if (bd->flags & BF_LARGE) {
- evacuate_large((P_)q);
+ evacuate_large(GCT_PARAM((P_)q));
return;
}
@@ -544,7 +543,7 @@ evacuate(StgClosure **p)
case MUT_VAR_DIRTY:
case MVAR_CLEAN:
case MVAR_DIRTY:
- copy(p,info,q,sizeW_fromITBL(INFO_PTR_TO_STRUCT(info)),gen_no);
+ copy(GCT_PARAM(p,info,q,sizeW_fromITBL(INFO_PTR_TO_STRUCT(info)),gen_no));
return;
// For ints and chars of low value, save space by replacing references to
@@ -573,7 +572,7 @@ evacuate(StgClosure **p)
);
}
else {
- copy_tag_nolock(p,info,q,sizeofW(StgHeader)+1,gen_no,tag);
+ copy_tag_nolock(GCT_PARAM(p,info,q,sizeofW(StgHeader)+1,gen_no,tag));
}
#endif
return;
@@ -582,12 +581,12 @@ evacuate(StgClosure **p)
case FUN_0_1:
case FUN_1_0:
case CONSTR_1_0:
- copy_tag_nolock(p,info,q,sizeofW(StgHeader)+1,gen_no,tag);
+ copy_tag_nolock(GCT_PARAM(p,info,q,sizeofW(StgHeader)+1,gen_no,tag));
return;
case THUNK_1_0:
case THUNK_0_1:
- copy(p,info,q,sizeofW(StgThunk)+1,gen_no);
+ copy(GCT_PARAM(p,info,q,sizeofW(StgThunk)+1,gen_no));
return;
case THUNK_1_1:
@@ -596,29 +595,29 @@ evacuate(StgClosure **p)
#ifdef NO_PROMOTE_THUNKS
#error bitrotted
#endif
- copy(p,info,q,sizeofW(StgThunk)+2,gen_no);
+ copy(GCT_PARAM(p,info,q,sizeofW(StgThunk)+2,gen_no));
return;
case FUN_1_1:
case FUN_2_0:
case FUN_0_2:
case CONSTR_1_1:
case CONSTR_2_0:
- copy_tag_nolock(p,info,q,sizeofW(StgHeader)+2,gen_no,tag);
+ copy_tag_nolock(GCT_PARAM(p,info,q,sizeofW(StgHeader)+2,gen_no,tag));
return;
case CONSTR_0_2:
- copy_tag_nolock(p,info,q,sizeofW(StgHeader)+2,gen_no,tag);
+ copy_tag_nolock(GCT_PARAM(p,info,q,sizeofW(StgHeader)+2,gen_no,tag));
return;
case THUNK:
- copy(p,info,q,thunk_sizeW_fromITBL(INFO_PTR_TO_STRUCT(info)),gen_no);
+ copy(GCT_PARAM(p,info,q,thunk_sizeW_fromITBL(INFO_PTR_TO_STRUCT(info)),gen_no));
return;
case FUN:
case IND_PERM:
case CONSTR:
- copy_tag_nolock(p,info,q,sizeW_fromITBL(INFO_PTR_TO_STRUCT(info)),gen_no,tag);
+ copy_tag_nolock(GCT_PARAM(p,info,q,sizeW_fromITBL(INFO_PTR_TO_STRUCT(info)),gen_no,tag));
return;
case BLACKHOLE:
@@ -636,7 +635,7 @@ evacuate(StgClosure **p)
|| i == &stg_WHITEHOLE_info
|| i == &stg_BLOCKING_QUEUE_CLEAN_info
|| i == &stg_BLOCKING_QUEUE_DIRTY_info) {
- copy(p,info,q,sizeofW(StgInd),gen_no);
+ copy(GCT_PARAM(p,info,q,sizeofW(StgInd),gen_no));
return;
}
ASSERT(i != &stg_IND_info);
@@ -650,15 +649,15 @@ evacuate(StgClosure **p)
case WEAK:
case PRIM:
case MUT_PRIM:
- copy(p,info,q,sizeW_fromITBL(INFO_PTR_TO_STRUCT(info)),gen_no);
+ copy(GCT_PARAM(p,info,q,sizeW_fromITBL(INFO_PTR_TO_STRUCT(info)),gen_no));
return;
case BCO:
- copy(p,info,q,bco_sizeW((StgBCO *)q),gen_no);
+ copy(GCT_PARAM(p,info,q,bco_sizeW((StgBCO *)q),gen_no));
return;
case THUNK_SELECTOR:
- eval_thunk_selector(p, (StgSelector *)q, rtsTrue);
+ eval_thunk_selector(GCT_PARAM(p, (StgSelector *)q, rtsTrue));
return;
case IND:
@@ -682,32 +681,32 @@ evacuate(StgClosure **p)
barf("evacuate: stack frame at %p\n", q);
case PAP:
- copy(p,info,q,pap_sizeW((StgPAP*)q),gen_no);
+ copy(GCT_PARAM(p,info,q,pap_sizeW((StgPAP*)q),gen_no));
return;
case AP:
- copy(p,info,q,ap_sizeW((StgAP*)q),gen_no);
+ copy(GCT_PARAM(p,info,q,ap_sizeW((StgAP*)q),gen_no));
return;
case AP_STACK:
- copy(p,info,q,ap_stack_sizeW((StgAP_STACK*)q),gen_no);
+ copy(GCT_PARAM(p,info,q,ap_stack_sizeW((StgAP_STACK*)q),gen_no));
return;
case ARR_WORDS:
// just copy the block
- copy(p,info,q,arr_words_sizeW((StgArrWords *)q),gen_no);
+ copy(GCT_PARAM(p,info,q,arr_words_sizeW((StgArrWords *)q),gen_no));
return;
case MUT_ARR_PTRS_CLEAN:
case MUT_ARR_PTRS_DIRTY:
case MUT_ARR_PTRS_FROZEN:
case MUT_ARR_PTRS_FROZEN0:
// just copy the block
- copy(p,info,q,mut_arr_ptrs_sizeW((StgMutArrPtrs *)q),gen_no);
+ copy(GCT_PARAM(p,info,q,mut_arr_ptrs_sizeW((StgMutArrPtrs *)q),gen_no));
return;
case TSO:
- copy(p,info,q,sizeofW(StgTSO),gen_no);
+ copy(GCT_PARAM(p,info,q,sizeofW(StgTSO),gen_no));
return;
case STACK:
@@ -721,8 +720,8 @@ evacuate(StgClosure **p)
StgPtr r, s;
rtsBool mine;
- mine = copyPart(p,(StgClosure *)stack, stack_sizeW(stack),
- sizeofW(StgStack), gen_no);
+ mine = copyPart(GCT_PARAM(p,(StgClosure *)stack, stack_sizeW(stack),
+ sizeofW(StgStack), gen_no));
if (mine) {
new_stack = (StgStack *)*p;
move_STACK(stack, new_stack);
@@ -736,7 +735,7 @@ evacuate(StgClosure **p)
}
case TREC_CHUNK:
- copy(p,info,q,sizeofW(StgTRecChunk),gen_no);
+ copy(GCT_PARAM(p,info,q,sizeofW(StgTRecChunk),gen_no));
return;
default:
@@ -810,7 +809,7 @@ unchain_thunk_selectors(StgSelector *p, StgClosure *val)
}
static void
-eval_thunk_selector (StgClosure **q, StgSelector * p, rtsBool evac)
+eval_thunk_selector (DECLARE_GCT_PARAM(StgClosure **q, StgSelector * p, rtsBool evac))
// NB. for legacy reasons, p & q are swapped around :(
{
nat field;
@@ -855,7 +854,7 @@ eval_thunk_selector (StgClosure **q, StgSelector * p, rtsBool evac)
if (bd->flags & BF_MARKED) {
// must call evacuate() to mark this closure if evac==rtsTrue
*q = (StgClosure *)p;
- if (evac) evacuate(q);
+ if (evac) evacuate(GCT_PARAM(q));
unchain_thunk_selectors(prev_thunk_selector, (StgClosure *)p);
return;
}
@@ -887,7 +886,7 @@ eval_thunk_selector (StgClosure **q, StgSelector * p, rtsBool evac)
// - undo the chain we've built to point to p.
SET_INFO(p, (const StgInfoTable *)info_ptr);
*q = (StgClosure *)p;
- if (evac) evacuate(q);
+ if (evac) evacuate(GCT_PARAM(q));
unchain_thunk_selectors(prev_thunk_selector, (StgClosure *)p);
return;
}
@@ -990,7 +989,7 @@ eval_thunk_selector (StgClosure **q, StgSelector * p, rtsBool evac)
// evacuate() cannot recurse through
// eval_thunk_selector(), because we know val is not
// a THUNK_SELECTOR.
- if (evac) evacuate(q);
+ if (evac) evacuate(GCT_PARAM(q));
return;
}
@@ -1042,7 +1041,7 @@ eval_thunk_selector (StgClosure **q, StgSelector * p, rtsBool evac)
// rtsFalse says "don't evacuate the result". It will,
// however, update any THUNK_SELECTORs that are evaluated
// along the way.
- eval_thunk_selector(&val, (StgSelector*)selectee, rtsFalse);
+ eval_thunk_selector(GCT_PARAM(&val, (StgSelector*)selectee, rtsFalse));
gct->thunk_selector_depth--;
// did we actually manage to evaluate it?
@@ -1079,7 +1078,7 @@ eval_thunk_selector (StgClosure **q, StgSelector * p, rtsBool evac)
// check whether it was updated in the meantime.
*q = (StgClosure *)p;
if (evac) {
- copy(q,(const StgInfoTable *)info_ptr,(StgClosure *)p,THUNK_SELECTOR_sizeW(),bd->dest_no);
+ copy(GCT_PARAM(q,(const StgInfoTable *)info_ptr,(StgClosure *)p,THUNK_SELECTOR_sizeW(),bd->dest_no));
}
unchain_thunk_selectors(prev_thunk_selector, *q);
return;
View
@@ -28,12 +28,22 @@
// their arguments on the stack.
#if __GNUC__ >= 2 && (defined(x86_64_HOST_ARCH) || defined(i386_HOST_ARCH))
#define REGPARM1 __attribute__((regparm(1)))
+#define REGPARM2 __attribute__((regparm(2)))
#else
#define REGPARM1
+#define REGPARM2
#endif
+#include "GCThread.h"
+#include "GCTDecl.h"
+
+#ifdef PASS_GCT_AS_PARAM
+REGPARM2 void evacuate (gc_thread* gct, StgClosure **p);
+REGPARM2 void evacuate1 (gc_thread* gct, StgClosure **p);
+#else
REGPARM1 void evacuate (StgClosure **p);
REGPARM1 void evacuate1 (StgClosure **p);
+#endif
extern lnat thunk_selector_depth;
Oops, something went wrong.

0 comments on commit ed77af5

Please sign in to comment.