mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-15 05:44:58 +00:00
Two related changes for accurate GC with the MLDS->C back-end:
Estimated hours taken: 2 Branches: main Two related changes for accurate GC with the MLDS->C back-end: - Add a new runtime option --heap-margin-size for the threshold of free heap space before a collection is invoked, rather than the previous hack of reusing --heap-zone-size for that purpose. - A minor optimization to reduce the cost of MR_gc_check(): cache the value of MR_zone_end - MR_heap_margin_size. runtime/mercury_wrapper.h: runtime/mercury_wrapper.c: runtime/mercury_memory.c: Add new variable `MR_heap_margin_size', and add a new runtime option `--heap-margin-size' to set it. runtime/mercury_memory_zones.h: Add new field `gc_threshold' to the MR_MemoryZone struct. runtime/mercury_memory_zones.c: Initialize the new field to point to the zone end minus MR_heap_margin_size. runtime/mercury.h: Change MR_GC_check() to use the `gc_threshold' field.
This commit is contained in:
@@ -514,8 +514,8 @@ MR_Box MR_asm_box_float(MR_Float f);
|
||||
*/
|
||||
#define MR_GC_check() \
|
||||
do { \
|
||||
if ((char *) MR_hp + MR_heap_zone_size >= \
|
||||
(char *) MR_ENGINE(MR_eng_heap_zone)->MR_zone_end) \
|
||||
if ((char *) MR_hp >= \
|
||||
MR_ENGINE(MR_eng_heap_zone)->gc_threshold) \
|
||||
{ \
|
||||
MR_save_registers(); \
|
||||
MR_garbage_collect(); \
|
||||
|
||||
@@ -137,6 +137,7 @@ MR_init_memory(void)
|
||||
MR_global_heap_zone_size = 0;
|
||||
MR_debug_heap_size = 0;
|
||||
MR_debug_heap_zone_size = 0;
|
||||
MR_heap_margin_size = 0;
|
||||
#else
|
||||
MR_heap_size = MR_round_up(MR_heap_size * 1024,
|
||||
MR_unit);
|
||||
@@ -155,6 +156,8 @@ MR_init_memory(void)
|
||||
MR_unit);
|
||||
MR_debug_heap_zone_size = MR_round_up(MR_debug_heap_zone_size * 1024,
|
||||
MR_unit);
|
||||
/* Note that there's no need for the heap margin to be rounded up */
|
||||
MR_heap_margin_size = MR_heap_margin_size * 1024;
|
||||
#endif
|
||||
MR_detstack_size = MR_round_up(MR_detstack_size * 1024,
|
||||
MR_unit);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 1998-2000 The University of Melbourne.
|
||||
** Copyright (C) 1998-2000, 2002 The University of Melbourne.
|
||||
** This file may only be copied under the terms of the GNU Library General
|
||||
** Public License - see the file COPYING.LIB in the Mercury distribution.
|
||||
*/
|
||||
@@ -424,6 +424,9 @@ MR_construct_zone(const char *name, int id, MR_Word *base,
|
||||
}
|
||||
#endif /* MR_PROTECTPAGE */
|
||||
|
||||
#if defined(NATIVE_GC) && defined(MR_HIGHLEVEL_CODE)
|
||||
zone->gc_threshold = (char *) zone->MR_zone_end - MR_heap_margin_size;
|
||||
#endif
|
||||
|
||||
return zone;
|
||||
} /* end MR_construct_zone() */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright (C) 1998-2001 University of Melbourne.
|
||||
** Copyright (C) 1998-2002 University of Melbourne.
|
||||
** This file may only be copied under the terms of the GNU Library General
|
||||
** Public License - see the file COPYING.LIB in the Mercury distribution.
|
||||
*/
|
||||
@@ -125,6 +125,15 @@ struct MR_MemoryZone_Struct {
|
||||
#else
|
||||
#define MR_zone_end top
|
||||
#endif
|
||||
|
||||
#if defined(NATIVE_GC) && defined(MR_HIGHLEVEL_CODE)
|
||||
/*
|
||||
** This field, which is only used for heap zones,
|
||||
** points to MR_heap_margin_size bytes before MR_zone_end.
|
||||
** It is used to decide when to do garbage collection.
|
||||
*/
|
||||
char *gc_threshold; /* == MR_zone_end - MR_heap_margin_size */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -82,6 +82,18 @@ size_t MR_debug_heap_zone_size = 16;
|
||||
size_t MR_generatorstack_zone_size = 16;
|
||||
size_t MR_cutstack_zone_size = 16;
|
||||
|
||||
/*
|
||||
** MR_heap_margin_size is used for accurate GC with the MLDS->C back-end.
|
||||
** It is used to decide when to actually do a garbage collection.
|
||||
** At each call to MR_GC_check(), which is normally done on entry
|
||||
** to each C function, we check whether there is less than this
|
||||
** amount of heap space still available, and if not, we call
|
||||
** MR_garbage_collect().
|
||||
** Like the sizes above, it is measured in kilobytes
|
||||
** (but we later multiply by 1024 to convert to bytes).
|
||||
*/
|
||||
size_t MR_heap_margin_size = 16;
|
||||
|
||||
/* primary cache size to optimize for, in bytes */
|
||||
size_t MR_pcache_size = 8192;
|
||||
|
||||
@@ -735,6 +747,7 @@ enum MR_long_option {
|
||||
MR_NONDETSTACK_REDZONE_SIZE,
|
||||
MR_SOLUTIONS_HEAP_REDZONE_SIZE,
|
||||
MR_TRAIL_REDZONE_SIZE,
|
||||
MR_HEAP_MARGIN_SIZE,
|
||||
MR_MDB_TTY,
|
||||
MR_MDB_IN,
|
||||
MR_MDB_OUT,
|
||||
@@ -754,6 +767,7 @@ struct MR_option MR_long_opts[] = {
|
||||
{ "nondetstack-redzone-size", 1, 0, MR_NONDETSTACK_REDZONE_SIZE },
|
||||
{ "solutions-heap-redzone-size",1, 0, MR_SOLUTIONS_HEAP_REDZONE_SIZE },
|
||||
{ "trail-redzone-size", 1, 0, MR_TRAIL_REDZONE_SIZE },
|
||||
{ "heap-margin-size", 1, 0, MR_HEAP_MARGIN_SIZE },
|
||||
{ "mdb-tty", 1, 0, MR_MDB_TTY },
|
||||
{ "mdb-in", 1, 0, MR_MDB_IN },
|
||||
{ "mdb-out", 1, 0, MR_MDB_OUT },
|
||||
@@ -845,6 +859,13 @@ process_options(int argc, char **argv)
|
||||
MR_trail_zone_size = size;
|
||||
break;
|
||||
|
||||
case MR_HEAP_MARGIN_SIZE:
|
||||
if (sscanf(MR_optarg, "%lu", &size) != 1)
|
||||
usage();
|
||||
|
||||
MR_heap_margin_size = size;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
case MR_MDB_IN:
|
||||
MR_mdb_in_filename = MR_copy_string(MR_optarg);
|
||||
|
||||
@@ -209,6 +209,9 @@ extern size_t MR_debug_heap_zone_size;
|
||||
extern size_t MR_generatorstack_zone_size;
|
||||
extern size_t MR_cutstack_zone_size;
|
||||
|
||||
/* heap margin for MLDS->C accurate GC (documented in mercury_wrapper.c) */
|
||||
extern size_t MR_heap_margin_size;
|
||||
|
||||
/* file names for the mdb debugging streams */
|
||||
extern const char *MR_mdb_in_filename;
|
||||
extern const char *MR_mdb_out_filename;
|
||||
|
||||
Reference in New Issue
Block a user