summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2021-09-23 20:13:42 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-12-01 03:08:07 -0500
commit4acfa0db473fa04a434c38b44da195d5c4455956 (patch)
treecc4c5db59f69b4ebe2b44ab4fb2a9c08d6aa2487
parentc7613493e637718492f03c2f9a020198244a7b18 (diff)
downloadhaskell-4acfa0db473fa04a434c38b44da195d5c4455956.tar.gz
rts: Refactor SRT representation selection
The goal here is to make the SRT selection logic a bit clearer and allow configurations which we currently don't support (e.g. using a full word in the info table even when TNTC is used).
-rw-r--r--compiler/GHC/Cmm/Info.hs3
-rw-r--r--compiler/GHC/Cmm/Info/Build.hs37
-rw-r--r--rts/include/rts/storage/InfoTables.h64
-rw-r--r--utils/deriveConstants/Main.hs5
4 files changed, 72 insertions, 37 deletions
diff --git a/compiler/GHC/Cmm/Info.hs b/compiler/GHC/Cmm/Info.hs
index d0397c8172..06100aa176 100644
--- a/compiler/GHC/Cmm/Info.hs
+++ b/compiler/GHC/Cmm/Info.hs
@@ -283,8 +283,7 @@ mkSRTLit platform _ (Just lbl) = ([CmmLabel lbl], CmmInt 1 (halfWordWidth platfo
-- See the section "Referring to an SRT from the info table" in
-- Note [SRTs] in "GHC.Cmm.Info.Build"
inlineSRT :: Platform -> Bool
-inlineSRT platform = platformArch platform == ArchX86_64
- && platformTablesNextToCode platform
+inlineSRT = pc_USE_INLINE_SRT_FIELD . platformConstants
-------------------------------------------------------------------------
--
diff --git a/compiler/GHC/Cmm/Info/Build.hs b/compiler/GHC/Cmm/Info/Build.hs
index ab0c32996e..191415274e 100644
--- a/compiler/GHC/Cmm/Info/Build.hs
+++ b/compiler/GHC/Cmm/Info/Build.hs
@@ -55,6 +55,7 @@ import Data.List (unzip4)
import GHC.Types.Name.Set
{- Note [SRTs]
+ ~~~~~~~~~~~
SRTs are the mechanism by which the garbage collector can determine
the live CAFs in the program.
@@ -112,9 +113,15 @@ The following things have SRTs:
- Static thunks (THUNK), ie. CAFs
- Continuations (RET_SMALL, etc.)
-In each case, the info table points to the SRT.
+In each case, the info table points to the SRT. There are three ways which we
+may encode the location of the SRT in the info table, described below.
-- info->srt is zero if there's no SRT, otherwise:
+USE_SRT_OFFSET
+--------------
+In this case we use the info->srt to encode whether or not there is an
+SRT and if so encode the offset to its location in info->f.srt_offset:
+
+- info->srt is 0 if there's no SRT, otherwise,
- info->srt == 1 and info->f.srt_offset points to the SRT
e.g. for a FUN with an SRT:
@@ -128,11 +135,26 @@ StgStdInfoTable +------+
info->type | ... |
|------|
-On x86_64, we optimise the info table representation further. The
-offset to the SRT can be stored in 32 bits (all code lives within a
-2GB region in x86_64's small memory model), so we can save a word in
-the info table by storing the srt_offset in the srt field, which is
-half a word.
+USE_SRT_POINTER
+---------------
+When tables-next-to-code isn't in use we rather encode an absolute pointer to
+the SRT in info->srt. e.g. for a FUN with an SRT:
+
+StgFunInfoTable +------+
+ info->f.srt_offset | ------------> pointer to SRT object
+StgStdInfoTable +------+
+ info->layout.ptrs | ... |
+ info->layout.nptrs | ... |
+ info->srt | 1 |
+ info->type | ... |
+ |------|
+USE_INLINE_SRT_FIELD
+--------------------
+When using TNTC on x86_64 (and other platforms using the small memory model),
+we optimise the info table representation further. The offset to the SRT can
+be stored in 32 bits (all code lives within a 2GB region in x86_64's small
+memory model), so we can save a word in the info table by storing the
+srt_offset in the srt field, which is half a word.
On x86_64 with TABLES_NEXT_TO_CODE (except on MachO, due to #15169):
@@ -368,6 +390,7 @@ Here we could use C = {A} and therefore [Inline] C = A.
-- ---------------------------------------------------------------------
{- Note [Invalid optimisation: shortcutting]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You might think that if we have something like
diff --git a/rts/include/rts/storage/InfoTables.h b/rts/include/rts/storage/InfoTables.h
index b97e12982b..55d9ad6542 100644
--- a/rts/include/rts/storage/InfoTables.h
+++ b/rts/include/rts/storage/InfoTables.h
@@ -16,6 +16,7 @@
position-independent code.
Note [x86-64-relative]
+ ~~~~~~~~~~~~~~~~~~~~~~
There is a complication on the x86_64 platform, where pointers are
64 bits, but the tools don't support 64-bit relative relocations.
However, the default memory model (small) ensures that all symbols
@@ -153,13 +154,26 @@ typedef union {
} StgClosureInfo;
-#if defined(x86_64_HOST_ARCH) && defined(TABLES_NEXT_TO_CODE)
-// On x86_64 we can fit a pointer offset in half a word, so put the SRT offset
-// in the info->srt field directly.
+#if defined(x86_64_HOST_ARCH)
+#define SMALL_MEMORY_MODEL
+#endif
+
+// This is where we choose how to represent the SRT location in the info
+// table. See the section "Referring to an SRT from the info table" in
+// Note [SRTs] in GHC.Cmm.Info.Build.
//
-// See the section "Referring to an SRT from the info table" in
-// Note [SRTs] in CmmBuildInfoTables.hs
+// Specifically we define one of the following:
+#if WORD_SIZE_IN_BITS == 64 && defined(SMALL_MEMORY_MODEL) && defined(TABLES_NEXT_TO_CODE)
+// On 64-bit platforms using the small memory model we can fit a pointer
+// offset in half a word, so put the SRT offset in the info->srt field
+// directly.
#define USE_INLINE_SRT_FIELD
+#elif defined(TABLES_NEXT_TO_CODE)
+// Otherwise use the srt_offset field...
+#define USE_SRT_OFFSET
+#else
+// If not using tables-next-to-code then simply use a full pointer...
+#define USE_SRT_POINTER
#endif
#if defined(USE_INLINE_SRT_FIELD)
@@ -219,14 +233,16 @@ typedef struct StgInfoTable_ {
-------------------------------------------------------------------------- */
/*
- Note [Encoding static reference tables]
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- As static reference tables appear frequently in code, we use a special
- compact encoding for the common case of a module defining only a few CAFs: We
- produce one table containing a list of CAFs in the module and then include a
- bitmap in each info table describing which entries of this table the closure
- references.
+ * Note [Encoding static reference tables]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ * As static reference tables appear frequently in code, we use a special
+ * compact encoding for the common case of a module defining only a few CAFs: We
+ * produce one table containing a list of CAFs in the module and then include a
+ * bitmap in each info table describing which entries of this table the closure
+ * references.
+ *
+ * See Note [SRTs] in "GHC.Cmm.Info.Build".
*/
typedef struct StgFunInfoExtraRev_ {
@@ -275,8 +291,8 @@ extern const StgWord stg_arg_bitmaps[];
*/
typedef struct {
-#if defined(TABLES_NEXT_TO_CODE)
-#if !defined(USE_INLINE_SRT_FIELD)
+#if !defined(USE_SRT_POINTER)
+#if defined(USE_SRT_OFFSET)
OFFSET_FIELD(srt_offset); /* offset to the SRT closure */
#endif
StgInfoTable i;
@@ -296,8 +312,8 @@ typedef struct {
*/
typedef struct StgThunkInfoTable_ {
-#if defined(TABLES_NEXT_TO_CODE)
-#if !defined(USE_INLINE_SRT_FIELD)
+#if !defined(USE_SRT_POINTER)
+#if defined(USE_SRT_OFFSET)
OFFSET_FIELD(srt_offset); /* offset to the SRT closure */
#endif
StgInfoTable i;
@@ -337,15 +353,13 @@ typedef struct StgConInfoTable_ {
* GET_SRT(info)
* info must be a Stg[Ret|Thunk]InfoTable* (an info table that has a SRT)
*/
-#if defined(TABLES_NEXT_TO_CODE)
-#if defined(x86_64_HOST_ARCH)
+#if defined(USE_INLINE_SRT_FIELD)
#define GET_SRT(info) \
((StgClosure*) (((StgWord) ((info)+1)) + (info)->i.srt))
-#else
+#elif defined(USE_SRT_OFFSET)
#define GET_SRT(info) \
((StgClosure*) (((StgWord) ((info)+1)) + (info)->srt_offset))
-#endif
-#else // !TABLES_NEXT_TO_CODE
+#else
#define GET_SRT(info) ((info)->srt)
#endif
@@ -364,14 +378,12 @@ typedef struct StgConInfoTable_ {
* GET_FUN_SRT(info)
* info must be a StgFunInfoTable*
*/
-#if defined(TABLES_NEXT_TO_CODE)
-#if defined(x86_64_HOST_ARCH)
+#if defined(USE_INLINE_SRT_FIELD)
#define GET_FUN_SRT(info) \
((StgClosure*) (((StgWord) ((info)+1)) + (info)->i.srt))
-#else
+#elif defined(USE_SRT_OFFSET)
#define GET_FUN_SRT(info) \
((StgClosure*) (((StgWord) ((info)+1)) + (info)->f.srt_offset))
-#endif
#else
#define GET_FUN_SRT(info) ((info)->f.srt)
#endif
diff --git a/utils/deriveConstants/Main.hs b/utils/deriveConstants/Main.hs
index f5ccad3641..7121e74245 100644
--- a/utils/deriveConstants/Main.hs
+++ b/utils/deriveConstants/Main.hs
@@ -167,8 +167,8 @@ constantWord w name expr = [(w, GetWord name (Fst (CExpr expr)))]
constantNatural :: Where -> Name -> String -> Wanteds
constantNatural w name expr = [(w, GetNatural name (Fst (CExpr expr)))]
--- constantBool :: Where -> Name -> String -> Wanteds
--- constantBool w name expr = [(w, GetBool name (Fst (CPPExpr expr)))]
+constantBool :: Where -> Name -> String -> Wanteds
+constantBool w name expr = [(w, GetBool name (Fst (CPPExpr expr)))]
fieldOffset :: Where -> String -> String -> Wanteds
fieldOffset w theType theField = fieldOffset_ w nameBase theType theField
@@ -673,6 +673,7 @@ wanteds os = concat
,constantNatural Haskell "ILDV_CREATE_MASK" "LDV_CREATE_MASK"
,constantNatural Haskell "ILDV_STATE_CREATE" "LDV_STATE_CREATE"
,constantNatural Haskell "ILDV_STATE_USE" "LDV_STATE_USE"
+ ,constantBool Haskell "USE_INLINE_SRT_FIELD" "defined(USE_INLINE_SRT_FIELD)"
]
getWanted :: Bool -> String -> FilePath -> FilePath -> [String] -> FilePath -> Maybe FilePath