From cb5a359b20ecf055d0c61db3543ed97cab3ca3a2 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 6 May 2021 12:43:51 -0400 Subject: [PATCH] fixup --- cli/Makefile | 2 +- src/julia_fasttls.h | 6 +++ src/julia_internal.h | 3 +- src/llvm-ptls.cpp | 17 +++++---- src/threading.c | 73 +++++++++++++++++++++++++------------ test/clangsa/MissingRoots.c | 8 ---- 6 files changed, 67 insertions(+), 42 deletions(-) diff --git a/cli/Makefile b/cli/Makefile index 45c38ed84b9c31..d4a1b2472c24d3 100644 --- a/cli/Makefile +++ b/cli/Makefile @@ -116,7 +116,7 @@ endif $(build_shlibdir)/libjulia-debug.$(JL_MAJOR_MINOR_SHLIB_EXT): $(LIB_DOBJS) $(SRCDIR)/list_strip_symbols.h | $(build_shlibdir) $(build_libdir) @$(call PRINT_LINK, $(CC) $(call IMPLIB_FLAGS,$@.tmp) $(LOADER_CFLAGS) -DLIBRARY_EXPORTS -shared $(DEBUGFLAGS) $(LIB_DOBJS) -o $@ \ $(JLIBLDFLAGS) $(LOADER_LDFLAGS) $(RPATH_LIB) $(call SONAME_FLAGS,libjulia-debug.$(JL_MAJOR_SHLIB_EXT))) - @$(INSTALL_NAME_CMD)libjulia-debug.$(SHLIB_EXT) $@.tmp + @$(INSTALL_NAME_CMD)libjulia-debug.$(SHLIB_EXT) $@ ifeq ($(OS), WINNT) @$(call PRINT_ANALYZE, $(OBJCOPY) $(build_libdir)/$(notdir $@).tmp.a $(STRIP_EXPORTED_FUNCS) $(build_libdir)/$(notdir $@).a && rm $(build_libdir)/$(notdir $@).tmp.a) endif diff --git a/src/julia_fasttls.h b/src/julia_fasttls.h index bdb637b6f93df2..0dc0c05c82e106 100644 --- a/src/julia_fasttls.h +++ b/src/julia_fasttls.h @@ -14,7 +14,13 @@ extern "C" { #include "support/dirpath.h" typedef struct _jl_gcframe_t jl_gcframe_t; + +#if defined(_OS_DARWIN_) +#include +typedef void *(jl_get_pgcstack_func)(pthread_key_t); // aka typeof(pthread_getspecific) +#else typedef jl_gcframe_t **(jl_get_pgcstack_func)(void); +#endif #if !defined(_OS_DARWIN_) && !defined(_OS_WINDOWS_) #define JULIA_DEFINE_FAST_TLS \ diff --git a/src/julia_internal.h b/src/julia_internal.h index 8ab6b0d6bba28e..090193dc46fd66 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -728,7 +728,6 @@ int jl_safepoint_consume_sigint(void); void jl_wake_libuv(void); void jl_set_pgcstack(jl_gcframe_t **) JL_NOTSAFEPOINT; -#if !defined(__clang_analyzer__) #if defined(_OS_DARWIN_) typedef pthread_key_t jl_pgcstack_key_t; #elif defined(_OS_WINDOWS_) @@ -737,6 +736,8 @@ typedef DWORD jl_pgcstack_key_t; typedef jl_gcframe_t ***(*jl_pgcstack_key_t)(void) JL_NOTSAFEPOINT; #endif void jl_pgcstack_getkey(jl_get_pgcstack_func **f, jl_pgcstack_key_t *k); + +#if !defined(__clang_analyzer__) static inline void jl_set_gc_and_wait(void) { jl_task_t *ct = jl_current_task; diff --git a/src/llvm-ptls.cpp b/src/llvm-ptls.cpp index 26dc417da30e59..9cecceac9a1875 100644 --- a/src/llvm-ptls.cpp +++ b/src/llvm-ptls.cpp @@ -50,6 +50,7 @@ struct LowerPTLS: public ModulePass { Function *pgcstack_getter; LLVMContext *ctx; MDNode *tbaa_const; + FunctionType *FT_pgcstack_getter; PointerType *T_pgcstack_getter; PointerType *T_ppjlvalue; PointerType *T_pppjlvalue; @@ -228,7 +229,7 @@ void LowerPTLS::fix_pgcstack_use(CallInst *pgcstack) auto key = new LoadInst(T_size, pgcstack_key_slot, "", false, pgcstack); key->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_const); key->setMetadata(llvm::LLVMContext::MD_invariant_load, MDNode::get(*ctx, None)); - auto new_pgcstack = CallInst::Create(T_pgcstack_getter, getter, {key}, "", pgcstack); + auto new_pgcstack = CallInst::Create(FT_pgcstack_getter, getter, {key}, "", pgcstack); new_pgcstack->takeName(pgcstack); pgcstack->replaceAllUsesWith(new_pgcstack); pgcstack->eraseFromParent(); @@ -252,7 +253,7 @@ void LowerPTLS::fix_pgcstack_use(CallInst *pgcstack) #if defined(_OS_DARWIN_) assert(sizeof(k) == sizeof(uintptr_t)); Constant *key = ConstantInt::get(T_size, (uintptr_t)k); - auto new_pgcstack = CallInst::Create(T_pgcstack_getter, val, {key}, "", pgcstack); + auto new_pgcstack = CallInst::Create(FT_pgcstack_getter, val, {key}, "", pgcstack); new_pgcstack->takeName(pgcstack); pgcstack->replaceAllUsesWith(new_pgcstack); pgcstack->eraseFromParent(); @@ -274,17 +275,17 @@ bool LowerPTLS::runOnModule(Module &_M) ctx = &M->getContext(); tbaa_const = tbaa_make_child("jtbaa_const", nullptr, true).first; - auto FT_pgcstack_getter = pgcstack_getter->getFunctionType(); + T_int8 = Type::getInt8Ty(*ctx); + T_size = sizeof(size_t) == 8 ? Type::getInt64Ty(*ctx) : Type::getInt32Ty(*ctx); + T_pint8 = T_int8->getPointerTo(); + FT_pgcstack_getter = pgcstack_getter->getFunctionType(); #if defined(_OS_DARWIN_) - assert(sizeof(key) == sizeof(unsigned long)); - FT_pgcstack_getter = FunctionType::get(FT_pgcstack_getter->getReturnType(), {key->getType()}); + assert(sizeof(jl_pgcstack_key_t) == sizeof(uintptr_t)); + FT_pgcstack_getter = FunctionType::get(FT_pgcstack_getter->getReturnType(), {T_size}, false); #endif T_pgcstack_getter = FT_pgcstack_getter->getPointerTo(); T_pppjlvalue = cast(FT_pgcstack_getter->getReturnType()); T_ppjlvalue = cast(T_pppjlvalue->getElementType()); - T_int8 = Type::getInt8Ty(*ctx); - T_size = sizeof(size_t) == 8 ? Type::getInt64Ty(*ctx) : Type::getInt32Ty(*ctx); - T_pint8 = T_int8->getPointerTo(); if (imaging_mode) { pgcstack_func_slot = create_aliased_global(T_pgcstack_getter, "jl_pgcstack_func_slot"); pgcstack_key_slot = create_aliased_global(T_size, "jl_pgcstack_key_slot"); // >= sizeof(jl_pgcstack_key_t) diff --git a/src/threading.c b/src/threading.c index 81086e7a9f5cc2..235bb9f870ba19 100644 --- a/src/threading.c +++ b/src/threading.c @@ -36,6 +36,13 @@ extern "C" { #include "threading.h" +JL_DLLEXPORT void *jl_get_ptls_states(void) +{ + // mostly deprecated: use current_task instead + return jl_current_task->ptls; +} + +#if !defined(_OS_WINDOWS_) static pthread_key_t jl_safe_restore_key; __attribute__((constructor)) void _jl_init_safe_restore(void) @@ -52,13 +59,7 @@ JL_DLLEXPORT void jl_set_safe_restore(jl_jmp_buf *sr) { pthread_setspecific(jl_safe_restore_key, (void*)sr); } - -JL_DLLEXPORT void *jl_get_ptls_states(void) -{ - // mostly deprecated: use current_task instead - return jl_current_task->ptls; -} - +#endif // The tls_states buffer: @@ -92,7 +93,7 @@ JL_CONST_FUNC jl_gcframe_t **jl_get_pgcstack(void) JL_NOTSAFEPOINT void jl_set_pgcstack(jl_gcframe_t **pgcstack) JL_NOTSAFEPOINT { - pthread_setspecific(jl_pgcstack_key, pgcstack); + pthread_setspecific(jl_pgcstack_key, (void*)pgcstack); } void jl_pgcstack_getkey(jl_get_pgcstack_func **f, pthread_key_t *k) @@ -113,6 +114,7 @@ JL_DLLEXPORT void jl_pgcstack_setkey(jl_get_pgcstack_func *f, pthread_key_t k) // reliably used from a shared library) either..... Use `TLSAlloc` instead. static DWORD jl_pgcstack_key; +static DWORD jl_safe_restore_key; // Put this here for now. We can move this out later if we find more use for it. BOOLEAN WINAPI DllMain(IN HINSTANCE hDllHandle, IN DWORD nReason, @@ -122,44 +124,67 @@ BOOLEAN WINAPI DllMain(IN HINSTANCE hDllHandle, IN DWORD nReason, case DLL_PROCESS_ATTACH: jl_pgcstack_key = TlsAlloc(); assert(jl_pgcstack_key != TLS_OUT_OF_INDEXES); + jl_safe_restore_key = TlsAlloc(); + assert(jl_safe_restore_key != TLS_OUT_OF_INDEXES); // Fall through case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: - TlsFree(jl_tls_key); + TlsFree(jl_pgcstack_key); + TlsFree(jl_safe_restore_key); break; } return 1; // success } -JL_CONST_FUNC jl_gcframe_t **jl_get_pgcstack(void) JL_NOTSAFEPOINT -{ #if defined(_CPU_X86_64_) - DWORD *plast_error = (DWORD*)(__readgsqword(0x30) + 0x68); - DWORD last_error = *plast_error; +#define SAVE_ERRNO \ + DWORD *plast_error = (DWORD*)(__readgsqword(0x30) + 0x68); \ + DWORD last_error = *plast_error +#define LOAD_ERRNO \ + *plast_error = last_error #elif defined(_CPU_X86_) - DWORD *plast_error = (DWORD*)(__readfsdword(0x18) + 0x34); - DWORD last_error = *plast_error; +#define SAVE_ERRNO \ + DWORD *plast_error = (DWORD*)(__readfsdword(0x18) + 0x34); \ + DWORD last_error = *plast_error +#define LOAD_ERRNO \ + *plast_error = last_error #else - DWORD last_error = GetLastError(); +#define SAVE_ERRNO \ + DWORD last_error = GetLastError() +#define LOAD_ERRNO \ + SetLastError(last_error) #endif + +JL_DLLEXPORT jl_jmp_buf *jl_get_safe_restore(void) +{ + SAVE_ERRNO; + jl_jmp_buf *sr = (jl_jmp_buf*)TlsGetValue(jl_safe_restore_key); + LOAD_ERRNO; + return sr; +} + +JL_DLLEXPORT void jl_set_safe_restore(jl_jmp_buf *sr) +{ + SAVE_ERRNO; + TlsSetValue(jl_safe_restore_key, (void*)sr); + LOAD_ERRNO; +} + +JL_CONST_FUNC jl_gcframe_t **jl_get_pgcstack(void) JL_NOTSAFEPOINT +{ + SAVE_ERRNO; jl_gcframe_t **pgcstack = (jl_ptls_t)TlsGetValue(jl_pgcstack_key); -#if defined(_CPU_X86_64_) - *plast_error = last_error; -#elif defined(_CPU_X86_) - *plast_error = last_error; -#else - SetLastError(last_error); -#endif + LOAD_ERRNO; return pgcstack; } void jl_set_pgcstack(jl_gcframe_t **pgcstack) JL_NOTSAFEPOINT { // n.b.: this smashes GetLastError - TlsSetValue(jl_pgcstack_key, pgcstack); + TlsSetValue(jl_pgcstack_key, (void*)pgcstack); } void jl_pgcstack_getkey(jl_get_pgcstack_func **f, DWORD *k) diff --git a/test/clangsa/MissingRoots.c b/test/clangsa/MissingRoots.c index 1c9f7c8e4ad705..78dcc195d59ced 100644 --- a/test/clangsa/MissingRoots.c +++ b/test/clangsa/MissingRoots.c @@ -409,14 +409,6 @@ void stack_rooted(jl_value_t *lb JL_MAYBE_UNROOTED, jl_value_t *ub JL_MAYBE_UNRO JL_GC_POP(); } -void JL_NORETURN throw_internal(jl_value_t *e JL_MAYBE_UNROOTED) -{ - jl_ptls_t ptls = jl_get_ptls_states(); - ptls->sig_exception = e; - jl_gc_unsafe_enter(ptls); - look_at_value(e); -} - JL_DLLEXPORT jl_value_t *jl_totally_used_function(int i) { jl_value_t *v = jl_box_int32(i); // expected-note{{Started tracking value here}}