Skip to content

Commit

Permalink
Add HIDDEN ijl_small_typeof as an optimization
Browse files Browse the repository at this point in the history
This allows us to avoid a linker indirection on, e.g., Linux and macOS
where symbol interposition means that an extra load is incurred to
support possible relocation of the symbol to a pre-empting library.
  • Loading branch information
topolarity committed Aug 30, 2023
1 parent a8f1a98 commit 21b9c1f
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2427,7 +2427,7 @@ FORCE_INLINE void gc_mark_outrefs(jl_ptls_t ptls, jl_gc_markqueue_t *mq, void *_
vtag == (jl_vararg_tag << 4)) {
// these objects have pointers in them, but no other special handling
// so we want these to fall through to the end
vtag = (uintptr_t)jl_small_typeof[vtag / sizeof(*jl_small_typeof)];
vtag = (uintptr_t)ijl_small_typeof[vtag / sizeof(*ijl_small_typeof)];
}
else if (vtag < jl_max_tags << 4) {
// these objects either have specialing handling
Expand Down Expand Up @@ -2532,7 +2532,7 @@ FORCE_INLINE void gc_mark_outrefs(jl_ptls_t ptls, jl_gc_markqueue_t *mq, void *_
objprofile_count(jl_string_type, bits == GC_OLD_MARKED, dtsz);
}
else {
jl_datatype_t *vt = jl_small_typeof[vtag / sizeof(*jl_small_typeof)];
jl_datatype_t *vt = ijl_small_typeof[vtag / sizeof(*ijl_small_typeof)];
size_t dtsz = jl_datatype_size(vt);
if (update_meta)
gc_setmark(ptls, o, bits, dtsz);
Expand Down
12 changes: 11 additions & 1 deletion src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extern "C" {
#endif

_Atomic(jl_value_t*) cmpswap_names JL_GLOBALLY_ROOTED;
jl_datatype_t *ijl_small_typeof[(jl_max_tags << 4) / sizeof(*ijl_small_typeof)]; // 16-bit aligned, like the GC

// compute empirical max-probe for a given size
#define max_probe(size) ((size) <= 1024 ? 16 : (size) >> 6)
Expand Down Expand Up @@ -2528,8 +2529,13 @@ static jl_tvar_t *tvar(const char *name)
(jl_value_t*)jl_any_type);
}

void export_jl_small_typeof(void)
{
memcpy(&jl_small_typeof, &ijl_small_typeof, sizeof(jl_small_typeof));
}

#define XX(name) \
jl_small_typeof[(jl_##name##_tag << 4) / sizeof(*jl_small_typeof)] = jl_##name##_type; \
ijl_small_typeof[(jl_##name##_tag << 4) / sizeof(*ijl_small_typeof)] = jl_##name##_type; \
jl_##name##_type->smalltag = jl_##name##_tag;
void jl_init_types(void) JL_GC_DISABLED
{
Expand Down Expand Up @@ -3351,6 +3357,8 @@ void jl_init_types(void) JL_GC_DISABLED

// override the preferred layout for a couple types
jl_lineinfonode_type->name->mayinlinealloc = 0; // FIXME: assumed to be a pointer by codegen

export_jl_small_typeof();
}

static jl_value_t *core(const char *name)
Expand Down Expand Up @@ -3431,6 +3439,8 @@ void post_boot_hooks(void)
}
}
}

export_jl_small_typeof();
}

void post_image_load_hooks(void) {
Expand Down
15 changes: 11 additions & 4 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -750,16 +750,23 @@ enum jl_small_typeof_tags {
jl_bitstags_first = jl_char_tag, // n.b. bool is not considered a bitstype, since it can be compared by pointer
jl_max_tags = 64
};
#ifndef JL_LIBRARY_EXPORTS
JL_DLLIMPORT
#endif
extern jl_datatype_t *jl_small_typeof[(jl_max_tags << 4) / sizeof(jl_datatype_t*)];
extern JL_DLLIMPORT jl_datatype_t *jl_small_typeof[(jl_max_tags << 4) / sizeof(jl_datatype_t*)];
#ifndef JL_LIBRARY_EXPORTS_INTERNAL
static inline jl_value_t *jl_to_typeof(uintptr_t t)
{
if (t < (jl_max_tags << 4))
return (jl_value_t*)jl_small_typeof[t / sizeof(*jl_small_typeof)];
return (jl_value_t*)t;
}
#else
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))
return (jl_value_t*)ijl_small_typeof[t / sizeof(*ijl_small_typeof)];
return (jl_value_t*)t;
}
#endif


// kinds
Expand Down
4 changes: 3 additions & 1 deletion src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -2839,6 +2839,7 @@ JL_DLLEXPORT void jl_set_sysimg_so(void *handle)
#endif

extern void rebuild_image_blob_tree(void);
extern void export_jl_small_typeof(void);

static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl_array_t *depmods, uint64_t checksum,
/* outputs */ jl_array_t **restored, jl_array_t **init_order,
Expand Down Expand Up @@ -2914,9 +2915,10 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl
*tag = jl_read_value(&s);
}
#define XX(name) \
jl_small_typeof[(jl_##name##_tag << 4) / sizeof(*jl_small_typeof)] = jl_##name##_type;
ijl_small_typeof[(jl_##name##_tag << 4) / sizeof(*ijl_small_typeof)] = jl_##name##_type;
JL_SMALL_TYPEOF(XX)
#undef XX
export_jl_small_typeof();
jl_global_roots_table = (jl_array_t*)jl_read_value(&s);
// set typeof extra-special values now that we have the type set by tags above
jl_astaggedvalue(jl_nothing)->header = (uintptr_t)jl_nothing_type | jl_astaggedvalue(jl_nothing)->header;
Expand Down

0 comments on commit 21b9c1f

Please sign in to comment.