Skip to content

Commit c15536b

Browse files
authored
Use the same threshold for out-of-cycle work for major and minor dependent allocs (#3616)
Use the same threshold for out-of-cycle work for major and minor dep alloc (Squashes a FIXME)
1 parent af711d6 commit c15536b

File tree

4 files changed

+21
-29
lines changed

4 files changed

+21
-29
lines changed

runtime/caml/custom.h

-3
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,6 @@ CAMLextern value caml_alloc_custom_dep(const struct custom_operations * ops,
8989
CAMLextern void
9090
caml_register_custom_operations(const struct custom_operations * ops);
9191

92-
/* Return the current [max] factor for [caml_alloc_custom_mem] allocations. */
93-
CAMLextern mlsize_t caml_custom_get_max_major (void);
94-
9592
/* Global variable moved to Caml_state in 4.10 */
9693
#define caml_compare_unordered (Caml_state_field(compare_unordered))
9794

runtime/custom.c

-16
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,6 @@ uintnat caml_custom_major_ratio = Custom_major_ratio_def;
3636
uintnat caml_custom_minor_ratio = Custom_minor_ratio_def;
3737
uintnat caml_custom_minor_max_bsz = Custom_minor_max_bsz_def;
3838

39-
mlsize_t caml_custom_get_max_major (void)
40-
{
41-
/* The major ratio is a percentage relative to the major heap size.
42-
A complete GC cycle will be done every time 2/3 of that much
43-
memory is allocated for blocks in the major heap. Assuming
44-
constant allocation and deallocation rates, this means there are
45-
at most [M/100 * major-heap-size] bytes of floating garbage at
46-
any time. The reason for a factor of 2/3 (or 1.5) is, roughly
47-
speaking, because the major GC takes 1.5 cycles (previous cycle +
48-
marking phase) before it starts to deallocate dead blocks
49-
allocated during the previous cycle. [heap_size / 150] is really
50-
[heap_size * (2/3) / 100] (but faster). */
51-
return caml_heap_size(Caml_state->shared_heap) / 150
52-
* caml_custom_major_ratio;
53-
}
54-
5539
static value alloc_custom_gen (const struct custom_operations * ops,
5640
uintnat bsz,
5741
bool minor_ok,

runtime/major_gc.c

+16-4
Original file line numberDiff line numberDiff line change
@@ -633,10 +633,22 @@ static void update_major_slice_work(intnat howmuch,
633633

634634
my_alloc_count = dom_st->allocated_words;
635635
my_alloc_direct_count = dom_st->allocated_words_direct;
636-
my_extra_count =
637-
(double)dom_st->allocated_dependent_bytes /
638-
(double)caml_custom_get_max_major ();
639-
if (my_extra_count > 1.0) my_extra_count = 1.0;
636+
{
637+
/* The major ratio is a percentage relative to the major heap size.
638+
A complete GC cycle will be done every time 2/3 of that much
639+
memory is allocated for blocks in the major heap. Assuming
640+
constant allocation and deallocation rates, this means there are
641+
at most [M/100 * major-heap-size] bytes of floating garbage at
642+
any time. The reason for a factor of 2/3 (or 1.5) is, roughly
643+
speaking, because the major GC takes 1.5 cycles (previous cycle +
644+
marking phase) before it starts to deallocate dead blocks
645+
allocated during the previous cycle. [heap_size / 150] is really
646+
[heap_size * (2/3) / 100] (but faster). */
647+
double max_major =
648+
caml_heap_size(Caml_state->shared_heap) / 150 * caml_custom_major_ratio;
649+
my_extra_count = (double)dom_st->allocated_dependent_bytes / max_major;
650+
if (my_extra_count > 1.0) my_extra_count = 1.0;
651+
}
640652
dom_st->stat_major_words += dom_st->allocated_words;
641653
dom_st->allocated_words = 0;
642654
dom_st->allocated_words_direct = 0;

runtime/memory.c

+5-6
Original file line numberDiff line numberDiff line change
@@ -240,21 +240,20 @@ CAMLexport void caml_alloc_dependent_memory (value v, mlsize_t nbytes)
240240
{
241241
if (nbytes == 0) return;
242242
CAMLassert (Is_block (v));
243+
/* Maximum dependent allocation before a minor GC or a major slice */
244+
uintnat max_alloc =
245+
Bsize_wsize (Caml_state->minor_heap_wsz) / 100 * caml_custom_minor_ratio;
243246
if (Is_young (v)){
244247
Caml_state->stat_minor_dependent_bytes += nbytes;
245248
add_to_dependent_table (&Caml_state->minor_tables->dependent, v, nbytes);
246249
Caml_state->minor_dependent_bsz += nbytes;
247-
uintnat max_minor =
248-
Bsize_wsize (Caml_state->minor_heap_wsz) / 100 * caml_custom_minor_ratio;
249-
if (Caml_state->minor_dependent_bsz > max_minor) {
250+
if (Caml_state->minor_dependent_bsz > max_alloc) {
250251
caml_request_minor_gc ();
251252
}
252253
} else {
253254
caml_add_dependent_bytes (Caml_state->shared_heap, nbytes);
254255
Caml_state->allocated_dependent_bytes += nbytes;
255-
/* FIXME sdolan: what's the right condition here? */
256-
uintnat max_major = caml_custom_get_max_major() / 5;
257-
if (Caml_state->allocated_dependent_bytes > max_major){
256+
if (Caml_state->allocated_dependent_bytes > max_alloc){
258257
CAML_EV_COUNTER (EV_C_REQUEST_MAJOR_ALLOC_SHR, 1);
259258
caml_request_major_slice(1);
260259
}

0 commit comments

Comments
 (0)