diff options
author | Peter Wang <novalazy@gmail.com> | 2021-06-09 23:17:51 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2021-06-09 23:22:05 +0300 |
commit | 9245e1154d271b9fd69c5c6de75c6ac37f3badc4 (patch) | |
tree | ca0f8d71f6eaeeee0be73e82ee68485441c51908 /mark.c | |
parent | 57b97be07c514fcc4b608b13768fd2bf637a5899 (diff) | |
download | bdwgc-9245e1154d271b9fd69c5c6de75c6ac37f3badc4.tar.gz |
Limit number of unmapped regions (Linux)
Issue #324 (bdwgc).
When the number of areas exceeds vm.max_map_count on Linux (~65530 by
default) then the mmap call in GC_unmap fails with ENOMEM.
This commit fixes the issue by establishing a soft limit on the
number of unmapped regions.
* allchblk.c (get_block_ending_at): New static function.
* allchblk.c [USE_MUNMAP && COUNT_UNMAPPED_REGIONS]
(calc_num_unmapped_regions_delta): Likewise.
* allchblk.c (GC_free_block_ending_at): Use get_block_ending_at().
* allchblk.c [GC_adjust_num_unmapped] (GC_adjust_num_unmapped): New
inline function.
* allchblk.c [USE_MUNMAP && COUNT_UNMAPPED_REGIONS] (GC_unmap_old):
Skip unmapping if GC_num_unmapped_regions exceeds
GC_UNMAPPED_REGIONS_SOFT_LIMIT, update GC_num_unmapped_regions value
otherwise (before GC_unmap).
* allchblk.c [USE_MUNMAP] (GC_merge_unmapped, GC_allochblk_nth): Call
GC_adjust_num_unmapped() before GC_remap() and GC_unmap().
* headers.c (GC_next_used_block, GC_prev_block): Move/refine comment
to gc_priv.h.
* headers.c (GC_next_used_block): Rename to GC_next_block and add
allow_free parameter.
* include/private/gc_priv.h (GC_next_used_block): Likewise.
* include/private/gc_priv.h [USE_MUNMAP && COUNT_UNMAPPED_REGIONS]
(_GC_arrays): Add _num_unmapped_regions field.
* include/private/gcconfig.h [(M68K || POWERPC || SPARC || I386
|| MIPS || OR1K || ALPHA || IA64 || S390 || AARCH64 || ARM32 || CRIS
|| SH && !SH4 || AVR32 || M32R || X86_64 || HEXAGON || TILEPRO
|| TILEGX || RISCV) && LINUX] (COUNT_UNMAPPED_REGIONS): Define macro.
* include/private/gcconfig.h [USE_MUNMAP && COUNT_UNMAPPED_REGIONS
&& !GC_UNMAPPED_REGIONS_SOFT_LIMIT] (GC_UNMAPPED_REGIONS_SOFT_LIMIT):
Likewise.
* os_dep.c [USE_MUNMAP] (GC_unmap_end): Move to gc_priv.h and make it
inline.
* mark.c (GC_push_next_marked, GC_push_next_marked_dirty,
GC_push_next_marked_uncollectable): Use GC_next_block(h, FALSE)
instead of GC_next_used_block(h).
Diffstat (limited to 'mark.c')
-rw-r--r-- | mark.c | 12 |
1 files changed, 6 insertions, 6 deletions
@@ -1939,8 +1939,8 @@ STATIC struct hblk * GC_push_next_marked(struct hblk *h) hdr * hhdr = HDR(h); if (EXPECT(IS_FORWARDING_ADDR_OR_NIL(hhdr) || HBLK_IS_FREE(hhdr), FALSE)) { - h = GC_next_used_block(h); - if (h == 0) return(0); + h = GC_next_block(h, FALSE); + if (NULL == h) return NULL; hhdr = GC_find_header((ptr_t)h); } else { # ifdef LINT2 @@ -1961,8 +1961,8 @@ STATIC struct hblk * GC_push_next_marked(struct hblk *h) for (;;) { if (EXPECT(IS_FORWARDING_ADDR_OR_NIL(hhdr) || HBLK_IS_FREE(hhdr), FALSE)) { - h = GC_next_used_block(h); - if (h == 0) return(0); + h = GC_next_block(h, FALSE); + if (NULL == h) return NULL; hhdr = GC_find_header((ptr_t)h); } else { # ifdef LINT2 @@ -2002,8 +2002,8 @@ STATIC struct hblk * GC_push_next_marked_uncollectable(struct hblk *h) for (;;) { if (EXPECT(IS_FORWARDING_ADDR_OR_NIL(hhdr) || HBLK_IS_FREE(hhdr), FALSE)) { - h = GC_next_used_block(h); - if (h == 0) return(0); + h = GC_next_block(h, FALSE); + if (NULL == h) return NULL; hhdr = GC_find_header((ptr_t)h); } else { # ifdef LINT2 |