From 2e2b8aa778a7de9c0c17fdfd570983e861d7f7a4 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sat, 28 May 2022 14:19:13 -0400 Subject: [PATCH] Don't use RAII for jl_llvmf_dump_t --- src/aotcompile.cpp | 12 ++++++++---- src/codegen-stubs.c | 6 +++--- src/disasm.cpp | 9 +++------ src/jitlayers.cpp | 7 ++++--- src/jitlayers.h | 5 ----- src/julia_internal.h | 11 ++++++++--- stdlib/InteractiveUtils/src/codeview.jl | 23 +++++++++++++++-------- 7 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index 5400bc98b0908..15e53bc3282f6 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -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 @@ -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); diff --git a/src/codegen-stubs.c b/src/codegen-stubs.c index bf220a0456066..f264be3706321 100644 --- a/src/codegen-stubs.c +++ b/src/codegen-stubs.c @@ -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 @@ -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 diff --git a/src/disasm.cpp b/src/disasm.cpp index ab1741abf38b4..838934a6c5893 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -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 dump(static_cast(f)); //RAII will release the module auto TSM = std::unique_ptr(unwrap(dump->TSM)); //If TSM is not passed in, then the context MUST be locked externally. @@ -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 ObjBufferSV; { // scope block - std::unique_ptr dump(static_cast(F)); auto TSM = std::unique_ptr(unwrap(dump->TSM)); llvm::raw_svector_ostream asmfile(ObjBufferSV); TSM->withModuleDo([&](Module &m) { diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 9b9016c25c0d9..712f54c149104 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -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) diff --git a/src/jitlayers.h b/src/jitlayers.h index 05f240a5848e0..ee3d0c14b3751 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -117,11 +117,6 @@ struct jl_returninfo_t { unsigned return_roots; }; -struct jl_llvmf_dump_t { - LLVMOrcThreadSafeModuleRef TSM; - LLVMValueRef F; -}; - typedef std::tuple jl_codegen_call_target_t; typedef struct _jl_codegen_params_t { diff --git a/src/julia_internal.h b/src/julia_internal.h index 327086e8fe98a..d14582d5b81e7 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -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, diff --git a/stdlib/InteractiveUtils/src/codeview.jl b/stdlib/InteractiveUtils/src/codeview.jl index cfb3835c671a6..8e66c881e415c 100644 --- a/stdlib/InteractiveUtils/src/codeview.jl +++ b/stdlib/InteractiveUtils/src/codeview.jl @@ -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 @@ -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