Skip to content

Commit 8ebb7a6

Browse files
xclercmshinwell
andauthored
Port upstream's #12193 (compaction) (#2078)
* Apply diff from upstream's #12193. * Remove deleted file from dune `install` stanza. * Fix to POOL_BLOCKS, and indentation fix to pool_free --------- Co-authored-by: Mark Shinwell <[email protected]>
1 parent 85beaa0 commit 8ebb7a6

25 files changed

+755
-172
lines changed

ocaml/.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ tools/ocaml-objcopy-macosx text eol=lf
193193
tools/ocamlsize text eol=lf
194194
tools/pre-commit-githook text eol=lf
195195
tools/markdown-add-pr-links.sh text eol=lf
196-
runtime/caml/sizeclasses.h typo.missing-header typo.white-at-eol
196+
runtime/caml/sizeclasses.h typo.missing-header
197197

198198
# Tests which include references spanning multiple lines fail with \r\n
199199
# endings, so use \n endings only, even on Windows.

ocaml/otherlibs/runtime_events/runtime_events.ml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ type runtime_phase =
7272
| EV_MINOR_LOCAL_ROOTS_PROMOTE
7373
| EV_DOMAIN_CONDITION_WAIT
7474
| EV_DOMAIN_RESIZE_HEAP_RESERVATION
75+
| EV_COMPACT
76+
| EV_COMPACT_EVACUATE
77+
| EV_COMPACT_FORWARD
78+
| EV_COMPACT_RELEASE
7579

7680
type lifecycle =
7781
EV_RING_START
@@ -153,6 +157,10 @@ let runtime_phase_name phase =
153157
| EV_DOMAIN_CONDITION_WAIT -> "domain_condition_wait"
154158
| EV_MAJOR_FINISH_CYCLE -> "major_finish_cycle"
155159
| EV_DOMAIN_RESIZE_HEAP_RESERVATION -> "domain_resize_heap_reservation"
160+
| EV_COMPACT -> "compaction"
161+
| EV_COMPACT_EVACUATE -> "compaction_evacuate"
162+
| EV_COMPACT_FORWARD -> "compaction_forward"
163+
| EV_COMPACT_RELEASE -> "compaction_release"
156164

157165
let lifecycle_name lifecycle =
158166
match lifecycle with

ocaml/otherlibs/runtime_events/runtime_events.mli

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ type runtime_phase =
130130
| EV_MINOR_LOCAL_ROOTS_PROMOTE
131131
| EV_DOMAIN_CONDITION_WAIT
132132
| EV_DOMAIN_RESIZE_HEAP_RESERVATION
133+
| EV_COMPACT
134+
| EV_COMPACT_EVACUATE
135+
| EV_COMPACT_FORWARD
136+
| EV_COMPACT_RELEASE
133137

134138
(** Lifecycle events for the ring itself *)
135139
type lifecycle =

ocaml/runtime/caml/compact.h

Lines changed: 0 additions & 36 deletions
This file was deleted.

ocaml/runtime/caml/dune

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
(callback.h as caml/callback.h)
4141
(camlatomic.h as caml/camlatomic.h)
4242
(codefrag.h as caml/codefrag.h)
43-
(compact.h as caml/compact.h)
4443
(compare.h as caml/compare.h)
4544
(config.h as caml/config.h)
4645
(custom.h as caml/custom.h)

ocaml/runtime/caml/major_gc.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ void caml_darken(void*, value, volatile value* ignored);
5353
void caml_darken_cont(value);
5454
void caml_mark_root(value, value*);
5555
void caml_empty_mark_stack(void);
56-
void caml_finish_major_cycle(void);
57-
56+
void caml_finish_major_cycle(int force_compaction);
57+
#ifdef DEBUG
58+
int caml_mark_stack_is_empty(void);
59+
#endif
5860
/* Ephemerons and finalisers */
5961
void caml_orphan_allocated_words(void);
6062
void caml_add_to_orphaned_ephe_list(struct caml_ephe_info* ephe_info);

ocaml/runtime/caml/osdeps.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ extern void caml_print_timestamp(FILE* channel, int formatted);
108108

109109
/* Memory management platform-specific operations */
110110

111-
void *caml_plat_mem_map(uintnat, uintnat, int);
111+
void *caml_plat_mem_map(uintnat, int);
112112
void *caml_plat_mem_commit(void *, uintnat);
113113
void caml_plat_mem_decommit(void *, uintnat);
114114
void caml_plat_mem_unmap(void *, uintnat);

ocaml/runtime/caml/platform.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,8 @@ uintnat caml_mem_round_up_pages(uintnat size);
122122
/* The size given to caml_mem_map and caml_mem_commit must be a multiple of
123123
caml_plat_pagesize. The size given to caml_mem_unmap and caml_mem_decommit
124124
must match the size given to caml_mem_map/caml_mem_commit for mem.
125-
126-
The Windows and Cygwin implementations do not support arbitrary alignment
127-
and will fail for alignment values greater than caml_plat_mmap_alignment.
128-
Luckily, this value is rather large on those platforms: 64KiB. This is enough
129-
for all alignments used in the runtime system so far, the larger being the
130-
major heap pools aligned on 32KiB boundaries. */
131-
void* caml_mem_map(uintnat size, uintnat alignment, int reserve_only);
125+
*/
126+
void* caml_mem_map(uintnat size, int reserve_only);
132127
void* caml_mem_commit(void* mem, uintnat size);
133128
void caml_mem_decommit(void* mem, uintnat size);
134129
void caml_mem_unmap(void* mem, uintnat size);

ocaml/runtime/caml/runtime_events.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,11 @@ typedef enum {
110110
EV_MINOR_REMEMBERED_SET_PROMOTE,
111111
EV_MINOR_LOCAL_ROOTS_PROMOTE,
112112
EV_DOMAIN_CONDITION_WAIT,
113-
EV_DOMAIN_RESIZE_HEAP_RESERVATION
113+
EV_DOMAIN_RESIZE_HEAP_RESERVATION,
114+
EV_COMPACT,
115+
EV_COMPACT_EVACUATE,
116+
EV_COMPACT_FORWARD,
117+
EV_COMPACT_RELEASE
114118
} ev_runtime_phase;
115119

116120
typedef enum {

ocaml/runtime/caml/shared_heap.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,16 @@
2424
#include "misc.h"
2525
#include "gc_stats.h"
2626

27+
CAMLextern atomic_uintnat caml_compactions_count;
28+
2729
struct caml_heap_state;
2830
struct pool;
2931

3032
struct caml_heap_state* caml_init_shared_heap(void);
3133
void caml_teardown_shared_heap(struct caml_heap_state* heap);
3234

3335
value* caml_shared_try_alloc(struct caml_heap_state*,
34-
mlsize_t, tag_t, reserved_t, int);
36+
mlsize_t, tag_t, reserved_t);
3537

3638
/* Copy the domain-local heap stats into a heap stats sample. */
3739
void caml_collect_heap_stats_sample(
@@ -45,7 +47,9 @@ uintnat caml_heap_size(struct caml_heap_state*);
4547
uintnat caml_top_heap_words(struct caml_heap_state*);
4648
uintnat caml_heap_blocks(struct caml_heap_state*);
4749

48-
struct pool* caml_pool_of_shared_block(value v);
50+
void caml_compact_heap(caml_domain_state* domain_state,
51+
int participating_count,
52+
caml_domain_state** participants);
4953

5054
void caml_shared_unpin(value v);
5155

ocaml/runtime/caml/sizeclasses.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
#define POOL_HEADER_WSIZE 4
44
#define SIZECLASS_MAX 128
55
#define NUM_SIZECLASSES 32
6-
static const unsigned int wsize_sizeclass[NUM_SIZECLASSES] =
6+
static const unsigned int wsize_sizeclass[NUM_SIZECLASSES] =
77
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 23, 26, 29, 33, 37, 42,
88
47, 53, 59, 65, 73, 81, 89, 99, 108, 118, 128 };
9-
static const unsigned char wastage_sizeclass[NUM_SIZECLASSES] =
9+
static const unsigned char wastage_sizeclass[NUM_SIZECLASSES] =
1010
{ 0, 0, 0, 0, 2, 0, 4, 4, 6, 2, 0, 4, 12, 6, 12, 21, 10, 3, 0, 22, 18, 3, 11,
1111
21, 62, 4, 42, 87, 33, 96, 80, 124 };
12-
static const unsigned char sizeclass_wsize[SIZECLASS_MAX + 1] =
12+
static const unsigned char sizeclass_wsize[SIZECLASS_MAX + 1] =
1313
{ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
1414
15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20,
1515
20, 20, 20, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23,

ocaml/runtime/domain.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -735,8 +735,7 @@ static void reserve_minor_heaps(void) {
735735
minor_heap_reservation_bsize = minor_heap_max_bsz * Max_domains;
736736

737737
/* reserve memory space for minor heaps */
738-
heaps_base = caml_mem_map(minor_heap_reservation_bsize, caml_plat_pagesize,
739-
1 /* reserve_only */);
738+
heaps_base = caml_mem_map(minor_heap_reservation_bsize, 1 /* reserve_only */);
740739
if (heaps_base == NULL)
741740
caml_fatal_error("Not enough heap memory to reserve minor heaps");
742741

@@ -1747,7 +1746,7 @@ static void handover_finalisers(caml_domain_state* domain_state)
17471746
if (caml_gc_phase != Phase_sweep_and_mark_main) {
17481747
/* Force a major GC cycle to simplify constraints for
17491748
* handing over finalisers. */
1750-
caml_finish_major_cycle();
1749+
caml_finish_major_cycle(0);
17511750
CAMLassert(caml_gc_phase == Phase_sweep_and_mark_main);
17521751
}
17531752
caml_add_orphaned_finalisers (f);

ocaml/runtime/gc_ctrl.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,12 @@ CAMLprim value caml_gc_quick_stat(value v)
5656
CAMLlocal1 (res);
5757

5858
/* get a copy of these before allocating anything... */
59-
intnat majcoll, mincoll;
59+
intnat majcoll, mincoll, compactions;
6060
struct gc_stats s;
6161
caml_compute_gc_stats(&s);
6262
majcoll = caml_major_cycles_completed;
6363
mincoll = atomic_load(&caml_minor_collections_count);
64+
compactions = atomic_load(&caml_compactions_count);
6465

6566
res = caml_alloc_tuple (17);
6667
Store_field (res, 0, caml_copy_double ((double)s.alloc_stats.minor_words));
@@ -81,7 +82,7 @@ CAMLprim value caml_gc_quick_stat(value v)
8182
Store_field (res, 10, Val_long (0));
8283
Store_field (res, 11, Val_long (0));
8384
Store_field (res, 12, Val_long (s.heap_stats.pool_frag_words));
84-
Store_field (res, 13, Val_long (0));
85+
Store_field (res, 13, Val_long (compactions));
8586
Store_field (res, 14, Val_long (
8687
s.heap_stats.pool_max_words + s.heap_stats.large_max_words));
8788
Store_field (res, 15, Val_long (0));
@@ -239,12 +240,12 @@ CAMLprim value caml_gc_minor(value v)
239240
return caml_raise_if_exception(exn);
240241
}
241242

242-
static value gc_major_exn(void)
243+
static value gc_major_exn(int force_compaction)
243244
{
244245
CAML_EV_BEGIN(EV_EXPLICIT_GC_MAJOR);
245246
caml_gc_log ("Major GC cycle requested");
246247
caml_empty_minor_heaps_once();
247-
caml_finish_major_cycle();
248+
caml_finish_major_cycle(force_compaction);
248249
value exn = caml_process_pending_actions_exn();
249250
CAML_EV_END(EV_EXPLICIT_GC_MAJOR);
250251
return exn;
@@ -254,7 +255,7 @@ CAMLprim value caml_gc_major(value v)
254255
{
255256
Caml_check_caml_state();
256257
CAMLassert (v == Val_unit);
257-
return caml_raise_if_exception(gc_major_exn());
258+
return caml_raise_if_exception(gc_major_exn(0));
258259
}
259260

260261
static value gc_full_major_exn(void)
@@ -267,7 +268,7 @@ static value gc_full_major_exn(void)
267268
currently-unreachable object to be collected. */
268269
for (i = 0; i < 3; i++) {
269270
caml_empty_minor_heaps_once();
270-
caml_finish_major_cycle();
271+
caml_finish_major_cycle(0);
271272
exn = caml_process_pending_actions_exn();
272273
if (Is_exception_result(exn)) break;
273274
}
@@ -296,13 +297,12 @@ CAMLprim value caml_gc_major_slice (value v)
296297
CAMLprim value caml_gc_compaction(value v)
297298
{
298299
Caml_check_caml_state();
299-
value exn = Val_unit;
300300
CAML_EV_BEGIN(EV_EXPLICIT_GC_COMPACT);
301301
CAMLassert (v == Val_unit);
302-
exn = gc_major_exn();
302+
value exn = gc_major_exn(1);
303303
++ Caml_state->stat_forced_major_collections;
304304
CAML_EV_END(EV_EXPLICIT_GC_COMPACT);
305-
return exn;
305+
return caml_raise_if_exception(exn);
306306
}
307307

308308
CAMLprim value caml_gc_stat(value v)

ocaml/runtime/intern.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,7 @@ static value intern_alloc_obj(struct caml_intern_state* s, caml_domain_state* d,
401401
s->intern_dest += 1 + wosize;
402402
} else {
403403
p = caml_shared_try_alloc(d->shared_heap, wosize, tag,
404-
0, /* no reserved bits */
405-
0 /* not pinned */);
404+
0 /* no reserved bits */);
406405
d->allocated_words += Whsize_wosize(wosize);
407406
if (p == NULL) {
408407
intern_cleanup (s);

0 commit comments

Comments
 (0)