summaryrefslogtreecommitdiff
path: root/compiler/GHC/Stg
diff options
context:
space:
mode:
authorSven Tennie <sven.tennie@gmail.com>2021-04-03 19:35:34 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-09-23 15:59:38 -0400
commit29717ecb0711cd03796510fbe9b4bff58c7da870 (patch)
tree850a449ef01caeedf8fd8e9156e7eedcd5a028ce /compiler/GHC/Stg
parent6f7f59901c047882ba8c9ae8812264f86b12483a (diff)
downloadhaskell-29717ecb0711cd03796510fbe9b4bff58c7da870.tar.gz
Use Info Table Provenances to decode cloned stack (#18163)
Emit an Info Table Provenance Entry (IPE) for every stack represeted info table if -finfo-table-map is turned on. To decode a cloned stack, lookupIPE() is used. It provides a mapping between info tables and their source location. Please see these notes for details: - [Stacktraces from Info Table Provenance Entries (IPE based stack unwinding)] - [Mapping Info Tables to Source Positions] Metric Increase: T12545
Diffstat (limited to 'compiler/GHC/Stg')
-rw-r--r--compiler/GHC/Stg/Debug.hs50
1 files changed, 28 insertions, 22 deletions
diff --git a/compiler/GHC/Stg/Debug.hs b/compiler/GHC/Stg/Debug.hs
index 77ef7910ec..bea6fe5c8e 100644
--- a/compiler/GHC/Stg/Debug.hs
+++ b/compiler/GHC/Stg/Debug.hs
@@ -33,7 +33,7 @@ data R = R { rDynFlags :: DynFlags, rModLocation :: ModLocation, rSpan :: Maybe
type M a = ReaderT R (State InfoTableProvMap) a
-withSpan :: (RealSrcSpan, String) -> M a -> M a
+withSpan :: IpeSourceLocation -> M a -> M a
withSpan (new_s, new_l) act = local maybe_replace act
where
maybe_replace r@R{ rModLocation = cur_mod, rSpan = Just (SpanWithLabel old_s _old_l) }
@@ -171,16 +171,21 @@ to a position in the source. The prime example is being able to map a THUNK to
a specific place in the source program, the mapping is usually quite precise because
a fresh info table is created for each distinct THUNK.
+The info table map is also used to generate stacktraces.
+See Note [Stacktraces from Info Table Provenance Entries (IPE based stack unwinding)]
+for details.
+
There are three parts to the implementation
-1. In GHC.Stg.Debug, the SourceNote information is used in order to give a source location to
-some specific closures.
-2. In StgToCmm, the actually used info tables are recorded in an IORef, this
-is important as it's hard to predict beforehand what code generation will do
-and which ids will end up in the generated program.
-3. During code generation, a mapping from the info table to the statically
-determined location is emitted which can then be queried at runtime by
-various tools.
+1. In GHC.Stg.Debug, the SourceNote information is used in order to give a source location
+ to some specific closures.
+2. In GHC.Driver.GenerateCgIPEStub, the actually used info tables are collected after the
+ Cmm pipeline. This is important as it's hard to predict beforehand what code generation
+ will do and which ids will end up in the generated program. Additionally, info tables of
+ return frames (used to create stacktraces) are generated in the Cmm pipeline and aren't
+ available before.
+3. During code generation, a mapping from the info table to the statically determined location
+ is emitted which can then be queried at runtime by various tools.
-- Giving Source Locations to Closures
@@ -189,6 +194,8 @@ is collected in the `InfoTableProvMap` which provides a mapping from:
1. Data constructors to a list of where they are used.
2. `Name`s and where they originate from.
+3. Stack represented info tables (return frames) to an approximated source location
+ of the call that pushed a contiunation on the stacks.
During the CoreToStg phase, this map is populated whenever something is turned into
a StgRhsClosure or an StgConApp. The current source position is recorded
@@ -197,28 +204,27 @@ depending on the location indicated by the surrounding SourceNote.
The functions which add information to the map are `recordStgIdPosition` and
`numberDataCon`.
-When the -fdistinct-constructor-tables` flag is turned on then every
+When the `-fdistinct-constructor-tables` flag is turned on then every
usage of a data constructor gets its own distinct info table. This is orchestrated
in `collectExpr` where an incrementing number is used to distinguish each
occurrence of a data constructor.
--- StgToCmm
+-- GenerateCgIPEStub
+
+The info tables which are actually used in the generated program are collected after
+the Cmm pipeline. `initInfoTableProv` is used to create a CStub, that initializes the
+map in C code.
-The info tables which are actually used in the generated program are recorded during the
-conversion from STG to Cmm. The used info tables are recorded in the `emitProc` function.
-All the used info tables are recorded in the `cgs_used_info` field. This step
-is necessary because when the information about names is collected in the previous
-phase it's unpredictable about which names will end up needing info tables. If
-you don't record which ones are actually used then you end up generating code
-which references info tables which don't exist.
+This step has to be done after the Cmm pipeline to make sure that all info tables are
+really used and, even more importantly, return frame info tables are generated by the
+pipeline.
-- Code Generation
The output of these two phases is combined together during code generation.
-A C stub is generated which
-creates the static map from info table pointer to the information about where that
-info table was created from. This is created by `ipInitCode` in the same manner as a
-C stub is generated for cost centres.
+A C stub is generated which creates the static map from info table pointer to the
+information about where that info table was created from. This is created by
+`ipInitCode` in the same manner as a C stub is generated for cost centres.
This information can be consumed in two ways.