Skip to content

Commit

Permalink
staticdata: encode link_id in tagged linkage (#48673)
Browse files Browse the repository at this point in the history
On 64-bit, we have enough space to encode (1) the tag, (2) the
`depmods` index, and (3) the offset all in a single 64-bit pointer
field. This means we don't need the external `link_id` arrays,
which reduces the size of many pkgimages by ~5%.

On 32-bit, we don't have enough bits to implement this strategy.
However, most linkages seem to be against the sysimage, and so
by giving that a separate tag we can achieve similar compression
because the `link_id` lists will be much shorter.

Co-authored-by: Tim Holy <tim.holy@gmail.com>
  • Loading branch information
vtjnash and timholy authored Feb 17, 2023
1 parent 892cd4f commit 8e3e970
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 88 deletions.
6 changes: 3 additions & 3 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4251,7 +4251,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const
bool cache_valid = ctx.use_cache;
bool external = false;
if (ctx.external_linkage) {
if (jl_object_in_image((jl_value_t*)codeinst)) {
if (0 && jl_object_in_image((jl_value_t*)codeinst)) {
// Target is present in another pkgimage
cache_valid = true;
external = true;
Expand Down Expand Up @@ -5617,7 +5617,7 @@ static Function *emit_tojlinvoke(jl_code_instance_t *codeinst, Module *M, jl_cod

bool cache_valid = params.cache;
if (params.external_linkage) {
if (jl_object_in_image((jl_value_t*)codeinst)) {
if (0 && jl_object_in_image((jl_value_t*)codeinst)) {
// Target is present in another pkgimage
cache_valid = true;
}
Expand Down Expand Up @@ -8529,7 +8529,7 @@ void jl_compile_workqueue(
auto invoke = jl_atomic_load_relaxed(&codeinst->invoke);
bool cache_valid = params.cache;
if (params.external_linkage) {
cache_valid = jl_object_in_image((jl_value_t*)codeinst);
cache_valid = 0 && jl_object_in_image((jl_value_t*)codeinst);
}
// WARNING: isspecsig is protected by the codegen-lock. If that lock is removed, then the isspecsig load needs to be properly atomically sequenced with this.
if (cache_valid && invoke != NULL) {
Expand Down
3 changes: 2 additions & 1 deletion src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1985,6 +1985,7 @@ STATIC_INLINE void gc_mark_array8(jl_ptls_t ptls, jl_value_t *ary8_parent, jl_va
jl_gc_markqueue_t *mq = &ptls->mark_queue;
jl_value_t *new_obj;
size_t elsize = ((jl_array_t *)ary8_parent)->elsize / sizeof(jl_value_t *);
assert(elsize > 0);
// Decide whether need to chunk ary8
size_t nrefs = (ary8_end - ary8_begin) / elsize;
if (nrefs > MAX_REFS_AT_ONCE) {
Expand Down Expand Up @@ -2016,6 +2017,7 @@ STATIC_INLINE void gc_mark_array16(jl_ptls_t ptls, jl_value_t *ary16_parent, jl_
jl_gc_markqueue_t *mq = &ptls->mark_queue;
jl_value_t *new_obj;
size_t elsize = ((jl_array_t *)ary16_parent)->elsize / sizeof(jl_value_t *);
assert(elsize > 0);
// Decide whether need to chunk ary16
size_t nrefs = (ary16_end - ary16_begin) / elsize;
if (nrefs > MAX_REFS_AT_ONCE) {
Expand Down Expand Up @@ -2668,7 +2670,6 @@ static void gc_mark_roots(jl_gc_markqueue_t *mq)
}
gc_try_claim_and_push(mq, jl_all_methods, NULL);
gc_try_claim_and_push(mq, _jl_debug_method_invalidation, NULL);
gc_try_claim_and_push(mq, jl_build_ids, NULL);
// constants
gc_try_claim_and_push(mq, jl_emptytuple_type, NULL);
gc_try_claim_and_push(mq, cmpswap_names, NULL);
Expand Down
2 changes: 0 additions & 2 deletions src/jl_exported_data.inc
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,6 @@
XX(jl_voidpointer_type) \
XX(jl_void_type) \
XX(jl_weakref_type) \
XX(jl_build_ids) \
XX(jl_linkage_blobs) \

// Data symbols that are defined inside the public libjulia
#define JL_EXPORTED_DATA_SYMBOLS(XX) \
Expand Down
10 changes: 3 additions & 7 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,8 @@ extern tracer_cb jl_newmeth_tracer;
void jl_call_tracer(tracer_cb callback, jl_value_t *tracee);
void print_func_loc(JL_STREAM *s, jl_method_t *m);
extern jl_array_t *_jl_debug_method_invalidation JL_GLOBALLY_ROOTED;
extern arraylist_t jl_linkage_blobs; // external linkage: sysimg/pkgimages
extern jl_array_t *jl_build_ids JL_GLOBALLY_ROOTED; // external linkage: corresponding build_ids
extern arraylist_t jl_image_relocs; // external linkage: sysimg/pkgimages
JL_DLLEXPORT extern arraylist_t jl_linkage_blobs; // external linkage: sysimg/pkgimages
JL_DLLEXPORT extern arraylist_t jl_image_relocs; // external linkage: sysimg/pkgimages

extern JL_DLLEXPORT size_t jl_page_size;
extern jl_function_t *jl_typeinf_func JL_GLOBALLY_ROOTED;
Expand Down Expand Up @@ -951,10 +950,7 @@ static inline void jl_set_gc_and_wait(void)
// Query if a Julia object is if a permalloc region (due to part of a sys- pkg-image)
STATIC_INLINE size_t n_linkage_blobs(void) JL_NOTSAFEPOINT
{
if (!jl_build_ids)
return 0;
assert(jl_is_array(jl_build_ids));
return jl_array_len(jl_build_ids);
return jl_image_relocs.len;
}

// TODO: Makes this a binary search
Expand Down
Loading

2 comments on commit 8e3e970

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Executing the daily package evaluation, I will reply here when finished:

@nanosoldier runtests(isdaily = true)

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your package evaluation job has completed - possible new issues were detected.
A full report can be found here.

Please sign in to comment.