summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2020-11-18 11:23:00 +0000
committerMatthew Pickering <matthewtpickering@gmail.com>2021-03-03 19:09:34 +0000
commit8402ea951b31e01a925ca691747d1757eaf31fcc (patch)
tree674d19535ff5bbd3c31ae723e62b148f240f4bb1
parent2f7e879bd993b61d26db999246b34c1096d0f70e (diff)
downloadhaskell-8402ea951b31e01a925ca691747d1757eaf31fcc.tar.gz
Profiling by info table mode (-hi)
This profiling mode creates bands by the address of the info table for each closure. This provides a much more fine-grained profiling output than any of the other profiling modes. The `-hi` profiling mode does not require a profiling build.
-rw-r--r--docs/users_guide/profiling.rst5
-rw-r--r--includes/rts/EventLogFormat.h3
-rw-r--r--includes/rts/Flags.h11
-rw-r--r--libraries/base/GHC/RTS/Flags.hsc3
-rw-r--r--rts/ProfHeap.c9
-rw-r--r--rts/RtsFlags.c8
-rw-r--r--rts/eventlog/EventLog.c2
7 files changed, 35 insertions, 6 deletions
diff --git a/docs/users_guide/profiling.rst b/docs/users_guide/profiling.rst
index 6eb5008146..75569f6409 100644
--- a/docs/users_guide/profiling.rst
+++ b/docs/users_guide/profiling.rst
@@ -800,6 +800,11 @@ following RTS options select which break-down to use:
Biographical profiling is described in more detail below
(:ref:`biography-prof`).
+.. rts-flag:: -hi
+
+ Break down the graph by the address of the info table of a closure. This
+ profiling mode is intended to be used with :ghc-flag:`-finfo-table-map`.
+
.. rts-flag:: -l
:noindex:
diff --git a/includes/rts/EventLogFormat.h b/includes/rts/EventLogFormat.h
index 340a12d4e9..4b50adfe5b 100644
--- a/includes/rts/EventLogFormat.h
+++ b/includes/rts/EventLogFormat.h
@@ -221,7 +221,8 @@ typedef enum {
HEAP_PROF_BREAKDOWN_TYPE_DESCR,
HEAP_PROF_BREAKDOWN_RETAINER,
HEAP_PROF_BREAKDOWN_BIOGRAPHY,
- HEAP_PROF_BREAKDOWN_CLOSURE_TYPE
+ HEAP_PROF_BREAKDOWN_CLOSURE_TYPE,
+ HEAP_PROF_BREAKDOWN_INFO_TABLE
} HeapProfBreakdown;
#if !defined(EVENTLOG_CONSTANTS_ONLY)
diff --git a/includes/rts/Flags.h b/includes/rts/Flags.h
index 204ec525ac..eda961656d 100644
--- a/includes/rts/Flags.h
+++ b/includes/rts/Flags.h
@@ -132,15 +132,16 @@ typedef struct _COST_CENTRE_FLAGS {
/* See Note [Synchronization of flags and base APIs] */
typedef struct _PROFILING_FLAGS {
uint32_t doHeapProfile;
-# define NO_HEAP_PROFILING 0 /* N.B. Used as indexes into arrays */
-# define HEAP_BY_CCS 1
-# define HEAP_BY_MOD 2
-# define HEAP_BY_DESCR 4
-# define HEAP_BY_TYPE 5
+# define NO_HEAP_PROFILING 0 /* N.B. Used as indexes into arrays */
+# define HEAP_BY_CCS 1
+# define HEAP_BY_MOD 2
+# define HEAP_BY_DESCR 4
+# define HEAP_BY_TYPE 5
# define HEAP_BY_RETAINER 6
# define HEAP_BY_LDV 7
# define HEAP_BY_CLOSURE_TYPE 8
+# define HEAP_BY_INFO_TABLE 9
Time heapProfileInterval; /* time between samples */
uint32_t heapProfileIntervalTicks; /* ticks between samples (derived) */
diff --git a/libraries/base/GHC/RTS/Flags.hsc b/libraries/base/GHC/RTS/Flags.hsc
index 2f161c72c3..2abe5d7d85 100644
--- a/libraries/base/GHC/RTS/Flags.hsc
+++ b/libraries/base/GHC/RTS/Flags.hsc
@@ -256,6 +256,7 @@ data DoHeapProfile
| HeapByRetainer
| HeapByLDV
| HeapByClosureType
+ | HeapByInfoTable
deriving ( Show -- ^ @since 4.8.0.0
, Generic -- ^ @since 4.15.0.0
)
@@ -270,6 +271,7 @@ instance Enum DoHeapProfile where
fromEnum HeapByRetainer = #{const HEAP_BY_RETAINER}
fromEnum HeapByLDV = #{const HEAP_BY_LDV}
fromEnum HeapByClosureType = #{const HEAP_BY_CLOSURE_TYPE}
+ fromEnum HeapByInfoTable = #{const HEAP_BY_INFO_TABLE}
toEnum #{const NO_HEAP_PROFILING} = NoHeapProfiling
toEnum #{const HEAP_BY_CCS} = HeapByCCS
@@ -279,6 +281,7 @@ instance Enum DoHeapProfile where
toEnum #{const HEAP_BY_RETAINER} = HeapByRetainer
toEnum #{const HEAP_BY_LDV} = HeapByLDV
toEnum #{const HEAP_BY_CLOSURE_TYPE} = HeapByClosureType
+ toEnum #{const HEAP_BY_INFO_TABLE} = HeapByInfoTable
toEnum e = errorWithoutStackTrace ("invalid enum for DoHeapProfile: " ++ show e)
-- | Parameters of the cost-center profiler
diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c
index f880f5f406..b05c34d80f 100644
--- a/rts/ProfHeap.c
+++ b/rts/ProfHeap.c
@@ -197,6 +197,9 @@ closureIdentity( const StgClosure *p )
return closure_type_names[info->type];
}
}
+ case HEAP_BY_INFO_TABLE: {
+ return get_itbl(p);
+ }
default:
barf("closureIdentity");
@@ -905,6 +908,12 @@ dumpCensus( Census *census )
traceHeapProfSampleString(0, (char *)ctr->identity,
count * sizeof(W_));
break;
+ case HEAP_BY_INFO_TABLE:
+ fprintf(hp_file, "%p", ctr->identity);
+ char str[100];
+ sprintf(str, "%p", ctr->identity);
+ traceHeapProfSampleString(0, str, count * sizeof(W_));
+ break;
#if defined(PROFILING)
case HEAP_BY_CCS:
fprint_ccs(hp_file, (CostCentreStack *)ctr->identity,
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c
index bc7e86901f..fa4af7f7a6 100644
--- a/rts/RtsFlags.c
+++ b/rts/RtsFlags.c
@@ -1409,6 +1409,10 @@ error = true;
OPTION_UNSAFE;
RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CLOSURE_TYPE;
break;
+ case 'i':
+ OPTION_UNSAFE;
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_INFO_TABLE;
+ break;
default:
OPTION_SAFE;
PROFILING_BUILD_ONLY();
@@ -2173,6 +2177,7 @@ static bool read_heap_profiling_flag(const char *arg)
case 'd':
case 'Y':
case 'y':
+ case 'i':
case 'R':
case 'r':
case 'B':
@@ -2253,6 +2258,9 @@ static bool read_heap_profiling_flag(const char *arg)
case 'y':
RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_TYPE;
break;
+ case 'i':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_INFO_TABLE;
+ break;
case 'R':
case 'r':
RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_RETAINER;
diff --git a/rts/eventlog/EventLog.c b/rts/eventlog/EventLog.c
index 876f1ff7b6..c1eda283f5 100644
--- a/rts/eventlog/EventLog.c
+++ b/rts/eventlog/EventLog.c
@@ -1410,6 +1410,8 @@ static HeapProfBreakdown getHeapProfBreakdown(void)
return HEAP_PROF_BREAKDOWN_BIOGRAPHY;
case HEAP_BY_CLOSURE_TYPE:
return HEAP_PROF_BREAKDOWN_CLOSURE_TYPE;
+ case HEAP_BY_INFO_TABLE:
+ return HEAP_PROF_BREAKDOWN_INFO_TABLE;
default:
barf("getHeapProfBreakdown: unknown heap profiling mode");
}