-- | Dynamic pointer tagging -- -- See Note [Data constructor dynamic tags] module GHC.Platform.Tag ( DynTag , tAG_MASK , mAX_PTR_TAG , isSmallFamily ) where import GHC.Prelude import GHC.Platform -- | The tag on a pointer (from the dynamic-tagging paper) type DynTag = Int {- Note [Data constructor dynamic tags] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The family size of a data type (the number of constructors or the arity of a function) can be either: * small, if the family size < 2**tag_bits * big, otherwise. Small families can have the constructor tag in the tag bits. Big families always use the tag values 1..mAX_PTR_TAG to represent evaluatedness, the last one lumping together all overflowing ones. We don't have very many tag bits: for example, we have 2 bits on x86-32 and 3 bits on x86-64. Also see Note [Tagging big families] in GHC.StgToCmm.Expr The interpreter also needs to be updated if we change the tagging strategy; see tagConstr in rts/Interpreter.c. -} -- | Tag bits mask / maximum pointer tag value, derived from the -- number of tag bits on the platform. tAG_MASK, mAX_PTR_TAG :: Platform -> Int tAG_MASK :: Platform -> Int tAG_MASK Platform platform = (Int 1 Int -> Int -> Int forall a. Bits a => a -> Int -> a `shiftL` PlatformConstants -> Int pc_TAG_BITS (Platform -> PlatformConstants platformConstants Platform platform)) Int -> Int -> Int forall a. Num a => a -> a -> a - Int 1 mAX_PTR_TAG :: Platform -> Int mAX_PTR_TAG = Platform -> Int tAG_MASK -- | Is a data type family small enough that each constructor can get -- its own pointer tag? isSmallFamily :: Platform -> Int -> Bool isSmallFamily :: Platform -> Int -> Bool isSmallFamily Platform platform Int fam_size = Int fam_size Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <= Platform -> Int mAX_PTR_TAG Platform platform