From 558f44a2972ea8747aeac64e875a66f6a66483c6 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 28 Jun 2016 23:22:57 -0400 Subject: [PATCH 1/4] win: cleanup build warnings --- src/threading.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/threading.c b/src/threading.c index 32cc82ebcd138..1ab2c38b64054 100644 --- a/src/threading.c +++ b/src/threading.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "julia.h" #include "julia_internal.h" @@ -89,11 +90,12 @@ BOOLEAN WINAPI DllMain(IN HINSTANCE hDllHandle, IN DWORD nReason, TlsFree(jl_tls_key); break; } + return 1; // success } JL_DLLEXPORT JL_CONST_FUNC jl_tls_states_t *(jl_get_ptls_states)(void) { - return TlsGetValue(jl_tls_key); + return (jl_tls_states_t*)TlsGetValue(jl_tls_key); } jl_get_ptls_states_func jl_get_ptls_states_getter(void) @@ -545,7 +547,7 @@ JL_DLLEXPORT void jl_threading_profile(void) if (!fork_ns) return; printf("\nti profile:\n"); - printf("prep: %g (%llu)\n", NS_TO_SECS(prep_ns), (unsigned long long)prep_ns); + printf("prep: %g (%" PRIu64 ")\n", NS_TO_SECS(prep_ns), prep_ns); uint64_t min, max, avg; ti_timings(fork_ns, &min, &max, &avg); From bf3b97e0827bdbbce363e55d2ff8167dcc0e4060 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 28 Jun 2016 22:52:30 -0400 Subject: [PATCH 2/4] win64: add Julia personality --- src/codegen.cpp | 13 +++++++++++-- src/debuginfo.cpp | 9 +++------ src/jitlayers.cpp | 13 ++++++++++--- src/julia_internal.h | 2 ++ src/signals-win.c | 3 +-- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index f6ad5461e14c9..b4ceb26064caa 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3,13 +3,14 @@ #include "llvm-version.h" #include "platform.h" #include "options.h" -#if defined(_OS_WINDOWS_) && !defined(LLVM38) -// trick pre-llvm38 into skipping the generation of _chkstk calls +#if defined(_OS_WINDOWS_) && !defined(LLVM39) +// trick pre-llvm39 into skipping the generation of _chkstk calls // since it has some codegen issues associated with them: // (a) assumed to be within 32-bit offset // (b) bad asm is generated for certain code patterns: // see https://github.com/JuliaLang/julia/pull/11644#issuecomment-112276813 // also, use ELF because RuntimeDyld COFF I686 support didn't exist +// also, use ELF because RuntimeDyld COFF X86_64 doesn't seem to work (fails to generate function pointers)? #define FORCE_ELF #endif #if defined(_CPU_X86_) @@ -413,6 +414,9 @@ static Function *jlgetnthfieldchecked_func; //static Function *jlsetnthfield_func; #ifdef _OS_WINDOWS_ static Function *resetstkoflw_func; +#if defined(_CPU_X86_64_) +static Function *juliapersonality_func; +#endif #endif static Function *diff_gc_total_bytes_func; static Function *jlarray_data_owner_func; @@ -5410,6 +5414,11 @@ static void init_julia_llvm_env(Module *m) resetstkoflw_func = Function::Create(FunctionType::get(T_int32, false), Function::ExternalLinkage, "_resetstkoflw", m); add_named_global(resetstkoflw_func, &_resetstkoflw); +#if defined(_CPU_X86_64_) + juliapersonality_func = Function::Create(FunctionType::get(T_int32, true), + Function::ExternalLinkage, "__julia_personality", m); + add_named_global(juliapersonality_func, &__julia_personality); +#endif #ifndef FORCE_ELF #if defined(_CPU_X86_64_) #if defined(_COMPILER_MINGW_) diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index e55325fa193f6..ce39d8ec45de8 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -128,9 +128,6 @@ void jl_add_linfo_in_flight(StringRef name, jl_lambda_info_t *linfo, const DataL } #if defined(_OS_WINDOWS_) -#if defined(_CPU_X86_64_) -extern "C" EXCEPTION_DISPOSITION _seh_exception_handler(PEXCEPTION_RECORD ExceptionRecord,void *EstablisherFrame, PCONTEXT ContextRecord, void *DispatcherContext); -#endif static void create_PRUNTIME_FUNCTION(uint8_t *Code, size_t Size, StringRef fnname, uint8_t *Section, size_t Allocated, uint8_t *UnwindData) { @@ -143,7 +140,7 @@ static void create_PRUNTIME_FUNCTION(uint8_t *Code, size_t Size, StringRef fnnam if (!catchjmp[0]) { catchjmp[0] = 0x48; catchjmp[1] = 0xb8; // mov RAX, QWORD PTR [...] - *(uint64_t*)(&catchjmp[2]) = (uint64_t)&_seh_exception_handler; + *(uint64_t*)(&catchjmp[2]) = (uint64_t)&__julia_personality; catchjmp[10] = 0xff; catchjmp[11] = 0xe0; // jmp RAX UnwindData[0] = 0x09; // version info, UNW_FLAG_EHANDLER @@ -421,9 +418,9 @@ class JuliaJITEventListener: public JITEventListener assert(SectionAddrCheck); assert(SectionLoadOffset != 1); catchjmp[SectionLoadOffset] = 0x48; - catchjmp[SectionLoadOffset + 1] = 0xb8; // mov RAX, QWORD PTR [&_seh_exception_handle] + catchjmp[SectionLoadOffset + 1] = 0xb8; // mov RAX, QWORD PTR [&__julia_personality] *(uint64_t*)(&catchjmp[SectionLoadOffset + 2]) = - (uint64_t)&_seh_exception_handler; + (uint64_t)&__julia_personality; catchjmp[SectionLoadOffset + 10] = 0xff; catchjmp[SectionLoadOffset + 11] = 0xe0; // jmp RAX UnwindData[SectionLoadOffset] = 0x09; // version info, UNW_FLAG_EHANDLER diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 3476b821e7ee5..097565f955a8f 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -532,28 +532,35 @@ ExecutionEngine *jl_ExecutionEngine; #endif // MSVC's link.exe requires each function declaration to have a Comdat section -// rather than litter the code with conditionals, +// So rather than litter the code with conditionals, // all global values that get emitted call this function // and it decides whether the definition needs a Comdat section and adds the appropriate declaration // TODO: consider moving this into jl_add_to_shadow or jl_dump_shadow? the JIT doesn't care, so most calls are now no-ops template // for GlobalObject's static T *addComdat(T *G) { -#if defined(_OS_WINDOWS_) && defined(_COMPILER_MICROSOFT_) +#if defined(_OS_WINDOWS_) && defined(LLVM35) if (imaging_mode && !G->isDeclaration()) { -#ifdef LLVM35 // Add comdat information to make MSVC link.exe happy + // it's valid to emit this for ld.exe too, + // but makes it very slow to link for no benefit +#if defined(_COMPILER_MICROSOFT_) if (G->getParent() == shadow_output) { Comdat *jl_Comdat = G->getParent()->getOrInsertComdat(G->getName()); // ELF only supports Comdat::Any jl_Comdat->setSelectionKind(Comdat::NoDuplicates); G->setComdat(jl_Comdat); } +#endif // add __declspec(dllexport) to everything marked for export if (G->getLinkage() == GlobalValue::ExternalLinkage) G->setDLLStorageClass(GlobalValue::DLLExportStorageClass); else G->setDLLStorageClass(GlobalValue::DefaultStorageClass); +#if defined(_CPU_X86_64_) + // Add unwind exception personalities to functions to handle async exceptions + if (Function *F = dyn_cast(G)) + F->setPersonalityFn(juliapersonality_func); #endif } #endif diff --git a/src/julia_internal.h b/src/julia_internal.h index 2edfe782d1ad4..325de9c4d028c 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -343,6 +343,8 @@ typedef struct { uint64_t jl_getUnwindInfo(uint64_t dwBase); #ifdef _OS_WINDOWS_ #include +JL_DLLEXPORT EXCEPTION_DISPOSITION __julia_personality( + PEXCEPTION_RECORD ExceptionRecord, void *EstablisherFrame, PCONTEXT ContextRecord, void *DispatcherContext); extern HANDLE hMainThread; typedef CONTEXT bt_context_t; #if defined(_CPU_X86_64_) diff --git a/src/signals-win.c b/src/signals-win.c index 4950e0c6d016b..8569658c93664 100644 --- a/src/signals-win.c +++ b/src/signals-win.c @@ -278,8 +278,7 @@ static LONG WINAPI exception_handler(struct _EXCEPTION_POINTERS *ExceptionInfo) } #if defined(_CPU_X86_64_) -EXCEPTION_DISPOSITION _seh_exception_handler(PEXCEPTION_RECORD ExceptionRecord, void *EstablisherFrame, PCONTEXT ContextRecord, void *DispatcherContext) -{ +JL_DLLEXPORT EXCEPTION_DISPOSITION __julia_personality(PEXCEPTION_RECORD ExceptionRecord, void *EstablisherFrame, PCONTEXT ContextRecord, void *DispatcherContext) { EXCEPTION_POINTERS ExceptionInfo; ExceptionInfo.ExceptionRecord = ExceptionRecord; ExceptionInfo.ContextRecord = ContextRecord; From 9ad1357f79394afe9ddd1ae632122c8aeb98b3ad Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 28 Jun 2016 23:29:07 -0400 Subject: [PATCH 3/4] set precompiled=yes by default on windows also fix the test for this to actually test for this, instead of injecting a non-default build configuration in order to test for something that bootstrapping is already testing fix #16953 --- .travis.yml | 7 +++---- appveyor.yml | 2 +- contrib/windows/msys_build.sh | 1 - src/init.c | 5 ----- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 91a4a35d643fd..cc87e6ca68b39 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,6 @@ notifications: - http://julia.mit.edu:8000/travis-hook before_install: - make check-whitespace - - JULIA_SYSIMG_BUILD_FLAGS="--output-ji ../usr/lib/julia/sys.ji" - if [ `uname` = "Linux" ]; then contrib/travis_fastfail.sh || exit 1; mkdir -p $HOME/bin; @@ -93,7 +92,7 @@ script: - make -C moreutils mispipe - make $BUILDOPTS -C base version_git.jl.phony - moreutils/mispipe "make $BUILDOPTS NO_GIT=1 -C deps" bar > deps.log || cat deps.log - - make $BUILDOPTS NO_GIT=1 JULIA_SYSIMG_BUILD_FLAGS="$JULIA_SYSIMG_BUILD_FLAGS" prefix=/tmp/julia install | moreutils/ts -s "%.s" + - make $BUILDOPTS NO_GIT=1 prefix=/tmp/julia install | moreutils/ts -s "%.s" - make $BUILDOPTS NO_GIT=1 build-stats - du -sk /tmp/julia/* - if [ `uname` = "Darwin" ]; then @@ -102,8 +101,8 @@ script: done; fi - cd .. && mv julia julia2 - - cp /tmp/julia/lib/julia/sys.ji local.ji && /tmp/julia/bin/julia -J local.ji -e 'true' && - /tmp/julia/bin/julia-debug -J local.ji -e 'true' && rm local.ji + - /tmp/julia/bin/julia --precompiled=no -e 'true' && + /tmp/julia/bin/julia-debug --precompiled=no -e 'true' - /tmp/julia/bin/julia -e 'versioninfo()' - export JULIA_CPU_CORES=2 && export JULIA_TEST_MAXRSS_MB=600 && cd /tmp/julia/share/julia/test && /tmp/julia/bin/julia --check-bounds=yes runtests.jl $TESTSTORUN && diff --git a/appveyor.yml b/appveyor.yml index be1fa0d55b214..b417243521f8b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -53,6 +53,6 @@ build_script: test_script: - usr\bin\julia -e "versioninfo()" - - copy usr\lib\julia\sys.ji local.ji && usr\bin\julia -J local.ji -e "true" && del local.ji + - usr\bin\julia --precompiled=no -e "true" - cd test && ..\usr\bin\julia --check-bounds=yes runtests.jl all && ..\usr\bin\julia --check-bounds=yes runtests.jl libgit2-online pkg diff --git a/contrib/windows/msys_build.sh b/contrib/windows/msys_build.sh index fdb29f7711eed..aefa0b2864868 100755 --- a/contrib/windows/msys_build.sh +++ b/contrib/windows/msys_build.sh @@ -166,7 +166,6 @@ for lib in SUITESPARSE ARPACK BLAS LAPACK FFTW \ done echo 'override LIBLAPACK = $(LIBBLAS)' >> Make.user echo 'override LIBLAPACKNAME = $(LIBBLASNAME)' >> Make.user -echo 'JULIA_SYSIMG_BUILD_FLAGS=--output-ji ../usr/lib/julia/sys.ji' >> Make.user # Remaining dependencies: # libuv since its static lib is no longer included in the binaries diff --git a/src/init.c b/src/init.c index 06df5fb4112e1..5cb0ad17aed8f 100644 --- a/src/init.c +++ b/src/init.c @@ -73,12 +73,7 @@ jl_options_t jl_options = { 0, // quiet JL_OPTIONS_FAST_MATH_DEFAULT, 0, // worker JL_OPTIONS_HANDLE_SIGNALS_ON, -#ifdef _OS_WINDOWS_ -// TODO remove this when using LLVM 3.5+ - JL_OPTIONS_USE_PRECOMPILED_NO, -#else JL_OPTIONS_USE_PRECOMPILED_YES, -#endif JL_OPTIONS_USE_COMPILECACHE_YES, NULL, // bindto NULL, // outputbc From 5f31073da3af30ca30097838f5240cba24f22826 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 1 Jul 2016 19:24:39 -0400 Subject: [PATCH 4/4] Fix assertion failure on LLVM 3.8+ --- src/jitlayers.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 097565f955a8f..7b554811add50 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -544,24 +544,25 @@ static T *addComdat(T *G) // Add comdat information to make MSVC link.exe happy // it's valid to emit this for ld.exe too, // but makes it very slow to link for no benefit -#if defined(_COMPILER_MICROSOFT_) if (G->getParent() == shadow_output) { +#if defined(_COMPILER_MICROSOFT_) Comdat *jl_Comdat = G->getParent()->getOrInsertComdat(G->getName()); // ELF only supports Comdat::Any jl_Comdat->setSelectionKind(Comdat::NoDuplicates); G->setComdat(jl_Comdat); - } #endif +#if defined(_CPU_X86_64_) + // Add unwind exception personalities to functions to handle async exceptions + assert(!juliapersonality_func || juliapersonality_func->getParent() == shadow_output); + if (Function *F = dyn_cast(G)) + F->setPersonalityFn(juliapersonality_func); +#endif + } // add __declspec(dllexport) to everything marked for export if (G->getLinkage() == GlobalValue::ExternalLinkage) G->setDLLStorageClass(GlobalValue::DLLExportStorageClass); else G->setDLLStorageClass(GlobalValue::DefaultStorageClass); -#if defined(_CPU_X86_64_) - // Add unwind exception personalities to functions to handle async exceptions - if (Function *F = dyn_cast(G)) - F->setPersonalityFn(juliapersonality_func); -#endif } #endif return G;