diff options
author | Simon Marlow <marlowsd@gmail.com> | 2018-04-22 14:28:47 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2018-05-16 13:36:13 +0100 |
commit | 2b0918c9834be1873728176e4944bec26271234a (patch) | |
tree | f47689b64d3339c9cd92ad286fe01db478b53550 /includes | |
parent | fbd28e2c6b5f1302cd2d36d79149e3b0a9f01d84 (diff) | |
download | haskell-2b0918c9834be1873728176e4944bec26271234a.tar.gz |
Save a word in the info table on x86_64
Summary:
An info table with an SRT normally looks like this:
StgWord64 srt_offset
StgClosureInfo layout
StgWord32 layout
StgWord32 has_srt
But we only need 32 bits for srt_offset on x86_64, because the small
memory model requires that code segments are at most 2GB. So we can
optimise this to
StgClosureInfo layout
StgWord32 layout
StgWord32 srt_offset
saving a word. We can tell whether the info table has an SRT or not,
because zero is not a valid srt_offset, so zero still indicates that
there's no SRT.
Test Plan:
* validate
* For results, see D4632.
Reviewers: bgamari, niteria, osa1, erikd
Subscribers: thomie, carter
Differential Revision: https://phabricator.haskell.org/D4634
Diffstat (limited to 'includes')
-rw-r--r-- | includes/rts/storage/ClosureMacros.h | 2 | ||||
-rw-r--r-- | includes/rts/storage/InfoTables.h | 48 |
2 files changed, 40 insertions, 10 deletions
diff --git a/includes/rts/storage/ClosureMacros.h b/includes/rts/storage/ClosureMacros.h index 2b78ab44b8..7a3ecaa1d2 100644 --- a/includes/rts/storage/ClosureMacros.h +++ b/includes/rts/storage/ClosureMacros.h @@ -109,7 +109,7 @@ INLINE_HEADER const StgConInfoTable *get_con_itbl(const StgClosure *c) INLINE_HEADER StgHalfWord GET_TAG(const StgClosure *con) { - return get_itbl(con)->has_srt; + return get_itbl(con)->srt; } /* ----------------------------------------------------------------------------- diff --git a/includes/rts/storage/InfoTables.h b/includes/rts/storage/InfoTables.h index 0e25e14c8e..8107510321 100644 --- a/includes/rts/storage/InfoTables.h +++ b/includes/rts/storage/InfoTables.h @@ -153,6 +153,21 @@ typedef union { } StgClosureInfo; +#if defined(x86_64_TARGET_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. +#define USE_INLINE_SRT_FIELD +#endif + +#if defined(USE_INLINE_SRT_FIELD) +// offset to the SRT / closure, or zero if there's no SRT +typedef StgHalfInt StgSRTField; +#else +// non-zero if there is an SRT, the offset is in the optional srt field. +typedef StgHalfWord StgSRTField; +#endif + + /* * The "standard" part of an info table. Every info table has this bit. */ @@ -169,11 +184,14 @@ typedef struct StgInfoTable_ { StgClosureInfo layout; /* closure layout info (one word) */ StgHalfWord type; /* closure type */ - StgHalfWord has_srt; + StgSRTField srt; /* In a CONSTR: - the constructor tag In a FUN/THUNK - - non-zero if there is an SRT + - if USE_INLINE_SRT_FIELD + - offset to the SRT (or zero if no SRT) + - otherwise + - non-zero if there is an SRT, offset is in srt_offset */ #if defined(TABLES_NEXT_TO_CODE) @@ -214,7 +232,9 @@ typedef struct StgFunInfoExtraRev_ { StgWord bitmap; OFFSET_FIELD(bitmap_offset); /* arg ptr/nonptr bitmap */ } b; +#if !defined(USE_INLINE_SRT_FIELD) OFFSET_FIELD(srt_offset); /* pointer to the SRT closure */ +#endif StgHalfWord fun_type; /* function type */ StgHalfWord arity; /* function arity */ } StgFunInfoExtraRev; @@ -253,7 +273,9 @@ extern const StgWord stg_arg_bitmaps[]; typedef struct { #if defined(TABLES_NEXT_TO_CODE) +#if !defined(USE_INLINE_SRT_FIELD) OFFSET_FIELD(srt_offset); /* offset to the SRT closure */ +#endif StgInfoTable i; #else StgInfoTable i; @@ -271,16 +293,14 @@ typedef struct { */ typedef struct StgThunkInfoTable_ { -#if !defined(TABLES_NEXT_TO_CODE) - StgInfoTable i; -#endif #if defined(TABLES_NEXT_TO_CODE) +#if !defined(USE_INLINE_SRT_FIELD) OFFSET_FIELD(srt_offset); /* offset to the SRT closure */ -#else - StgClosure *srt; /* pointer to the SRT closure */ #endif -#if defined(TABLES_NEXT_TO_CODE) StgInfoTable i; +#else + StgInfoTable i; + StgClosure *srt; /* pointer to the SRT closure */ #endif } StgThunkInfoTable; @@ -315,9 +335,14 @@ typedef struct StgConInfoTable_ { * info must be a Stg[Ret|Thunk]InfoTable* (an info table that has a SRT) */ #if defined(TABLES_NEXT_TO_CODE) +#if x86_64_TARGET_ARCH #define GET_SRT(info) \ - ((StgClosure*) (((StgWord) ((info)+1)) + (info)->srt_offset)) + ((StgClosure*) (((StgWord) ((info)+1)) + (info)->i.srt)) #else +#define GET_SRT(info) \ + ((StgClosure*) (((StgWord) ((info)+1)) + (info)->srt_offset)) +#endif +#else // !TABLES_NEXT_TO_CODE #define GET_SRT(info) ((info)->srt) #endif @@ -337,8 +362,13 @@ typedef struct StgConInfoTable_ { * info must be a StgFunInfoTable* */ #if defined(TABLES_NEXT_TO_CODE) +#if x86_64_TARGET_ARCH +#define GET_FUN_SRT(info) \ + ((StgClosure*) (((StgWord) ((info)+1)) + (info)->i.srt)) +#else #define GET_FUN_SRT(info) \ ((StgClosure*) (((StgWord) ((info)+1)) + (info)->f.srt_offset)) +#endif #else #define GET_FUN_SRT(info) ((info)->f.srt) #endif |