summaryrefslogtreecommitdiff
path: root/includes/rts
diff options
context:
space:
mode:
Diffstat (limited to 'includes/rts')
-rw-r--r--includes/rts/Bytecodes.h116
-rw-r--r--includes/rts/Constants.h21
-rw-r--r--includes/rts/EventLogFormat.h19
-rw-r--r--includes/rts/Flags.h7
-rw-r--r--includes/rts/Libdw.h6
-rw-r--r--includes/rts/Linker.h14
-rw-r--r--includes/rts/Messages.h3
-rw-r--r--includes/rts/OSThreads.h2
-rw-r--r--includes/rts/Profiling.h17
-rw-r--r--includes/rts/SpinLock.h5
-rw-r--r--includes/rts/StableName.h32
-rw-r--r--includes/rts/StablePtr.h (renamed from includes/rts/Stable.h)11
-rw-r--r--includes/rts/Threads.h2
-rw-r--r--includes/rts/Time.h4
-rw-r--r--includes/rts/storage/Block.h11
-rw-r--r--includes/rts/storage/ClosureMacros.h60
-rw-r--r--includes/rts/storage/ClosureTypes.h18
-rw-r--r--includes/rts/storage/Closures.h22
-rw-r--r--includes/rts/storage/GC.h14
-rw-r--r--includes/rts/storage/Heap.h18
-rw-r--r--includes/rts/storage/InfoTables.h96
21 files changed, 310 insertions, 188 deletions
diff --git a/includes/rts/Bytecodes.h b/includes/rts/Bytecodes.h
index 6ca74bf36e..e5d55f694f 100644
--- a/includes/rts/Bytecodes.h
+++ b/includes/rts/Bytecodes.h
@@ -27,58 +27,70 @@
#define bci_PUSH_L 2
#define bci_PUSH_LL 3
#define bci_PUSH_LLL 4
-#define bci_PUSH_G 5
-#define bci_PUSH_ALTS 6
-#define bci_PUSH_ALTS_P 7
-#define bci_PUSH_ALTS_N 8
-#define bci_PUSH_ALTS_F 9
-#define bci_PUSH_ALTS_D 10
-#define bci_PUSH_ALTS_L 11
-#define bci_PUSH_ALTS_V 12
-#define bci_PUSH_UBX 13
-#define bci_PUSH_APPLY_N 14
-#define bci_PUSH_APPLY_F 15
-#define bci_PUSH_APPLY_D 16
-#define bci_PUSH_APPLY_L 17
-#define bci_PUSH_APPLY_V 18
-#define bci_PUSH_APPLY_P 19
-#define bci_PUSH_APPLY_PP 20
-#define bci_PUSH_APPLY_PPP 21
-#define bci_PUSH_APPLY_PPPP 22
-#define bci_PUSH_APPLY_PPPPP 23
-#define bci_PUSH_APPLY_PPPPPP 24
-/* #define bci_PUSH_APPLY_PPPPPPP 25 */
-#define bci_SLIDE 26
-#define bci_ALLOC_AP 27
-#define bci_ALLOC_AP_NOUPD 28
-#define bci_ALLOC_PAP 29
-#define bci_MKAP 30
-#define bci_MKPAP 31
-#define bci_UNPACK 32
-#define bci_PACK 33
-#define bci_TESTLT_I 34
-#define bci_TESTEQ_I 35
-#define bci_TESTLT_F 36
-#define bci_TESTEQ_F 37
-#define bci_TESTLT_D 38
-#define bci_TESTEQ_D 39
-#define bci_TESTLT_P 40
-#define bci_TESTEQ_P 41
-#define bci_CASEFAIL 42
-#define bci_JMP 43
-#define bci_CCALL 44
-#define bci_SWIZZLE 45
-#define bci_ENTER 46
-#define bci_RETURN 47
-#define bci_RETURN_P 48
-#define bci_RETURN_N 49
-#define bci_RETURN_F 50
-#define bci_RETURN_D 51
-#define bci_RETURN_L 52
-#define bci_RETURN_V 53
-#define bci_BRK_FUN 54
-#define bci_TESTLT_W 55
-#define bci_TESTEQ_W 56
+#define bci_PUSH8 5
+#define bci_PUSH16 6
+#define bci_PUSH32 7
+#define bci_PUSH8_W 8
+#define bci_PUSH16_W 9
+#define bci_PUSH32_W 10
+#define bci_PUSH_G 11
+#define bci_PUSH_ALTS 12
+#define bci_PUSH_ALTS_P 13
+#define bci_PUSH_ALTS_N 14
+#define bci_PUSH_ALTS_F 15
+#define bci_PUSH_ALTS_D 16
+#define bci_PUSH_ALTS_L 17
+#define bci_PUSH_ALTS_V 18
+#define bci_PUSH_PAD8 19
+#define bci_PUSH_PAD16 20
+#define bci_PUSH_PAD32 21
+#define bci_PUSH_UBX8 22
+#define bci_PUSH_UBX16 23
+#define bci_PUSH_UBX32 24
+#define bci_PUSH_UBX 25
+#define bci_PUSH_APPLY_N 26
+#define bci_PUSH_APPLY_F 27
+#define bci_PUSH_APPLY_D 28
+#define bci_PUSH_APPLY_L 29
+#define bci_PUSH_APPLY_V 30
+#define bci_PUSH_APPLY_P 31
+#define bci_PUSH_APPLY_PP 32
+#define bci_PUSH_APPLY_PPP 33
+#define bci_PUSH_APPLY_PPPP 34
+#define bci_PUSH_APPLY_PPPPP 35
+#define bci_PUSH_APPLY_PPPPPP 36
+/* #define bci_PUSH_APPLY_PPPPPPP 37 */
+#define bci_SLIDE 38
+#define bci_ALLOC_AP 39
+#define bci_ALLOC_AP_NOUPD 40
+#define bci_ALLOC_PAP 41
+#define bci_MKAP 42
+#define bci_MKPAP 43
+#define bci_UNPACK 44
+#define bci_PACK 45
+#define bci_TESTLT_I 46
+#define bci_TESTEQ_I 47
+#define bci_TESTLT_F 48
+#define bci_TESTEQ_F 49
+#define bci_TESTLT_D 50
+#define bci_TESTEQ_D 51
+#define bci_TESTLT_P 52
+#define bci_TESTEQ_P 53
+#define bci_CASEFAIL 54
+#define bci_JMP 55
+#define bci_CCALL 56
+#define bci_SWIZZLE 57
+#define bci_ENTER 58
+#define bci_RETURN 59
+#define bci_RETURN_P 60
+#define bci_RETURN_N 61
+#define bci_RETURN_F 62
+#define bci_RETURN_D 63
+#define bci_RETURN_L 64
+#define bci_RETURN_V 65
+#define bci_BRK_FUN 66
+#define bci_TESTLT_W 67
+#define bci_TESTEQ_W 68
/* If you need to go past 255 then you will run into the flags */
/* If you need to go below 0x0100 then you will run into the instructions */
diff --git a/includes/rts/Constants.h b/includes/rts/Constants.h
index 27097bf45b..2f0ee5b10d 100644
--- a/includes/rts/Constants.h
+++ b/includes/rts/Constants.h
@@ -113,16 +113,33 @@
/* -----------------------------------------------------------------------------
How large is the stack frame saved by StgRun?
world. Used in StgCRun.c.
+
+ The size has to be enough to save the registers (see StgCRun)
+ plus padding if the result is not 16 byte aligned.
+ See the Note [Stack Alignment on X86] in StgCRun.c for details.
+
-------------------------------------------------------------------------- */
#if defined(x86_64_HOST_ARCH)
# if defined(mingw32_HOST_OS)
-/* 8 larger than necessary to make the alignment right*/
-# define STG_RUN_STACK_FRAME_SIZE 80
+# define STG_RUN_STACK_FRAME_SIZE 144
# else
# define STG_RUN_STACK_FRAME_SIZE 48
# endif
#endif
+/* -----------------------------------------------------------------------------
+ StgRun related labels shared between StgCRun.c and StgStartup.cmm.
+ -------------------------------------------------------------------------- */
+
+#if defined(LEADING_UNDERSCORE)
+#define STG_RUN "_StgRun"
+#define STG_RUN_JMP _StgRunJmp
+#define STG_RETURN "_StgReturn"
+#else
+#define STG_RUN "StgRun"
+#define STG_RUN_JMP StgRunJmp
+#define STG_RETURN "StgReturn"
+#endif
/* -----------------------------------------------------------------------------
How much Haskell stack space to reserve for the saving of registers
diff --git a/includes/rts/EventLogFormat.h b/includes/rts/EventLogFormat.h
index f839be04a1..63303c93b7 100644
--- a/includes/rts/EventLogFormat.h
+++ b/includes/rts/EventLogFormat.h
@@ -178,12 +178,15 @@
#define EVENT_HEAP_PROF_SAMPLE_BEGIN 162
#define EVENT_HEAP_PROF_SAMPLE_COST_CENTRE 163
#define EVENT_HEAP_PROF_SAMPLE_STRING 164
+
+#define EVENT_USER_BINARY_MSG 181
+
/*
* The highest event code +1 that ghc itself emits. Note that some event
* ranges higher than this are reserved but not currently emitted by ghc.
* This must match the size of the EventDesc[] array in EventLog.c
*/
-#define NUM_GHC_EVENT_TAGS 165
+#define NUM_GHC_EVENT_TAGS 182
#if 0 /* DEPRECATED EVENTS: */
/* we don't actually need to record the thread, it's implicit */
@@ -231,6 +234,19 @@
#define CAPSET_TYPE_OSPROCESS 2 /* caps belong to the same OS process */
#define CAPSET_TYPE_CLOCKDOMAIN 3 /* caps share a local clock/time */
+/*
+ * Heap profile breakdown types. See EVENT_HEAP_PROF_BEGIN.
+ */
+typedef enum {
+ HEAP_PROF_BREAKDOWN_COST_CENTRE = 0x1,
+ HEAP_PROF_BREAKDOWN_MODULE,
+ HEAP_PROF_BREAKDOWN_CLOSURE_DESCR,
+ HEAP_PROF_BREAKDOWN_TYPE_DESCR,
+ HEAP_PROF_BREAKDOWN_RETAINER,
+ HEAP_PROF_BREAKDOWN_BIOGRAPHY,
+ HEAP_PROF_BREAKDOWN_CLOSURE_TYPE
+} HeapProfBreakdown;
+
#if !defined(EVENTLOG_CONSTANTS_ONLY)
typedef StgWord16 EventTypeNum;
@@ -244,4 +260,5 @@ typedef StgWord16 EventCapsetType; /* types for EVENT_CAPSET_CREATE */
typedef StgWord64 EventTaskId; /* for EVENT_TASK_* */
typedef StgWord64 EventKernelThreadId; /* for EVENT_TASK_CREATE */
+#define EVENT_PAYLOAD_SIZE_MAX STG_WORD16_MAX
#endif
diff --git a/includes/rts/Flags.h b/includes/rts/Flags.h
index 6700f9d95f..6487947749 100644
--- a/includes/rts/Flags.h
+++ b/includes/rts/Flags.h
@@ -65,6 +65,8 @@ typedef struct _GC_FLAGS {
Time idleGCDelayTime; /* units: TIME_RESOLUTION */
bool doIdleGC;
+ Time longGCSync; /* units: TIME_RESOLUTION */
+
StgWord heapBase; /* address to ask the OS for memory */
StgWord allocLimitGrace; /* units: *blocks*
@@ -189,7 +191,11 @@ typedef struct _CONCURRENT_FLAGS {
typedef struct _MISC_FLAGS {
Time tickInterval; /* units: TIME_RESOLUTION */
bool install_signal_handlers;
+ bool install_seh_handlers;
+ bool generate_dump_file;
+ bool generate_stack_trace;
bool machineReadable;
+ bool internalCounters; /* See Note [Internal Counter Stats] */
StgWord linkerMemBase; /* address to ask the OS for memory
* for the linker, NULL ==> off */
} MISC_FLAGS;
@@ -263,7 +269,6 @@ extern RTS_FLAGS RtsFlags;
#define STATS_FILENAME_MAXLEN 128
#define GR_FILENAME_FMT "%0.124s.gr"
-#define GR_FILENAME_FMT_GUM "%0.120s.%03d.%s"
#define HP_FILENAME_FMT "%0.124s.hp"
#define LIFE_FILENAME_FMT "%0.122s.life"
#define PROF_FILENAME_FMT "%0.122s.prof"
diff --git a/includes/rts/Libdw.h b/includes/rts/Libdw.h
index 391847552e..d7bd55d06e 100644
--- a/includes/rts/Libdw.h
+++ b/includes/rts/Libdw.h
@@ -8,6 +8,9 @@
#pragma once
+// for FILE
+#include <stdio.h>
+
// Chunk capacity
// This is rather arbitrary
#define BACKTRACE_CHUNK_SZ 256
@@ -89,3 +92,6 @@ Backtrace *libdwGetBacktrace(LibdwSession *session);
/* Lookup Location information for the given address.
* Returns 0 if successful, 1 if address could not be found. */
int libdwLookupLocation(LibdwSession *session, Location *loc, StgPtr pc);
+
+/* Pretty-print a backtrace to the given FILE */
+void libdwPrintBacktrace(LibdwSession *session, FILE *file, Backtrace *bt);
diff --git a/includes/rts/Linker.h b/includes/rts/Linker.h
index 793195b3ab..298dc6a366 100644
--- a/includes/rts/Linker.h
+++ b/includes/rts/Linker.h
@@ -47,6 +47,20 @@ HsInt insertSymbol(pathchar* obj_name, char* key, void* data);
/* lookup a symbol in the hash table */
void *lookupSymbol( char *lbl );
+/* See Linker.c Note [runtime-linker-phases] */
+typedef enum {
+ OBJECT_LOADED,
+ OBJECT_NEEDED,
+ OBJECT_RESOLVED,
+ OBJECT_UNLOADED,
+ OBJECT_DONT_RESOLVE,
+ OBJECT_NOT_LOADED /* The object was either never loaded or has been
+ fully unloaded */
+} OStatus;
+
+/* check object load status */
+OStatus getObjectLoadStatus( pathchar *path );
+
/* delete an object from the pool */
HsInt unloadObj( pathchar *path );
diff --git a/includes/rts/Messages.h b/includes/rts/Messages.h
index 2a6a84b821..c3199b23d9 100644
--- a/includes/rts/Messages.h
+++ b/includes/rts/Messages.h
@@ -40,7 +40,8 @@
* expected to return.
*/
void barf(const char *s, ...)
- GNUC3_ATTRIBUTE(__noreturn__);
+ GNUC3_ATTRIBUTE(__noreturn__)
+ GNUC3_ATTRIBUTE(format(PRINTF, 1, 2));
void vbarf(const char *s, va_list ap)
GNUC3_ATTRIBUTE(__noreturn__);
diff --git a/includes/rts/OSThreads.h b/includes/rts/OSThreads.h
index abb3120088..d2c4a6a54e 100644
--- a/includes/rts/OSThreads.h
+++ b/includes/rts/OSThreads.h
@@ -166,7 +166,7 @@ extern OSThreadId osThreadId ( void );
extern void shutdownThread ( void ) GNUC3_ATTRIBUTE(__noreturn__);
extern void yieldThread ( void );
-typedef void OSThreadProcAttr OSThreadProc(void *);
+typedef void* OSThreadProcAttr OSThreadProc(void *);
extern int createOSThread ( OSThreadId* tid, char *name,
OSThreadProc *startProc, void *param);
diff --git a/includes/rts/Profiling.h b/includes/rts/Profiling.h
new file mode 100644
index 0000000000..f1dafb78f5
--- /dev/null
+++ b/includes/rts/Profiling.h
@@ -0,0 +1,17 @@
+/* -----------------------------------------------------------------------------
+ *
+ * (c) The GHC Team, 2017-2018
+ *
+ * Cost-centre profiling API
+ *
+ * Do not #include this file directly: #include "Rts.h" instead.
+ *
+ * To understand the structure of the RTS headers, see the wiki:
+ * http://ghc.haskell.org/trac/ghc/wiki/Commentary/SourceTree/Includes
+ *
+ * -------------------------------------------------------------------------- */
+
+#pragma once
+
+void registerCcList(CostCentre **cc_list);
+void registerCcsList(CostCentreStack **cc_list);
diff --git a/includes/rts/SpinLock.h b/includes/rts/SpinLock.h
index 6530a3a2f0..1dca02f795 100644
--- a/includes/rts/SpinLock.h
+++ b/includes/rts/SpinLock.h
@@ -27,7 +27,8 @@
typedef struct SpinLock_
{
StgWord lock;
- StgWord64 spin; // DEBUG version counts how much it spins
+ StgWord64 spin; // incremented every time we spin in ACQUIRE_SPIN_LOCK
+ StgWord64 yield; // incremented every time we yield in ACQUIRE_SPIN_LOCK
} SpinLock;
#else
typedef StgWord SpinLock;
@@ -49,6 +50,7 @@ INLINE_HEADER void ACQUIRE_SPIN_LOCK(SpinLock * p)
p->spin++;
busy_wait_nop();
}
+ p->yield++;
yieldThread();
} while (1);
}
@@ -66,6 +68,7 @@ INLINE_HEADER void initSpinLock(SpinLock * p)
write_barrier();
p->lock = 1;
p->spin = 0;
+ p->yield = 0;
}
#else
diff --git a/includes/rts/StableName.h b/includes/rts/StableName.h
new file mode 100644
index 0000000000..d43ffcb2f6
--- /dev/null
+++ b/includes/rts/StableName.h
@@ -0,0 +1,32 @@
+/* -----------------------------------------------------------------------------
+ *
+ * (c) The GHC Team, 1998-2009
+ *
+ * Stable Names
+ *
+ * Do not #include this file directly: #include "Rts.h" instead.
+ *
+ * To understand the structure of the RTS headers, see the wiki:
+ * http://ghc.haskell.org/trac/ghc/wiki/Commentary/SourceTree/Includes
+ *
+ * ---------------------------------------------------------------------------*/
+
+#pragma once
+
+/* -----------------------------------------------------------------------------
+ PRIVATE from here.
+ -------------------------------------------------------------------------- */
+
+typedef struct {
+ StgPtr addr; // Haskell object when entry is in use, next free
+ // entry (NULL when this is the last free entry)
+ // otherwise. May be NULL temporarily during GC (when
+ // pointee dies).
+
+ StgPtr old; // Old Haskell object, used during GC
+
+ StgClosure *sn_obj; // The StableName object, or NULL when the entry is
+ // free
+} snEntry;
+
+extern DLL_IMPORT_RTS snEntry *stable_name_table;
diff --git a/includes/rts/Stable.h b/includes/rts/StablePtr.h
index 75fcf4f7eb..0d3642fbfe 100644
--- a/includes/rts/Stable.h
+++ b/includes/rts/StablePtr.h
@@ -21,16 +21,11 @@ StgStablePtr getStablePtr (StgPtr p);
-------------------------------------------------------------------------- */
typedef struct {
- StgPtr addr; /* Haskell object, free list, or NULL */
- StgPtr old; /* old Haskell object, used during GC */
- StgClosure *sn_obj; /* the StableName object (or NULL) */
-} snEntry;
-
-typedef struct {
- StgPtr addr;
+ StgPtr addr; // Haskell object when entry is in use, next free
+ // entry (NULL when this is the last free entry)
+ // otherwise.
} spEntry;
-extern DLL_IMPORT_RTS snEntry *stable_name_table;
extern DLL_IMPORT_RTS spEntry *stable_ptr_table;
EXTERN_INLINE
diff --git a/includes/rts/Threads.h b/includes/rts/Threads.h
index fceacdc75d..f72f5ed121 100644
--- a/includes/rts/Threads.h
+++ b/includes/rts/Threads.h
@@ -43,8 +43,6 @@ StgRegTable * resumeThread (void *);
//
int cmp_thread (StgPtr tso1, StgPtr tso2);
int rts_getThreadId (StgPtr tso);
-HsInt64 rts_getThreadAllocationCounter (StgPtr tso);
-void rts_setThreadAllocationCounter (StgPtr tso, HsInt64 i);
void rts_enableThreadAllocationLimit (StgPtr tso);
void rts_disableThreadAllocationLimit (StgPtr tso);
diff --git a/includes/rts/Time.h b/includes/rts/Time.h
index 5fa166e125..12c6d2767d 100644
--- a/includes/rts/Time.h
+++ b/includes/rts/Time.h
@@ -21,8 +21,10 @@ typedef int64_t Time;
#if TIME_RESOLUTION == 1000000000
// I'm being lazy, but it's awkward to define fully general versions of these
+#define TimeToMS(t) ((t) / 1000000)
#define TimeToUS(t) ((t) / 1000)
#define TimeToNS(t) (t)
+#define MSToTime(t) ((Time)(t) * 1000000)
#define USToTime(t) ((Time)(t) * 1000)
#define NSToTime(t) ((Time)(t))
#else
@@ -38,3 +40,5 @@ INLINE_HEADER Time fsecondsToTime (double t)
{
return (Time)(t * TIME_RESOLUTION);
}
+
+Time getProcessElapsedTime (void);
diff --git a/includes/rts/storage/Block.h b/includes/rts/storage/Block.h
index c1d251856a..ecd6bf5dd8 100644
--- a/includes/rts/storage/Block.h
+++ b/includes/rts/storage/Block.h
@@ -143,8 +143,6 @@ typedef struct bdescr_ {
#define BF_PINNED 4
/* Block is to be marked, not copied */
#define BF_MARKED 8
-/* Block is free, and on the free list (TODO: is this used?) */
-#define BF_FREE 16
/* Block is executable */
#define BF_EXEC 32
/* Block contains only a small amount of live data */
@@ -340,13 +338,4 @@ round_to_mblocks(StgWord words)
return words;
}
-INLINE_HEADER StgWord
-round_up_to_mblocks(StgWord words)
-{
- words += FIRST_BLOCK_OFF/sizeof(W_);
- words = ((words / MBLOCK_SIZE_W) + 1) * MBLOCK_SIZE_W;
- words -= FIRST_BLOCK_OFF/sizeof(W_);
- return words;
-}
-
#endif /* !CMINUSMINUS */
diff --git a/includes/rts/storage/ClosureMacros.h b/includes/rts/storage/ClosureMacros.h
index be1569ba8e..e52059e790 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)->srt_bitmap;
+ return get_itbl(con)->srt;
}
/* -----------------------------------------------------------------------------
@@ -172,7 +172,6 @@ INLINE_HEADER StgHalfWord GET_TAG(const StgClosure *con)
-------------------------------------------------------------------------- */
/* These are hard-coded. */
-#define FUN_STATIC_LINK(p) (&(p)->payload[0])
#define THUNK_STATIC_LINK(p) (&(p)->payload[1])
#define IND_STATIC_LINK(p) (&(p)->payload[1])
@@ -182,8 +181,6 @@ STATIC_LINK(const StgInfoTable *info, StgClosure *p)
switch (info->type) {
case THUNK_STATIC:
return THUNK_STATIC_LINK(p);
- case FUN_STATIC:
- return FUN_STATIC_LINK(p);
case IND_STATIC:
return IND_STATIC_LINK(p);
default:
@@ -404,13 +401,13 @@ closure_sizeW_ (const StgClosure *p, const StgInfoTable *info)
return arr_words_sizeW((StgArrBytes *)p);
case MUT_ARR_PTRS_CLEAN:
case MUT_ARR_PTRS_DIRTY:
- case MUT_ARR_PTRS_FROZEN:
- case MUT_ARR_PTRS_FROZEN0:
+ case MUT_ARR_PTRS_FROZEN_CLEAN:
+ case MUT_ARR_PTRS_FROZEN_DIRTY:
return mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
case SMALL_MUT_ARR_PTRS_CLEAN:
case SMALL_MUT_ARR_PTRS_DIRTY:
- case SMALL_MUT_ARR_PTRS_FROZEN:
- case SMALL_MUT_ARR_PTRS_FROZEN0:
+ case SMALL_MUT_ARR_PTRS_FROZEN_CLEAN:
+ case SMALL_MUT_ARR_PTRS_FROZEN_DIRTY:
return small_mut_arr_ptrs_sizeW((StgSmallMutArrPtrs*)p);
case TSO:
return sizeofW(StgTSO);
@@ -533,8 +530,7 @@ INLINE_HEADER StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n)
#if ZERO_SLOP_FOR_LDV_PROF || ZERO_SLOP_FOR_SANITY_CHECK
#define OVERWRITING_CLOSURE(c) overwritingClosure(c)
-#define OVERWRITING_CLOSURE_OFS(c,n) \
- overwritingClosureOfs(c,n)
+#define OVERWRITING_CLOSURE_OFS(c,n) overwritingClosureOfs(c,n)
#else
#define OVERWRITING_CLOSURE(c) /* nothing */
#define OVERWRITING_CLOSURE_OFS(c,n) /* nothing */
@@ -544,28 +540,32 @@ INLINE_HEADER StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n)
void LDV_recordDead (const StgClosure *c, uint32_t size);
#endif
-EXTERN_INLINE void overwritingClosure (StgClosure *p);
-EXTERN_INLINE void overwritingClosure (StgClosure *p)
+EXTERN_INLINE void overwritingClosure_ (StgClosure *p,
+ uint32_t offset /* in words */,
+ uint32_t size /* closure size, in words */);
+EXTERN_INLINE void overwritingClosure_ (StgClosure *p, uint32_t offset, uint32_t size)
{
- uint32_t size, i;
-
#if ZERO_SLOP_FOR_LDV_PROF && !ZERO_SLOP_FOR_SANITY_CHECK
// see Note [zeroing slop], also #8402
if (era <= 0) return;
#endif
- size = closure_sizeW(p);
-
// For LDV profiling, we need to record the closure as dead
#if defined(PROFILING)
LDV_recordDead(p, size);
#endif
- for (i = 0; i < size - sizeofW(StgThunkHeader); i++) {
- ((StgThunk *)(p))->payload[i] = 0;
+ for (uint32_t i = offset; i < size; i++) {
+ ((StgWord *)p)[i] = 0;
}
}
+EXTERN_INLINE void overwritingClosure (StgClosure *p);
+EXTERN_INLINE void overwritingClosure (StgClosure *p)
+{
+ overwritingClosure_(p, sizeofW(StgThunkHeader), closure_sizeW(p));
+}
+
// Version of 'overwritingClosure' which overwrites only a suffix of a
// closure. The offset is expressed in words relative to 'p' and shall
// be less than or equal to closure_sizeW(p), and usually at least as
@@ -576,22 +576,12 @@ EXTERN_INLINE void overwritingClosure (StgClosure *p)
EXTERN_INLINE void overwritingClosureOfs (StgClosure *p, uint32_t offset);
EXTERN_INLINE void overwritingClosureOfs (StgClosure *p, uint32_t offset)
{
- uint32_t size, i;
-
-#if ZERO_SLOP_FOR_LDV_PROF && !ZERO_SLOP_FOR_SANITY_CHECK
- // see Note [zeroing slop], also #8402
- if (era <= 0) return;
-#endif
-
- size = closure_sizeW(p);
-
- ASSERT(offset <= size);
-
- // For LDV profiling, we need to record the closure as dead
-#if defined(PROFILING)
- LDV_recordDead(p, size);
-#endif
+ overwritingClosure_(p, offset, closure_sizeW(p));
+}
- for (i = offset; i < size; i++)
- ((StgWord *)p)[i] = 0;
+// Version of 'overwritingClosure' which takes closure size as argument.
+EXTERN_INLINE void overwritingClosureSize (StgClosure *p, uint32_t size /* in words */);
+EXTERN_INLINE void overwritingClosureSize (StgClosure *p, uint32_t size)
+{
+ overwritingClosure_(p, sizeofW(StgThunkHeader), size);
}
diff --git a/includes/rts/storage/ClosureTypes.h b/includes/rts/storage/ClosureTypes.h
index 68cc919257..85dc1a0ce4 100644
--- a/includes/rts/storage/ClosureTypes.h
+++ b/includes/rts/storage/ClosureTypes.h
@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------------
- *
+ *
* (c) The GHC Team, 1998-2005
*
* Closure Type Constants: out here because the native code generator
@@ -9,11 +9,13 @@
#pragma once
-/*
+/*
* WARNING WARNING WARNING
*
- * If you add or delete any closure types, don't forget to update
- * the closure flags table in rts/ClosureFlags.c.
+ * If you add or delete any closure types, don't forget to update the following,
+ * - the closure flags table in rts/ClosureFlags.c
+ * - isRetainer in rts/RetainerProfile.c
+ * - the closure_type_names list in rts/Printer.c
*/
/* Object tag 0 raises an internal error */
@@ -62,8 +64,8 @@
#define ARR_WORDS 42
#define MUT_ARR_PTRS_CLEAN 43
#define MUT_ARR_PTRS_DIRTY 44
-#define MUT_ARR_PTRS_FROZEN0 45
-#define MUT_ARR_PTRS_FROZEN 46
+#define MUT_ARR_PTRS_FROZEN_DIRTY 45
+#define MUT_ARR_PTRS_FROZEN_CLEAN 46
#define MUT_VAR_CLEAN 47
#define MUT_VAR_DIRTY 48
#define WEAK 49
@@ -78,7 +80,7 @@
#define WHITEHOLE 58
#define SMALL_MUT_ARR_PTRS_CLEAN 59
#define SMALL_MUT_ARR_PTRS_DIRTY 60
-#define SMALL_MUT_ARR_PTRS_FROZEN0 61
-#define SMALL_MUT_ARR_PTRS_FROZEN 62
+#define SMALL_MUT_ARR_PTRS_FROZEN_DIRTY 61
+#define SMALL_MUT_ARR_PTRS_FROZEN_CLEAN 62
#define COMPACT_NFDATA 63
#define N_CLOSURE_TYPES 64
diff --git a/includes/rts/storage/Closures.h b/includes/rts/storage/Closures.h
index af89507f97..15231e01f0 100644
--- a/includes/rts/storage/Closures.h
+++ b/includes/rts/storage/Closures.h
@@ -122,8 +122,10 @@ typedef struct {
typedef struct {
StgHeader header;
StgClosure *indirectee;
- StgClosure *static_link;
+ StgClosure *static_link; // See Note [CAF lists]
const StgInfoTable *saved_info;
+ // `saved_info` also used for the link field for `debug_caf_list`,
+ // see `newCAF` and Note [CAF lists] in rts/sm/Storage.h.
} StgIndStatic;
typedef struct StgBlockingQueue_ {
@@ -306,7 +308,7 @@ typedef struct StgTRecHeader_ StgTRecHeader;
typedef struct StgTVarWatchQueue_ {
StgHeader header;
- StgClosure *closure; // StgTSO or StgAtomicInvariant
+ StgClosure *closure; // StgTSO
struct StgTVarWatchQueue_ *next_queue_entry;
struct StgTVarWatchQueue_ *prev_queue_entry;
} StgTVarWatchQueue;
@@ -318,13 +320,6 @@ typedef struct {
StgInt volatile num_updates;
} StgTVar;
-typedef struct {
- StgHeader header;
- StgClosure *code;
- StgTRecHeader *last_execution;
- StgWord lock;
-} StgAtomicInvariant;
-
/* new_value == expected_value for read-only accesses */
/* new_value is a StgTVarWatchQueue entry when trec in state TREC_WAITING */
typedef struct {
@@ -353,25 +348,16 @@ typedef enum {
TREC_WAITING, /* Transaction currently waiting */
} TRecState;
-typedef struct StgInvariantCheckQueue_ {
- StgHeader header;
- StgAtomicInvariant *invariant;
- StgTRecHeader *my_execution;
- struct StgInvariantCheckQueue_ *next_queue_entry;
-} StgInvariantCheckQueue;
-
struct StgTRecHeader_ {
StgHeader header;
struct StgTRecHeader_ *enclosing_trec;
StgTRecChunk *current_chunk;
- StgInvariantCheckQueue *invariants_to_check;
TRecState state;
};
typedef struct {
StgHeader header;
StgClosure *code;
- StgTVarWatchQueue *next_invariant_to_check;
StgClosure *result;
} StgAtomicallyFrame;
diff --git a/includes/rts/storage/GC.h b/includes/rts/storage/GC.h
index 387bd260d3..1571975852 100644
--- a/includes/rts/storage/GC.h
+++ b/includes/rts/storage/GC.h
@@ -109,7 +109,12 @@ typedef struct generation_ {
memcount n_compact_blocks_in_import; // no. of blocks used by compacts
// being imported
- memcount max_blocks; // max blocks
+ // Max blocks to allocate in this generation before collecting it. Collect
+ // this generation when
+ //
+ // n_blocks + n_large_blocks + n_compact_blocks > max_blocks
+ //
+ memcount max_blocks;
StgTSO * threads; // threads in this gen
// linked via global_link
@@ -120,7 +125,7 @@ typedef struct generation_ {
// stats information
uint32_t collections;
uint32_t par_collections;
- uint32_t failed_promotions;
+ uint32_t failed_promotions; // Currently unused
// ------------------------------------
// Fields below are used during GC only
@@ -184,8 +189,9 @@ extern generation * oldest_gen;
-------------------------------------------------------------------------- */
-StgPtr allocate ( Capability *cap, W_ n );
-StgPtr allocatePinned ( Capability *cap, W_ n );
+StgPtr allocate ( Capability *cap, W_ n );
+StgPtr allocateMightFail ( Capability *cap, W_ n );
+StgPtr allocatePinned ( Capability *cap, W_ n );
/* memory allocator for executable memory */
typedef void* AdjustorWritable;
diff --git a/includes/rts/storage/Heap.h b/includes/rts/storage/Heap.h
new file mode 100644
index 0000000000..2e908279bf
--- /dev/null
+++ b/includes/rts/storage/Heap.h
@@ -0,0 +1,18 @@
+/* -----------------------------------------------------------------------------
+ *
+ * (c) The University of Glasgow 2006-2017
+ *
+ * Introspection into GHC's heap representation
+ *
+ * ---------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "rts/storage/Closures.h"
+
+StgMutArrPtrs *heap_view_closurePtrs(Capability *cap, StgClosure *closure);
+
+void heap_view_closure_ptrs_in_pap_payload(StgClosure *ptrs[], StgWord *nptrs
+ , StgClosure *fun, StgClosure **payload, StgWord size);
+
+StgWord heap_view_closureSize(StgClosure *closure);
diff --git a/includes/rts/storage/InfoTables.h b/includes/rts/storage/InfoTables.h
index c621e5e749..db50d1613b 100644
--- a/includes/rts/storage/InfoTables.h
+++ b/includes/rts/storage/InfoTables.h
@@ -124,31 +124,6 @@ typedef struct {
StgWord bitmap[];
} StgLargeBitmap;
-/* -----------------------------------------------------------------------------
- SRTs (Static Reference Tables)
-
- These tables are used to keep track of the static objects referred
- to by the code for a closure or stack frame, so that we can follow
- static data references from code and thus accurately
- garbage-collect CAFs.
- -------------------------------------------------------------------------- */
-
-/* An SRT is just an array of closure pointers: */
-typedef StgClosure* StgSRT[];
-
-/*
- * Each info table refers to some subset of the closure pointers in an
- * SRT. It does this using a pair of an StgSRT pointer and a
- * half-word bitmap. If the half-word bitmap isn't large enough, then
- * we fall back to a large SRT, including an unbounded bitmap. If the
- * half-word bitmap is set to all ones (0xffff), then the StgSRT
- * pointer instead points to an StgLargeSRT:
- */
-typedef struct StgLargeSRT_ {
- StgSRT *srt;
- StgLargeBitmap l;
-} StgLargeSRT;
-
/* ----------------------------------------------------------------------------
Info Tables
------------------------------------------------------------------------- */
@@ -178,6 +153,24 @@ 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.
+//
+// See the section "Referring to an SRT from the info table" in
+// Note [SRTs] in CmmBuildInfoTables.hs
+#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.
*/
@@ -194,11 +187,14 @@ typedef struct StgInfoTable_ {
StgClosureInfo layout; /* closure layout info (one word) */
StgHalfWord type; /* closure type */
- StgHalfWord srt_bitmap;
+ StgSRTField srt;
/* In a CONSTR:
- the constructor tag
In a FUN/THUNK
- - a bitmap of SRT entries
+ - 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)
@@ -217,7 +213,7 @@ typedef struct StgInfoTable_ {
and bitmap fields may be left out (they are at the end, so omitting
them doesn't affect the layout).
- - If srt_bitmap (in the std info table part) is zero, then the srt
+ - If has_srt (in the std info table part) is zero, then the srt
field needn't be set. This only applies if the slow_apply and
bitmap fields have also been omitted.
-------------------------------------------------------------------------- */
@@ -239,7 +235,9 @@ typedef struct StgFunInfoExtraRev_ {
StgWord bitmap;
OFFSET_FIELD(bitmap_offset); /* arg ptr/nonptr bitmap */
} b;
- OFFSET_FIELD(srt_offset); /* pointer to the SRT table */
+#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;
@@ -247,7 +245,7 @@ typedef struct StgFunInfoExtraRev_ {
typedef struct StgFunInfoExtraFwd_ {
StgHalfWord fun_type; /* function type */
StgHalfWord arity; /* function arity */
- StgSRT *srt; /* pointer to the SRT table */
+ StgClosure *srt; /* pointer to the SRT closure */
union { /* union for compat. with TABLES_NEXT_TO_CODE version */
StgWord bitmap; /* arg ptr/nonptr bitmap */
} b;
@@ -273,16 +271,18 @@ extern const StgWord stg_arg_bitmaps[];
/*
* When info tables are laid out backwards, we can omit the SRT
- * pointer iff srt_bitmap is zero.
+ * pointer iff has_srt is zero.
*/
typedef struct {
#if defined(TABLES_NEXT_TO_CODE)
- OFFSET_FIELD(srt_offset); /* offset to the SRT table */
+#if !defined(USE_INLINE_SRT_FIELD)
+ OFFSET_FIELD(srt_offset); /* offset to the SRT closure */
+#endif
StgInfoTable i;
#else
StgInfoTable i;
- StgSRT *srt; /* pointer to the SRT table */
+ StgClosure *srt; /* pointer to the SRT closure */
#endif
} StgRetInfoTable;
@@ -292,20 +292,18 @@ typedef struct {
/*
* When info tables are laid out backwards, we can omit the SRT
- * pointer iff srt_bitmap is zero.
+ * pointer iff has_srt is zero.
*/
typedef struct StgThunkInfoTable_ {
-#if !defined(TABLES_NEXT_TO_CODE)
- StgInfoTable i;
-#endif
#if defined(TABLES_NEXT_TO_CODE)
- OFFSET_FIELD(srt_offset); /* offset to the SRT table */
-#else
- StgSRT *srt; /* pointer to the SRT table */
+#if !defined(USE_INLINE_SRT_FIELD)
+ OFFSET_FIELD(srt_offset); /* offset 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;
@@ -340,8 +338,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)
-#define GET_SRT(info) ((StgSRT*) (((StgWord) ((info)+1)) + (info)->srt_offset))
+#if defined(x86_64_TARGET_ARCH)
+#define GET_SRT(info) \
+ ((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
@@ -361,7 +365,13 @@ typedef struct StgConInfoTable_ {
* info must be a StgFunInfoTable*
*/
#if defined(TABLES_NEXT_TO_CODE)
-#define GET_FUN_SRT(info) ((StgSRT*) (((StgWord) ((info)+1)) + (info)->f.srt_offset))
+#if defined(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