Skip to content

Commit

Permalink
adjust peak-memory logging
Browse files Browse the repository at this point in the history
Show peak administrative as a parenthesized delta on peak space.

For BC, this extra delta is small, because BC compacts (instead of
copying) old-generation objects. For CS, the extra delta can large ---
typically an extra 50%, but potentially another 100% --- because a
full collection copies all old-generation objects.

Also, for BC, fix cumulative-allocation reporting to include child
places.
  • Loading branch information
mflatt committed Apr 22, 2020
1 parent 859e7b4 commit dccd841
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 36 deletions.
3 changes: 2 additions & 1 deletion racket/src/cs/main.sps
Expand Up @@ -685,8 +685,9 @@
(let ([debug-GC? (log-level?* root-logger 'debug 'GC)]
[debug-GC:major? (log-level?* root-logger 'debug 'GC:major)])
(when (or debug-GC? debug-GC:major?)
(let ([msg (chez:format "GC: 0:atexit peak ~a; alloc ~a; major ~a; minor ~a; ~ams"
(let ([msg (chez:format "GC: 0:atexit peak ~a(+~a); alloc ~a; major ~a; minor ~a; ~ams"
(K "" peak-mem)
(K "" (- (maximum-memory-bytes) peak-mem))
(K "" (- (+ (bytes-deallocated) (bytes-allocated)) (initial-bytes-allocated)))
major-gcs
minor-gcs
Expand Down
11 changes: 8 additions & 3 deletions racket/src/racket/gc2/gc2.h
Expand Up @@ -145,14 +145,19 @@ GC2_EXTERN void GC_dump(void);

GC2_EXTERN intptr_t GC_get_memory_use(void *c);
/*
Returns the number of currently-allocated bytes (speficilly for
Returns the number of currently-allocated bytes (specifically for
custodian c, as much as the GC's accounting makes possible). */

GC2_EXTERN intptr_t GC_get_memory_ever_allocated();
GC2_EXTERN intptr_t GC_get_memory_ever_used();
/*
Returns the number of total number of allocated bytes, including
Returns the total number of allocated bytes, including
bytes that have since been reclaimed. */

GC2_EXTERN intptr_t GC_get_memory_max_allocated();
/*
Returns the maximum number of bytes allocated at once, including
GC overhead but not including phantom bytes. */

GC2_EXTERN int GC_accouting_enabled();
/*
Reports whether memory accounting is enabled. */
Expand Down
35 changes: 30 additions & 5 deletions racket/src/racket/gc2/newgc.c
Expand Up @@ -980,13 +980,22 @@ void GC_register_traversers(short tag, Size_Proc size, Mark_Proc mark,
(Fixup2_Proc)fixup, constant_Size, atomic);
}

static uintptr_t get_place_child_memory_use()
#define PLACE_CHILD_MEMORY_USE 1
#define PLACE_CHILD_MEMORY_CUMULATIVE 2
#define PLACE_CHILD_MEMORY_MAX 3

static uintptr_t get_place_child_memory(int which)
{
#ifdef MZ_USE_PLACES
NewGC *gc = GC_get_GC();
uintptr_t amt;
mzrt_mutex_lock(gc->child_total_lock);
amt = gc->child_gc_total;
if (which == PLACE_CHILD_MEMORY_USE)
amt = gc->child_gc_total;
else if (which == PLACE_CHILD_MEMORY_CUMULATIVE)
amt = gc->child_gc_cumulative;
else
amt = gc->child_gc_max;
mzrt_mutex_unlock(gc->child_total_lock);
return amt;
#else
Expand All @@ -1006,22 +1015,38 @@ intptr_t GC_get_memory_use(void *o)
amt = add_no_overflow(gen0_size_in_use(gc), gc->memory_in_use);
amt = add_no_overflow(amt, gc->gen0_phantom_count);
#ifdef MZ_USE_PLACES
amt = add_no_overflow(amt, get_place_child_memory_use());
amt = add_no_overflow(amt, get_place_child_memory(PLACE_CHILD_MEMORY_USE));
#endif

return (intptr_t)amt;
}

intptr_t GC_get_memory_ever_allocated()
intptr_t GC_get_memory_ever_used()
{
NewGC *gc = GC_get_GC();
uintptr_t amt;

amt = add_no_overflow(gen0_size_in_use(gc), gc->total_memory_allocated);
#ifdef MZ_USE_PLACES
amt = add_no_overflow(amt, get_place_child_memory(PLACE_CHILD_MEMORY_CUMULATIVE));
#endif

return (intptr_t)amt;
}

intptr_t GC_get_memory_max_allocated()
{
NewGC *gc = GC_get_GC();
uintptr_t amt;

amt = mmu_memory_max_allocated(gc->mmu);
#ifdef MZ_USE_PLACES
amt = add_no_overflow(amt, get_place_child_memory(PLACE_CHILD_MEMORY_MAX));
#endif

return amt;
}

/*****************************************************************************/
/* Write barrier */
/* */
Expand Down Expand Up @@ -6352,7 +6377,7 @@ void GC_dump_with_traces(int flags,

GCWARN((GCOUTF,"\n"));
GCWARN((GCOUTF,"Current memory use: %" PRIdPTR "\n", GC_get_memory_use(NULL)));
GCWARN((GCOUTF," part current use from child places: %" PRIdPTR "\n", get_place_child_memory_use()));
GCWARN((GCOUTF," part current use from child places: %" PRIdPTR "\n", get_place_child_memory(PLACE_CHILD_MEMORY_USE)));
GCWARN((GCOUTF,"Peak memory use before a collection: %" PRIdPTR "\n", gc->peak_pre_memory_use));
GCWARN((GCOUTF,"Peak memory use after a collection: %" PRIdPTR "\n", gc->peak_memory_use));
GCWARN((GCOUTF,"Allocated (+reserved) page sizes: %" PRIdPTR " (+%" PRIdPTR ")\n",
Expand Down
5 changes: 5 additions & 0 deletions racket/src/racket/gc2/newgc.h
Expand Up @@ -386,10 +386,15 @@ typedef struct NewGC {

#ifdef MZ_USE_PLACES
struct NewGC *parent_gc; /* parent for the purpose of reporting memory use */
/* keeping track of previously reported lets us adjust parent that has multiple child places */
intptr_t previously_reported_total; /* how much we previously reported to the parent */
intptr_t previously_reported_cumulative; /* how much we previously reported to the parent */
intptr_t previously_reported_max; /* how much we previously reported to the parent */
mzrt_mutex *child_total_lock; /* lock on `child_gc_total' */
#endif
uintptr_t child_gc_total;
uintptr_t child_gc_cumulative;
uintptr_t child_gc_max;

uintptr_t place_memory_limit; /* set to propagate a custodian limit from a parent place */

Expand Down
37 changes: 31 additions & 6 deletions racket/src/racket/gc2/places_gc.c
Expand Up @@ -357,10 +357,18 @@ void GC_destruct_child_gc() {
if (gc->parent_gc) {
/* update parent's view of memory use */
intptr_t delta = -gc->previously_reported_total;
intptr_t cumulative_b = gc->total_memory_allocated + gc->child_gc_cumulative;
intptr_t cumulative_delta = cumulative_b - gc->previously_reported_cumulative;
intptr_t max_b = mmu_memory_max_allocated(gc->mmu) + gc->child_gc_max;
intptr_t max_delta = max_b - gc->previously_reported_max;
mzrt_mutex_lock(gc->parent_gc->child_total_lock);
gc->parent_gc->child_gc_total += delta;
gc->parent_gc->child_gc_cumulative += cumulative_delta;
gc->parent_gc->child_gc_max += max_delta;
mzrt_mutex_unlock(gc->parent_gc->child_total_lock);
gc->previously_reported_total = 0;
gc->previously_reported_cumulative = cumulative_b;
gc->previously_reported_max = max_b;
}

free_child_gc();
Expand Down Expand Up @@ -508,12 +516,29 @@ intptr_t GC_propagate_hierarchy_memory_use()
#ifdef MZ_USE_PLACES
if (gc->parent_gc) {
/* report memory use to parent */
intptr_t total = gc->memory_in_use + gc->child_gc_total;
intptr_t delta = total - gc->previously_reported_total;
mzrt_mutex_lock(gc->parent_gc->child_total_lock);
gc->parent_gc->child_gc_total += delta;
mzrt_mutex_unlock(gc->parent_gc->child_total_lock);
gc->previously_reported_total = total;
intptr_t total, cumulative_b, max_b;

mzrt_mutex_lock(gc->child_total_lock);
total = gc->memory_in_use + gc->child_gc_total;
cumulative_b = gc->total_memory_allocated + gc->child_gc_cumulative;
max_b = mmu_memory_max_allocated(gc->mmu) + gc->child_gc_max;
mzrt_mutex_unlock(gc->child_total_lock);

{
intptr_t delta = total - gc->previously_reported_total;
intptr_t cumulative_delta = cumulative_b - gc->previously_reported_cumulative;
intptr_t max_delta = max_b - gc->previously_reported_max;

mzrt_mutex_lock(gc->parent_gc->child_total_lock);
gc->parent_gc->child_gc_total += delta;
gc->parent_gc->child_gc_cumulative += cumulative_delta;
gc->parent_gc->child_gc_max += max_delta;
mzrt_mutex_unlock(gc->parent_gc->child_total_lock);

gc->previously_reported_total = total;
gc->previously_reported_cumulative = cumulative_b;
gc->previously_reported_max = max_b;
}
}
#endif

Expand Down
18 changes: 16 additions & 2 deletions racket/src/racket/gc2/vm.c
Expand Up @@ -52,7 +52,8 @@ typedef struct MMU {
Page_Range *page_range;
#endif
intptr_t memory_allocated; /* allocated from OS */
intptr_t memory_used; /* subset of alloctaed from OS that's being used */
intptr_t memory_max_allocated; /* max ever allocated from OS */
intptr_t memory_used; /* subset of allocated from OS that's being used */
size_t os_pagesize;
NewGC *gc;
} MMU;
Expand All @@ -68,6 +69,7 @@ static void os_protect_pages(void *p, size_t len, int writable);
/* provides */
static inline size_t mmu_get_os_page_size(MMU *mmu) { return mmu->os_pagesize; }
static size_t mmu_memory_allocated(MMU *mmu);
static size_t mmu_memory_max_allocated(MMU *mmu);

static inline size_t align_up(const size_t len, const size_t boundary) {
const size_t modulo = (len & (boundary - 1));
Expand Down Expand Up @@ -146,7 +148,13 @@ static void *mmu_alloc_page(MMU* mmu, size_t len, size_t alignment, int dirty, i
mmu_assert_os_page_aligned(mmu, len);
mmu->memory_used += len;
#ifdef USE_BLOCK_CACHE
return block_cache_alloc_page(mmu->block_cache, len, alignment, dirty, type, expect_mprotect, src_block, &mmu->memory_allocated);
{
void *p;
p = block_cache_alloc_page(mmu->block_cache, len, alignment, dirty, type, expect_mprotect, src_block, &mmu->memory_allocated);
if (mmu->memory_max_allocated < mmu->memory_allocated)
mmu->memory_max_allocated = mmu->memory_allocated;
return p;
}
#else
*src_block = NULL;
# if defined(USE_ALLOC_CACHE)
Expand All @@ -157,6 +165,8 @@ static void *mmu_alloc_page(MMU* mmu, size_t len, size_t alignment, int dirty, i
}
# else
mmu->memory_allocated += len;
if (mmu->memory_max_allocated < mmu->memory_allocated)
mmu->memory_max_allocated = mmu->memory_allocated;
# ifdef OS_ALLOCATOR_NEEDS_ALIGNMENT
return os_alloc_aligned_pages(len, alignment, dirty);
# else
Expand Down Expand Up @@ -258,6 +268,10 @@ static size_t mmu_memory_allocated(MMU *mmu) {
return mmu->memory_allocated;
}

static size_t mmu_memory_max_allocated(MMU *mmu) {
return mmu->memory_max_allocated;
}

static size_t mmu_memory_allocated_and_used(MMU *mmu) {
return mmu->memory_used;
}
Expand Down
12 changes: 11 additions & 1 deletion racket/src/racket/sgc/sgc.c
Expand Up @@ -775,7 +775,7 @@ static intptr_t mem_use, mem_limit = FIRST_GC_LIMIT;
int GC_free_space_divisor = 4;
#endif

static intptr_t mem_real_use, mem_uncollectable_use, mem_cumulative_use;
static intptr_t mem_real_use, mem_uncollectable_use, mem_cumulative_use, mem_peak_use;

static intptr_t sector_mem_use, sector_admin_mem_use, sector_free_mem_use;
static intptr_t manage_mem_use, manage_real_mem_use;
Expand Down Expand Up @@ -1649,6 +1649,7 @@ void GC_add_roots(void *start, void *end)
naya = (uintptr_t *)malloc_managed(sizeof(uintptr_t) * (roots_size + 1));

mem_real_use += (sizeof(uintptr_t) * roots_size);
if (mem_peak_use < mem_real_use) mem_peak_use = mem_real_use;

if (roots) {
memcpy((void *)naya, (void *)roots,
Expand Down Expand Up @@ -2225,6 +2226,11 @@ size_t GC_get_memory_use()
return (size_t)mem_real_use;
}

size_t GC_get_memory_peak_use()
{
return (size_t)mem_peak_use;
}

size_t GC_get_total_bytes()
{
return (size_t)mem_cumulative_use;
Expand Down Expand Up @@ -2496,6 +2502,7 @@ static void *do_malloc(SET_NO_BACKINFO
mem_use += size;
mem_real_use += (size + sizeof(MemoryChunk));
mem_cumulative_use += (size + sizeof(MemoryChunk));
if (mem_peak_use < mem_real_use) mem_peak_use = mem_real_use;
num_chunks++;

if (!low_plausible || (c->start < low_plausible))
Expand Down Expand Up @@ -2635,6 +2642,7 @@ static void *do_malloc(SET_NO_BACKINFO

mem_real_use += SECTOR_SEGMENT_SIZE;
mem_cumulative_use += SECTOR_SEGMENT_SIZE;
if (mem_peak_use < mem_real_use) mem_peak_use = mem_real_use;

block_top:

Expand Down Expand Up @@ -2869,6 +2877,7 @@ static void register_disappearing_link(void **p, void *a, int late)
GC_dl_entries++;

mem_real_use += sizeof(DisappearingLink);
if (mem_peak_use < mem_real_use) mem_peak_use = mem_real_use;
}

void GC_register_indirect_disappearing_link(void **p, void *a)
Expand Down Expand Up @@ -2944,6 +2953,7 @@ static void register_finalizer(void *p, void (*f)(void *p, void *data),
fn = (Finalizer *)malloc_managed(sizeof(Finalizer));
mem_real_use += sizeof(Finalizer);
mem_cumulative_use += sizeof(Finalizer);
if (mem_peak_use < mem_real_use) mem_peak_use = mem_real_use;
GC_fo_entries++;
}

Expand Down
1 change: 1 addition & 0 deletions racket/src/racket/sgc/sgc.h
Expand Up @@ -36,6 +36,7 @@ SGC_EXTERN void *GC_base(void *);
SGC_EXTERN void GC_dump(void);

SGC_EXTERN size_t GC_get_memory_use();
SGC_EXTERN size_t GC_get_memory_peak_use();
SGC_EXTERN size_t GC_get_total_bytes();

SGC_EXTERN void GC_end_stubborn_change(void *);
Expand Down

0 comments on commit dccd841

Please sign in to comment.