Skip to content

Commit

Permalink
avoid duplicates in remset
Browse files Browse the repository at this point in the history
  • Loading branch information
Diogo Netto authored and Diogo Netto committed Aug 12, 2022
1 parent 0dbb1b1 commit 5d5dadc
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 21 deletions.
35 changes: 35 additions & 0 deletions src/gc-pool-alloc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// This file is a part of Julia. License is MIT: https://julialang.org/license

#include "gc-markqueue.h"
#include "gc.h"

#ifdef __cplusplus
extern "C" {
#endif

static size_t pow2[10] = {1, 2, 4, 8. 16, 32, 64, 128, 256, 512, 1024};

static ws_queue_t gc_recycled_pages;

jl_taggedvalue_t *gc_pool_alloc(jl_ptls_t ptls, size_t sz)
{
int i = 0;
for (; pow2[i] < sz; i++)
;

jl_thread_heap_t *pheap = &ptls->heap;
jl_gc_pagedir_entry_t *entry = &pheap->pa_dir_entries[i];

jl_taggedvalue_t *obj;

if (entry->head->pfl != NULL) {
obj = entry->head->pfl;
entry->head->pfl = obj->next;
}

return obj;
}

#ifdef __cplusplus
}
#endif
16 changes: 16 additions & 0 deletions src/gc-pool-alloc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// This file is a part of Julia. License is MIT: https://julialang.org/license

#ifndef JL_GC_POOL_ALLOC_H
#define JL_GC_POOL_ALLOC_H

#include "gc.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif
35 changes: 14 additions & 21 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2582,13 +2582,11 @@ static void gc_premark(jl_ptls_t ptls2)
for (size_t i = 0; i < len; i++) {
jl_value_t *item = (jl_value_t *)items[i];
objprofile_count(jl_typeof(item), 2, 0);
jl_astaggedvalue(item)->bits.gc = GC_OLD_MARKED;
}
len = ptls2->heap.rem_bindings.len;
items = ptls2->heap.rem_bindings.items;
for (size_t i = 0; i < len; i++) {
void *ptr = items[i];
jl_astaggedvalue(ptr)->bits.gc = GC_OLD_MARKED;
// Avoid duplicates in the `remset`
if (jl_astaggedvalue(item)->bits.gc == GC_MARKED) {
jl_astaggedvalue(item)->bits.gc = GC_OLD_MARKED;
gc_mark_outrefs(ptls2, &ptls2->mark_queue, item, 1);
}
}
}

Expand All @@ -2615,20 +2613,14 @@ static void gc_queue_bt_buf(jl_gc_markqueue_t *mq, jl_ptls_t ptls2)
}
}

static void gc_queue_remset(jl_ptls_t ptls, jl_ptls_t ptls2)
static void gc_queue_rem_binding(jl_ptls_t ptls)
{
size_t len = ptls2->heap.last_remset->len;
void **items = ptls2->heap.last_remset->items;
for (size_t i = 0; i < len; i++) {
// Objects in the `remset` are already marked,
// so a `gc_try_claim_and_push` wouldn't work here
gc_mark_outrefs(ptls, &ptls->mark_queue, (jl_value_t *)items[i], 1);
}
int n_bnd_refyoung = 0;
len = ptls2->heap.rem_bindings.len;
items = ptls2->heap.rem_bindings.items;
size_t len = ptls->heap.rem_bindings.len;
void **items = ptls->heap.rem_bindings.items;
for (size_t i = 0; i < len; i++) {
jl_binding_t *ptr = (jl_binding_t *)items[i];
jl_astaggedvalue(ptr)->bits.gc = GC_OLD_MARKED;
// A null pointer can happen here when the binding is cleaned up
// as an exception is thrown after it was already queued (#10221)
jl_value_t *v = jl_atomic_load_relaxed(&ptr->value);
Expand All @@ -2638,7 +2630,7 @@ static void gc_queue_remset(jl_ptls_t ptls, jl_ptls_t ptls2)
n_bnd_refyoung++;
}
}
ptls2->heap.rem_bindings.len = n_bnd_refyoung;
ptls->heap.rem_bindings.len = n_bnd_refyoung;
}

extern jl_value_t *cmpswap_names JL_GLOBALLY_ROOTED;
Expand Down Expand Up @@ -2805,7 +2797,8 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
// main mark-loop
uint64_t start_mark_time = jl_hrtime();
JL_PROBE_GC_MARK_BEGIN();
// 1. fix GC bits of objects in the remset.
// 1. fix GC bits of objects in the remset and mark outgoing
// references from them
for (int t_i = 0; t_i < jl_n_threads; t_i++) {
gc_premark(jl_all_tls_states[t_i]);
}
Expand All @@ -2815,8 +2808,8 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
gc_queue_thread_local(&ptls2->mark_queue, ptls2);
// 2.2 mark any managed objects in the backtrace buffer
gc_queue_bt_buf(&ptls2->mark_queue, ptls2);
// 2.3. mark every object in the `last_remsets` and `rem_binding`
gc_queue_remset(ptls2, ptls2);
// 2.3. mark every object in the `rem_binding`
gc_queue_rem_binding(ptls2);
}
// 3. walk roots
gc_mark_roots(&ptls->mark_queue);
Expand Down

0 comments on commit 5d5dadc

Please sign in to comment.