summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik de Castro Lopo <erikd@mega-nerd.com>2016-05-02 20:22:00 +1000
committerErik de Castro Lopo <erikd@mega-nerd.com>2016-05-05 08:51:24 +1000
commitc9fe98d49a2a07e369df6d7935ea7e3cac651373 (patch)
treeeef945bc0270ba1b945f03a4a561ad0bfbcdc2a3
parenta5c7d2db6d53a7b83177f5e04cca712cd24c7bd6 (diff)
downloadhaskell-c9fe98d49a2a07e369df6d7935ea7e3cac651373.tar.gz
rts/ProfHeap.c: Use `ssize_t` instead of `long`.
On x64 Windows `sizeof long` is 4 which could easily overflow resulting in incorrect heap profiling results. This change does not affect either Linux or OS X where `sizeof long` == `sizeof ssize_t` regardless of machine word size.
-rw-r--r--rts/ProfHeap.c45
1 files changed, 22 insertions, 23 deletions
diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c
index 875cc7ed33..11e4274e54 100644
--- a/rts/ProfHeap.c
+++ b/rts/ProfHeap.c
@@ -50,13 +50,14 @@ static uint32_t max_era;
typedef struct _counter {
void *identity;
union {
- uint32_t resid;
+ size_t resid;
struct {
- long prim; // total size of 'inherently used' closures
- long not_used; // total size of 'never used' closures
- long used; // total size of 'used at least once' closures
- long void_total; // current total size of 'destroyed without being used' closures
- long drag_total; // current total size of 'used at least once and waiting to die'
+ // Total sizes of:
+ ssize_t prim; // 'inherently used' closures
+ ssize_t not_used; // 'never used' closures
+ ssize_t used; // 'used at least once' closures
+ ssize_t void_total; // 'destroyed without being used' closures
+ ssize_t drag_total; // 'used at least once and waiting to die'
} ldv;
} c;
struct _counter *next;
@@ -79,11 +80,11 @@ typedef struct {
Arena * arena;
// for LDV profiling, when just displaying by LDV
- long prim;
- long not_used;
- long used;
- long void_total;
- long drag_total;
+ size_t prim;
+ size_t not_used;
+ size_t used;
+ size_t void_total;
+ size_t drag_total;
} Census;
static Census *censuses = NULL;
@@ -193,14 +194,14 @@ LDV_recordDead( StgClosure *c, uint32_t size )
t = (LDVW((c)) & LDV_CREATE_MASK) >> LDV_SHIFT;
if (t < era) {
if (RtsFlags.ProfFlags.bioSelector == NULL) {
- censuses[t].void_total += (long)size;
- censuses[era].void_total -= (long)size;
+ censuses[t].void_total += size;
+ censuses[era].void_total -= size;
ASSERT(censuses[t].void_total < censuses[t].not_used);
} else {
id = closureIdentity(c);
ctr = lookupHashTable(censuses[t].hash, (StgWord)id);
ASSERT( ctr != NULL );
- ctr->c.ldv.void_total += (long)size;
+ ctr->c.ldv.void_total += size;
ctr = lookupHashTable(censuses[era].hash, (StgWord)id);
if (ctr == NULL) {
ctr = arenaAlloc(censuses[era].arena, sizeof(counter));
@@ -210,7 +211,7 @@ LDV_recordDead( StgClosure *c, uint32_t size )
ctr->next = censuses[era].ctrs;
censuses[era].ctrs = ctr;
}
- ctr->c.ldv.void_total -= (long)size;
+ ctr->c.ldv.void_total -= size;
}
}
} else {
@@ -224,7 +225,7 @@ LDV_recordDead( StgClosure *c, uint32_t size )
id = closureIdentity(c);
ctr = lookupHashTable(censuses[t+1].hash, (StgWord)id);
ASSERT( ctr != NULL );
- ctr->c.ldv.drag_total += (long)size;
+ ctr->c.ldv.drag_total += size;
ctr = lookupHashTable(censuses[era].hash, (StgWord)id);
if (ctr == NULL) {
ctr = arenaAlloc(censuses[era].arena, sizeof(counter));
@@ -234,7 +235,7 @@ LDV_recordDead( StgClosure *c, uint32_t size )
ctr->next = censuses[era].ctrs;
censuses[era].ctrs = ctr;
}
- ctr->c.ldv.drag_total -= (long)size;
+ ctr->c.ldv.drag_total -= size;
}
}
}
@@ -739,7 +740,7 @@ static void
dumpCensus( Census *census )
{
counter *ctr;
- long count;
+ size_t count;
printSample(rtsTrue, census->time);
@@ -778,8 +779,6 @@ dumpCensus( Census *census )
count = ctr->c.resid;
}
- ASSERT( count >= 0 );
-
if (count == 0) continue;
#if !defined(PROFILING)
@@ -835,7 +834,7 @@ dumpCensus( Census *census )
}
-static void heapProfObject(Census *census, StgClosure *p, uint32_t size,
+static void heapProfObject(Census *census, StgClosure *p, size_t size,
rtsBool prim
#ifndef PROFILING
STG_UNUSED
@@ -843,7 +842,7 @@ static void heapProfObject(Census *census, StgClosure *p, uint32_t size,
)
{
void *identity;
- uint32_t real_size;
+ size_t real_size;
counter *ctr;
identity = NULL;
@@ -920,7 +919,7 @@ heapCensusChain( Census *census, bdescr *bd )
{
StgPtr p;
StgInfoTable *info;
- uint32_t size;
+ size_t size;
rtsBool prim;
for (; bd != NULL; bd = bd->link) {