Skip to content

Commit

Permalink
Don't use RAII for jl_llvmf_dump_t
Browse files Browse the repository at this point in the history
  • Loading branch information
vchuravy committed May 28, 2022
1 parent 8e30135 commit 2e2b8aa
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 32 deletions.
12 changes: 8 additions & 4 deletions src/aotcompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,12 +990,13 @@ llvmGetPassPluginInfo() {
// this is paired with jl_dump_function_ir, jl_dump_function_asm, jl_dump_method_asm in particular ways:
// misuse will leak memory or cause read-after-free
extern "C" JL_DLLEXPORT
void *jl_get_llvmf_defn_impl(jl_method_instance_t *mi, size_t world, char getwrapper, char optimize, const jl_cgparams_t params)
void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, size_t world, char getwrapper, char optimize, const jl_cgparams_t params)
{
if (jl_is_method(mi->def.method) && mi->def.method->source == NULL &&
mi->def.method->generator == NULL) {
// not a generic function
return NULL;
dump->F = NULL;
return;
}

// get the source code for this function
Expand Down Expand Up @@ -1071,8 +1072,11 @@ void *jl_get_llvmf_defn_impl(jl_method_instance_t *mi, size_t world, char getwra
if (measure_compile_time_enabled)
jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, (jl_hrtime() - compiler_start_time));
JL_UNLOCK(&jl_codegen_lock); // Might GC
if (F)
return new jl_llvmf_dump_t{wrap(new orc::ThreadSafeModule(std::move(m))), wrap(F)};
if (F) {
dump->TSM = wrap(new orc::ThreadSafeModule(std::move(m)));
dump->F = wrap(F);
return;
}
}

const char *mname = name_from_method_instance(mi);
Expand Down
6 changes: 3 additions & 3 deletions src/codegen-stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ JL_DLLEXPORT int32_t jl_get_llvm_gv_fallback(void *native_code, jl_value_t *p) U
JL_DLLEXPORT void jl_extern_c_fallback(jl_function_t *f, jl_value_t *rt, jl_value_t *argt, char *name) UNAVAILABLE
JL_DLLEXPORT jl_value_t *jl_dump_method_asm_fallback(jl_method_instance_t *linfo, size_t world,
char raw_mc, char getwrapper, const char* asm_variant, const char *debuginfo, char binary) UNAVAILABLE
JL_DLLEXPORT jl_value_t *jl_dump_function_ir_fallback(void *f, char strip_ir_metadata, char dump_module, const char *debuginfo) UNAVAILABLE
JL_DLLEXPORT void *jl_get_llvmf_defn_fallback(jl_method_instance_t *linfo, size_t world, char getwrapper, char optimize, const jl_cgparams_t params) UNAVAILABLE
JL_DLLEXPORT jl_value_t *jl_dump_function_ir_fallback(jl_llvmf_dump_t *dump, char strip_ir_metadata, char dump_module, const char *debuginfo) UNAVAILABLE
JL_DLLEXPORT void jl_get_llvmf_defn_fallback(jl_llvmf_dump_t *dump, jl_method_instance_t *linfo, size_t world, char getwrapper, char optimize, const jl_cgparams_t params) UNAVAILABLE

JL_DLLEXPORT void *jl_LLVMCreateDisasm_fallback(const char *TripleName, void *DisInfo, int TagType, void *GetOpInfo, void *SymbolLookUp) UNAVAILABLE
JL_DLLEXPORT size_t jl_LLVMDisasmInstruction_fallback(void *DC, uint8_t *Bytes, uint64_t BytesSize, uint64_t PC, char *OutString, size_t OutStringSize) UNAVAILABLE
Expand Down Expand Up @@ -90,7 +90,7 @@ JL_DLLEXPORT void jl_dump_llvm_opt_fallback(void *s)

JL_DLLEXPORT jl_value_t *jl_dump_fptr_asm_fallback(uint64_t fptr, char raw_mc, const char* asm_variant, const char *debuginfo, char binary) UNAVAILABLE

JL_DLLEXPORT jl_value_t *jl_dump_function_asm_fallback(void *F, char raw_mc, const char* asm_variant, const char *debuginfo, char binary) UNAVAILABLE
JL_DLLEXPORT jl_value_t *jl_dump_function_asm_fallback(jl_llvmf_dump_t* dump, char raw_mc, const char* asm_variant, const char *debuginfo, char binary) UNAVAILABLE

JL_DLLEXPORT void jl_get_function_id_fallback(void *native_code, jl_code_instance_t *ncode,
int32_t *func_idx, int32_t *specfunc_idx) UNAVAILABLE
Expand Down
9 changes: 3 additions & 6 deletions src/disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,16 +488,14 @@ void jl_strip_llvm_addrspaces(Module *m)
}

// print an llvm IR acquired from jl_get_llvmf
// warning: this takes ownership of, and destroys, f->getParent()
// warning: this takes ownership of, and destroys, dump->TSM
extern "C" JL_DLLEXPORT
jl_value_t *jl_dump_function_ir_impl(void *f, char strip_ir_metadata, char dump_module, const char *debuginfo)
jl_value_t *jl_dump_function_ir_impl(jl_llvmf_dump_t *dump, char strip_ir_metadata, char dump_module, const char *debuginfo)
{
std::string code;
raw_string_ostream stream(code);

{
//RAII will release the struct itself
std::unique_ptr<jl_llvmf_dump_t> dump(static_cast<jl_llvmf_dump_t*>(f));
//RAII will release the module
auto TSM = std::unique_ptr<orc::ThreadSafeModule>(unwrap(dump->TSM));
//If TSM is not passed in, then the context MUST be locked externally.
Expand Down Expand Up @@ -1203,12 +1201,11 @@ class LineNumberPrinterHandler : public AsmPrinterHandler {

// get a native assembly for llvm::Function
extern "C" JL_DLLEXPORT
jl_value_t *jl_dump_function_asm_impl(void *F, char raw_mc, const char* asm_variant, const char *debuginfo, char binary)
jl_value_t *jl_dump_function_asm_impl(jl_llvmf_dump_t* dump, char raw_mc, const char* asm_variant, const char *debuginfo, char binary)
{
// precise printing via IR assembler
SmallVector<char, 4096> ObjBufferSV;
{ // scope block
std::unique_ptr<jl_llvmf_dump_t> dump(static_cast<jl_llvmf_dump_t*>(F));
auto TSM = std::unique_ptr<orc::ThreadSafeModule>(unwrap(dump->TSM));
llvm::raw_svector_ostream asmfile(ObjBufferSV);
TSM->withModuleDo([&](Module &m) {
Expand Down
7 changes: 4 additions & 3 deletions src/jitlayers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,10 +472,11 @@ jl_value_t *jl_dump_method_asm_impl(jl_method_instance_t *mi, size_t world,
}

// whatever, that didn't work - use the assembler output instead
void *F = jl_get_llvmf_defn(mi, world, getwrapper, true, jl_default_cgparams);
if (!F)
jl_llvmf_dump_t llvmf_dump;
jl_get_llvmf_defn(&llvmf_dump, mi, world, getwrapper, true, jl_default_cgparams);
if (!llvmf_dump.F)
return jl_an_empty_string;
return jl_dump_function_asm(F, raw_mc, asm_variant, debuginfo, binary);
return jl_dump_function_asm(&llvmf_dump, raw_mc, asm_variant, debuginfo, binary);
}

CodeGenOpt::Level CodeGenOptLevelFor(int optlevel)
Expand Down
5 changes: 0 additions & 5 deletions src/jitlayers.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,6 @@ struct jl_returninfo_t {
unsigned return_roots;
};

struct jl_llvmf_dump_t {
LLVMOrcThreadSafeModuleRef TSM;
LLVMValueRef F;
};

typedef std::tuple<jl_returninfo_t::CallingConv, unsigned, llvm::Function*, bool> jl_codegen_call_target_t;

typedef struct _jl_codegen_params_t {
Expand Down
11 changes: 8 additions & 3 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -845,12 +845,17 @@ static inline void jl_set_gc_and_wait(void)
#endif
void jl_gc_set_permalloc_region(void *start, void *end);

typedef struct {
LLVMOrcThreadSafeModuleRef TSM;
LLVMValueRef F;
} jl_llvmf_dump_t;

JL_DLLEXPORT jl_value_t *jl_dump_method_asm(jl_method_instance_t *linfo, size_t world,
char raw_mc, char getwrapper, const char* asm_variant, const char *debuginfo, char binary);
JL_DLLEXPORT void *jl_get_llvmf_defn(jl_method_instance_t *linfo, size_t world, char getwrapper, char optimize, const jl_cgparams_t params);
JL_DLLEXPORT void jl_get_llvmf_defn(jl_llvmf_dump_t* dump, jl_method_instance_t *linfo, size_t world, char getwrapper, char optimize, const jl_cgparams_t params);
JL_DLLEXPORT jl_value_t *jl_dump_fptr_asm(uint64_t fptr, char raw_mc, const char* asm_variant, const char *debuginfo, char binary);
JL_DLLEXPORT jl_value_t *jl_dump_function_ir(void *f, char strip_ir_metadata, char dump_module, const char *debuginfo);
JL_DLLEXPORT jl_value_t *jl_dump_function_asm(void *F, char raw_mc, const char* asm_variant, const char *debuginfo, char binary);
JL_DLLEXPORT jl_value_t *jl_dump_function_ir(jl_llvmf_dump_t *dump, char strip_ir_metadata, char dump_module, const char *debuginfo);
JL_DLLEXPORT jl_value_t *jl_dump_function_asm(jl_llvmf_dump_t *dump, char raw_mc, const char* asm_variant, const char *debuginfo, char binary);

void *jl_create_native(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int policy);
void jl_dump_native(void *native_code,
Expand Down
23 changes: 15 additions & 8 deletions stdlib/InteractiveUtils/src/codeview.jl
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,18 @@ function _dump_function_linfo_native(linfo::Core.MethodInstance, world::UInt, wr
return str
end

struct LLVMFDump
tsm::Ptr{Cvoid} # opaque
f::Ptr{Cvoid} # opaque
end

function _dump_function_linfo_native(linfo::Core.MethodInstance, world::UInt, wrapper::Bool, syntax::Symbol, debuginfo::Symbol, binary::Bool, params::CodegenParams)
llvmf = ccall(:jl_get_llvmf_defn, Ptr{Cvoid}, (Any, UInt, Bool, Bool, CodegenParams), linfo, world, wrapper, true, params)
llvmf == C_NULL && error("could not compile the specified method")
llvmf_dump = Ref{LLVMFDump}()
ccall(:jl_get_llvmf_defn, Cvoid, (Ptr{LLVMFDump}, Any, UInt, Bool, Bool, CodegenParams), llvmf_dump, linfo, world, wrapper, true, params)
llvmf_dump[].f == C_NULL && error("could not compile the specified method")
str = ccall(:jl_dump_function_asm, Ref{String},
(Ptr{Cvoid}, Bool, Ptr{UInt8}, Ptr{UInt8}, Bool),
llvmf, false, syntax, debuginfo, binary)
(Ptr{LLVMFDump}, Bool, Ptr{UInt8}, Ptr{UInt8}, Bool),
llvmf_dump, false, syntax, debuginfo, binary)
return str
end

Expand All @@ -225,11 +231,12 @@ function _dump_function_linfo_llvm(
strip_ir_metadata::Bool, dump_module::Bool,
optimize::Bool, debuginfo::Symbol,
params::CodegenParams)
llvmf = ccall(:jl_get_llvmf_defn, Ptr{Cvoid}, (Any, UInt, Bool, Bool, CodegenParams), linfo, world, wrapper, optimize, params)
llvmf == C_NULL && error("could not compile the specified method")
llvmf_dump = Ref{LLVMFDump}()
ccall(:jl_get_llvmf_defn, Cvoid, (Ptr{LLVMFDump}, Any, UInt, Bool, Bool, CodegenParams), llvmf_dump, linfo, world, wrapper, optimize, params)
llvmf_dump[].f == C_NULL && error("could not compile the specified method")
str = ccall(:jl_dump_function_ir, Ref{String},
(Ptr{Cvoid}, Bool, Bool, Ptr{UInt8}),
llvmf, strip_ir_metadata, dump_module, debuginfo)
(Ptr{LLVMFDump}, Bool, Bool, Ptr{UInt8}),
llvmf_dump, strip_ir_metadata, dump_module, debuginfo)
return str
end

Expand Down

0 comments on commit 2e2b8aa

Please sign in to comment.