X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=includes%2FCmm.h;h=06a66a79ef724925a117fa5f8dd43af638409472;hp=b23a37be040e5bda37a37c90ebbde5172a00fc05;hb=176fa33f17dd78355cc572e006d2ab26898e2c69;hpb=d31dfb32ea936c22628b508c28a36c12e631430a diff --git a/includes/Cmm.h b/includes/Cmm.h index b23a37b..06a66a7 100644 --- a/includes/Cmm.h +++ b/includes/Cmm.h @@ -25,7 +25,7 @@ * - Hp += n ==> Hp_adj(n) * - R1.i ==> R1 (similarly for R1.w, R1.cl etc.) * - You need to explicitly dereference variables; eg. - * context_switch ==> CInt[context_switch] + * alloc_blocks ==> CInt[alloc_blocks] * - convert all word offsets into byte offsets: * - e ==> WDS(e) * - sizeofW(StgFoo) ==> SIZEOF_StgFoo @@ -88,15 +88,28 @@ #define I16 bits16 #define I32 bits32 #define I64 bits64 +#define P_ gcptr #if SIZEOF_VOID_P == 4 #define W_ bits32 +/* Maybe it's better to include MachDeps.h */ +#define TAG_BITS 2 #elif SIZEOF_VOID_P == 8 #define W_ bits64 +/* Maybe it's better to include MachDeps.h */ +#define TAG_BITS 3 #else #error Unknown word size #endif +/* + * The RTS must sometimes UNTAG a pointer before dereferencing it. + * See the wiki page Commentary/Rts/HaskellExecution/PointerTagging + */ +#define TAG_MASK ((1 << TAG_BITS) - 1) +#define UNTAG(p) (p & ~TAG_MASK) +#define GETTAG(p) (p & TAG_MASK) + #if SIZEOF_INT == 4 #define CInt bits32 #elif SIZEOF_INT == 8 @@ -228,12 +241,24 @@ ToDo: range should end in N_CLOSURE_TYPES-1, not N_CLOSURE_TYPES, but switch doesn't allow us to use exprs there yet. + + If R1 points to a tagged object it points either to + * A constructor. + * A function with arity <= TAG_MASK. + In both cases the right thing to do is to return. + Note: it is rather lucky that we can use the tag bits to do this + for both objects. Maybe it points to a brittle design? + + Indirections can contain tagged pointers, so their tag is checked. -------------------------------------------------------------------------- */ #define ENTER() \ again: \ W_ info; \ - info = %INFO_PTR(R1); \ + if (GETTAG(P1) != 0) { \ + jump %ENTRY_CODE(Sp(0)); \ + } \ + info = %INFO_PTR(P1); \ switch [INVALID_OBJECT .. N_CLOSURE_TYPES] \ (TO_W_( %INFO_TYPE(%STD_INFO(info)) )) { \ case \ @@ -243,18 +268,17 @@ IND_OLDGEN_PERM, \ IND_STATIC: \ { \ - R1 = StgInd_indirectee(R1); \ + P1 = StgInd_indirectee(P1); \ goto again; \ } \ case \ - BCO, \ FUN, \ FUN_1_0, \ FUN_0_1, \ FUN_2_0, \ FUN_1_1, \ - FUN_0_2, \ - FUN_STATIC, \ + FUN_STATIC, \ + BCO, \ PAP: \ { \ jump %ENTRY_CODE(Sp(0)); \ @@ -265,6 +289,10 @@ } \ } +// The FUN cases almost never happen: a pointer to a non-static FUN +// should always be tagged. This unfortunately isn't true for the +// interpreter right now, which leaves untagged FUNs on the stack. + /* ----------------------------------------------------------------------------- Constants. -------------------------------------------------------------------------- */ @@ -274,7 +302,7 @@ #include "ClosureTypes.h" #include "StgFun.h" #include "OSThreads.h" -#include "SMP.h" +#include "SMPClosureOps.h" /* * Need MachRegs, because some of the RTS code is conditionally @@ -370,12 +398,15 @@ #define BITMAP_BITS(bitmap) ((bitmap) >> BITMAP_BITS_SHIFT) /* Debugging macros */ -#define LOOKS_LIKE_INFO_PTR(p) \ - ((p) != NULL && \ - (TO_W_(%INFO_TYPE(%STD_INFO(p))) != INVALID_OBJECT) && \ +#define LOOKS_LIKE_INFO_PTR(p) \ + ((p) != NULL && \ + LOOKS_LIKE_INFO_PTR_NOT_NULL(p)) + +#define LOOKS_LIKE_INFO_PTR_NOT_NULL(p) \ + ( (TO_W_(%INFO_TYPE(%STD_INFO(p))) != INVALID_OBJECT) && \ (TO_W_(%INFO_TYPE(%STD_INFO(p))) < N_CLOSURE_TYPES)) -#define LOOKS_LIKE_CLOSURE_PTR(p) (LOOKS_LIKE_INFO_PTR(GET_INFO(p))) +#define LOOKS_LIKE_CLOSURE_PTR(p) (LOOKS_LIKE_INFO_PTR(GET_INFO(UNTAG(p)))) /* * The layout of the StgFunInfoExtra part of an info table changes @@ -514,9 +545,6 @@ #define END_TSO_QUEUE stg_END_TSO_QUEUE_closure #define END_INVARIANT_CHECK_QUEUE stg_END_INVARIANT_CHECK_QUEUE_closure -#define dirtyTSO(tso) \ - StgTSO_flags(tso) = StgTSO_flags(tso) | TSO_DIRTY::I32; - #define recordMutableCap(p, gen, regs) \ W_ __bd; \ W_ mut_list; \ @@ -534,9 +562,13 @@ W_[free] = p; \ bdescr_free(__bd) = free + WDS(1); -#define recordMutable(p, regs) \ - W_ __p; \ - __p = p; \ - recordMutableCap(__p, TO_W_(bdescr_gen_no(Bdescr(__p))), regs) +#define recordMutable(p, regs) \ + P_ __p; \ + W_ __bd; \ + W_ __gen; \ + __p = p; \ + __bd = Bdescr(__p); \ + __gen = TO_W_(bdescr_gen_no(__bd)); \ + if (__gen > 0) { recordMutableCap(__p, __gen, regs); } #endif /* CMM_H */