Skip to content

Commit

Permalink
Addressing PR comments
Browse files Browse the repository at this point in the history
  • Loading branch information
udesou committed Sep 16, 2024
1 parent e72ca2f commit b4c573a
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 111 deletions.
134 changes: 78 additions & 56 deletions src/gc-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,15 +491,9 @@ int gc_n_threads;
jl_ptls_t* gc_all_tls_states;

// =========================================================================== //
// MISC
// Allocation
// =========================================================================== //

JL_DLLEXPORT jl_weakref_t *jl_gc_new_weakref(jl_value_t *value)
{
jl_ptls_t ptls = jl_current_task->ptls;
return jl_gc_new_weakref_th(ptls, value);
}

JL_DLLEXPORT void * jl_gc_alloc_typed(jl_ptls_t ptls, size_t sz, void *ty)
{
return jl_gc_alloc(ptls, sz, ty);
Expand Down Expand Up @@ -575,17 +569,9 @@ JL_DLLEXPORT jl_value_t *(jl_gc_alloc)(jl_ptls_t ptls, size_t sz, void *ty)
return jl_gc_alloc_(ptls, sz, ty);
}

const uint64_t _jl_buff_tag[3] = {0x4eadc0004eadc000ull, 0x4eadc0004eadc000ull, 0x4eadc0004eadc000ull}; // aka 0xHEADER00
JL_DLLEXPORT uintptr_t jl_get_buff_tag(void) JL_NOTSAFEPOINT
{
return jl_buff_tag;
}

// callback for passing OOM errors from gmp
JL_DLLEXPORT void jl_throw_out_of_memory_error(void)
{
jl_throw(jl_memory_exception);
}
// =========================================================================== //
// Generic Memory
// =========================================================================== //

size_t jl_genericmemory_nbytes(jl_genericmemory_t *m) JL_NOTSAFEPOINT
{
Expand Down Expand Up @@ -613,6 +599,66 @@ void jl_gc_track_malloced_genericmemory(jl_ptls_t ptls, jl_genericmemory_t *m, i
ptls->gc_tls.heap.mallocarrays = ma;
}

// =========================================================================== //
// GC Debug
// =========================================================================== //

int gc_slot_to_fieldidx(void *obj, void *slot, jl_datatype_t *vt) JL_NOTSAFEPOINT
{
int nf = (int)jl_datatype_nfields(vt);
for (int i = 1; i < nf; i++) {
if (slot < (void*)((char*)obj + jl_field_offset(vt, i)))
return i - 1;
}
return nf - 1;
}

int gc_slot_to_arrayidx(void *obj, void *_slot) JL_NOTSAFEPOINT
{
char *slot = (char*)_slot;
jl_datatype_t *vt = (jl_datatype_t*)jl_typeof(obj);
char *start = NULL;
size_t len = 0;
size_t elsize = sizeof(void*);
if (vt == jl_module_type) {
jl_module_t *m = (jl_module_t*)obj;
start = (char*)m->usings.items;
len = m->usings.len;
}
else if (vt == jl_simplevector_type) {
start = (char*)jl_svec_data(obj);
len = jl_svec_len(obj);
}
if (slot < start || slot >= start + elsize * len)
return -1;
return (slot - start) / elsize;
}

// =========================================================================== //
// GC Control
// =========================================================================== //

JL_DLLEXPORT uint32_t jl_get_gc_disable_counter(void) {
return jl_atomic_load_acquire(&jl_gc_disable_counter);
}

JL_DLLEXPORT int jl_gc_is_enabled(void)
{
jl_ptls_t ptls = jl_current_task->ptls;
return !ptls->disable_gc;
}

int gc_logging_enabled = 0;

JL_DLLEXPORT void jl_enable_gc_logging(int enable) {
gc_logging_enabled = enable;
}

JL_DLLEXPORT int jl_is_gc_logging_enabled(void) {
return gc_logging_enabled;
}


// collector entry point and control
_Atomic(uint32_t) jl_gc_disable_counter = 1;

Expand All @@ -637,54 +683,30 @@ JL_DLLEXPORT int jl_gc_enable(int on)
return prev;
}

JL_DLLEXPORT int jl_gc_is_enabled(void)
// =========================================================================== //
// MISC
// =========================================================================== //

JL_DLLEXPORT jl_weakref_t *jl_gc_new_weakref(jl_value_t *value)
{
jl_ptls_t ptls = jl_current_task->ptls;
return !ptls->disable_gc;
}

int gc_logging_enabled = 0;

JL_DLLEXPORT void jl_enable_gc_logging(int enable) {
gc_logging_enabled = enable;
return jl_gc_new_weakref_th(ptls, value);
}

JL_DLLEXPORT int jl_is_gc_logging_enabled(void) {
return gc_logging_enabled;
JL_DLLEXPORT jl_datatype_t **jl_get_ijl_small_typeof(void) {
return ijl_small_typeof;
}

// gc-debug common functions
// ---

int gc_slot_to_fieldidx(void *obj, void *slot, jl_datatype_t *vt) JL_NOTSAFEPOINT
const uint64_t _jl_buff_tag[3] = {0x4eadc0004eadc000ull, 0x4eadc0004eadc000ull, 0x4eadc0004eadc000ull}; // aka 0xHEADER00
JL_DLLEXPORT uintptr_t jl_get_buff_tag(void) JL_NOTSAFEPOINT
{
int nf = (int)jl_datatype_nfields(vt);
for (int i = 1; i < nf; i++) {
if (slot < (void*)((char*)obj + jl_field_offset(vt, i)))
return i - 1;
}
return nf - 1;
return jl_buff_tag;
}

int gc_slot_to_arrayidx(void *obj, void *_slot) JL_NOTSAFEPOINT
// callback for passing OOM errors from gmp
JL_DLLEXPORT void jl_throw_out_of_memory_error(void)
{
char *slot = (char*)_slot;
jl_datatype_t *vt = (jl_datatype_t*)jl_typeof(obj);
char *start = NULL;
size_t len = 0;
size_t elsize = sizeof(void*);
if (vt == jl_module_type) {
jl_module_t *m = (jl_module_t*)obj;
start = (char*)m->usings.items;
len = m->usings.len;
}
else if (vt == jl_simplevector_type) {
start = (char*)jl_svec_data(obj);
len = jl_svec_len(obj);
}
if (slot < start || slot >= start + elsize * len)
return -1;
return (slot - start) / elsize;
jl_throw(jl_memory_exception);
}

#ifdef __cplusplus
Expand Down
6 changes: 6 additions & 0 deletions src/gc-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,10 @@ JL_DLLEXPORT void jl_finalize_th(jl_task_t *ct, jl_value_t *o);
extern int gc_n_threads;
extern jl_ptls_t* gc_all_tls_states;

// =========================================================================== //
// Logging
// =========================================================================== //

extern int gc_logging_enabled;

#endif // JL_GC_COMMON_H
2 changes: 0 additions & 2 deletions src/gc-debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,8 +1105,6 @@ void gc_count_pool(void)
jl_safe_printf("************************\n");
}

extern int gc_logging_enabled;

void _report_gc_finished(uint64_t pause, uint64_t freed, int full, int recollect, int64_t live_bytes) JL_NOTSAFEPOINT {
if (!gc_logging_enabled) {
return;
Expand Down
30 changes: 2 additions & 28 deletions src/gc-interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ JL_DLLEXPORT void jl_gc_set_max_memory(uint64_t max_mem);
// should run a collection cycle again (e.g. a full mark right after a full sweep to ensure
// we do a full heap traversal).
JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t collection);
// Returns whether the thread with `tid` is a collector thread
JL_DLLEXPORT int gc_is_collector_thread(int tid) JL_NOTSAFEPOINT;

// ========================================================================= //
// Metrics
Expand Down Expand Up @@ -162,26 +164,6 @@ JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz);
JL_DLLEXPORT void jl_gc_counted_free_with_size(void *p, size_t sz);
// Wrapper around Libc realloc that updates Julia allocation counters.
JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size_t sz);
// Wrapper around Libc malloc that allocates a memory region with a few additional machine
// words before the actual payload that are used to record the size of the requested
// allocation. Also updates Julia allocation counters. The function returns a pointer to the
// payload as a result of the allocation.
JL_DLLEXPORT void *jl_malloc(size_t sz);
// Wrapper around Libc calloc that allocates a memory region with a few additional machine
// words before the actual payload that are used to record the size of the requested
// allocation. Also updates Julia allocation counters. The function returns a pointer to the
// payload as a result of the allocation.
JL_DLLEXPORT void *jl_calloc(size_t nm, size_t sz);
// Wrapper around Libc free that takes a pointer to the payload of a memory region allocated
// with jl_malloc or jl_calloc, and uses the size information stored in the first machine
// words of the memory buffer update Julia allocation counters, and then frees the
// corresponding memory buffer.
JL_DLLEXPORT void jl_free(void *p);
// Wrapper around Libc realloc that takes a memory region allocated with jl_malloc or
// jl_calloc, and uses the size information stored in the first machine words of the memory
// buffer to update Julia allocation counters, reallocating the corresponding memory buffer
// in the end.
JL_DLLEXPORT void *jl_realloc(void *p, size_t sz);
// Wrapper around Libc malloc that's used to dynamically allocate memory for Arrays and
// Strings. It increments Julia allocation counters and should check whether we're close to
// the Julia heap target, and therefore, whether we should run a collection. Note that this
Expand All @@ -195,14 +177,6 @@ JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz);
// thread-local allocator of the thread referenced by the first jl_ptls_t argument.
JL_DLLEXPORT struct _jl_weakref_t *jl_gc_new_weakref_th(struct _jl_tls_states_t *ptls,
struct _jl_value_t *value);
// Allocates a new weak-reference, assigns its value and increments Julia allocation
// counters. If thread-local allocators are used, then this function should allocate in the
// thread-local allocator of the current thread.
JL_DLLEXPORT struct _jl_weakref_t *jl_gc_new_weakref(struct _jl_value_t *value);
// Allocates an object whose size is specified by the function argument and increments Julia
// allocation counters. If thread-local allocators are used, then this function should
// allocate in the thread-local allocator of the current thread.
JL_DLLEXPORT struct _jl_value_t *jl_gc_allocobj(size_t sz);
// Permanently allocates a memory slot of the size specified by the first parameter. This
// block of memory is allocated in an immortal region that is never swept. The second
// parameter specifies whether the memory should be filled with zeros. The third and fourth
Expand Down
18 changes: 3 additions & 15 deletions src/gc-stock.c
Original file line number Diff line number Diff line change
Expand Up @@ -2786,19 +2786,8 @@ static void sweep_finalizer_list(arraylist_t *list)
list->len = j;
}

int gc_is_parallel_collector_thread(int tid) JL_NOTSAFEPOINT
{
return tid >= gc_first_tid && tid <= gc_last_parallel_collector_thread_id();
}

int gc_is_concurrent_collector_thread(int tid) JL_NOTSAFEPOINT
{
if (jl_n_sweepthreads == 0) {
return 0;
}
int last_parallel_collector_thread_id = gc_last_parallel_collector_thread_id();
int concurrent_collector_thread_id = last_parallel_collector_thread_id + 1;
return tid == concurrent_collector_thread_id;
int gc_is_collector_thread(int tid) JL_NOTSAFEPOINT {
return gc_is_parallel_collector_thread(tid) || gc_is_concurrent_collector_thread(tid);
}

JL_DLLEXPORT void jl_gc_get_total_bytes(int64_t *bytes) JL_NOTSAFEPOINT
Expand Down Expand Up @@ -3182,8 +3171,7 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
// free empty GC state for threads that have exited
if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) {
// GC threads should never exit
assert(!gc_is_parallel_collector_thread(t_i));
assert(!gc_is_concurrent_collector_thread(t_i));
assert(!gc_is_collector_thread(t_i));
jl_thread_heap_t *heap = &ptls2->gc_tls.heap;
if (heap->weak_refs.len == 0)
small_arraylist_free(&heap->weak_refs);
Expand Down
15 changes: 15 additions & 0 deletions src/gc-stock.h
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,21 @@ STATIC_INLINE int gc_ith_parallel_collector_thread_id(int i) JL_NOTSAFEPOINT
return gc_first_tid + i;
}

STATIC_INLINE int gc_is_parallel_collector_thread(int tid) JL_NOTSAFEPOINT
{
return tid >= gc_first_tid && tid <= gc_last_parallel_collector_thread_id();
}

STATIC_INLINE int gc_is_concurrent_collector_thread(int tid) JL_NOTSAFEPOINT
{
if (jl_n_sweepthreads == 0) {
return 0;
}
int last_parallel_collector_thread_id = gc_last_parallel_collector_thread_id();
int concurrent_collector_thread_id = last_parallel_collector_thread_id + 1;
return tid == concurrent_collector_thread_id;
}

STATIC_INLINE int gc_random_parallel_collector_thread_id(jl_ptls_t ptls) JL_NOTSAFEPOINT
{
assert(jl_n_markthreads > 0);
Expand Down
2 changes: 1 addition & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,7 @@ static inline jl_value_t *jl_to_typeof(uintptr_t t)
return (jl_value_t*)t;
}
#else
extern JL_DLLEXPORT jl_datatype_t *ijl_small_typeof[(jl_max_tags << 4) / sizeof(jl_datatype_t*)];
extern JL_HIDDEN jl_datatype_t *ijl_small_typeof[(jl_max_tags << 4) / sizeof(jl_datatype_t*)];
static inline jl_value_t *jl_to_typeof(uintptr_t t)
{
if (t < (jl_max_tags << 4))
Expand Down
4 changes: 3 additions & 1 deletion src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ extern jl_function_t *jl_typeinf_func JL_GLOBALLY_ROOTED;
extern JL_DLLEXPORT size_t jl_typeinf_world;
extern _Atomic(jl_typemap_entry_t*) call_cache[N_CALL_CACHE] JL_GLOBALLY_ROOTED;

extern void free_stack(void *stkbuf, size_t bufsz) JL_NOTSAFEPOINT;

JL_DLLEXPORT extern int jl_lineno;
JL_DLLEXPORT extern const char *jl_filename;

Expand Down Expand Up @@ -1050,7 +1052,7 @@ STATIC_INLINE int jl_addr_is_safepoint(uintptr_t addr)
return addr >= safepoint_addr && addr < safepoint_addr + jl_page_size * 4;
}
extern _Atomic(uint32_t) jl_gc_running;
extern JL_DLLEXPORT _Atomic(uint32_t) jl_gc_disable_counter;
extern _Atomic(uint32_t) jl_gc_disable_counter;
// All the functions are safe to be called from within a signal handler
// provided that the thread will not be interrupted by another asynchronous
// signal.
Expand Down
10 changes: 2 additions & 8 deletions src/stackwalk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1294,8 +1294,6 @@ JL_DLLEXPORT void jl_print_backtrace(void) JL_NOTSAFEPOINT
}

extern int gc_first_tid;
extern int gc_is_parallel_collector_thread(int tid) JL_NOTSAFEPOINT;
extern int gc_is_concurrent_collector_thread(int tid) JL_NOTSAFEPOINT;

// Print backtraces for all live tasks, for all threads, to jl_safe_printf stderr
JL_DLLEXPORT void jl_print_task_backtraces(int show_done) JL_NOTSAFEPOINT
Expand All @@ -1304,12 +1302,8 @@ JL_DLLEXPORT void jl_print_task_backtraces(int show_done) JL_NOTSAFEPOINT
jl_ptls_t *allstates = jl_atomic_load_relaxed(&jl_all_tls_states);
for (size_t i = 0; i < nthreads; i++) {
jl_ptls_t ptls2 = allstates[i];
if (gc_is_parallel_collector_thread(i)) {
jl_safe_printf("==== Skipping backtrace for parallel GC thread %zu\n", i + 1);
continue;
}
if (gc_is_concurrent_collector_thread(i)) {
jl_safe_printf("==== Skipping backtrace for concurrent GC thread %zu\n", i + 1);
if (gc_is_collector_thread(i)) {
jl_safe_printf("==== Skipping backtrace for parallel/concurrent GC thread %zu\n", i + 1);
continue;
}
if (ptls2 == NULL) {
Expand Down

0 comments on commit b4c573a

Please sign in to comment.