Skip to content

Commit

Permalink
Add JL_DLLIMPORT to small_typeof declaration (#50892)
Browse files Browse the repository at this point in the history
Resolves #50714
  • Loading branch information
topolarity committed Sep 1, 2023
1 parent 631b5c3 commit 91b8c9b
Show file tree
Hide file tree
Showing 14 changed files with 61 additions and 45 deletions.
2 changes: 1 addition & 1 deletion cli/jl_exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ JL_EXPORTED_DATA_SYMBOLS(XX)

// define a copy of exported data
#define jl_max_tags 64
JL_DLLEXPORT void *small_typeof[(jl_max_tags << 4) / sizeof(void*)]; // 16-bit aligned, like the GC
JL_DLLEXPORT void *jl_small_typeof[(jl_max_tags << 4) / sizeof(void*)]; // 16-bit aligned, like the GC

// Declare list of exported functions (sans type)
#define XX(name) JL_DLLEXPORT void name(void);
Expand Down
7 changes: 6 additions & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,12 @@ clang-tidy-%: $(SRCDIR)/%.cpp $(build_shlibdir)/libImplicitAtomicsPlugin.$(SHLIB
-- $(CLANGSA_FLAGS) $(CLANGSA_CXXFLAGS) $(LLVM_CXXFLAGS) $(JCPPFLAGS_CLANG) $(JCXXFLAGS_CLANG) $(JL_CXXFLAGS) $(DEBUGFLAGS_CLANG) -fcolor-diagnostics --system-header-prefix=llvm -Wno-deprecated-declarations -fno-caret-diagnostics -x c++)

# set the exports for the source files based on where they are getting linked
clang-sa-% clang-sagc-% clang-tidy-%: DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS
$(addprefix clang-sa-,$(SRCS)): DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS_INTERNAL
$(addprefix clang-sagc-,$(SRCS)): DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS_INTERNAL
$(addprefix clang-tidy-,$(SRCS)): DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS_INTERNAL
$(addprefix clang-sa-,$(CODEGEN_SRCS)): DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS_CODEGEN
$(addprefix clang-sagc-,$(CODEGEN_SRCS)): DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS_CODEGEN
$(addprefix clang-tidy-,$(CODEGEN_SRCS)): DEBUGFLAGS_CLANG += -DJL_LIBRARY_EXPORTS_CODEGEN

# Add C files as a target of `analyzesrc` and `analyzegc` and `tidysrc`
tidysrc: $(addprefix clang-tidy-,$(filter-out $(basename $(SKIP_IMPLICIT_ATOMICS)),$(CODEGEN_SRCS) $(SRCS)))
Expand Down
20 changes: 10 additions & 10 deletions src/aotcompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1642,10 +1642,10 @@ void jl_dump_native_impl(void *native_code,

// let the compiler know we are going to internalize a copy of this,
// if it has a current usage with ExternalLinkage
auto small_typeof_copy = dataM.getGlobalVariable("small_typeof");
if (small_typeof_copy) {
small_typeof_copy->setVisibility(GlobalValue::HiddenVisibility);
small_typeof_copy->setDSOLocal(true);
auto jl_small_typeof_copy = dataM.getGlobalVariable("jl_small_typeof");
if (jl_small_typeof_copy) {
jl_small_typeof_copy->setVisibility(GlobalValue::HiddenVisibility);
jl_small_typeof_copy->setDSOLocal(true);
}
}

Expand Down Expand Up @@ -1721,21 +1721,21 @@ void jl_dump_native_impl(void *native_code,
auto shards = emit_shard_table(metadataM, T_size, T_psize, threads);
auto ptls = emit_ptls_table(metadataM, T_size, T_psize);
auto header = emit_image_header(metadataM, threads, nfvars, ngvars);
auto AT = ArrayType::get(T_size, sizeof(small_typeof) / sizeof(void*));
auto small_typeof_copy = new GlobalVariable(metadataM, AT, false,
auto AT = ArrayType::get(T_size, sizeof(jl_small_typeof) / sizeof(void*));
auto jl_small_typeof_copy = new GlobalVariable(metadataM, AT, false,
GlobalVariable::ExternalLinkage,
Constant::getNullValue(AT),
"small_typeof");
small_typeof_copy->setVisibility(GlobalValue::HiddenVisibility);
small_typeof_copy->setDSOLocal(true);
"jl_small_typeof");
jl_small_typeof_copy->setVisibility(GlobalValue::HiddenVisibility);
jl_small_typeof_copy->setDSOLocal(true);
AT = ArrayType::get(T_psize, 5);
auto pointers = new GlobalVariable(metadataM, AT, false,
GlobalVariable::ExternalLinkage,
ConstantArray::get(AT, {
ConstantExpr::getBitCast(header, T_psize),
ConstantExpr::getBitCast(shards, T_psize),
ConstantExpr::getBitCast(ptls, T_psize),
ConstantExpr::getBitCast(small_typeof_copy, T_psize),
ConstantExpr::getBitCast(jl_small_typeof_copy, T_psize),
ConstantExpr::getBitCast(target_ids, T_psize)
}),
"jl_image_pointers");
Expand Down
2 changes: 1 addition & 1 deletion src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ JL_DLLEXPORT int jl_egal__unboxed(const jl_value_t *a JL_MAYBE_UNROOTED, const j
JL_DLLEXPORT int jl_egal__bitstag(const jl_value_t *a JL_MAYBE_UNROOTED, const jl_value_t *b JL_MAYBE_UNROOTED, uintptr_t dtag) JL_NOTSAFEPOINT
{
if (dtag < jl_max_tags << 4) {
switch ((enum jlsmall_typeof_tags)(dtag >> 4)) {
switch ((enum jl_small_typeof_tags)(dtag >> 4)) {
case jl_int8_tag:
case jl_uint8_tag:
return *(uint8_t*)a == *(uint8_t*)b;
Expand Down
6 changes: 3 additions & 3 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ static Constant *literal_pointer_val_slot(jl_codectx_t &ctx, jl_value_t *p)
if (addr->smalltag) {
// some common builtin datatypes have a special pool for accessing them by smalltag id
Constant *tag = ConstantInt::get(getInt32Ty(ctx.builder.getContext()), addr->smalltag << 4);
Constant *smallp = ConstantExpr::getInBoundsGetElementPtr(getInt8Ty(ctx.builder.getContext()), prepare_global_in(jl_Module, jlsmall_typeof_var), tag);
Constant *smallp = ConstantExpr::getInBoundsGetElementPtr(getInt8Ty(ctx.builder.getContext()), prepare_global_in(jl_Module, jl_small_typeof_var), tag);
return ConstantExpr::getBitCast(smallp, ctx.types().T_ppjlvalue);
}
// DataTypes are prefixed with a +
Expand Down Expand Up @@ -1086,7 +1086,7 @@ static Value *emit_typeof(jl_codectx_t &ctx, const jl_cgval_t &p, bool maybenull
if (jl_has_intersect_type_not_kind(typ))
return false;
for (size_t i = 0; i < jl_tags_count; i++) {
jl_datatype_t *dt = small_typeof[(i << 4) / sizeof(*small_typeof)];
jl_datatype_t *dt = jl_small_typeof[(i << 4) / sizeof(*jl_small_typeof)];
if (dt && !jl_has_empty_intersection((jl_value_t*)dt, typ))
return false;
}
Expand Down Expand Up @@ -1439,7 +1439,7 @@ static Value *emit_typeof(jl_codectx_t &ctx, Value *v, bool maybenull, bool just
// we lied a bit: this wasn't really an object (though it was valid for GC rooting)
// and we need to use it as an index to get the real object now
Module *M = jl_Module;
Value *smallp = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), prepare_global_in(M, jlsmall_typeof_var), tag);
Value *smallp = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), prepare_global_in(M, jl_small_typeof_var), tag);
smallp = ctx.builder.CreateBitCast(smallp, typetag->getType()->getPointerTo(0));
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const);
auto small = ctx.builder.CreateAlignedLoad(typetag->getType(), smallp, M->getDataLayout().getPointerABIAlignment(0));
Expand Down
6 changes: 3 additions & 3 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,8 +691,8 @@ static const auto jldlli_var = new JuliaVariable{
true,
[](Type *T_size) -> Type * { return getInt8PtrTy(T_size->getContext()); },
};
static const auto jlsmall_typeof_var = new JuliaVariable{
XSTR(small_typeof),
static const auto jl_small_typeof_var = new JuliaVariable{
XSTR(jl_small_typeof),
true,
[](Type *T_size) -> Type * { return getInt8Ty(T_size->getContext()); },
};
Expand Down Expand Up @@ -9184,7 +9184,7 @@ static void init_f16_funcs(void)

static void init_jit_functions(void)
{
add_named_global(jlsmall_typeof_var, &small_typeof);
add_named_global(jl_small_typeof_var, &jl_small_typeof);
add_named_global(jlstack_chk_guard_var, &__stack_chk_guard);
add_named_global(jlRTLD_DEFAULT_var, &jl_RTLD_DEFAULT_handle);
add_named_global(jlexe_var, &jl_exe_handle);
Expand Down
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)small_typeof[vtag / sizeof(*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 = small_typeof[vtag / sizeof(*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
20 changes: 8 additions & 12 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extern "C" {
#endif

_Atomic(jl_value_t*) cmpswap_names JL_GLOBALLY_ROOTED;
jl_datatype_t *small_typeof[(jl_max_tags << 4) / sizeof(*small_typeof)]; // 16-bit aligned, like the GC
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 @@ -2529,19 +2529,13 @@ static jl_tvar_t *tvar(const char *name)
(jl_value_t*)jl_any_type);
}

void export_small_typeof(void)
void export_jl_small_typeof(void)
{
void *copy;
#ifdef _OS_WINDOWS_
jl_dlsym(jl_libjulia_handle, "small_typeof", &copy, 1);
#else
jl_dlsym(jl_libjulia_internal_handle, "small_typeof", &copy, 1);
#endif
memcpy(copy, &small_typeof, sizeof(small_typeof));
memcpy(&jl_small_typeof, &ijl_small_typeof, sizeof(jl_small_typeof));
}

#define XX(name) \
small_typeof[(jl_##name##_tag << 4) / sizeof(*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 @@ -3363,7 +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_small_typeof();

export_jl_small_typeof();
}

static jl_value_t *core(const char *name)
Expand Down Expand Up @@ -3444,7 +3439,8 @@ void post_boot_hooks(void)
}
}
}
export_small_typeof();

export_jl_small_typeof();
}

void post_image_load_hooks(void) {
Expand Down
1 change: 0 additions & 1 deletion src/julia.expmap.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
ios_*;
arraylist_grow;
small_arraylist_grow;
small_typeof;
jl_*;
ijl_*;
_jl_mutex_*;
Expand Down
16 changes: 13 additions & 3 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,7 @@ typedef struct {
/* XX(slotnumber) */ \
/* XX(ssavalue) */ \
/* end of JL_SMALL_TYPEOF */
enum jlsmall_typeof_tags {
enum jl_small_typeof_tags {
jl_null_tag = 0,
#define XX(name) jl_##name##_tag,
JL_SMALL_TYPEOF(XX)
Expand All @@ -750,13 +750,23 @@ enum jlsmall_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
};
extern jl_datatype_t *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*)small_typeof[t / sizeof(*small_typeof)];
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
2 changes: 1 addition & 1 deletion src/processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ static inline jl_image_t parse_sysimg(void *hdl, F &&callback)
*tls_offset_idx = (uintptr_t)(jl_tls_offset == -1 ? 0 : jl_tls_offset);
}

res.small_typeof = pointers->small_typeof;
res.jl_small_typeof = pointers->jl_small_typeof;

return res;
}
Expand Down
6 changes: 3 additions & 3 deletions src/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ typedef struct {
const int32_t *gvars_offsets;
uint32_t ngvars;
jl_image_fptrs_t fptrs;
void **small_typeof;
void **jl_small_typeof;
} jl_image_t;

// The header for each image
Expand Down Expand Up @@ -197,8 +197,8 @@ typedef struct {
const jl_image_shard_t *shards; // points to header->nshards length array
// The TLS data pointer
const jl_image_ptls_t *ptls;
// A copy of small_typeof[]
void **small_typeof;
// A copy of jl_small_typeof[]
void **jl_small_typeof;

// serialized target data
// This contains the number of targets
Expand Down
8 changes: 4 additions & 4 deletions src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -1985,7 +1985,7 @@ static void jl_update_all_fptrs(jl_serializer_state *s, jl_image_t *image)
if (fvars.base == NULL)
return;

memcpy(image->small_typeof, &small_typeof, sizeof(small_typeof));
memcpy(image->jl_small_typeof, &jl_small_typeof, sizeof(jl_small_typeof));

int img_fvars_max = s->fptr_record->size / sizeof(void*);
size_t i;
Expand Down Expand Up @@ -2839,7 +2839,7 @@ JL_DLLEXPORT void jl_set_sysimg_so(void *handle)
#endif

extern void rebuild_image_blob_tree(void);
extern void export_small_typeof(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 @@ -2915,10 +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) \
small_typeof[(jl_##name##_tag << 4) / sizeof(*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_small_typeof();
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
6 changes: 6 additions & 0 deletions test/embedding/embedding.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ int main()
checked_eval_string("f28825()");
}

{
// jl_typeof works (#50714)
jl_value_t *v = checked_eval_string("sqrt(2.0)");
jl_value_t *t = jl_typeof(v);
}

JL_TRY {
jl_error("exception thrown");
}
Expand Down

0 comments on commit 91b8c9b

Please sign in to comment.