Skip to content

Commit 21b9c1f

Browse files
committed
Add HIDDEN ijl_small_typeof as an optimization
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.
1 parent a8f1a98 commit 21b9c1f

File tree

4 files changed

+27
-8
lines changed

4 files changed

+27
-8
lines changed

src/gc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,7 +2427,7 @@ FORCE_INLINE void gc_mark_outrefs(jl_ptls_t ptls, jl_gc_markqueue_t *mq, void *_
24272427
vtag == (jl_vararg_tag << 4)) {
24282428
// these objects have pointers in them, but no other special handling
24292429
// so we want these to fall through to the end
2430-
vtag = (uintptr_t)jl_small_typeof[vtag / sizeof(*jl_small_typeof)];
2430+
vtag = (uintptr_t)ijl_small_typeof[vtag / sizeof(*ijl_small_typeof)];
24312431
}
24322432
else if (vtag < jl_max_tags << 4) {
24332433
// these objects either have specialing handling
@@ -2532,7 +2532,7 @@ FORCE_INLINE void gc_mark_outrefs(jl_ptls_t ptls, jl_gc_markqueue_t *mq, void *_
25322532
objprofile_count(jl_string_type, bits == GC_OLD_MARKED, dtsz);
25332533
}
25342534
else {
2535-
jl_datatype_t *vt = jl_small_typeof[vtag / sizeof(*jl_small_typeof)];
2535+
jl_datatype_t *vt = ijl_small_typeof[vtag / sizeof(*ijl_small_typeof)];
25362536
size_t dtsz = jl_datatype_size(vt);
25372537
if (update_meta)
25382538
gc_setmark(ptls, o, bits, dtsz);

src/jltypes.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ extern "C" {
2020
#endif
2121

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

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

2532+
void export_jl_small_typeof(void)
2533+
{
2534+
memcpy(&jl_small_typeof, &ijl_small_typeof, sizeof(jl_small_typeof));
2535+
}
2536+
25312537
#define XX(name) \
2532-
jl_small_typeof[(jl_##name##_tag << 4) / sizeof(*jl_small_typeof)] = jl_##name##_type; \
2538+
ijl_small_typeof[(jl_##name##_tag << 4) / sizeof(*ijl_small_typeof)] = jl_##name##_type; \
25332539
jl_##name##_type->smalltag = jl_##name##_tag;
25342540
void jl_init_types(void) JL_GC_DISABLED
25352541
{
@@ -3351,6 +3357,8 @@ void jl_init_types(void) JL_GC_DISABLED
33513357

33523358
// override the preferred layout for a couple types
33533359
jl_lineinfonode_type->name->mayinlinealloc = 0; // FIXME: assumed to be a pointer by codegen
3360+
3361+
export_jl_small_typeof();
33543362
}
33553363

33563364
static jl_value_t *core(const char *name)
@@ -3431,6 +3439,8 @@ void post_boot_hooks(void)
34313439
}
34323440
}
34333441
}
3442+
3443+
export_jl_small_typeof();
34343444
}
34353445

34363446
void post_image_load_hooks(void) {

src/julia.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -750,16 +750,23 @@ enum jl_small_typeof_tags {
750750
jl_bitstags_first = jl_char_tag, // n.b. bool is not considered a bitstype, since it can be compared by pointer
751751
jl_max_tags = 64
752752
};
753-
#ifndef JL_LIBRARY_EXPORTS
754-
JL_DLLIMPORT
755-
#endif
756-
extern jl_datatype_t *jl_small_typeof[(jl_max_tags << 4) / sizeof(jl_datatype_t*)];
753+
extern JL_DLLIMPORT jl_datatype_t *jl_small_typeof[(jl_max_tags << 4) / sizeof(jl_datatype_t*)];
754+
#ifndef JL_LIBRARY_EXPORTS_INTERNAL
757755
static inline jl_value_t *jl_to_typeof(uintptr_t t)
758756
{
759757
if (t < (jl_max_tags << 4))
760758
return (jl_value_t*)jl_small_typeof[t / sizeof(*jl_small_typeof)];
761759
return (jl_value_t*)t;
762760
}
761+
#else
762+
extern JL_HIDDEN jl_datatype_t *ijl_small_typeof[(jl_max_tags << 4) / sizeof(jl_datatype_t*)];
763+
static inline jl_value_t *jl_to_typeof(uintptr_t t)
764+
{
765+
if (t < (jl_max_tags << 4))
766+
return (jl_value_t*)ijl_small_typeof[t / sizeof(*ijl_small_typeof)];
767+
return (jl_value_t*)t;
768+
}
769+
#endif
763770

764771

765772
// kinds

src/staticdata.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2839,6 +2839,7 @@ JL_DLLEXPORT void jl_set_sysimg_so(void *handle)
28392839
#endif
28402840

28412841
extern void rebuild_image_blob_tree(void);
2842+
extern void export_jl_small_typeof(void);
28422843

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

0 commit comments

Comments
 (0)