X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fincludes%2FRegs.h;h=2181de24d5fcac4b1e0685dd3dfc4b091c43f1b2;hb=eba7b660a36878cd8d926845807913d7ec5734c9;hp=10e0b3fbdaa3d8d60e2377f289c371191939e1e3;hpb=03dc2dd3dd814ad85cc4c45e9cafc7b73163c8be;p=ghc-hetmet.git diff --git a/ghc/includes/Regs.h b/ghc/includes/Regs.h index 10e0b3f..2181de2 100644 --- a/ghc/includes/Regs.h +++ b/ghc/includes/Regs.h @@ -22,16 +22,20 @@ #ifndef REGS_H #define REGS_H +#include "gmp.h" // Needs MP_INT definition -/* - * This is the table that holds shadow-locations for all the STG - * registers. The shadow locations are used when: - * - * 1) the particular register isn't mapped to a real machine - * register, probably because there's a shortage of real registers. - * 2) caller-saves registers are saved across a CCall +/* + * Spark pools: used to store pending sparks + * (THREADED_RTS & PARALLEL_HASKELL only) + * This is a circular buffer. Invariants: + * - base <= hd < lim + * - base <= tl < lim + * - if hd==tl, then the pool is empty. + * - if hd == tl+1, then the pool is full. + * Adding to the pool is done by assigning to *tl++ (wrapping round as + * necessary). When adding to a full pool, we have the option of + * throwing away either the oldest (hd++) or the most recent (tl--) entry. */ - typedef struct StgSparkPool_ { StgClosure **base; StgClosure **lim; @@ -39,6 +43,12 @@ typedef struct StgSparkPool_ { StgClosure **tl; } StgSparkPool; +#define ASSERT_SPARK_POOL_INVARIANTS(p) \ + ASSERT((p)->base <= (p)->hd); \ + ASSERT((p)->hd < (p)->lim); \ + ASSERT((p)->base <= (p)->tl); \ + ASSERT((p)->tl < (p)->lim); + typedef struct { StgFunPtr stgGCEnter1; StgFunPtr stgGCFun; @@ -63,6 +73,14 @@ typedef union { StgTSOPtr t; } StgUnion; +/* + * This is the table that holds shadow-locations for all the STG + * registers. The shadow locations are used when: + * + * 1) the particular register isn't mapped to a real machine + * register, probably because there's a shortage of real registers. + * 2) caller-saves registers are saved across a CCall + */ typedef struct StgRegTable_ { StgUnion rR1; StgUnion rR2; @@ -86,39 +104,24 @@ typedef struct StgRegTable_ { StgPtr rHp; StgPtr rHpLim; struct StgTSO_ *rCurrentTSO; - struct bdescr_ *rNursery; - struct bdescr_ *rCurrentNursery; + struct step_ *rNursery; + struct bdescr_ *rCurrentNursery; /* Hp/HpLim point into this block */ + struct bdescr_ *rCurrentAlloc; /* for allocation using allocate() */ StgWord rHpAlloc; /* number of *bytes* being allocated in heap */ -#if defined(SMP) || defined(PAR) - StgSparkPool rSparks; /* per-task spark pool */ + // rmp_tmp1..rmp_result2 are only used in THREADED_RTS builds to + // avoid per-thread temps in bss, but currently always incldue here + // so we just run mkDerivedConstants once + StgInt rmp_tmp_w; + MP_INT rmp_tmp1; + MP_INT rmp_tmp2; + MP_INT rmp_result1; + MP_INT rmp_result2; + StgWord rRet; // holds the return code of the thread +#if defined(THREADED_RTS) || defined(PAR) + StgSparkPool rSparks; /* per-task spark pool */ #endif } StgRegTable; - -/* A capability is a combination of a FunTable and a RegTable. In STG - * code, BaseReg normally points to the RegTable portion of this - * structure, so that we can index both forwards and backwards to take - * advantage of shorter instruction forms on some archs (eg. x86). - */ -typedef struct Capability_ { - StgFunTable f; - StgRegTable r; -#if defined(SMP) - struct Capability_ *link; /* per-task register tables are linked together */ -#endif -} Capability; - -/* No such thing as a MainCapability under SMP - each thread must have - * its own Capability. - */ -#ifndef SMP -#if IN_STG_CODE -extern W_ MainCapability[]; -#else -extern DLL_IMPORT_RTS Capability MainCapability; -#endif -#endif - #if IN_STG_CODE /* @@ -317,13 +320,42 @@ GLOBAL_REG_DECL(StgWord64,L1,REG_L1) * concurrent Haskell, MainRegTable otherwise). */ +/* A capability is a combination of a FunTable and a RegTable. In STG + * code, BaseReg normally points to the RegTable portion of this + * structure, so that we can index both forwards and backwards to take + * advantage of shorter instruction forms on some archs (eg. x86). + * This is a cut-down version of the Capability structure; the full + * version is defined in Capability.h. + */ +struct PartCapability_ { + StgFunTable f; + StgRegTable r; +}; + +/* No such thing as a MainCapability under THREADED_RTS - each thread must have + * its own Capability. + */ +#if IN_STG_CODE && !defined(THREADED_RTS) +extern W_ MainCapability[]; +#endif + +/* + * Assigning to BaseReg (the ASSIGN_BaseReg macro): this happens on + * return from a "safe" foreign call, when the thread might be running + * on a new Capability. Obviously if BaseReg is not a register, then + * we are restricted to a single Capability (this invariant is enforced + * in Capability.c:initCapabilities), and assigning to BaseReg can be omitted. + */ + #if defined(REG_Base) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base) +#define ASSIGN_BaseReg(e) (BaseReg = (e)) #else -#ifdef SMP -#error BaseReg must be in a register for SMP +#ifdef THREADED_RTS +#error BaseReg must be in a register for THREADED_RTS #endif -#define BaseReg (&((Capability *)MainCapability)[0].r) +#define BaseReg (&((struct PartCapability_ *)MainCapability)->r) +#define ASSIGN_BaseReg(e) /*nothing*/ #endif #if defined(REG_Sp) && !defined(NO_GLOBAL_REG_DECLS) @@ -598,8 +630,8 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim) #endif #ifdef CALLER_SAVES_Base -#ifdef SMP -#error "Can't have caller-saved BaseReg with SMP" +#ifdef THREADED_RTS +#error "Can't have caller-saved BaseReg with THREADED_RTS" #endif #define CALLER_SAVE_Base /* nothing */ #define CALLER_RESTORE_Base BaseReg = &MainRegTable;