Skip to content

Commit

Permalink
Promote all finalizers (and objects with finalizers) in the minor gc …
Browse files Browse the repository at this point in the history
…to allow early release
  • Loading branch information
ctk21 committed Feb 14, 2020
1 parent 188f98f commit c56f5d5
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 16 deletions.
4 changes: 2 additions & 2 deletions byterun/finalise.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ static void generic_final_minor_update (struct domain* d, struct finalisable * f
CAMLassert (final->old <= final->young);
for (i = final->old; i < final->young; i++){
CAMLassert (Is_block (final->table[i].val));
if (Is_minor(final->table[i].val) && Hd_val(final->table[i].val) != 0){
if (Is_minor(final->table[i].val) && get_header_val(final->table[i].val) != 0){
++ todo_count;
}
}
Expand All @@ -248,7 +248,7 @@ static void generic_final_minor_update (struct domain* d, struct finalisable * f
for (i = final->old; i < final->young; i++) {
CAMLassert (Is_block (final->table[i].val));
CAMLassert (Tag_val (final->table[i].val) != Forward_tag);
if (Is_minor(final->table[j].val) && Hd_val(final->table[i].val) != 0) {
if (Is_minor(final->table[j].val) && get_header_val(final->table[i].val) != 0) {
/** dead */
fi->todo_tail->item[k] = final->table[i];
/* The finalisation function is called with unit not with the value */
Expand Down
47 changes: 34 additions & 13 deletions byterun/minor_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,24 +487,27 @@ CAMLexport value caml_promote(struct domain* domain, value root)



void caml_empty_minor_heap_domain_finalizers (struct domain* domain, void* unused)
void caml_minor_heap_domain_finalizers_admin (struct domain* domain, void* unused)
{
caml_domain_state* domain_state = domain->state;
struct caml_minor_tables *minor_tables = domain_state->minor_tables;
struct caml_custom_elt *elt;

/* need to do the finalizer data structure book-keeping */
caml_final_update_last_minor(domain);
/* Run custom block finalisation of dead minor values */
for (elt = minor_tables->custom.base; elt < minor_tables->custom.ptr; elt++) {

/* There will be no dead minor values as we can not tell the state of
a minor heap aliveness until all domains complete */
/*for (elt = minor_tables->custom.base; elt < minor_tables->custom.ptr; elt++) {
value v = elt->block;
if (get_header_val(v) == 0) {
if (get_header_val(v) == 0) {*/
/* !!caml_adjust_gc_speed(elt->mem, elt->max); */
} else {
/*} else {*/
/* Block will be freed: call finalisation function, if any */
void (*final_fun)(value) = Custom_ops_val(v)->finalize;
/* void (*final_fun)(value) = Custom_ops_val(v)->finalize;
if (final_fun != NULL) final_fun(v);
}
}
}*/
}

void caml_empty_minor_heap_domain_clear (struct domain* domain, void* unused)
Expand Down Expand Up @@ -543,6 +546,7 @@ void caml_empty_minor_heap_promote (struct domain* domain, int domains_in_minor_
{
caml_domain_state* domain_state = domain->state;
struct caml_minor_tables *self_minor_tables = domain_state->minor_tables;
struct caml_custom_elt *elt;
unsigned rewrite_successes = 0;
unsigned rewrite_failures = 0;
char* young_ptr = domain_state->young_ptr;
Expand Down Expand Up @@ -622,15 +626,36 @@ void caml_empty_minor_heap_promote (struct domain* domain, int domains_in_minor_
}
#endif

/* promote the finalizers unconditionally as we want to allow early release */
caml_ev_begin("minor_gc/finalizers/oldify");
for (elt = self_minor_tables->custom.base; elt < self_minor_tables->custom.ptr; elt++) {
value *v = &elt->block;
if (Is_block(*v) && Is_minor(*v)) {
resolve_infix_val(v);
if (get_header_val(*v) == 0) { /* value copied to major heap */
*v = Op_val(*v)[0];
} else {
oldify_one(&st, *v, v);
}
}
}
caml_final_do_young_roots (&oldify_one, &st, domain, 0);
caml_ev_end("minor_gc/finalizers/oldify");

caml_ev_begin("minor_gc/remembered_set/promote");
oldify_mopup (&st, 1); /* ephemerons promoted here */
caml_ev_end("minor_gc/remembered_set/promote");
caml_ev_end("minor_gc/remembered_set");
caml_gc_log("promoted %d roots, %d bytes", remembered_roots, st.live_bytes);
caml_gc_log("promoted %d roots, %lu bytes", remembered_roots, st.live_bytes);

caml_ev_begin("minor_gc/finalizers_admin");
caml_gc_log("running stw minor_heap_domain_finalizers_admin");
caml_minor_heap_domain_finalizers_admin(domain, 0);
caml_ev_end("minor_gc/finalizers_admin");

#ifdef DEBUG
caml_global_barrier();
caml_gc_log("ref_base: %ul, ref_ptr: %ul", self_minor_tables->major_ref.base, self_minor_tables->major_ref.ptr);
caml_gc_log("ref_base: %lu, ref_ptr: %lu", self_minor_tables->major_ref.base, self_minor_tables->major_ref.ptr);
for (r = self_minor_tables->major_ref.base;
r < self_minor_tables->major_ref.ptr; r++) {
value vnew = **r;
Expand Down Expand Up @@ -713,10 +738,6 @@ void caml_stw_empty_minor_heap (struct domain* domain, void* unused)
caml_ev_end("minor_gc/leave_barrier");
}

caml_ev_begin("minor_gc/finalizers");
caml_gc_log("running stw empty_minor_heap_domain_finalizers");
caml_empty_minor_heap_domain_finalizers(domain, 0);
caml_ev_end("minor_gc/finalizers");
caml_ev_begin("minor_gc/clear");
caml_gc_log("running stw empty_minor_heap_domain_clear");
caml_empty_minor_heap_domain_clear(domain, 0);
Expand Down
1 change: 0 additions & 1 deletion byterun/roots.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ CAMLexport void caml_do_local_roots (scanning_action f, void* fdata,
}
}
}
caml_final_do_young_roots (f, fdata, domain, do_final_val);
/* Hook */
if (caml_scan_roots_hook != NULL) (*caml_scan_roots_hook)(f, fdata, domain);
}

0 comments on commit c56f5d5

Please sign in to comment.