Commit beb5737b authored by Simon Marlow's avatar Simon Marlow
Browse files

make the smp way RTS-only, normal libraries now work with -smp

We had to bite the bullet here and add an extra word to every thunk,
to enable running ordinary libraries on SMP.  Otherwise, we would have
needed to ship an extra set of libraries with GHC 6.6 in addition to
the two sets we already ship (normal + profiled), and all Cabal
packages would have to be compiled for SMP too.  We decided it best
just to take the hit now, making SMP easily accessible to everyone in
GHC 6.6.

Incedentally, although this increases allocation by around 12% on
average, the performance hit is around 5%, and much less if your inner
loop doesn't use any laziness.
parent 76e37427
...@@ -32,7 +32,7 @@ import MachOp ...@@ -32,7 +32,7 @@ import MachOp
import SMRep import SMRep
import ForeignCall import ForeignCall
import Constants import Constants
import StaticFlags ( opt_SccProfilingOn, opt_SMP ) import StaticFlags ( opt_SccProfilingOn )
import Outputable import Outputable
import Monad ( when ) import Monad ( when )
...@@ -85,11 +85,10 @@ emitForeignCall results (CCall (CCallSpec target cconv safety)) args live ...@@ -85,11 +85,10 @@ emitForeignCall results (CCall (CCallSpec target cconv safety)) args live
) )
stmtC (the_call vols) stmtC (the_call vols)
stmtC (CmmCall (CmmForeignCall resumeThread CCallConv) stmtC (CmmCall (CmmForeignCall resumeThread CCallConv)
(if opt_SMP then [(CmmGlobal BaseReg, PtrHint)] else []) [ (CmmGlobal BaseReg, PtrHint) ]
-- Assign the result to BaseReg: we might now have -- Assign the result to BaseReg: we
-- a different Capability! Small optimisation: -- might now have a different
-- only do this in SMP mode, where there are >1 -- Capability!
-- Capabilities.
[ (CmmReg id, PtrHint) ] [ (CmmReg id, PtrHint) ]
(Just vols) (Just vols)
) )
......
...@@ -23,7 +23,6 @@ module CgHeapery ( ...@@ -23,7 +23,6 @@ module CgHeapery (
#include "HsVersions.h" #include "HsVersions.h"
import Constants ( mIN_UPD_SIZE )
import StgSyn ( AltType(..) ) import StgSyn ( AltType(..) )
import CLabel ( CLabel, mkRtsCodeLabel ) import CLabel ( CLabel, mkRtsCodeLabel )
import CgUtils ( mkWordCLit, cmmRegOffW, cmmOffsetW, import CgUtils ( mkWordCLit, cmmRegOffW, cmmOffsetW,
...@@ -212,8 +211,7 @@ mkStaticClosureFields cl_info ccs caf_refs payload ...@@ -212,8 +211,7 @@ mkStaticClosureFields cl_info ccs caf_refs payload
padding_wds padding_wds
| not is_caf = [] | not is_caf = []
| otherwise = replicate n (mkIntCLit 0) -- a bunch of 0s | otherwise = ASSERT(null payload) [mkIntCLit 0]
where n = max 0 (mIN_UPD_SIZE - length payload)
static_link_field static_link_field
| is_caf || staticClosureNeedsLink cl_info = [static_link_value] | is_caf || staticClosureNeedsLink cl_info = [static_link_value]
......
...@@ -28,7 +28,7 @@ import SMRep ...@@ -28,7 +28,7 @@ import SMRep
import PrimOp ( PrimOp(..) ) import PrimOp ( PrimOp(..) )
import SMRep ( tablesNextToCode ) import SMRep ( tablesNextToCode )
import Constants ( wORD_SIZE, wORD_SIZE_IN_BITS ) import Constants ( wORD_SIZE, wORD_SIZE_IN_BITS )
import StaticFlags ( opt_Parallel, opt_SMP ) import StaticFlags ( opt_Parallel )
import Outputable import Outputable
-- --------------------------------------------------------------------------- -- ---------------------------------------------------------------------------
...@@ -113,9 +113,6 @@ emitPrimOp [res_r,res_c] IntSubCOp [aa,bb] live ...@@ -113,9 +113,6 @@ emitPrimOp [res_r,res_c] IntSubCOp [aa,bb] live
emitPrimOp [res] ParOp [arg] live emitPrimOp [res] ParOp [arg] live
| not (opt_Parallel || opt_SMP)
= stmtC (CmmAssign res (CmmLit (mkIntCLit 1)))
| otherwise
= do = do
-- for now, just implement this in a C function -- for now, just implement this in a C function
-- later, we might want to inline it. -- later, we might want to inline it.
......
...@@ -61,11 +61,10 @@ import SMRep -- all of it ...@@ -61,11 +61,10 @@ import SMRep -- all of it
import CLabel import CLabel
import Constants ( mIN_UPD_SIZE, mIN_SIZE_NonUpdHeapObject ) import Constants ( mIN_PAYLOAD_SIZE )
import Packages ( isDllName, HomeModules ) import Packages ( isDllName, HomeModules )
import StaticFlags ( opt_SccProfilingOn, opt_OmitBlackHoling, import StaticFlags ( opt_SccProfilingOn, opt_OmitBlackHoling,
opt_Parallel, opt_DoTickyProfiling, opt_Parallel, opt_DoTickyProfiling )
opt_SMP )
import Id ( Id, idType, idArity, idName ) import Id ( Id, idType, idArity, idName )
import DataCon ( DataCon, dataConTyCon, isNullaryRepDataCon, dataConName ) import DataCon ( DataCon, dataConTyCon, isNullaryRepDataCon, dataConName )
import Name ( Name, nameUnique, getOccName, getOccString ) import Name ( Name, nameUnique, getOccName, getOccString )
...@@ -387,16 +386,8 @@ Computing slop size. WARNING: this looks dodgy --- it has deep ...@@ -387,16 +386,8 @@ Computing slop size. WARNING: this looks dodgy --- it has deep
knowledge of what the storage manager does with the various knowledge of what the storage manager does with the various
representations... representations...
Slop Requirements: Slop Requirements: every thunk gets an extra padding word in the
header, which takes the the updated value.
- Updatable closures must be mIN_UPD_SIZE.
- Heap-resident Closures must be mIN_SIZE_NonUpdHeapObject
(to make room for an StgEvacuated during GC).
In SMP mode, we don't play the mIN_UPD_SIZE game. Instead, every
thunk gets an extra padding word in the header, which takes the
the updated value.
\begin{code} \begin{code}
slopSize cl_info = computeSlopSize payload_size cl_info slopSize cl_info = computeSlopSize payload_size cl_info
...@@ -423,16 +414,14 @@ minPayloadSize smrep updatable ...@@ -423,16 +414,14 @@ minPayloadSize smrep updatable
BlackHoleRep -> min_upd_size BlackHoleRep -> min_upd_size
GenericRep _ _ _ _ | updatable -> min_upd_size GenericRep _ _ _ _ | updatable -> min_upd_size
GenericRep True _ _ _ -> 0 -- static GenericRep True _ _ _ -> 0 -- static
GenericRep False _ _ _ -> mIN_SIZE_NonUpdHeapObject GenericRep False _ _ _ -> mIN_PAYLOAD_SIZE
-- ^^^^^___ dynamic -- ^^^^^___ dynamic
where where
min_upd_size min_upd_size =
| opt_SMP = ASSERT(mIN_SIZE_NonUpdHeapObject <= ASSERT(mIN_PAYLOAD_SIZE <= sIZEOF_StgSMPThunkHeader)
sIZEOF_StgSMPThunkHeader) 0 -- check that we already have enough
0 -- check that we already have enough -- room for mIN_SIZE_NonUpdHeapObject,
-- room for mIN_SIZE_NonUpdHeapObject, -- due to the extra header word in SMP
-- due to the extra header word in SMP
| otherwise = mIN_UPD_SIZE
\end{code} \end{code}
%************************************************************************ %************************************************************************
...@@ -600,9 +589,11 @@ getCallMethod hmods name (LFThunk _ _ updatable std_form_info is_fun) n_args ...@@ -600,9 +589,11 @@ getCallMethod hmods name (LFThunk _ _ updatable std_form_info is_fun) n_args
-- is the fast-entry code] -- is the fast-entry code]
| updatable || opt_DoTickyProfiling -- to catch double entry | updatable || opt_DoTickyProfiling -- to catch double entry
|| opt_SMP -- Always enter via node on SMP, since the {- OLD: || opt_SMP
-- thunk might have been blackholed in the I decided to remove this, because in SMP mode it doesn't matter
-- meantime. if we enter the same thunk multiple times, so the optimisation
of jumping directly to the entry code is still valid. --SDM
-}
= ASSERT( n_args == 0 ) EnterIt = ASSERT( n_args == 0 ) EnterIt
| otherwise -- Jump direct to code for single-entry thunks | otherwise -- Jump direct to code for single-entry thunks
......
...@@ -43,7 +43,7 @@ import Type ( Type, typePrimRep, PrimRep(..) ) ...@@ -43,7 +43,7 @@ import Type ( Type, typePrimRep, PrimRep(..) )
import TyCon ( TyCon, tyConPrimRep ) import TyCon ( TyCon, tyConPrimRep )
import MachOp-- ( MachRep(..), MachHint(..), wordRep ) import MachOp-- ( MachRep(..), MachHint(..), wordRep )
import StaticFlags ( opt_SccProfilingOn, opt_GranMacros, import StaticFlags ( opt_SccProfilingOn, opt_GranMacros,
opt_Unregisterised, opt_SMP ) opt_Unregisterised )
import Constants import Constants
import Outputable import Outputable
...@@ -289,8 +289,7 @@ arrPtrsHdrSize = fixedHdrSize*wORD_SIZE + sIZEOF_StgMutArrPtrs_NoHdr ...@@ -289,8 +289,7 @@ arrPtrsHdrSize = fixedHdrSize*wORD_SIZE + sIZEOF_StgMutArrPtrs_NoHdr
-- Thunks have an extra header word on SMP, so the update doesn't -- Thunks have an extra header word on SMP, so the update doesn't
-- splat the payload. -- splat the payload.
thunkHdrSize :: WordOff thunkHdrSize :: WordOff
thunkHdrSize | opt_SMP = fixedHdrSize + smp_hdr thunkHdrSize = fixedHdrSize + smp_hdr
| otherwise = fixedHdrSize
where smp_hdr = sIZEOF_StgSMPThunkHeader `quot` wORD_SIZE where smp_hdr = sIZEOF_StgSMPThunkHeader `quot` wORD_SIZE
\end{code} \end{code}
......
...@@ -254,6 +254,7 @@ mkBits findLabel st proto_insns ...@@ -254,6 +254,7 @@ mkBits findLabel st proto_insns
ALLOC_AP n -> instr2 st bci_ALLOC_AP n ALLOC_AP n -> instr2 st bci_ALLOC_AP n
ALLOC_PAP arity n -> instr3 st bci_ALLOC_PAP arity n ALLOC_PAP arity n -> instr3 st bci_ALLOC_PAP arity n
MKAP off sz -> instr3 st bci_MKAP off sz MKAP off sz -> instr3 st bci_MKAP off sz
MKPAP off sz -> instr3 st bci_MKPAP off sz
UNPACK n -> instr2 st bci_UNPACK n UNPACK n -> instr2 st bci_UNPACK n
PACK dcon sz -> do (itbl_no,st2) <- itbl st dcon PACK dcon sz -> do (itbl_no,st2) <- itbl st dcon
instr3 st2 bci_PACK itbl_no sz instr3 st2 bci_PACK itbl_no sz
...@@ -398,6 +399,7 @@ instrSize16s instr ...@@ -398,6 +399,7 @@ instrSize16s instr
ALLOC_AP{} -> 2 ALLOC_AP{} -> 2
ALLOC_PAP{} -> 3 ALLOC_PAP{} -> 3
MKAP{} -> 3 MKAP{} -> 3
MKPAP{} -> 3
UNPACK{} -> 2 UNPACK{} -> 2
PACK{} -> 3 PACK{} -> 3
LABEL{} -> 0 -- !! LABEL{} -> 0 -- !!
......
...@@ -52,7 +52,7 @@ import Bitmap ( intsToReverseBitmap, mkBitmap ) ...@@ -52,7 +52,7 @@ import Bitmap ( intsToReverseBitmap, mkBitmap )
import OrdList import OrdList
import Constants ( wORD_SIZE ) import Constants ( wORD_SIZE )
import Data.List ( intersperse, sortBy, zip4, zip5, partition ) import Data.List ( intersperse, sortBy, zip4, zip6, partition )
import Foreign ( Ptr, castPtr, mallocBytes, pokeByteOff, Word8, import Foreign ( Ptr, castPtr, mallocBytes, pokeByteOff, Word8,
withForeignPtr ) withForeignPtr )
import Foreign.C ( CInt ) import Foreign.C ( CInt )
...@@ -361,26 +361,28 @@ schemeE d s p (AnnLet binds (_,body)) ...@@ -361,26 +361,28 @@ schemeE d s p (AnnLet binds (_,body))
zipE = zipEqual "schemeE" zipE = zipEqual "schemeE"
-- ToDo: don't build thunks for things with no free variables -- ToDo: don't build thunks for things with no free variables
build_thunk dd [] size bco off build_thunk dd [] size bco off arity
= returnBc (PUSH_BCO bco = returnBc (PUSH_BCO bco `consOL` unitOL (mkap (off+size) size))
`consOL` unitOL (MKAP (off+size) size)) where
build_thunk dd (fv:fvs) size bco off = do mkap | arity == 0 = MKAP
| otherwise = MKPAP
build_thunk dd (fv:fvs) size bco off arity = do
(push_code, pushed_szw) <- pushAtom dd p' (AnnVar fv) (push_code, pushed_szw) <- pushAtom dd p' (AnnVar fv)
more_push_code <- build_thunk (dd+pushed_szw) fvs size bco off more_push_code <- build_thunk (dd+pushed_szw) fvs size bco off arity
returnBc (push_code `appOL` more_push_code) returnBc (push_code `appOL` more_push_code)
alloc_code = toOL (zipWith mkAlloc sizes arities) alloc_code = toOL (zipWith mkAlloc sizes arities)
where mkAlloc sz 0 = ALLOC_AP sz where mkAlloc sz 0 = ALLOC_AP sz
mkAlloc sz arity = ALLOC_PAP arity sz mkAlloc sz arity = ALLOC_PAP arity sz
compile_bind d' fvs x rhs size off = do compile_bind d' fvs x rhs size arity off = do
bco <- schemeR fvs (x,rhs) bco <- schemeR fvs (x,rhs)
build_thunk d' fvs size bco off build_thunk d' fvs size bco off arity
compile_binds = compile_binds =
[ compile_bind d' fvs x rhs size n [ compile_bind d' fvs x rhs size arity n
| (fvs, x, rhs, size, n) <- | (fvs, x, rhs, size, arity, n) <-
zip5 fvss xs rhss sizes [n_binds, n_binds-1 .. 1] zip6 fvss xs rhss sizes arities [n_binds, n_binds-1 .. 1]
] ]
in do in do
body_code <- schemeE d' s p' body body_code <- schemeE d' s p' body
......
...@@ -89,7 +89,8 @@ data BCInstr ...@@ -89,7 +89,8 @@ data BCInstr
-- To do with the heap -- To do with the heap
| ALLOC_AP Int -- make an AP with this many payload words | ALLOC_AP Int -- make an AP with this many payload words
| ALLOC_PAP Int Int -- make a PAP with this arity / payload words | ALLOC_PAP Int Int -- make a PAP with this arity / payload words
| MKAP Int{-ptr to AP/PAP is this far down stack-} Int{-# words-} | MKAP Int{-ptr to AP is this far down stack-} Int{-# words-}
| MKPAP Int{-ptr to PAP is this far down stack-} Int{-# words-}
| UNPACK Int -- unpack N words from t.o.s Constr | UNPACK Int -- unpack N words from t.o.s Constr
| PACK DataCon Int | PACK DataCon Int
-- after assembly, the DataCon is an index into the -- after assembly, the DataCon is an index into the
...@@ -250,5 +251,6 @@ bciStackUse SWIZZLE{} = 0 ...@@ -250,5 +251,6 @@ bciStackUse SWIZZLE{} = 0
-- so can't use this info. Not that it matters much. -- so can't use this info. Not that it matters much.
bciStackUse SLIDE{} = 0 bciStackUse SLIDE{} = 0
bciStackUse MKAP{} = 0 bciStackUse MKAP{} = 0
bciStackUse MKPAP{} = 0
bciStackUse PACK{} = 1 -- worst case is PACK 0 words bciStackUse PACK{} = 1 -- worst case is PACK 0 words
\end{code} \end{code}
...@@ -16,7 +16,7 @@ import NameEnv ...@@ -16,7 +16,7 @@ import NameEnv
import SMRep ( typeCgRep ) import SMRep ( typeCgRep )
import DataCon ( DataCon, dataConRepArgTys ) import DataCon ( DataCon, dataConRepArgTys )
import TyCon ( TyCon, tyConFamilySize, isDataTyCon, tyConDataCons ) import TyCon ( TyCon, tyConFamilySize, isDataTyCon, tyConDataCons )
import Constants ( mIN_SIZE_NonUpdHeapObject, wORD_SIZE ) import Constants ( mIN_PAYLOAD_SIZE, wORD_SIZE )
import CgHeapery ( mkVirtHeapOffsets ) import CgHeapery ( mkVirtHeapOffsets )
import FastString ( FastString(..) ) import FastString ( FastString(..) )
import Util ( lengthIs, listLengthCmp ) import Util ( lengthIs, listLengthCmp )
...@@ -94,8 +94,8 @@ make_constr_itbls cons ...@@ -94,8 +94,8 @@ make_constr_itbls cons
ptrs = ptr_wds ptrs = ptr_wds
nptrs = tot_wds - ptr_wds nptrs = tot_wds - ptr_wds
nptrs_really nptrs_really
| ptrs + nptrs >= mIN_SIZE_NonUpdHeapObject = nptrs | ptrs + nptrs >= mIN_PAYLOAD_SIZE = nptrs
| otherwise = mIN_SIZE_NonUpdHeapObject - ptrs | otherwise = mIN_PAYLOAD_SIZE - ptrs
itbl = StgInfoTable { itbl = StgInfoTable {
ptrs = fromIntegral ptrs, ptrs = fromIntegral ptrs,
nptrs = fromIntegral nptrs_really, nptrs = fromIntegral nptrs_really,
......
...@@ -40,8 +40,7 @@ mAX_SPEC_SELECTEE_SIZE = (MAX_SPEC_SELECTEE_SIZE :: Int) ...@@ -40,8 +40,7 @@ mAX_SPEC_SELECTEE_SIZE = (MAX_SPEC_SELECTEE_SIZE :: Int)
mAX_SPEC_AP_SIZE = (MAX_SPEC_AP_SIZE :: Int) mAX_SPEC_AP_SIZE = (MAX_SPEC_AP_SIZE :: Int)
-- closure sizes: these do NOT include the header (see below for header sizes) -- closure sizes: these do NOT include the header (see below for header sizes)
mIN_UPD_SIZE = (MIN_UPD_SIZE::Int) mIN_PAYLOAD_SIZE = (MIN_PAYLOAD_SIZE::Int)
mIN_SIZE_NonUpdHeapObject = (MIN_NONUPD_SIZE::Int)
\end{code} \end{code}
\begin{code} \begin{code}
......
...@@ -32,7 +32,6 @@ module StaticFlags ( ...@@ -32,7 +32,6 @@ module StaticFlags (
opt_MaxContextReductionDepth, opt_MaxContextReductionDepth,
opt_IrrefutableTuples, opt_IrrefutableTuples,
opt_Parallel, opt_Parallel,
opt_SMP,
opt_RuntimeTypes, opt_RuntimeTypes,
opt_Flatten, opt_Flatten,
...@@ -256,7 +255,6 @@ opt_DictsStrict = lookUp FSLIT("-fdicts-strict") ...@@ -256,7 +255,6 @@ opt_DictsStrict = lookUp FSLIT("-fdicts-strict")
opt_IrrefutableTuples = lookUp FSLIT("-firrefutable-tuples") opt_IrrefutableTuples = lookUp FSLIT("-firrefutable-tuples")
opt_MaxContextReductionDepth = lookup_def_int "-fcontext-stack" mAX_CONTEXT_REDUCTION_DEPTH opt_MaxContextReductionDepth = lookup_def_int "-fcontext-stack" mAX_CONTEXT_REDUCTION_DEPTH
opt_Parallel = lookUp FSLIT("-fparallel") opt_Parallel = lookUp FSLIT("-fparallel")
opt_SMP = lookUp FSLIT("-fsmp")
opt_Flatten = lookUp FSLIT("-fflatten") opt_Flatten = lookUp FSLIT("-fflatten")
-- optimisation opts -- optimisation opts
...@@ -315,7 +313,6 @@ isStaticFlag f = ...@@ -315,7 +313,6 @@ isStaticFlag f =
"fdicts-strict", "fdicts-strict",
"firrefutable-tuples", "firrefutable-tuples",
"fparallel", "fparallel",
"fsmp",
"fflatten", "fflatten",
"fsemi-tagging", "fsemi-tagging",
"flet-no-escape", "flet-no-escape",
...@@ -558,15 +555,15 @@ way_details = ...@@ -558,15 +555,15 @@ way_details =
, "-optc-DGRAN" , "-optc-DGRAN"
, "-package concurrent" ]), , "-package concurrent" ]),
(WaySMP, Way "s" False "SMP" (WaySMP, Way "s" True "SMP"
[ "-fsmp" [
#if !defined(mingw32_TARGET_OS) #if !defined(mingw32_TARGET_OS)
, "-optc-pthread" "-optc-pthread"
#endif #endif
#if !defined(mingw32_TARGET_OS) && !defined(freebsd_TARGET_OS) #if !defined(mingw32_TARGET_OS) && !defined(freebsd_TARGET_OS)
, "-optl-pthread" , "-optl-pthread"
#endif #endif
, "-optc-DSMP" ]), ]),
(WayNDP, Way "ndp" False "Nested data parallelism" (WayNDP, Way "ndp" False "Nested data parallelism"
[ "-fparr" [ "-fparr"
......
...@@ -52,28 +52,29 @@ ...@@ -52,28 +52,29 @@
#define bci_ALLOC_AP 27 #define bci_ALLOC_AP 27
#define bci_ALLOC_PAP 28 #define bci_ALLOC_PAP 28
#define bci_MKAP 29 #define bci_MKAP 29
#define bci_UNPACK 30 #define bci_MKPAP 30
#define bci_PACK 31 #define bci_UNPACK 31
#define bci_TESTLT_I 32 #define bci_PACK 32
#define bci_TESTEQ_I 33 #define bci_TESTLT_I 33
#define bci_TESTLT_F 34 #define bci_TESTEQ_I 34
#define bci_TESTEQ_F 35 #define bci_TESTLT_F 35
#define bci_TESTLT_D 36 #define bci_TESTEQ_F 36
#define bci_TESTEQ_D 37 #define bci_TESTLT_D 37
#define bci_TESTLT_P 38 #define bci_TESTEQ_D 38
#define bci_TESTEQ_P 39 #define bci_TESTLT_P 39
#define bci_CASEFAIL 40 #define bci_TESTEQ_P 40
#define bci_JMP 41 #define bci_CASEFAIL 41
#define bci_CCALL 42 #define bci_JMP 42
#define bci_SWIZZLE 43 #define bci_CCALL 43
#define bci_ENTER 44 #define bci_SWIZZLE 44
#define bci_RETURN 45 #define bci_ENTER 45
#define bci_RETURN_P 46 #define bci_RETURN 46
#define bci_RETURN_N 47 #define bci_RETURN_P 47
#define bci_RETURN_F 48 #define bci_RETURN_N 48
#define bci_RETURN_D 49 #define bci_RETURN_F 49
#define bci_RETURN_L 50 #define bci_RETURN_D 50
#define bci_RETURN_V 51 #define bci_RETURN_L 51
#define bci_RETURN_V 52
/* If a BCO definitely requires less than this many words of stack, /* If a BCO definitely requires less than this many words of stack,
don't include an explicit STKCHECK insn in it. The interpreter don't include an explicit STKCHECK insn in it. The interpreter
......
...@@ -36,9 +36,15 @@ typedef struct { ...@@ -36,9 +36,15 @@ typedef struct {
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
The SMP header The SMP header
In SMP mode, we have an extra word of padding in a thunk's header. A thunk has a padding word to take the updated value. This is so
(Note: thunks only; other closures do not have this padding word). that the update doesn't overwrite the payload, so we can avoid
needing to lock the thunk during entry and update.
Note: this doesn't apply to THUNK_STATICs, which have no payload.
Note: we leave this padding word in all ways, rather than just SMP,
so that we don't have to recompile all our libraries for SMP.
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
typedef struct { typedef struct {
...@@ -62,13 +68,6 @@ typedef struct { ...@@ -62,13 +68,6 @@ typedef struct {
#endif #endif
} StgHeader; } StgHeader;
/*
* In SMP mode, a thunk has a padding word to take the updated value.
* This is so that the update doesn't overwrite the payload, so we can
* avoid needing to lock the thunk during entry and update.
*
* Note: this doesn't apply to THUNK_STATICs, which have no payload.
*/
typedef struct { typedef struct {
const struct _StgInfoTable* info; const struct _StgInfoTable* info;
#ifdef PROFILING #ifdef PROFILING
...@@ -77,11 +76,11 @@ typedef struct { ...@@ -77,11 +76,11 @@ typedef struct {
#ifdef GRAN #ifdef GRAN
StgGranHeader gran; StgGranHeader gran;
#endif #endif
#ifdef SMP
StgSMPThunkHeader smp; StgSMPThunkHeader smp;
#endif
} StgThunkHeader; } StgThunkHeader;
#define THUNK_EXTRA_HEADER_W (sizeofW(StgThunkHeader)-sizeofW(StgHeader))
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Closure Types Closure Types
......
...@@ -340,11 +340,7 @@ ...@@ -340,11 +340,7 @@
* the value from GHC, but it seems like too much trouble to do that * the value from GHC, but it seems like too much trouble to do that
* for StgThunkHeader. * for StgThunkHeader.
*/ */
#ifdef SMP
#define SIZEOF_StgThunkHeader SIZEOF_StgHeader+SIZEOF_StgSMPThunkHeader #define SIZEOF_StgThunkHeader SIZEOF_StgHeader+SIZEOF_StgSMPThunkHeader
#else
#define SIZEOF_StgThunkHeader SIZEOF_StgHeader
#endif
#define StgThunk_payload(__ptr__,__ix__) \ #define StgThunk_payload(__ptr__,__ix__) \
W_[__ptr__+SIZEOF_StgThunkHeader+ WDS(__ix__)] W_[__ptr__+SIZEOF_StgThunkHeader+ WDS(__ix__)]
......
...@@ -20,29 +20,12 @@ ...@@ -20,29 +20,12 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Minimum closure sizes Minimum closure sizes
Here we define the minimum size for updatable closures. All updates This is the minimum number of words in the payload of a
will be performed on closures of this size. For non-updatable closures heap-allocated closure, so that the closure has enough room to be
the minimum size is 1 to allow for a forwarding pointer. overwritten with a forwarding pointer during garbage collection.
When we used to keep the mutable list threaded through closures on
the heap, MIN_UPD_SIZE used to be 2. Now it's 1.
o MIN_UPD_SIZE doesn't apply to stack closures, static closures
or non-updateable objects like PAPs or CONSTRs
o MIN_UPD_SIZE is big enough to contain any of the following:
o EVACUATED
o BLACKHOLE
o BLOCKING QUEUE
o IND, IND_PERM, IND_OLDGEN and IND_OLDGEN_PERM
(it need not be big enough for IND_STATIC - but it is)
o MIN_NONUPD_SIZE doesn't apply to stack closures, static closures
or updateable objects like APs, THUNKS or THUNK_SELECTORs
o MIN_NONUPD_SIZE is big enough to contain any of the following:
o EVACUATED
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
#define MIN_UPD_SIZE 1 #define MIN_PAYLOAD_SIZE 1
#define MIN_NONUPD_SIZE 1
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Constants to do with specialised closure types. Constants to do with specialised closure types.
......
...@@ -312,10 +312,10 @@ INLINE_HEADER StgOffset CONSTR_sizeW( nat p, nat np ) ...@@ -312,10 +312,10 @@ INLINE_HEADER StgOffset CONSTR_sizeW( nat p, nat np )
{ return sizeofW(StgHeader) + p + np; } { return sizeofW(StgHeader) + p + np; }
INLINE_HEADER StgOffset THUNK_SELECTOR_sizeW ( void ) INLINE_HEADER StgOffset THUNK_SELECTOR_sizeW ( void )
{ return stg_max(sizeofW(StgHeader)+MIN_UPD_SIZE, sizeofW(StgSelector)); } { return sizeofW(StgSelector); }
INLINE_HEADER StgOffset BLACKHOLE_sizeW ( void ) INLINE_HEADER StgOffset BLACKHOLE_sizeW ( void )
{ return sizeofW(StgHeader)+MIN_UPD_SIZE; } { return sizeofW(StgHeader)+MIN_PAYLOAD_SIZE; }