From 1f87ccf0ae8f7ef422fc93415e507066ba5e2273 Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Sat, 19 Oct 2024 15:03:32 -0400 Subject: [PATCH 001/198] Test for showing AnnotatedIOBuffer --- test/strings/annotated.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/strings/annotated.jl b/test/strings/annotated.jl index 85acab74abf7b..9418ff26ef43a 100644 --- a/test/strings/annotated.jl +++ b/test/strings/annotated.jl @@ -244,4 +244,8 @@ end @test write(wrapio, Base.AnnotatedChar('a', [(:y, 2)])) == 1 @test read(seekstart(aio), Base.AnnotatedString) == Base.AnnotatedString("heya", [(1:3, :x, 1), (4:4, :y, 2)]) + # show-ing an AnnotatedIOBuffer + aio = Base.AnnotatedIOBuffer() + write(aio, Base.AnnotatedString("hello", [(1:5, :tag, 1)])) + @test sprint(show, aio) == "Base.AnnotatedIOBuffer(5 bytes, 1 annotation)" end From d32843b606bdb59957662d267f258d3dc7bf27b5 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sat, 30 Nov 2024 16:34:42 +0100 Subject: [PATCH 002/198] Automatically enable JITPROFILING with ITTAPI (#55598) This helps when profiling remotely since VTunes doesn't support setting environment variables on remote systems. Will still respect `ENABLE_JITPROFILING=0`. --- src/codegen.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 0b483696567ad..b8bed0793730b 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -81,6 +81,10 @@ #include #include +#ifdef USE_ITTAPI +#include "ittapi/ittnotify.h" +#endif + using namespace llvm; static bool jl_fpo_disabled(const Triple &TT) { @@ -10427,8 +10431,16 @@ extern "C" void jl_init_llvm(void) const char *jit_profiling = getenv("ENABLE_JITPROFILING"); #if defined(JL_USE_INTEL_JITEVENTS) - if (jit_profiling && atoi(jit_profiling)) { - jl_using_intel_jitevents = 1; + if (jit_profiling) { + if (atoi(jit_profiling)) { + jl_using_intel_jitevents = 1; + } + } else { +#ifdef USE_ITTAPI + __itt_collection_state state = __itt_get_collection_state(); + jl_using_intel_jitevents = state == __itt_collection_init_successful || + state == __itt_collection_collector_exists; +#endif } #endif From ef328064a96fb143c28e2765f5a84b3ab8c43c87 Mon Sep 17 00:00:00 2001 From: Zentrik Date: Sun, 1 Dec 2024 04:35:39 +0000 Subject: [PATCH 003/198] Fix string handling in jlchecksum (#56720) A `TAGGED_RELEASE_BANNER` with spaces such as `Official https://julialang.org release` produces the error `/cache/build/builder-amdci4-5/julialang/julia-master/deps/tools/jlchecksum: 66: [: Official: unexpected operator`. --- deps/tools/jlchecksum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/tools/jlchecksum b/deps/tools/jlchecksum index 329d3a2a845d4..9945ec89e6bda 100755 --- a/deps/tools/jlchecksum +++ b/deps/tools/jlchecksum @@ -63,7 +63,7 @@ find_checksum() fi done if [ ! -f "$DEPSDIR/checksums/$BASENAME/$CHECKSUM_TYPE" ]; then - if [ ${TAGGED_RELEASE_BANNER:-} ]; then + if [ "${TAGGED_RELEASE_BANNER:-}" ]; then echo "WARNING: $CHECKSUM_TYPE checksum for $BASENAME not found in deps/checksums/, failing release build." >&2 exit 3 fi From ea421126d831b18fa00408794247317b544b18d8 Mon Sep 17 00:00:00 2001 From: Priynsh <119518987+Priynsh@users.noreply.github.com> Date: Mon, 2 Dec 2024 00:29:52 +0530 Subject: [PATCH 004/198] Clarifying ispunct behavior difference between Julia and C in documentation (#56727) Fixes #56680. This PR updates the documentation for the ispunct function in Julia to explicitly note its differing behavior from the similarly named function in C. --------- Co-authored-by: Lilith Orion Hafner --- base/strings/unicode.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/base/strings/unicode.jl b/base/strings/unicode.jl index ad047514c85a6..fcb4a371e9898 100644 --- a/base/strings/unicode.jl +++ b/base/strings/unicode.jl @@ -534,11 +534,17 @@ iscntrl(c::AbstractChar) = c <= '\x1f' || '\x7f' <= c <= '\u9f' Tests whether a character belongs to the Unicode general category Punctuation, i.e. a character whose category code begins with 'P'. +!!! note + This behavior is different from the `ispunct` function in C. + # Examples ```jldoctest julia> ispunct('α') false +julia> ispunct('=') +false + julia> ispunct('/') true From 8ce7d0fce419746e36556d561fe7d1c89704e291 Mon Sep 17 00:00:00 2001 From: Christian Guinard <28689358+christiangnrd@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:13:51 -0400 Subject: [PATCH 005/198] [NEWS.md] Add PR numbers and remove some 1.11 changes that accidentally came back. (#56722) --- NEWS.md | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/NEWS.md b/NEWS.md index 61bad831e261c..c1d5f38f337b0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -55,11 +55,11 @@ Command-line option changes --------------------------- * The `-m/--module` flag can be passed to run the `main` function inside a package with a set of arguments. - This `main` function should be declared using `@main` to indicate that it is an entry point. + This `main` function should be declared using `@main` to indicate that it is an entry point. ([#52103]) * Enabling or disabling color text in Julia can now be controlled with the [`NO_COLOR`](https://no-color.org/) or [`FORCE_COLOR`](https://force-color.org/) environment variables. These variables are also honored by Julia's build system ([#53742], [#56346]). -* `--project=@temp` starts Julia with a temporary environment. +* `--project=@temp` starts Julia with a temporary environment. ([#51149]) * New `--trace-compile-timing` option to report how long each method reported by `--trace-compile` took to compile, in ms. ([#54662]) * `--trace-compile` now prints recompiled methods in yellow or with a trailing comment if color is not supported ([#55763]) @@ -72,7 +72,7 @@ Multi-threading changes a `OncePerProcess{T}` type, which allows defining a function that should be run exactly once the first time it is called, and then always return the same result value of type `T` every subsequent time afterwards. There are also `OncePerThread{T}` and `OncePerTask{T}` types for - similar usage with threads or tasks. ([#TBD]) + similar usage with threads or tasks. ([#55793]) Build system changes -------------------- @@ -86,32 +86,15 @@ New library functions * The new `isfull(c::Channel)` function can be used to check if `put!(c, some_value)` will block. ([#53159]) * `waitany(tasks; throw=false)` and `waitall(tasks; failfast=false, throw=false)` which wait multiple tasks at once ([#53341]). * `uuid7()` creates an RFC 9652 compliant UUID with version 7 ([#54834]). -* `insertdims(array; dims)` allows to insert singleton dimensions into an array which is the inverse operation to `dropdims` +* `insertdims(array; dims)` allows to insert singleton dimensions into an array which is the inverse operation to `dropdims`. ([#45793]) * The new `Fix` type is a generalization of `Fix1/Fix2` for fixing a single argument ([#54653]). New library features -------------------- -* `invmod(n, T)` where `T` is a native integer type now computes the modular inverse of `n` in the modular integer ring that `T` defines ([#52180]). -* `invmod(n)` is an abbreviation for `invmod(n, typeof(n))` for native integer types ([#52180]). -* `replace(string, pattern...)` now supports an optional `IO` argument to - write the output to a stream rather than returning a string ([#48625]). -* `sizehint!(s, n)` now supports an optional `shrink` argument to disable shrinking ([#51929]). -* New function `Docs.hasdoc(module, symbol)` tells whether a name has a docstring ([#52139]). -* New function `Docs.undocumented_names(module)` returns a module's undocumented public names ([#52413]). -* Passing an `IOBuffer` as a stdout argument for `Process` spawn now works as - expected, synchronized with `wait` or `success`, so a `Base.BufferStream` is - no longer required there for correctness to avoid data races ([#52461]). -* After a process exits, `closewrite` will no longer be automatically called on - the stream passed to it. Call `wait` on the process instead to ensure the - content is fully written, then call `closewrite` manually to avoid - data-races. Or use the callback form of `open` to have all that handled - automatically. -* `@timed` now additionally returns the elapsed compilation and recompilation time ([#52889]) * `escape_string` takes additional keyword arguments `ascii=true` (to escape all non-ASCII characters) and `fullhex=true` (to require full 4/8-digit hex numbers - for u/U escapes, e.g. for C compatibility) [#55099]). -* `filter` can now act on a `NamedTuple` ([#50795]). + for u/U escapes, e.g. for C compatibility) ([#55099]). * `tempname` can now take a suffix string to allow the file name to include a suffix and include that suffix in the uniquing checking ([#53474]) * `RegexMatch` objects can now be used to construct `NamedTuple`s and `Dict`s ([#50988]) @@ -133,7 +116,7 @@ Standard library changes * A new standard library for applying syntax highlighting to Julia code, this uses `JuliaSyntax` and `StyledStrings` to implement a `highlight` function - that creates an `AnnotatedString` with syntax highlighting applied. + that creates an `AnnotatedString` with syntax highlighting applied. ([#51810]) #### Package Manager From 6a0de347469abe38c970b9efbf0244f2d60806ca Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Sat, 30 Nov 2024 18:06:26 -0500 Subject: [PATCH 006/198] ircode: cleanup code crud - support gc running - don't duplicate field 4 - remove some unused code only previously needed for handling cycles (which are not valid in IR) --- src/clangsa/GCChecker.cpp | 3 +- src/ircode.c | 399 +++++++++++++++++++++++++------------- src/serialize.h | 69 ------- 3 files changed, 263 insertions(+), 208 deletions(-) diff --git a/src/clangsa/GCChecker.cpp b/src/clangsa/GCChecker.cpp index cac89a6761d01..40093ca15859b 100644 --- a/src/clangsa/GCChecker.cpp +++ b/src/clangsa/GCChecker.cpp @@ -847,7 +847,8 @@ bool GCChecker::isGCTrackedType(QualType QT) { Name.ends_with_insensitive("jl_vararg_t") || Name.ends_with_insensitive("jl_opaque_closure_t") || Name.ends_with_insensitive("jl_globalref_t") || - // Probably not technically true for these, but let's allow it + // Probably not technically true for these, but let's allow it as a root + Name.ends_with_insensitive("jl_ircode_state") || Name.ends_with_insensitive("typemap_intersection_env") || Name.ends_with_insensitive("interpreter_state") || Name.ends_with_insensitive("jl_typeenv_t") || diff --git a/src/ircode.c b/src/ircode.c index bec8d46513eef..d3137ce26edef 100644 --- a/src/ircode.c +++ b/src/ircode.c @@ -10,17 +10,76 @@ #include "julia_internal.h" #include "serialize.h" -#ifndef _OS_WINDOWS_ -#include -#endif - -#include "valgrind.h" #include "julia_assert.h" #ifdef __cplusplus extern "C" { #endif +#define TAG_SYMBOL 2 +#define TAG_SSAVALUE 3 +#define TAG_DATATYPE 4 +#define TAG_SLOTNUMBER 5 +#define TAG_SVEC 6 +// #define TAG_UNUSED 7 +#define TAG_NULL 8 +#define TAG_EXPR 9 +#define TAG_PHINODE 10 +#define TAG_PHICNODE 11 +#define TAG_LONG_SYMBOL 12 +#define TAG_LONG_SVEC 13 +#define TAG_LONG_EXPR 14 +#define TAG_LONG_PHINODE 15 +#define TAG_LONG_PHICNODE 16 +#define TAG_METHODROOT 17 +#define TAG_EDGE 18 +#define TAG_STRING 19 +#define TAG_SHORT_INT64 20 +//#define TAG_UNUSED 21 +#define TAG_CNULL 22 +#define TAG_ARRAY1D 23 +#define TAG_SINGLETON 24 +#define TAG_MODULE 25 +#define TAG_TVAR 26 +#define TAG_METHOD_INSTANCE 27 +#define TAG_METHOD 28 +#define TAG_CODE_INSTANCE 29 +#define TAG_COMMONSYM 30 +#define TAG_NEARBYGLOBAL 31 +#define TAG_GLOBALREF 32 +#define TAG_CORE 33 +#define TAG_BASE 34 +#define TAG_BITYPENAME 35 +#define TAG_NEARBYMODULE 36 +#define TAG_INT32 37 +#define TAG_INT64 38 +#define TAG_UINT8 39 +#define TAG_VECTORTY 40 +#define TAG_PTRTY 41 +#define TAG_LONG_SSAVALUE 42 +#define TAG_LONG_METHODROOT 43 +#define TAG_LONG_EDGE 44 +#define TAG_SHORTER_INT64 45 +#define TAG_SHORT_INT32 46 +#define TAG_CALL1 47 +#define TAG_CALL2 48 +#define TAG_SHORT_BACKREF 49 +#define TAG_BACKREF 50 +#define TAG_UNIONALL 51 +#define TAG_GOTONODE 52 +#define TAG_QUOTENODE 53 +#define TAG_GENERAL 54 +#define TAG_GOTOIFNOT 55 +#define TAG_RETURNNODE 56 +#define TAG_ARGUMENT 57 +#define TAG_RELOC_METHODROOT 58 +#define TAG_BINDING 59 +#define TAG_MEMORYT 60 +#define TAG_ENTERNODE 61 + +#define LAST_TAG 61 + + typedef struct { ios_t *s; // method we're compressing for @@ -38,29 +97,29 @@ static jl_value_t *deser_tag[256]; static htable_t common_symbol_tag; static jl_value_t *deser_symbols[256]; -void *jl_lookup_ser_tag(jl_value_t *v) +static void *jl_lookup_ser_tag(jl_value_t *v) { return ptrhash_get(&ser_tag, v); } -void *jl_lookup_common_symbol(jl_value_t *v) +static void *jl_lookup_common_symbol(jl_value_t *v) { return ptrhash_get(&common_symbol_tag, v); } -jl_value_t *jl_deser_tag(uint8_t tag) +static jl_value_t *jl_deser_tag(uint8_t tag) { return deser_tag[tag]; } -jl_value_t *jl_deser_symbol(uint8_t tag) +static jl_value_t *jl_deser_symbol(uint8_t tag) { return deser_symbols[tag]; } // --- encoding --- -static void jl_encode_value_(jl_ircode_state *s, jl_value_t *v, int as_literal) JL_GC_DISABLED; +static void jl_encode_value_(jl_ircode_state *s, jl_value_t *v, int as_literal); #define jl_encode_value(s, v) jl_encode_value_((s), (jl_value_t*)(v), 0) static void tagged_root(rle_reference *rr, jl_ircode_state *s, int i) @@ -69,7 +128,7 @@ static void tagged_root(rle_reference *rr, jl_ircode_state *s, int i) s->relocatability = 0; } -static void literal_val_id(rle_reference *rr, jl_ircode_state *s, jl_value_t *v) JL_GC_DISABLED +static void literal_val_id(rle_reference *rr, jl_ircode_state *s, jl_value_t *v) { jl_array_t *rs = s->method->roots; int i, l = jl_array_nrows(rs); @@ -142,7 +201,7 @@ static void jl_encode_as_indexed_root(jl_ircode_state *s, jl_value_t *v) } } -static void jl_encode_memory_slice(jl_ircode_state *s, jl_genericmemory_t *mem, size_t offset, size_t len) JL_GC_DISABLED +static void jl_encode_memory_slice(jl_ircode_state *s, jl_genericmemory_t *mem, size_t offset, size_t len) { jl_datatype_t *t = (jl_datatype_t*)jl_typetagof(mem); size_t i; @@ -180,7 +239,7 @@ static void jl_encode_memory_slice(jl_ircode_state *s, jl_genericmemory_t *mem, } } -static void jl_encode_value_(jl_ircode_state *s, jl_value_t *v, int as_literal) JL_GC_DISABLED +static void jl_encode_value_(jl_ircode_state *s, jl_value_t *v, int as_literal) { size_t i; @@ -306,8 +365,11 @@ static void jl_encode_value_(jl_ircode_state *s, jl_value_t *v, int as_literal) } for (i = 0; i < l; i++) { int32_t e = jl_array_data(edges, int32_t)[i]; - if (e <= 20) - jl_encode_value(s, jl_box_int32(e)); + if (e <= 0 && e <= 20) { // 1-byte encodings + jl_value_t *ebox = jl_box_int32(e); + JL_GC_PROMISE_ROOTED(ebox); + jl_encode_value(s, ebox); + } else jl_encode_int32(s, e); } @@ -333,25 +395,39 @@ static void jl_encode_value_(jl_ircode_state *s, jl_value_t *v, int as_literal) } else if (jl_is_gotonode(v)) { write_uint8(s->s, TAG_GOTONODE); - jl_encode_value(s, jl_get_nth_field(v, 0)); + jl_value_t *f = jl_get_nth_field(v, 0); + JL_GC_PUSH1(&f); + jl_encode_value(s, f); + JL_GC_POP(); } else if (jl_is_gotoifnot(v)) { write_uint8(s->s, TAG_GOTOIFNOT); - jl_encode_value(s, jl_get_nth_field(v, 0)); - jl_encode_value(s, jl_get_nth_field(v, 1)); + jl_value_t *f = jl_get_nth_field_noalloc(v, 0); + JL_GC_PUSH1(&f); + jl_encode_value(s, f); + f = jl_get_nth_field(v, 1); + jl_encode_value(s, f); + JL_GC_POP(); } else if (jl_is_enternode(v)) { write_uint8(s->s, TAG_ENTERNODE); - jl_encode_value(s, jl_get_nth_field(v, 0)); - jl_encode_value(s, jl_get_nth_field(v, 1)); + jl_value_t *f = jl_get_nth_field(v, 0); + JL_GC_PUSH1(&f); + jl_encode_value(s, f); + f = jl_get_nth_field_noalloc(v, 1); + jl_encode_value(s, f); + JL_GC_POP(); } else if (jl_is_argument(v)) { write_uint8(s->s, TAG_ARGUMENT); - jl_encode_value(s, jl_get_nth_field(v, 0)); + jl_value_t *f = jl_get_nth_field(v, 0); + JL_GC_PUSH1(&f); + jl_encode_value(s, f); + JL_GC_POP(); } else if (jl_is_returnnode(v)) { write_uint8(s->s, TAG_RETURNNODE); - jl_encode_value(s, jl_get_nth_field(v, 0)); + jl_encode_value(s, jl_returnnode_value(v)); } else if (jl_is_quotenode(v)) { write_uint8(s->s, TAG_QUOTENODE); @@ -394,19 +470,15 @@ static void jl_encode_value_(jl_ircode_state *s, jl_value_t *v, int as_literal) write_int32(s->s, jl_string_len(v)); ios_write(s->s, jl_string_data(v), jl_string_len(v)); } - else if (as_literal && jl_is_array(v)) { + else if (as_literal && jl_is_array(v) && jl_array_ndims(v)) { jl_array_t *ar = (jl_array_t*)v; - if (jl_array_ndims(ar) == 1) { - write_uint8(s->s, TAG_ARRAY1D); - } - else { - write_uint8(s->s, TAG_ARRAY); - write_uint16(s->s, jl_array_ndims(ar)); - } - for (i = 0; i < jl_array_ndims(ar); i++) - jl_encode_value(s, jl_box_long(jl_array_dim(ar, i))); + write_uint8(s->s, TAG_ARRAY1D); + size_t l = jl_array_dim0(ar); + jl_value_t *lbox = jl_box_long(l); + JL_GC_PUSH1(&lbox); + jl_encode_value(s, lbox); + JL_GC_POP(); jl_encode_value(s, jl_typeof(ar)); - size_t l = jl_array_len(ar); const jl_datatype_layout_t *layout = ((jl_datatype_t*)jl_typetagof(ar->ref.mem))->layout; size_t offset; if (layout->flags.arrayelem_isunion || layout->size == 0) @@ -419,7 +491,10 @@ static void jl_encode_value_(jl_ircode_state *s, jl_value_t *v, int as_literal) jl_genericmemory_t* m = (jl_genericmemory_t*)v; write_uint8(s->s, TAG_MEMORYT); jl_encode_value(s, (jl_datatype_t*)jl_typetagof(v)); - jl_encode_value(s, jl_box_long(m->length)); + jl_value_t *lbox = jl_box_long(m->length); + JL_GC_PUSH1(&lbox); + jl_encode_value(s, lbox); + JL_GC_POP(); jl_encode_memory_slice(s, m, 0, m->length); } else if (as_literal && jl_is_layout_opaque(((jl_datatype_t*)jl_typeof(v))->layout)) { @@ -428,16 +503,8 @@ static void jl_encode_value_(jl_ircode_state *s, jl_value_t *v, int as_literal) else if (as_literal || jl_is_uniontype(v) || jl_is_newvarnode(v) || jl_is_linenode(v) || jl_is_upsilonnode(v) || jl_is_pinode(v) || jl_is_slotnumber(v) || jl_is_ssavalue(v) || (jl_isbits(jl_typeof(v)) && jl_datatype_size(jl_typeof(v)) <= 64)) { + write_uint8(s->s, TAG_GENERAL); jl_datatype_t *t = (jl_datatype_t*)jl_typeof(v); - size_t tsz = jl_datatype_size(t); - if (tsz <= 255) { - write_uint8(s->s, TAG_SHORT_GENERAL); - write_uint8(s->s, tsz); - } - else { - write_uint8(s->s, TAG_GENERAL); - write_int32(s->s, tsz); - } jl_encode_value(s, t); char *data = (char*)jl_data_ptr(v); @@ -492,34 +559,35 @@ static jl_code_info_flags_t code_info_flags(uint8_t propagate_inbounds, uint8_t // --- decoding --- -static jl_value_t *jl_decode_value(jl_ircode_state *s) JL_GC_DISABLED; +static jl_value_t *jl_decode_value(jl_ircode_state *s); -static jl_value_t *jl_decode_value_svec(jl_ircode_state *s, uint8_t tag) JL_GC_DISABLED +static jl_value_t *jl_decode_value_svec(jl_ircode_state *s, uint8_t tag) { size_t i, len; if (tag == TAG_SVEC) len = read_uint8(s->s); else len = read_int32(s->s); - jl_svec_t *sv = jl_alloc_svec_uninit(len); - jl_value_t **data = jl_svec_data(sv); - for (i = 0; i < len; i++) { - data[i] = jl_decode_value(s); - } + jl_svec_t *sv = jl_alloc_svec(len); + JL_GC_PUSH1(&sv); + for (i = 0; i < len; i++) + jl_svecset(sv, i, jl_decode_value(s)); + JL_GC_POP(); return (jl_value_t*)sv; } -static jl_value_t *jl_decode_value_memory(jl_ircode_state *s, jl_value_t *mty, size_t nel) JL_GC_DISABLED +static jl_genericmemory_t *jl_decode_value_memory(jl_ircode_state *s, jl_value_t *mty, size_t nel) { jl_genericmemory_t *m = jl_alloc_genericmemory(mty, nel); + JL_GC_PUSH1(&m); const jl_datatype_layout_t *layout = ((jl_datatype_t*)mty)->layout; if (layout->flags.arrayelem_isboxed) { jl_value_t **data = (jl_value_t**)m->ptr; size_t i, numel = m->length; for (i = 0; i < numel; i++) { data[i] = jl_decode_value(s); + jl_gc_wb(m, data[i]); } - assert(jl_astaggedvalue(m)->bits.gc == GC_CLEAN); // gc is disabled } else if (layout->first_ptr >= 0) { size_t i, numel = m->length; @@ -534,49 +602,48 @@ static jl_value_t *jl_decode_value_memory(jl_ircode_state *s, jl_value_t *mty, s if ((char*)fld != start) ios_readall(s->s, start, (const char*)fld - start); *fld = jl_decode_value(s); + jl_gc_wb(m, fld); start = (char*)&fld[1]; } data += elsz; if (data != start) ios_readall(s->s, start, data - start); } - assert(jl_astaggedvalue(m)->bits.gc == GC_CLEAN); // gc is disabled } else { size_t extra = jl_genericmemory_isbitsunion(m) ? m->length : 0; size_t tot = m->length * layout->size + extra; ios_readall(s->s, (char*)m->ptr, tot); } - return (jl_value_t*)m; + JL_GC_POP(); + return m; } JL_DLLEXPORT jl_array_t *jl_alloc_array_nd(jl_value_t *atype, size_t *dims, size_t ndims); -static jl_value_t *jl_decode_value_array(jl_ircode_state *s, uint8_t tag) JL_GC_DISABLED +static jl_value_t *jl_decode_value_array1d(jl_ircode_state *s, uint8_t tag) { - int16_t i, ndims; - if (tag == TAG_ARRAY1D) - ndims = 1; - else - ndims = read_uint16(s->s); - size_t *dims = (size_t*)alloca(ndims * sizeof(size_t)); - size_t len = 1; - for (i = 0; i < ndims; i++) { - dims[i] = jl_unbox_long(jl_decode_value(s)); - len *= dims[i]; - } + int16_t ndims = 1; + size_t dim0 = jl_unbox_long(jl_decode_value(s)); + size_t len = dim0; jl_value_t *aty = jl_decode_value(s); - jl_array_t *a = jl_alloc_array_nd(aty, dims, ndims); - a->ref.mem = (jl_genericmemory_t*)jl_decode_value_memory(s, jl_field_type_concrete((jl_datatype_t*)jl_field_type_concrete((jl_datatype_t*)aty, 0), 1), len); + JL_GC_PROMISE_ROOTED(aty); // (JL_ALWAYS_LEAFTYPE) + jl_genericmemory_t *mem = jl_decode_value_memory(s, jl_field_type_concrete((jl_datatype_t*)jl_field_type_concrete((jl_datatype_t*)aty, 0), 1), len); + JL_GC_PUSH1(&mem); + int tsz = sizeof(jl_array_t) + ndims*sizeof(size_t); + jl_array_t *a = (jl_array_t*)jl_gc_alloc(s->ptls, tsz, aty); + a->ref.mem = mem; const jl_datatype_layout_t *layout = ((jl_datatype_t*)jl_typetagof(a->ref.mem))->layout; if (layout->flags.arrayelem_isunion || layout->size == 0) a->ref.ptr_or_offset = (void*)0; else a->ref.ptr_or_offset = a->ref.mem->ptr; + a->dimsize[0] = dim0; + JL_GC_POP(); return (jl_value_t*)a; } -static jl_value_t *jl_decode_value_expr(jl_ircode_state *s, uint8_t tag) JL_GC_DISABLED +static jl_value_t *jl_decode_value_expr(jl_ircode_state *s, uint8_t tag) { size_t i, len; jl_sym_t *head = NULL; @@ -597,14 +664,18 @@ static jl_value_t *jl_decode_value_expr(jl_ircode_state *s, uint8_t tag) JL_GC_D if (head == NULL) head = (jl_sym_t*)jl_decode_value(s); jl_expr_t *e = jl_exprn(head, len); + JL_GC_PUSH1(&e); jl_value_t **data = jl_array_ptr_data(e->args); + jl_value_t *owner = jl_array_owner(e->args); for (i = 0; i < len; i++) { data[i] = jl_decode_value(s); + jl_gc_wb(owner, data[i]); } + JL_GC_POP(); return (jl_value_t*)e; } -static jl_value_t *jl_decode_value_phi(jl_ircode_state *s, uint8_t tag) JL_GC_DISABLED +static jl_value_t *jl_decode_value_phi(jl_ircode_state *s, uint8_t tag) { size_t i, len_e, len_v; if (tag == TAG_PHINODE) { @@ -614,9 +685,13 @@ static jl_value_t *jl_decode_value_phi(jl_ircode_state *s, uint8_t tag) JL_GC_DI len_e = read_int32(s->s); len_v = read_int32(s->s); } - jl_array_t *e = jl_alloc_array_1d(jl_array_int32_type, len_e); - jl_array_t *v = jl_alloc_vec_any(len_v); - jl_value_t *phi = jl_new_struct(jl_phinode_type, e, v); + jl_array_t *e = NULL; + jl_array_t *v = NULL; + jl_value_t *phi = NULL; + JL_GC_PUSH3(&e, &v, &phi); + e = jl_alloc_array_1d(jl_array_int32_type, len_e); + v = jl_alloc_vec_any(len_v); + phi = jl_new_struct(jl_phinode_type, e, v); int32_t *data_e = jl_array_data(e, int32_t); for (i = 0; i < len_e; i++) { data_e[i] = jl_unbox_int32(jl_decode_value(s)); @@ -624,11 +699,13 @@ static jl_value_t *jl_decode_value_phi(jl_ircode_state *s, uint8_t tag) JL_GC_DI jl_value_t **data_v = jl_array_ptr_data(v); for (i = 0; i < len_v; i++) { data_v[i] = jl_decode_value(s); + jl_gc_wb(jl_array_owner(v), data_v[i]); } + JL_GC_POP(); return phi; } -static jl_value_t *jl_decode_value_phic(jl_ircode_state *s, uint8_t tag) JL_GC_DISABLED +static jl_value_t *jl_decode_value_phic(jl_ircode_state *s, uint8_t tag) { size_t i, len; if (tag == TAG_PHICNODE) @@ -636,41 +713,53 @@ static jl_value_t *jl_decode_value_phic(jl_ircode_state *s, uint8_t tag) JL_GC_D else len = read_int32(s->s); jl_array_t *v = jl_alloc_vec_any(len); - jl_value_t *phic = jl_new_struct(jl_phicnode_type, v); + jl_value_t *phic = (jl_value_t*)v; + JL_GC_PUSH1(&phic); + phic = jl_new_struct(jl_phicnode_type, v); jl_value_t **data = jl_array_ptr_data(v); for (i = 0; i < len; i++) { data[i] = jl_decode_value(s); + jl_gc_wb(jl_array_owner(v), data[i]); } + JL_GC_POP(); return phic; } -static jl_value_t *jl_decode_value_globalref(jl_ircode_state *s) JL_GC_DISABLED +static jl_value_t *jl_decode_value_globalref(jl_ircode_state *s) { - jl_value_t *mod = jl_decode_value(s); - jl_value_t *var = jl_decode_value(s); - return jl_module_globalref((jl_module_t*)mod, (jl_sym_t*)var); + jl_module_t *mod = (jl_module_t*)jl_decode_value(s); + JL_GC_PROMISE_ROOTED(mod); + jl_sym_t *var = (jl_sym_t*)jl_decode_value(s); + JL_GC_PROMISE_ROOTED(var); + return jl_module_globalref(mod, var); } -static jl_value_t *jl_decode_value_any(jl_ircode_state *s, uint8_t tag) JL_GC_DISABLED +static jl_value_t *jl_decode_value_any(jl_ircode_state *s) { - int32_t sz = (tag == TAG_SHORT_GENERAL ? read_uint8(s->s) : read_int32(s->s)); - jl_value_t *v = jl_gc_alloc(s->ptls, sz, NULL); - jl_set_typeof(v, (void*)(intptr_t)0xf50); jl_datatype_t *dt = (jl_datatype_t*)jl_decode_value(s); - if (dt->smalltag) + JL_GC_PROMISE_ROOTED(dt); // (JL_ALWAYS_LEAFTYPE) + // jl_new_struct_uninit + size_t sz = jl_datatype_size(dt); + jl_value_t *v = jl_gc_alloc(s->ptls, sz, dt); + if (dt->smalltag) // TODO: do we need this? jl_set_typetagof(v, dt->smalltag, 0); - else - jl_set_typeof(v, dt); char *data = (char*)jl_data_ptr(v); size_t i, np = dt->layout->npointers; char *start = data; - for (i = 0; i < np; i++) { - uint32_t ptr = jl_ptr_offset(dt, i); - jl_value_t **fld = &((jl_value_t**)data)[ptr]; - if ((char*)fld != start) - ios_readall(s->s, start, (const char*)fld - start); - *fld = jl_decode_value(s); - start = (char*)&fld[1]; + if (np) { + if (sz > 0) + memset(v, 0, sz); + JL_GC_PUSH1(&v); + for (i = 0; i < np; i++) { + uint32_t ptr = jl_ptr_offset(dt, i); + jl_value_t **fld = &((jl_value_t**)data)[ptr]; + if ((char*)fld != start) + ios_readall(s->s, start, (const char*)fld - start); + *fld = jl_decode_value(s); + jl_gc_wb(v, *fld); + start = (char*)&fld[1]; + } + JL_GC_POP(); } data += jl_datatype_size(dt); if (data != start) @@ -678,7 +767,7 @@ static jl_value_t *jl_decode_value_any(jl_ircode_state *s, uint8_t tag) JL_GC_DI return v; } -static jl_value_t *jl_decode_value(jl_ircode_state *s) JL_GC_DISABLED +static jl_value_t *jl_decode_value(jl_ircode_state *s) { assert(!ios_eof(s->s)); jl_value_t *v; @@ -724,10 +813,12 @@ static jl_value_t *jl_decode_value(jl_ircode_state *s) JL_GC_DISABLED case TAG_SLOTNUMBER: v = jl_box_slotnumber(read_uint16(s->s)); return v; - case TAG_ARRAY: JL_FALLTHROUGH; case TAG_ARRAY1D: - return jl_decode_value_array(s, tag); + case TAG_ARRAY1D: + return jl_decode_value_array1d(s, tag); case TAG_MEMORYT: - return jl_decode_value_memory(s, jl_decode_value(s), jl_unbox_long(jl_decode_value(s))); + v = jl_decode_value(s); + JL_GC_PROMISE_ROOTED(v); // (JL_ALWAYS_LEAFTYPE) + return (jl_value_t*)jl_decode_value_memory(s, v, jl_unbox_long(jl_decode_value(s))); case TAG_EXPR: JL_FALLTHROUGH; case TAG_LONG_EXPR: JL_FALLTHROUGH; case TAG_CALL1: JL_FALLTHROUGH; @@ -738,27 +829,47 @@ static jl_value_t *jl_decode_value(jl_ircode_state *s) JL_GC_DISABLED case TAG_PHICNODE: JL_FALLTHROUGH; case TAG_LONG_PHICNODE: return jl_decode_value_phic(s, tag); case TAG_GOTONODE: JL_FALLTHROUGH; case TAG_QUOTENODE: + { v = jl_new_struct_uninit(tag == TAG_GOTONODE ? jl_gotonode_type : jl_quotenode_type); + JL_GC_PUSH1(&v); set_nth_field(tag == TAG_GOTONODE ? jl_gotonode_type : jl_quotenode_type, v, 0, jl_decode_value(s), 0); + JL_GC_POP(); return v; + } case TAG_GOTOIFNOT: + { v = jl_new_struct_uninit(jl_gotoifnot_type); + JL_GC_PUSH1(&v); set_nth_field(jl_gotoifnot_type, v, 0, jl_decode_value(s), 0); set_nth_field(jl_gotoifnot_type, v, 1, jl_decode_value(s), 0); + JL_GC_POP(); return v; + } case TAG_ENTERNODE: + { v = jl_new_struct_uninit(jl_enternode_type); + JL_GC_PUSH1(&v); set_nth_field(jl_enternode_type, v, 0, jl_decode_value(s), 0); set_nth_field(jl_enternode_type, v, 1, jl_decode_value(s), 0); + JL_GC_POP(); return v; + } case TAG_ARGUMENT: + { v = jl_new_struct_uninit(jl_argument_type); + JL_GC_PUSH1(&v); set_nth_field(jl_argument_type, v, 0, jl_decode_value(s), 0); + JL_GC_POP(); return v; + } case TAG_RETURNNODE: + { v = jl_new_struct_uninit(jl_returnnode_type); + JL_GC_PUSH1(&v); set_nth_field(jl_returnnode_type, v, 0, jl_decode_value(s), 0); + JL_GC_POP(); return v; + } case TAG_SHORTER_INT64: v = jl_box_int64((int16_t)read_uint16(s->s)); return v; @@ -777,9 +888,14 @@ static jl_value_t *jl_decode_value(jl_ircode_state *s) JL_GC_DISABLED case TAG_UINT8: return jl_box_uint8(read_uint8(s->s)); case TAG_NEARBYGLOBAL: - assert(s->method != NULL); + { + jl_method_t *m = s->method; + assert(m != NULL); + JL_GC_PROMISE_ROOTED(m); v = jl_decode_value(s); - return jl_module_globalref(s->method->module, (jl_sym_t*)v); + JL_GC_PROMISE_ROOTED(v); // symbol + return jl_module_globalref(m->module, (jl_sym_t*)v); + } case TAG_NEARBYMODULE: assert(s->method != NULL); return (jl_value_t*)s->method->module; @@ -792,19 +908,29 @@ static jl_value_t *jl_decode_value(jl_ircode_state *s) JL_GC_DISABLED case TAG_BASE: return (jl_value_t*)jl_base_module; case TAG_VECTORTY: + { v = jl_decode_value(s); - return jl_apply_type2((jl_value_t*)jl_array_type, v, jl_box_long(1)); + JL_GC_PUSH1(&v); + v = jl_apply_type2((jl_value_t*)jl_array_type, v, jl_box_long(1)); + JL_GC_POP(); + return v; + } case TAG_PTRTY: + { v = jl_decode_value(s); - return jl_apply_type1((jl_value_t*)jl_pointer_type, v); + JL_GC_PUSH1(&v); + v = jl_apply_type1((jl_value_t*)jl_pointer_type, v); + JL_GC_POP(); + return v; + } case TAG_STRING: n = read_int32(s->s); v = jl_alloc_string(n); ios_readall(s->s, jl_string_data(v), n); return v; default: - assert(tag == TAG_GENERAL || tag == TAG_SHORT_GENERAL); - return jl_decode_value_any(s, tag); + assert(tag == TAG_GENERAL); + return jl_decode_value_any(s); } } @@ -880,8 +1006,6 @@ JL_DLLEXPORT jl_string_t *jl_compress_ir(jl_method_t *m, jl_code_info_t *code) assert(jl_array_nrows(code->code) == codelocs_nstmts(code->debuginfo->codelocs) || jl_string_len(code->debuginfo->codelocs) == 0); ios_t dest; ios_mem(&dest, 0); - int en = jl_gc_enable(0); // Might GC - size_t i; if (m->roots == NULL) { m->roots = jl_alloc_vec_any(0); @@ -919,38 +1043,35 @@ JL_DLLEXPORT jl_string_t *jl_compress_ir(jl_method_t *m, jl_code_info_t *code) write_int32(s.s, (int32_t)nargs); } - for (i = 0; i < 5; i++) { - int copy = 1; - if (i == 1) { // skip debuginfo - assert(jl_field_offset(jl_code_info_type, i) == offsetof(jl_code_info_t, debuginfo)); - continue; - } - jl_encode_value_(&s, jl_get_nth_field((jl_value_t*)code, i), copy); - } + jl_encode_value_(&s, (jl_value_t*)code->code, 1); + jl_encode_value_(&s, (jl_value_t*)code->ssavaluetypes, 1); + jl_encode_value_(&s, (jl_value_t*)code->ssaflags, 1); // For opaque closure, also save the slottypes. We technically only need the first slot type, // but this is simpler for now. We may want to refactor where this gets stored in the future. if (m->is_for_opaque_closure) jl_encode_value_(&s, code->slottypes, 1); + jl_string_t *v = NULL; + JL_GC_PUSH1(&v); // Slotnames. For regular methods, we require that m->slot_syms matches the // CodeInfo's slotnames, so we do not need to save it here. - if (m->generator) + if (m->generator) { // can't optimize generated functions - jl_encode_value_(&s, (jl_value_t*)jl_compress_argnames(code->slotnames), 1); - else + v = jl_compress_argnames(code->slotnames); + jl_encode_value_(&s, (jl_value_t*)v, 1); + } + else { jl_encode_value(&s, jl_nothing); + } write_uint8(s.s, s.relocatability); ios_flush(s.s); - jl_string_t *v = jl_pchar_to_string(s.s->buf, s.s->size); + v = jl_pchar_to_string(s.s->buf, s.s->size); ios_close(s.s); - if (jl_array_nrows(m->roots) == 0) { + if (jl_array_nrows(m->roots) == 0) m->roots = NULL; - } - JL_GC_PUSH1(&v); - jl_gc_enable(en); JL_UNLOCK(&m->writelock); // Might GC JL_GC_POP(); @@ -965,12 +1086,10 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t JL_LOCK(&m->writelock); // protect the roots array (Might GC) assert(jl_is_method(m)); assert(jl_is_string(data)); - size_t i; ios_t src; ios_mem(&src, 0); ios_setbuf(&src, (char*)jl_string_data(data), jl_string_len(data), 0); src.size = jl_string_len(data); - int en = jl_gc_enable(0); // Might GC jl_ircode_state s = { &src, m, @@ -978,8 +1097,10 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t jl_current_task->ptls, 1 }; - jl_code_info_t *code = jl_new_code_info_uninit(); + jl_value_t *slotnames = NULL; + JL_GC_PUSH2(&code, &slotnames); + jl_code_info_flags_t flags; flags.packed = read_uint16(s.s); code->inlining = flags.bits.inlining; @@ -991,9 +1112,9 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t code->purity.bits = read_uint16(s.s); code->inlining_cost = read_uint16(s.s); - size_t nslots = read_int32(s.s); code->slotflags = jl_alloc_array_1d(jl_array_uint8_type, nslots); + jl_gc_wb(code, code->slotflags); ios_readall(s.s, jl_array_data(code->slotflags, char), nslots); if (flags.bits.nargsmatchesmethod) { @@ -1002,25 +1123,29 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t code->nargs = read_int32(s.s); } - for (i = 0; i < 5; i++) { - if (i == 1) // skip debuginfo - continue; - assert(jl_field_isptr(jl_code_info_type, i)); - jl_value_t **fld = (jl_value_t**)((char*)jl_data_ptr(code) + jl_field_offset(jl_code_info_type, i)); - *fld = jl_decode_value(&s); - } - if (m->is_for_opaque_closure) + code->code = (jl_array_t*)jl_decode_value(&s); + jl_gc_wb(code, code->code); + code->ssavaluetypes = jl_decode_value(&s); + jl_gc_wb(code, code->ssavaluetypes); + code->ssaflags = (jl_array_t*)jl_decode_value(&s); + jl_gc_wb(code, code->ssaflags); + + if (m->is_for_opaque_closure) { code->slottypes = jl_decode_value(&s); + jl_gc_wb(code, code->slottypes); + } - jl_value_t *slotnames = jl_decode_value(&s); + slotnames = jl_decode_value(&s); if (!jl_is_string(slotnames)) slotnames = m->slot_syms; code->slotnames = jl_uncompress_argnames(slotnames); + jl_gc_wb(code, code->slotnames); if (metadata) code->debuginfo = jl_atomic_load_relaxed(&metadata->debuginfo); else code->debuginfo = m->debuginfo; + jl_gc_wb(code, code->debuginfo); assert(code->debuginfo); assert(jl_array_nrows(code->code) == codelocs_nstmts(code->debuginfo->codelocs) || jl_string_len(code->debuginfo->codelocs) == 0); @@ -1029,10 +1154,7 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t assert(ios_getc(s.s) == -1); ios_close(s.s); - JL_GC_PUSH1(&code); - jl_gc_enable(en); JL_UNLOCK(&m->writelock); // Might GC - JL_GC_POP(); if (metadata) { code->parent = metadata->def; jl_gc_wb(code, code->parent); @@ -1043,6 +1165,7 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t code->edges = (jl_value_t*)s.edges; jl_gc_wb(code, s.edges); } + JL_GC_POP(); return code; } @@ -1470,7 +1593,7 @@ void jl_init_serializer(void) deser_tag[TAG_DATATYPE] = (jl_value_t*)jl_datatype_type; deser_tag[TAG_SLOTNUMBER] = (jl_value_t*)jl_slotnumber_type; deser_tag[TAG_SVEC] = (jl_value_t*)jl_simplevector_type; - deser_tag[TAG_ARRAY] = (jl_value_t*)jl_array_type; + deser_tag[TAG_ARRAY1D] = (jl_value_t*)jl_array_type; deser_tag[TAG_MEMORYT] = (jl_value_t*)jl_genericmemory_type; deser_tag[TAG_EXPR] = (jl_value_t*)jl_expr_type; deser_tag[TAG_PHINODE] = (jl_value_t*)jl_phinode_type; diff --git a/src/serialize.h b/src/serialize.h index 3aa82a1d09a9b..549c1588073ff 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -7,69 +7,6 @@ extern "C" { #endif -#define TAG_SYMBOL 2 -#define TAG_SSAVALUE 3 -#define TAG_DATATYPE 4 -#define TAG_SLOTNUMBER 5 -#define TAG_SVEC 6 -#define TAG_ARRAY 7 -#define TAG_NULL 8 -#define TAG_EXPR 9 -#define TAG_PHINODE 10 -#define TAG_PHICNODE 11 -#define TAG_LONG_SYMBOL 12 -#define TAG_LONG_SVEC 13 -#define TAG_LONG_EXPR 14 -#define TAG_LONG_PHINODE 15 -#define TAG_LONG_PHICNODE 16 -#define TAG_METHODROOT 17 -#define TAG_EDGE 18 -#define TAG_STRING 19 -#define TAG_SHORT_INT64 20 -#define TAG_SHORT_GENERAL 21 -#define TAG_CNULL 22 -#define TAG_ARRAY1D 23 -#define TAG_SINGLETON 24 -#define TAG_MODULE 25 -#define TAG_TVAR 26 -#define TAG_METHOD_INSTANCE 27 -#define TAG_METHOD 28 -#define TAG_CODE_INSTANCE 29 -#define TAG_COMMONSYM 30 -#define TAG_NEARBYGLOBAL 31 -#define TAG_GLOBALREF 32 -#define TAG_CORE 33 -#define TAG_BASE 34 -#define TAG_BITYPENAME 35 -#define TAG_NEARBYMODULE 36 -#define TAG_INT32 37 -#define TAG_INT64 38 -#define TAG_UINT8 39 -#define TAG_VECTORTY 40 -#define TAG_PTRTY 41 -#define TAG_LONG_SSAVALUE 42 -#define TAG_LONG_METHODROOT 43 -#define TAG_LONG_EDGE 44 -#define TAG_SHORTER_INT64 45 -#define TAG_SHORT_INT32 46 -#define TAG_CALL1 47 -#define TAG_CALL2 48 -#define TAG_SHORT_BACKREF 49 -#define TAG_BACKREF 50 -#define TAG_UNIONALL 51 -#define TAG_GOTONODE 52 -#define TAG_QUOTENODE 53 -#define TAG_GENERAL 54 -#define TAG_GOTOIFNOT 55 -#define TAG_RETURNNODE 56 -#define TAG_ARGUMENT 57 -#define TAG_RELOC_METHODROOT 58 -#define TAG_BINDING 59 -#define TAG_MEMORYT 60 -#define TAG_ENTERNODE 61 - -#define LAST_TAG 61 - #define write_uint8(s, n) ios_putc((n), (s)) #define read_uint8(s) ((uint8_t)ios_getc((s))) #define write_int8(s, n) write_uint8((s), (n)) @@ -137,12 +74,6 @@ static inline uint32_t read_uint32(ios_t *s) JL_NOTSAFEPOINT #define read_uint(s) read_uint32(s) #endif - -void *jl_lookup_ser_tag(jl_value_t *v); -void *jl_lookup_common_symbol(jl_value_t *v); -jl_value_t *jl_deser_tag(uint8_t tag); -jl_value_t *jl_deser_symbol(uint8_t tag); - #ifdef __cplusplus } #endif From 42e14d6983ac855726b31b753adba05aaefcf884 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Mon, 2 Dec 2024 12:32:16 -0500 Subject: [PATCH 007/198] ircode: small optimization for nearby ssavalue Since most ssavalue are used just after their def, this gives a small memory savings on compressed IR (a fraction of a percent). --- src/ircode.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/ircode.c b/src/ircode.c index d3137ce26edef..de27f8dbeefca 100644 --- a/src/ircode.c +++ b/src/ircode.c @@ -21,7 +21,7 @@ extern "C" { #define TAG_DATATYPE 4 #define TAG_SLOTNUMBER 5 #define TAG_SVEC 6 -// #define TAG_UNUSED 7 +#define TAG_NEARBYSSAVALUE 7 #define TAG_NULL 8 #define TAG_EXPR 9 #define TAG_PHINODE 10 @@ -82,6 +82,7 @@ extern "C" { typedef struct { ios_t *s; + size_t ssaid; // method we're compressing for jl_method_t *method; jl_svec_t *edges; @@ -307,6 +308,10 @@ static void jl_encode_value_(jl_ircode_state *s, jl_value_t *v, int as_literal) jl_encode_value(s, jl_globalref_name(v)); } } + else if (jl_is_ssavalue(v) && s->ssaid - ((jl_ssavalue_t*)v)->id < 256) { + write_uint8(s->s, TAG_NEARBYSSAVALUE); + write_uint8(s->s, s->ssaid - ((jl_ssavalue_t*)v)->id); + } else if (jl_is_ssavalue(v) && ((jl_ssavalue_t*)v)->id < 256 && ((jl_ssavalue_t*)v)->id >= 0) { write_uint8(s->s, TAG_SSAVALUE); write_uint8(s->s, ((jl_ssavalue_t*)v)->id); @@ -807,6 +812,9 @@ static jl_value_t *jl_decode_value(jl_ircode_state *s) case TAG_SSAVALUE: v = jl_box_ssavalue(read_uint8(s->s)); return v; + case TAG_NEARBYSSAVALUE: + v = jl_box_ssavalue(s->ssaid - read_uint8(s->s)); + return v; case TAG_LONG_SSAVALUE: v = jl_box_ssavalue(read_uint16(s->s)); return v; @@ -1014,6 +1022,7 @@ JL_DLLEXPORT jl_string_t *jl_compress_ir(jl_method_t *m, jl_code_info_t *code) jl_value_t *edges = code->edges; jl_ircode_state s = { &dest, + 0, m, (!isdef && jl_is_svec(edges)) ? (jl_svec_t*)edges : jl_emptysvec, jl_current_task->ptls, @@ -1043,7 +1052,13 @@ JL_DLLEXPORT jl_string_t *jl_compress_ir(jl_method_t *m, jl_code_info_t *code) write_int32(s.s, (int32_t)nargs); } - jl_encode_value_(&s, (jl_value_t*)code->code, 1); + size_t i, l = jl_array_dim0(code->code); + write_uint64(s.s, l); + for (i = 0; i < l; i++) { + s.ssaid = i; + jl_encode_value(&s, jl_array_ptr_ref(code->code, i)); + } + s.ssaid = 0; jl_encode_value_(&s, (jl_value_t*)code->ssavaluetypes, 1); jl_encode_value_(&s, (jl_value_t*)code->ssaflags, 1); @@ -1092,6 +1107,7 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t src.size = jl_string_len(data); jl_ircode_state s = { &src, + 0, m, metadata == NULL ? NULL : jl_atomic_load_relaxed(&metadata->edges), jl_current_task->ptls, @@ -1123,8 +1139,14 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t code->nargs = read_int32(s.s); } - code->code = (jl_array_t*)jl_decode_value(&s); + size_t i, n = read_uint64(s.s); + code->code = jl_alloc_array_1d(jl_array_any_type, n); jl_gc_wb(code, code->code); + for (i = 0; i < n; i++) { + s.ssaid = i; + jl_array_ptr_set(code->code, i, jl_decode_value(&s)); + } + s.ssaid = 0; code->ssavaluetypes = jl_decode_value(&s); jl_gc_wb(code, code->ssavaluetypes); code->ssaflags = (jl_array_t*)jl_decode_value(&s); From f1b0b010dd20591a013c71d8f3f7a09503e55baf Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Mon, 2 Dec 2024 18:02:41 -0500 Subject: [PATCH 008/198] Fix scope of hoisted signature-local variables (#56712) When we declare inner methods, e.g. the `f` in ``` function fs() f(lhs::Integer) = 1 f(lhs::Integer, rhs::(local x=Integer; x)) = 2 return f end ``` we must hoist the definition of the (appropriately mangled) generic function `f` to top-level, including all variables that were used in the signature definition of `f`. This situation is a bit unique in the language because it uses inner function scope, but gets executed in toplevel scope. For example, you're not allowed to use a local of the inner function in the signature definition: ``` julia> function fs() local x=Integer f(lhs::Integer, rhs::x) = 2 return f end ERROR: syntax: local variable x cannot be used in closure declaration Stacktrace: [1] top-level scope @ REPL[3]:1 ``` In particular, the restriction is signature-local: ``` julia> function fs() f(rhs::(local x=Integer; x)) = 1 f(lhs::Integer, rhs::x) = 2 return f end ERROR: syntax: local variable x cannot be used in closure declaration Stacktrace: [1] top-level scope @ REPL[4]:1 ``` There's a special intermediate form `moved-local` that gets generated for this definition. In c6c3d72d1cbddb3d27e0df0e739bb27dd709a413, this form stopped getting generated for certain inner methods. I suspect this happened because of the incorrect assumption that the set of moved locals is being computed over all signatures, rather than being a per-signature property. The result of all of this was that this is one of the few places where lowering still generated a symbol as the lhs of an assignment for a global (instead of globalref), because the code that generates the assignment assumes it's a local, but the later pass doesn't know this. Because we still retain the code for this from before we started using globalref consistently, this wasn't generally causing a problems, except possibly leaking a global (or potentially assigning to a global when this wasn't intended). However, in follow on work, I want to make use of knowing whether the LHS is a global or local in lowering, so this was causing me trouble. Fix all of this by putting back the `moved-local` where it was dropped. Fixes #56711 --- src/julia-syntax.scm | 1 + test/syntax.jl | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 72e97da3c2daa..852d5eb4d6f86 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -4279,6 +4279,7 @@ f(x) = yt(x) (if (or exists (and short (pair? alldefs))) `(toplevel-butfirst (null) + ,@(map (lambda (v) `(moved-local ,v)) moved-vars) ,@sp-inits ,@mk-method (latestworld)) diff --git a/test/syntax.jl b/test/syntax.jl index d9d311ac6615d..0fb752bae480f 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -4033,3 +4033,11 @@ end @test isa(create_inner_f_no_methods(), Function) @test length(methods(create_inner_f_no_methods())) == 0 @test Base.invoke_in_world(first(methods(create_inner_f_one_method)).primary_world, create_inner_f_one_method()) == 1 + +# Issue 56711 - Scope of signature hoisting +function fs56711() + f(lhs::Integer) = 1 + f(lhs::Integer, rhs::(local x_should_not_be_defined=Integer; x_should_not_be_defined)) = 2 + return f +end +@test !@isdefined(x_should_not_be_defined) From 1b37a2f9e0afc5f684e0b2a0af17cd9526aae529 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Mon, 2 Dec 2024 20:09:26 -0500 Subject: [PATCH 009/198] ircode: avoid serializing ssaflags in the common case when they are all zero When not all-zero, run-length encoding would also probably be great here for lowered code (before inference). --- Compiler/test/interpreter_exec.jl | 6 +++--- src/ircode.c | 30 +++++++++++++++++++++++------- src/julia_internal.h | 1 + 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/Compiler/test/interpreter_exec.jl b/Compiler/test/interpreter_exec.jl index 4972df1a27202..b1d450f8f4286 100644 --- a/Compiler/test/interpreter_exec.jl +++ b/Compiler/test/interpreter_exec.jl @@ -23,7 +23,7 @@ let m = Meta.@lower 1 + 1 ] nstmts = length(src.code) src.ssavaluetypes = nstmts - src.ssaflags = fill(UInt8(0x00), nstmts) + src.ssaflags = fill(zero(UInt32), nstmts) src.debuginfo = Core.DebugInfo(:none) Compiler.verify_ir(Compiler.inflate_ir(src)) global test29262 = true @@ -63,7 +63,7 @@ let m = Meta.@lower 1 + 1 ] nstmts = length(src.code) src.ssavaluetypes = nstmts - src.ssaflags = fill(UInt8(0x00), nstmts) + src.ssaflags = fill(zero(UInt32), nstmts) src.debuginfo = Core.DebugInfo(:none) m.args[1] = copy(src) Compiler.verify_ir(Compiler.inflate_ir(src)) @@ -103,7 +103,7 @@ let m = Meta.@lower 1 + 1 ] nstmts = length(src.code) src.ssavaluetypes = nstmts - src.ssaflags = fill(UInt8(0x00), nstmts) + src.ssaflags = fill(zero(UInt32), nstmts) src.debuginfo = Core.DebugInfo(:none) Compiler.verify_ir(Compiler.inflate_ir(src)) global test29262 = true diff --git a/src/ircode.c b/src/ircode.c index de27f8dbeefca..9e64e3fe2b574 100644 --- a/src/ircode.c +++ b/src/ircode.c @@ -549,7 +549,8 @@ static void jl_encode_value_(jl_ircode_state *s, jl_value_t *v, int as_literal) static jl_code_info_flags_t code_info_flags(uint8_t propagate_inbounds, uint8_t has_fcall, uint8_t nospecializeinfer, uint8_t isva, - uint8_t inlining, uint8_t constprop, uint8_t nargsmatchesmethod) + uint8_t inlining, uint8_t constprop, uint8_t nargsmatchesmethod, + jl_array_t *ssaflags) { jl_code_info_flags_t flags; flags.bits.propagate_inbounds = propagate_inbounds; @@ -559,6 +560,11 @@ static jl_code_info_flags_t code_info_flags(uint8_t propagate_inbounds, uint8_t flags.bits.inlining = inlining; flags.bits.constprop = constprop; flags.bits.nargsmatchesmethod = nargsmatchesmethod; + flags.bits.has_ssaflags = 0; + const uint32_t *ssaflag_data = jl_array_data(ssaflags, uint32_t); + for (size_t i = 0, l = jl_array_dim0(ssaflags); i < l; i++) + if (ssaflag_data[i]) + flags.bits.has_ssaflags = 1; return flags; } @@ -1033,7 +1039,8 @@ JL_DLLEXPORT jl_string_t *jl_compress_ir(jl_method_t *m, jl_code_info_t *code) jl_code_info_flags_t flags = code_info_flags(code->propagate_inbounds, code->has_fcall, code->nospecializeinfer, code->isva, code->inlining, code->constprop, - nargsmatchesmethod); + nargsmatchesmethod, + code->ssaflags); write_uint16(s.s, checked_size(flags.packed, IR_DATASIZE_FLAGS)); write_uint16(s.s, checked_size(code->purity.bits, IR_DATASIZE_PURITY)); write_uint16(s.s, checked_size(code->inlining_cost, IR_DATASIZE_INLINING_COST)); @@ -1060,7 +1067,11 @@ JL_DLLEXPORT jl_string_t *jl_compress_ir(jl_method_t *m, jl_code_info_t *code) } s.ssaid = 0; jl_encode_value_(&s, (jl_value_t*)code->ssavaluetypes, 1); - jl_encode_value_(&s, (jl_value_t*)code->ssaflags, 1); + assert(jl_typetagis(code->ssaflags, jl_array_uint32_type)); + assert(jl_array_dim0(code->ssaflags) == l); + const uint32_t *ssaflags_data = jl_array_data(code->ssaflags, uint32_t); + if (flags.bits.has_ssaflags) + ios_write(s.s, (const char*)ssaflags_data, l * sizeof(*ssaflags_data)); // For opaque closure, also save the slottypes. We technically only need the first slot type, // but this is simpler for now. We may want to refactor where this gets stored in the future. @@ -1139,18 +1150,23 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t code->nargs = read_int32(s.s); } - size_t i, n = read_uint64(s.s); - code->code = jl_alloc_array_1d(jl_array_any_type, n); + size_t i, l = read_uint64(s.s); + code->code = jl_alloc_array_1d(jl_array_any_type, l); jl_gc_wb(code, code->code); - for (i = 0; i < n; i++) { + for (i = 0; i < l; i++) { s.ssaid = i; jl_array_ptr_set(code->code, i, jl_decode_value(&s)); } s.ssaid = 0; code->ssavaluetypes = jl_decode_value(&s); jl_gc_wb(code, code->ssavaluetypes); - code->ssaflags = (jl_array_t*)jl_decode_value(&s); + code->ssaflags = jl_alloc_array_1d(jl_array_uint32_type, l); jl_gc_wb(code, code->ssaflags); + uint32_t *ssaflags_data = jl_array_data(code->ssaflags, uint32_t); + if (flags.bits.has_ssaflags) + ios_readall(s.s, (char*)ssaflags_data, l * sizeof(*ssaflags_data)); + else + memset(ssaflags_data, 0, l * sizeof(*ssaflags_data)); if (m->is_for_opaque_closure) { code->slottypes = jl_decode_value(&s); diff --git a/src/julia_internal.h b/src/julia_internal.h index e081c94329deb..2178f603441e0 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -651,6 +651,7 @@ typedef struct { uint16_t nargsmatchesmethod:1; uint16_t inlining:2; // 0 = use heuristic; 1 = aggressive; 2 = none uint16_t constprop:2; // 0 = use heuristic; 1 = aggressive; 2 = none + uint16_t has_ssaflags:1; } jl_code_info_flags_bitfield_t; typedef union { From efa917e8775cd40fdd74b657d1e5d2db2342cd07 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Mon, 2 Dec 2024 20:28:05 -0500 Subject: [PATCH 010/198] Extend `invoke` to accept CodeInstance (#56660) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is an alternative mechanism to #56650 that largely achieves the same result, but by hooking into `invoke` rather than a generated function. They are orthogonal mechanisms, and its possible we want both. However, in #56650, both Jameson and Valentin were skeptical of the generated function signature bottleneck. This PR is sort of a hybrid of mechanism in #52964 and what I proposed in https://github.com/JuliaLang/julia/pull/56650#issuecomment-2493800877. In particular, this PR: 1. Extends `invoke` to support a CodeInstance in place of its usual `types` argument. 2. Adds a new `typeinf` optimized generic. The semantics of this optimized generic allow the compiler to instead call a companion `typeinf_edge` function, allowing a mid-inference interpreter switch (like #52964), without being forced through a concrete signature bottleneck. However, if calling `typeinf_edge` does not work (e.g. because the compiler version is mismatched), this still has well defined semantics, you just don't get inference support. The additional benefit of the `typeinf` optimized generic is that it lets custom cache owners tell the runtime how to "cure" code instances that have lost their native code. Currently the runtime only knows how to do that for `owner == nothing` CodeInstances (by re-running inference). This extension is not implemented, but the idea is that the runtime would be permitted to call the `typeinf` optimized generic on the dead CodeInstance's `owner` and `def` fields to obtain a cured CodeInstance (or a user-actionable error from the plugin). This PR includes an implementation of `with_new_compiler` from #56650. This PR includes just enough compiler support to make the compiler optimize this to the same code that #56650 produced: ``` julia> @code_typed with_new_compiler(sin, 1.0) CodeInfo( 1 ─ $(Expr(:foreigncall, :(:jl_get_tls_world_age), UInt64, svec(), 0, :(:ccall)))::UInt64 │ %2 = builtin Core.getfield(args, 1)::Float64 │ %3 = invoke sin(%2::Float64)::Float64 └── return %3 ) => Float64 ``` However, the implementation here is extremely incomplete. I'm putting it up only as a directional sketch to see if people prefer it over #56650. If so, I would prepare a cleaned up version of this PR that has the optimized generics as well as the curing support, but not the full inference integration (which needs a fair bit more work). --- .../extras/CompilerDevTools/Manifest.toml | 15 +++++ Compiler/extras/CompilerDevTools/Project.toml | 5 ++ .../CompilerDevTools/src/CompilerDevTools.jl | 56 +++++++++++++++++++ Compiler/src/abstractinterpretation.jl | 48 +++++++++++++--- Compiler/src/abstractlattice.jl | 2 +- Compiler/src/bootstrap.jl | 10 +++- Compiler/src/stmtinfo.jl | 11 ++++ Compiler/src/utilities.jl | 4 +- NEWS.md | 2 + base/docs/basedocs.jl | 17 ++++++ base/optimized_generics.jl | 27 +++++++++ src/builtins.c | 22 ++++++++ src/interpreter.c | 24 +++++++- test/core.jl | 14 +++++ 14 files changed, 242 insertions(+), 15 deletions(-) create mode 100644 Compiler/extras/CompilerDevTools/Manifest.toml create mode 100644 Compiler/extras/CompilerDevTools/Project.toml create mode 100644 Compiler/extras/CompilerDevTools/src/CompilerDevTools.jl diff --git a/Compiler/extras/CompilerDevTools/Manifest.toml b/Compiler/extras/CompilerDevTools/Manifest.toml new file mode 100644 index 0000000000000..bcc78f1ded34a --- /dev/null +++ b/Compiler/extras/CompilerDevTools/Manifest.toml @@ -0,0 +1,15 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.0-DEV" +manifest_format = "2.0" +project_hash = "84f495a1bf065c95f732a48af36dd0cd2cefb9d5" + +[[deps.Compiler]] +path = "../.." +uuid = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1" +version = "0.0.2" + +[[deps.CompilerDevTools]] +path = "." +uuid = "92b2d91f-d2bd-4c05-9214-4609ac33433f" +version = "0.0.0" diff --git a/Compiler/extras/CompilerDevTools/Project.toml b/Compiler/extras/CompilerDevTools/Project.toml new file mode 100644 index 0000000000000..a2749a9a56a84 --- /dev/null +++ b/Compiler/extras/CompilerDevTools/Project.toml @@ -0,0 +1,5 @@ +name = "CompilerDevTools" +uuid = "92b2d91f-d2bd-4c05-9214-4609ac33433f" + +[deps] +Compiler = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1" diff --git a/Compiler/extras/CompilerDevTools/src/CompilerDevTools.jl b/Compiler/extras/CompilerDevTools/src/CompilerDevTools.jl new file mode 100644 index 0000000000000..cd3f7b7b4bdac --- /dev/null +++ b/Compiler/extras/CompilerDevTools/src/CompilerDevTools.jl @@ -0,0 +1,56 @@ +module CompilerDevTools + +using Compiler +using Core.IR + +struct SplitCacheOwner; end +struct SplitCacheInterp <: Compiler.AbstractInterpreter + world::UInt + inf_params::Compiler.InferenceParams + opt_params::Compiler.OptimizationParams + inf_cache::Vector{Compiler.InferenceResult} + function SplitCacheInterp(; + world::UInt = Base.get_world_counter(), + inf_params::Compiler.InferenceParams = Compiler.InferenceParams(), + opt_params::Compiler.OptimizationParams = Compiler.OptimizationParams(), + inf_cache::Vector{Compiler.InferenceResult} = Compiler.InferenceResult[]) + new(world, inf_params, opt_params, inf_cache) + end +end + +Compiler.InferenceParams(interp::SplitCacheInterp) = interp.inf_params +Compiler.OptimizationParams(interp::SplitCacheInterp) = interp.opt_params +Compiler.get_inference_world(interp::SplitCacheInterp) = interp.world +Compiler.get_inference_cache(interp::SplitCacheInterp) = interp.inf_cache +Compiler.cache_owner(::SplitCacheInterp) = SplitCacheOwner() + +import Core.OptimizedGenerics.CompilerPlugins: typeinf, typeinf_edge +@eval @noinline typeinf(::SplitCacheOwner, mi::MethodInstance, source_mode::UInt8) = + Base.invoke_in_world(which(typeinf, Tuple{SplitCacheOwner, MethodInstance, UInt8}).primary_world, Compiler.typeinf_ext, SplitCacheInterp(; world=Base.tls_world_age()), mi, source_mode) + +@eval @noinline function typeinf_edge(::SplitCacheOwner, mi::MethodInstance, parent_frame::Compiler.InferenceState, world::UInt, source_mode::UInt8) + # TODO: This isn't quite right, we're just sketching things for now + interp = SplitCacheInterp(; world) + Compiler.typeinf_edge(interp, mi.def, mi.specTypes, Core.svec(), parent_frame, false, false) +end + +# TODO: This needs special compiler support to properly case split for multiple +# method matches, etc. +@noinline function mi_for_tt(tt, world=Base.tls_world_age()) + interp = SplitCacheInterp(; world) + match, _ = Compiler.findsup(tt, Compiler.method_table(interp)) + Base.specialize_method(match) +end + +function with_new_compiler(f, args...) + tt = Base.signature_type(f, typeof(args)) + world = Base.tls_world_age() + new_compiler_ci = Core.OptimizedGenerics.CompilerPlugins.typeinf( + SplitCacheOwner(), mi_for_tt(tt), Compiler.SOURCE_MODE_ABI + ) + invoke(f, new_compiler_ci, args...) +end + +export with_new_compiler + +end diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 5946adf80ad52..ffb4f4312cdcf 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -2218,16 +2218,46 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt ft = widenconst(ft′) ft === Bottom && return Future(CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo())) types = argtype_by_index(argtypes, 3) - if types isa Const && types.val isa Method - method = types.val::Method - types = method # argument value - lookupsig = method.sig # edge kind - argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft)) - nargtype = typeintersect(lookupsig, argtype) - nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())) - nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below + if types isa Const && types.val isa Union{Method, CodeInstance} + method_or_ci = types.val + if isa(method_or_ci, CodeInstance) + our_world = sv.world.this + argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft)) + sig = method_or_ci.def.specTypes + exct = method_or_ci.exctype + if !hasintersect(argtype, sig) + return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())) + elseif !(argtype <: sig) + exct = Union{exct, TypeError} + end + callee_valid_range = WorldRange(method_or_ci.min_world, method_or_ci.max_world) + if !(our_world in callee_valid_range) + if our_world < first(callee_valid_range) + update_valid_age!(sv, WorldRange(first(sv.world.valid_worlds), first(callee_valid_range)-1)) + else + update_valid_age!(sv, WorldRange(last(callee_valid_range)+1, last(sv.world.valid_worlds))) + end + return Future(CallMeta(Bottom, ErrorException, EFFECTS_THROWS, NoCallInfo())) + end + # TODO: When we add curing, we may want to assume this is nothrow + if (method_or_ci.owner === Nothing && method_ir_ci.def.def isa Method) + exct = Union{exct, ErrorException} + end + update_valid_age!(sv, callee_valid_range) + return Future(CallMeta(method_or_ci.rettype, exct, Effects(decode_effects(method_or_ci.ipo_purity_bits), nothrow=(exct===Bottom)), + InvokeCICallInfo(method_or_ci))) + else + method = method_or_ci::Method + types = method # argument value + lookupsig = method.sig # edge kind + argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft)) + nargtype = typeintersect(lookupsig, argtype) + nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())) + nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below + # Fall through to generic invoke handling + end else - widenconst(types) >: Method && return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) + widenconst(types) >: Union{Method, CodeInstance} && return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) (types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3), false) isexact || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) unwrapped = unwrap_unionall(types) diff --git a/Compiler/src/abstractlattice.jl b/Compiler/src/abstractlattice.jl index c1f3050739170..7a9cff8918175 100644 --- a/Compiler/src/abstractlattice.jl +++ b/Compiler/src/abstractlattice.jl @@ -229,7 +229,7 @@ end if isa(t, Const) # don't consider mutable values useful constants val = t.val - return isa(val, Symbol) || isa(val, Type) || isa(val, Method) || !ismutable(val) + return isa(val, Symbol) || isa(val, Type) || isa(val, Method) || isa(val, CodeInstance) || !ismutable(val) end isa(t, PartialTypeVar) && return false # this isn't forwardable return is_const_prop_profitable_arg(widenlattice(𝕃), t) diff --git a/Compiler/src/bootstrap.jl b/Compiler/src/bootstrap.jl index 7ee439cc7ac67..475c53e317152 100644 --- a/Compiler/src/bootstrap.jl +++ b/Compiler/src/bootstrap.jl @@ -5,7 +5,15 @@ # especially try to make sure any recursive and leaf functions have concrete signatures, # since we won't be able to specialize & infer them at runtime -activate_codegen!() = ccall(:jl_set_typeinf_func, Cvoid, (Any,), typeinf_ext_toplevel) +function activate_codegen!() + ccall(:jl_set_typeinf_func, Cvoid, (Any,), typeinf_ext_toplevel) + Core.eval(Compiler, quote + let typeinf_world_age = Base.tls_world_age() + @eval Core.OptimizedGenerics.CompilerPlugins.typeinf(::Nothing, mi::MethodInstance, source_mode::UInt8) = + Base.invoke_in_world($(Expr(:$, :typeinf_world_age)), typeinf_ext_toplevel, mi, Base.tls_world_age(), source_mode) + end + end) +end function bootstrap!() let time() = ccall(:jl_clock_now, Float64, ()) diff --git a/Compiler/src/stmtinfo.jl b/Compiler/src/stmtinfo.jl index 830bfa02d2d99..9f0f1f38d4c8a 100644 --- a/Compiler/src/stmtinfo.jl +++ b/Compiler/src/stmtinfo.jl @@ -268,6 +268,17 @@ end add_edges_impl(edges::Vector{Any}, info::UnionSplitApplyCallInfo) = for split in info.infos; add_edges!(edges, split); end +""" + info::InvokeCICallInfo + +Represents a resolved call to `Core.invoke` targeting a `Core.CodeInstance` +""" +struct InvokeCICallInfo <: CallInfo + edge::CodeInstance +end +add_edges_impl(edges::Vector{Any}, info::InvokeCICallInfo) = + add_one_edge!(edges, info.edge) + """ info::InvokeCallInfo diff --git a/Compiler/src/utilities.jl b/Compiler/src/utilities.jl index 29f3dfa4afd4a..da20f9aafbfb2 100644 --- a/Compiler/src/utilities.jl +++ b/Compiler/src/utilities.jl @@ -54,8 +54,8 @@ function count_const_size(@nospecialize(x), count_self::Bool = true) # No definite size (isa(x, GenericMemory) || isa(x, String) || isa(x, SimpleVector)) && return MAX_INLINE_CONST_SIZE + 1 - if isa(x, Module) || isa(x, Method) - # We allow modules and methods, because we already assume they are externally + if isa(x, Module) || isa(x, Method) || isa(x, CodeInstance) + # We allow modules, methods and CodeInstance, because we already assume they are externally # rooted, so we count their contents as 0 size. return sizeof(Ptr{Cvoid}) end diff --git a/NEWS.md b/NEWS.md index c1d5f38f337b0..b77a786c24823 100644 --- a/NEWS.md +++ b/NEWS.md @@ -103,6 +103,8 @@ New library features * New `ltruncate`, `rtruncate` and `ctruncate` functions for truncating strings to text width, accounting for char widths ([#55351]) * `isless` (and thus `cmp`, sorting, etc.) is now supported for zero-dimensional `AbstractArray`s ([#55772]) * `invoke` now supports passing a Method instead of a type signature making this interface somewhat more flexible for certain uncommon use cases ([#56692]). +* `invoke` now supports passing a CodeInstance instead of a type, which can enable +certain compiler plugin workflows ([#56660]). Standard library changes ------------------------ diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index 5119ceaf2164a..141950f5e92ff 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -2031,6 +2031,7 @@ applicable """ invoke(f, argtypes::Type, args...; kwargs...) invoke(f, argtypes::Method, args...; kwargs...) + invoke(f, argtypes::CodeInstance, args...; kwargs...) Invoke a method for the given generic function `f` matching the specified types `argtypes` on the specified arguments `args` and passing the keyword arguments `kwargs`. The arguments `args` must @@ -2056,6 +2057,22 @@ Note in particular that the specified `Method` may be entirely unreachable from If the method is part of the ordinary method table, this call behaves similar to `invoke(f, method.sig, args...)`. +!!! compat "Julia 1.12" + Passing a `Method` requires Julia 1.12. + +# Passing a `CodeInstance` instead of a signature +The `argtypes` argument may be a `CodeInstance`, bypassing both method lookup and specialization. +The semantics of this invocation are similar to a function pointer call of the `CodeInstance`'s +`invoke` pointer. It is an error to invoke a `CodeInstance` with arguments that do not match its +parent MethodInstance or from a world age not included in the `min_world`/`max_world` range. +It is undefined behavior to invoke a CodeInstance whose behavior does not match the constraints +specified in its fields. For some code instances with `owner !== nothing` (i.e. those generated +by external compilers), it may be an error to invoke them after passing through precompilation. +This is an advanced interface intended for use with external compiler plugins. + +!!! compat "Julia 1.12" + Passing a `CodeInstance` requires Julia 1.12. + # Examples ```jldoctest julia> f(x::Real) = x^2; diff --git a/base/optimized_generics.jl b/base/optimized_generics.jl index 86b54a294564d..c0b953777ca94 100644 --- a/base/optimized_generics.jl +++ b/base/optimized_generics.jl @@ -54,4 +54,31 @@ module KeyValue function get end end +# Compiler-recognized intrinsics for compiler plugins +""" + module CompilerPlugins + +Implements a pair of functions `typeinf`/`typeinf_edge`. When the optimizer sees +a call to `typeinf`, it has license to instead call `typeinf_edge`, supplying the +current inference stack in `parent_frame` (but otherwise supplying the arguments +to `typeinf`). typeinf_edge will return the `CodeInstance` that `typeinf` would +have returned at runtime. The optimizer may perform a non-IPO replacement of +the call to `typeinf` by the result of `typeinf_edge`. In addition, the IPO-safe +fields of the `CodeInstance` may be propagated in IPO mode. +""" +module CompilerPlugins + """ + typeinf(owner, mi, source_mode)::CodeInstance + + Return a `CodeInstance` for the given `mi` whose valid results include at + the least current tls world and satisfies the requirements of `source_mode`. + """ + function typeinf end + + """ + typeinf_edge(owner, mi, parent_frame, world, abi_mode)::CodeInstance + """ + function typeinf_edge end +end + end diff --git a/src/builtins.c b/src/builtins.c index c6b0bf130550b..3f555da9d2a83 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1587,6 +1587,28 @@ JL_CALLABLE(jl_f_invoke) if (!jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)m->sig)) jl_type_error("invoke: argument type error", argtypes, arg_tuple(args[0], &args[2], nargs - 1)); return jl_gf_invoke_by_method(m, args[0], &args[2], nargs - 1); + } else if (jl_is_code_instance(argtypes)) { + jl_code_instance_t *codeinst = (jl_code_instance_t*)args[1]; + jl_callptr_t invoke = jl_atomic_load_acquire(&codeinst->invoke); + if (jl_tuple1_isa(args[0], &args[2], nargs - 2, (jl_datatype_t*)codeinst->def->specTypes)) { + jl_type_error("invoke: argument type error", codeinst->def->specTypes, arg_tuple(args[0], &args[2], nargs - 2)); + } + if (jl_atomic_load_relaxed(&codeinst->min_world) > jl_current_task->world_age || + jl_current_task->world_age > jl_atomic_load_relaxed(&codeinst->max_world)) { + jl_error("invoke: CodeInstance not valid for this world"); + } + if (!invoke) { + jl_compile_codeinst(codeinst); + invoke = jl_atomic_load_acquire(&codeinst->invoke); + } + if (invoke) { + return invoke(args[0], &args[2], nargs - 2, codeinst); + } else { + if (codeinst->owner != jl_nothing || !jl_is_method(codeinst->def->def.value)) { + jl_error("Failed to invoke or compile external codeinst"); + } + return jl_gf_invoke_by_method(codeinst->def->def.method, args[0], &args[2], nargs - 1); + } } if (!jl_is_tuple_type(jl_unwrap_unionall(argtypes))) jl_type_error("invoke", (jl_value_t*)jl_anytuple_type_type, argtypes); diff --git a/src/interpreter.c b/src/interpreter.c index 49a3afed14f0c..2dc1c9ed5a0c4 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -137,8 +137,28 @@ static jl_value_t *do_invoke(jl_value_t **args, size_t nargs, interpreter_state argv[i-1] = eval_value(args[i], s); jl_value_t *c = args[0]; assert(jl_is_code_instance(c) || jl_is_method_instance(c)); - jl_method_instance_t *meth = jl_is_method_instance(c) ? (jl_method_instance_t*)c : ((jl_code_instance_t*)c)->def; - jl_value_t *result = jl_invoke(argv[0], nargs == 2 ? NULL : &argv[1], nargs - 2, meth); + jl_value_t *result = NULL; + if (jl_is_code_instance(c)) { + jl_code_instance_t *codeinst = (jl_code_instance_t*)c; + assert(jl_atomic_load_relaxed(&codeinst->min_world) <= jl_current_task->world_age && + jl_current_task->world_age <= jl_atomic_load_relaxed(&codeinst->max_world)); + jl_callptr_t invoke = jl_atomic_load_acquire(&codeinst->invoke); + if (!invoke) { + jl_compile_codeinst(codeinst); + invoke = jl_atomic_load_acquire(&codeinst->invoke); + } + if (invoke) { + result = invoke(argv[0], nargs == 2 ? NULL : &argv[1], nargs - 2, codeinst); + + } else { + if (codeinst->owner != jl_nothing) { + jl_error("Failed to invoke or compile external codeinst"); + } + result = jl_invoke(argv[0], nargs == 2 ? NULL : &argv[1], nargs - 2, codeinst->def); + } + } else { + result = jl_invoke(argv[0], nargs == 2 ? NULL : &argv[1], nargs - 2, (jl_method_instance_t*)c); + } JL_GC_POP(); return result; } diff --git a/test/core.jl b/test/core.jl index 39d02d5d567c9..63952e8728e1e 100644 --- a/test/core.jl +++ b/test/core.jl @@ -8353,9 +8353,23 @@ end @test eval(Expr(:toplevel, :(@define_call(f_macro_defined1)))) == 1 @test @define_call(f_macro_defined2) == 1 +# `invoke` of `Method` let m = which(+, (Int, Int)) @eval f56692(i) = invoke(+, $m, i, 4) global g56692() = f56692(5) == 9 ? "true" : false end @test @inferred(f56692(3)) == 7 @test @inferred(g56692()) == "true" + +# `invoke` of `CodeInstance` +f_invalidate_me() = return 1 +f_invoke_me() = return f_invalidate_me() +@test f_invoke_me() == 1 +const f_invoke_me_ci = Base.specialize_method(Base._which(Tuple{typeof(f_invoke_me)})).cache +f_call_me() = invoke(f_invoke_me, f_invoke_me_ci) +@test invoke(f_invoke_me, f_invoke_me_ci) == 1 +@test f_call_me() == 1 +@test_throws TypeError invoke(f_invoke_me, f_invoke_me_ci, 1) +f_invalidate_me() = 2 +@test_throws ErrorException invoke(f_invoke_me, f_invoke_me_ci) +@test_throws ErrorException f_call_me() From ba8290ea4cf47abd69ff45d2e011259dca161ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1ll=20Haraldsson?= Date: Tue, 3 Dec 2024 01:46:24 +0000 Subject: [PATCH 011/198] Update references to LTS from v1.6 to v1.10 (#56729) --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fd7f1c89420d6..9a3fe2cd441b3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -278,8 +278,8 @@ Be sure to change the UUID value back before making the pull request. The process of [creating a patch release](https://docs.julialang.org/en/v1/devdocs/build/distributing/#Point-releasing-101) is roughly as follows: -1. Create a new branch (e.g. `backports-release-1.6`) against the relevant minor release - branch (e.g. `release-1.6`). Usually a corresponding pull request is created as well. +1. Create a new branch (e.g. `backports-release-1.10`) against the relevant minor release + branch (e.g. `release-1.10`). Usually a corresponding pull request is created as well. 2. Add commits, nominally from `master` (hence "backports"), to that branch. See below for more information on this process. @@ -291,8 +291,8 @@ The process of [creating a patch release](https://docs.julialang.org/en/v1/devdo the pull request associated with the backports branch. Fix any issues. 4. Once all test and benchmark reports look good, merge the backports branch into - the corresponding release branch (e.g. merge `backports-release-1.6` into - `release-1.6`). + the corresponding release branch (e.g. merge `backports-release-1.10` into + `release-1.10`). 5. Open a pull request that bumps the version of the relevant minor release to the next patch version, e.g. as in [this pull request](https://github.com/JuliaLang/julia/pull/37718). From 2c87290f2e7d5c057d1f4bdce9c5568c01f31d69 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Tue, 3 Dec 2024 01:19:03 -0500 Subject: [PATCH 012/198] lowering: Canonicalize to builtins for global assignment (#56713) This adjusts lowering to emit `setglobal!` for assignment to globals, thus making the `=` expr head used only for slots in `CodeInfo` and entirely absent in `IRCode`. The primary reason for this is just to reduce the number of special cases that compiler passes have to reason about. In IRCode, `=` was already essentially equivalent to `setglobal!`, so there's no good reason not to canonicalize. Finally, the `=` syntax form for globals already gets recognized specially to insert `convert` calls to their declared binding type, so this doesn't impose any additional requirements on lowering to distinguish local from global assignments. In general, I'd also like to separate syntax and intermediate forms as much as possible where their semantics differ, which this accomplises by just using the builtin. This change is mostly semantically invisible, except that spliced-in GlobalRefs now declare their binding because they are indistinguishable from ordinary assignments at the stage where I inserted the lowering. If we want to, we can preserve the difference, but it'd be a bit more annoying for not much benefit, because: 1. The spliced in version was only recently made to work anyway, and 2. The semantics of when exactly bindings are declared is still messy on master anyway and will get tweaked shortly in further binding partitions work. --- Compiler/src/abstractinterpretation.jl | 8 +------- Compiler/src/optimize.jl | 11 +---------- Compiler/src/ssair/EscapeAnalysis.jl | 12 ------------ Compiler/src/ssair/verify.jl | 10 ++-------- Compiler/test/inline.jl | 2 +- src/interpreter.c | 24 +++++------------------- src/julia-syntax.scm | 14 ++++++++++---- test/syntax.jl | 5 +++-- 8 files changed, 23 insertions(+), 63 deletions(-) diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index ffb4f4312cdcf..24daaf1e6f626 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -4050,13 +4050,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState, nextr end effects === nothing || merge_override_effects!(interp, effects, frame) if lhs !== nothing && rt !== Bottom - if isa(lhs, SlotNumber) - changes = StateUpdate(lhs, VarState(rt, false)) - elseif isa(lhs, GlobalRef) - handle_global_assignment!(interp, frame, currsaw_latestworld, lhs, rt) - else - merge_effects!(interp, frame, EFFECTS_UNKNOWN) - end + changes = StateUpdate(lhs::SlotNumber, VarState(rt, false)) end end if !has_curr_ssaflag(frame, IR_FLAG_NOTHROW) diff --git a/Compiler/src/optimize.jl b/Compiler/src/optimize.jl index d2dfd26bfa00d..856e64e404388 100644 --- a/Compiler/src/optimize.jl +++ b/Compiler/src/optimize.jl @@ -1408,16 +1408,7 @@ function statement_cost(ex::Expr, line::Int, src::Union{CodeInfo, IRCode}, sptyp extyp = line == -1 ? Any : argextype(SSAValue(line), src, sptypes) return extyp === Union{} ? 0 : UNKNOWN_CALL_COST elseif head === :(=) - if ex.args[1] isa GlobalRef - cost = UNKNOWN_CALL_COST - else - cost = 0 - end - a = ex.args[2] - if a isa Expr - cost = plus_saturate(cost, statement_cost(a, -1, src, sptypes, params)) - end - return cost + return statement_cost(ex.args[2], -1, src, sptypes, params) elseif head === :copyast return 100 end diff --git a/Compiler/src/ssair/EscapeAnalysis.jl b/Compiler/src/ssair/EscapeAnalysis.jl index 47a7840628bb5..4f32550d056b2 100644 --- a/Compiler/src/ssair/EscapeAnalysis.jl +++ b/Compiler/src/ssair/EscapeAnalysis.jl @@ -642,13 +642,6 @@ function analyze_escapes(ir::IRCode, nargs::Int, 𝕃ₒ::AbstractLattice, get_e escape_invoke!(astate, pc, stmt.args) elseif head === :new || head === :splatnew escape_new!(astate, pc, stmt.args) - elseif head === :(=) - lhs, rhs = stmt.args - if isa(lhs, GlobalRef) # global store - add_escape_change!(astate, rhs, ⊤) - else - unexpected_assignment!(ir, pc) - end elseif head === :foreigncall escape_foreigncall!(astate, pc, stmt.args) elseif head === :throw_undef_if_not # XXX when is this expression inserted ? @@ -981,11 +974,6 @@ function escape_unanalyzable_obj!(astate::AnalysisState, @nospecialize(obj), obj return objinfo end -@noinline function unexpected_assignment!(ir::IRCode, pc::Int) - @eval Main (ir = $ir; pc = $pc) - error("unexpected assignment found: inspect `Main.pc` and `Main.pc`") -end - is_nothrow(ir::IRCode, pc::Int) = has_flag(ir[SSAValue(pc)], IR_FLAG_NOTHROW) # NOTE if we don't maintain the alias set that is separated from the lattice state, we can do diff --git a/Compiler/src/ssair/verify.jl b/Compiler/src/ssair/verify.jl index 59051058e1750..072a564a31f78 100644 --- a/Compiler/src/ssair/verify.jl +++ b/Compiler/src/ssair/verify.jl @@ -363,14 +363,8 @@ function verify_ir(ir::IRCode, print::Bool=true, isforeigncall = false if isa(stmt, Expr) if stmt.head === :(=) - if stmt.args[1] isa SSAValue - @verify_error "SSAValue as assignment LHS" - raise_error() - end - if stmt.args[2] isa GlobalRef - # undefined GlobalRef as assignment RHS is OK - continue - end + @verify_error "Assignment should have been removed during SSA conversion" + raise_error() elseif stmt.head === :isdefined if length(stmt.args) > 2 || (length(stmt.args) == 2 && !isa(stmt.args[2], Bool)) @verify_error "malformed isdefined" diff --git a/Compiler/test/inline.jl b/Compiler/test/inline.jl index 46b78db3b781c..5f95fb761859e 100644 --- a/Compiler/test/inline.jl +++ b/Compiler/test/inline.jl @@ -2111,7 +2111,7 @@ for run_finalizer_escape_test in (run_finalizer_escape_test1, run_finalizer_esca global finalizer_escape::Int = 0 let src = code_typed1(run_finalizer_escape_test, Tuple{Bool, Bool}) - @test any(x->isexpr(x, :(=)), src.code) + @test any(iscall((src, Core.setglobal!)), src.code) end let diff --git a/src/interpreter.c b/src/interpreter.c index 2dc1c9ed5a0c4..fa4fba94a60a5 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -589,25 +589,11 @@ static jl_value_t *eval_body(jl_array_t *stmts, interpreter_state *s, size_t ip, s->locals[n - 1] = rhs; } else { - jl_module_t *modu; - jl_sym_t *sym; - // Plain assignment is allowed to create bindings at - // toplevel and only for the current module - int alloc = toplevel; - if (jl_is_globalref(lhs)) { - modu = jl_globalref_mod(lhs); - sym = jl_globalref_name(lhs); - alloc &= modu == s->module; - } - else { - assert(jl_is_symbol(lhs)); - modu = s->module; - sym = (jl_sym_t*)lhs; - } - JL_GC_PUSH1(&rhs); - jl_binding_t *b = jl_get_binding_wr(modu, sym, alloc); - jl_checked_assignment(b, modu, sym, rhs); - JL_GC_POP(); + // This is an unmodeled error. Our frontend only generates + // legal `=` expressions, but since GlobalRef used to be legal + // here, give a loud error in case any package is modifying + // internals. + jl_error("Invalid IR: Assignment LHS not a Slot"); } } else if (head == jl_leave_sym) { diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 852d5eb4d6f86..c7ca5d553bb31 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -4607,14 +4607,20 @@ f(x) = yt(x) (cdr cnd) (list cnd)))))) tests)) + (define (emit-assignment-or-setglobal lhs rhs) + (if (globalref? lhs) + (begin + (emit `(global ,lhs)) + (emit `(call (top setglobal!) ,(cadr lhs) (inert ,(caddr lhs)) ,rhs))) + (emit `(= ,lhs ,rhs)))) (define (emit-assignment lhs rhs) (if rhs (if (valid-ir-rvalue? lhs rhs) - (emit `(= ,lhs ,rhs)) + (emit-assignment-or-setglobal lhs rhs) (let ((rr (make-ssavalue))) (emit `(= ,rr ,rhs)) - (emit `(= ,lhs ,rr)))) - (emit `(= ,lhs (null)))) ; in unreachable code (such as after return), still emit the assignment so that the structure of those uses is preserved + (emit-assignment-or-setglobal lhs rr))) + (emit-assignment-or-setglobal lhs `(null))) ; in unreachable code (such as after return), still emit the assignment so that the structure of those uses is preserved #f) ;; the interpreter loop. `break-labels` keeps track of the labels to jump to ;; for all currently closing break-blocks. @@ -4693,7 +4699,7 @@ f(x) = yt(x) rhs (make-ssavalue)))) (if (not (eq? rr rhs)) (emit `(= ,rr ,rhs))) - (emit `(= ,lhs ,rr)) + (emit-assignment-or-setglobal lhs rr) (if tail (emit-return tail rr)) rr) (emit-assignment lhs rhs)))))) diff --git a/test/syntax.jl b/test/syntax.jl index 0fb752bae480f..315f2d8b0f38b 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -3713,7 +3713,7 @@ end module Foreign54607 # Syntactic, not dynamic try_to_create_binding1() = (Foreign54607.foo = 2) - # GlobalRef is allowed for same-module assignment + # GlobalRef is allowed for same-module assignment and declares the binding @eval try_to_create_binding2() = ($(GlobalRef(Foreign54607, :foo2)) = 2) function global_create_binding() global bar @@ -3728,7 +3728,7 @@ module Foreign54607 end @test_throws ErrorException (Foreign54607.foo = 1) @test_throws ErrorException Foreign54607.try_to_create_binding1() -@test_throws ErrorException Foreign54607.try_to_create_binding2() +Foreign54607.try_to_create_binding2() function assign_in_foreign_module() (Foreign54607.foo = 1) nothing @@ -3744,6 +3744,7 @@ Foreign54607.global_create_binding() @test isdefined(Foreign54607, :baz) @test isdefined(Foreign54607, :compiled_assign) @test isdefined(Foreign54607, :gr_assign) +@test isdefined(Foreign54607, :foo2) Foreign54607.bar = 8 @test Foreign54607.bar == 8 begin From 9acf1129c91cddd9194f529ad9cc82afd2694190 Mon Sep 17 00:00:00 2001 From: Julius Krumbiegel <22495855+jkrumbiegel@users.noreply.github.com> Date: Tue, 3 Dec 2024 08:45:28 +0100 Subject: [PATCH 013/198] Actually show glyphs for latex or emoji shortcodes being suggested in the REPL (#54800) When a user requests a completion for a backslash shortcode, this PR adds the glyphs for all the suggestions to the output. This makes it much easier to find the result one is looking for, especially if the user doesn't know all latex and emoji specifiers by heart. Before: image After: image --------- Co-authored-by: Dilum Aluthge --- stdlib/REPL/src/LineEdit.jl | 38 +++++++++++++++++++++++++---- stdlib/REPL/src/REPL.jl | 6 ++--- stdlib/REPL/src/REPLCompletions.jl | 34 +++++++++++++++++--------- stdlib/REPL/test/replcompletions.jl | 33 +++++++++++++++++-------- 4 files changed, 81 insertions(+), 30 deletions(-) diff --git a/stdlib/REPL/src/LineEdit.jl b/stdlib/REPL/src/LineEdit.jl index e881a65ca6b1c..e15807f645119 100644 --- a/stdlib/REPL/src/LineEdit.jl +++ b/stdlib/REPL/src/LineEdit.jl @@ -181,7 +181,18 @@ struct EmptyHistoryProvider <: HistoryProvider end reset_state(::EmptyHistoryProvider) = nothing -complete_line(c::EmptyCompletionProvider, s; hint::Bool=false) = String[], "", true +# Before, completions were always given as strings. But at least for backslash +# completions, it's nice to see what glyphs are available in the completion preview. +# To separate between what's shown in the preview list of possible matches, and what's +# actually completed, we introduce this struct. +struct NamedCompletion + completion::String # what is actually completed, for example "\trianglecdot" + name::String # what is displayed in lists of possible completions, for example "◬ \trianglecdot" +end + +NamedCompletion(completion::String) = NamedCompletion(completion, completion) + +complete_line(c::EmptyCompletionProvider, s; hint::Bool=false) = NamedCompletion[], "", true # complete_line can be specialized for only two arguments, when the active module # doesn't matter (e.g. Pkg does this) @@ -308,6 +319,7 @@ end set_action!(s, command::Symbol) = nothing +common_prefix(completions::Vector{NamedCompletion}) = common_prefix(map(x -> x.completion, completions)) function common_prefix(completions::Vector{String}) ret = "" c1 = completions[1] @@ -330,6 +342,8 @@ end # does not restrict column length when multiple columns are used. const MULTICOLUMN_THRESHOLD = 5 +show_completions(s::PromptState, completions::Vector{NamedCompletion}) = show_completions(s, map(x -> x.name, completions)) + # Show available completions function show_completions(s::PromptState, completions::Vector{String}) # skip any lines of input after the cursor @@ -374,6 +388,18 @@ function complete_line(s::MIState) end end +# due to close coupling of the Pkg ReplExt `complete_line` can still return a vector of strings, +# so we convert those in this helper +function complete_line_named(args...; kwargs...)::Tuple{Vector{NamedCompletion},String,Bool} + result = complete_line(args...; kwargs...)::Union{Tuple{Vector{NamedCompletion},String,Bool},Tuple{Vector{String},String,Bool}} + if result isa Tuple{Vector{NamedCompletion},String,Bool} + return result + else + completions, partial, should_complete = result + return map(NamedCompletion, completions), partial, should_complete + end +end + function check_for_hint(s::MIState) st = state(s) if !options(st).hint_tab_completes || !eof(buffer(st)) @@ -383,12 +409,14 @@ function check_for_hint(s::MIState) return clear_hint(st) end - completions, partial, should_complete = try - complete_line(st.p.complete, st, s.active_module; hint = true)::Tuple{Vector{String},String,Bool} + named_completions, partial, should_complete = try + complete_line_named(st.p.complete, st, s.active_module; hint = true) catch @debug "error completing line for hint" exception=current_exceptions() return clear_hint(st) end + completions = map(x -> x.completion, named_completions) + isempty(completions) && return clear_hint(st) # Don't complete for single chars, given e.g. `x` completes to `xor` if length(partial) > 1 && should_complete @@ -425,7 +453,7 @@ function clear_hint(s::ModeState) end function complete_line(s::PromptState, repeats::Int, mod::Module; hint::Bool=false) - completions, partial, should_complete = complete_line(s.p.complete, s, mod; hint)::Tuple{Vector{String},String,Bool} + completions, partial, should_complete = complete_line_named(s.p.complete, s, mod; hint) isempty(completions) && return false if !should_complete # should_complete is false for cases where we only want to show @@ -435,7 +463,7 @@ function complete_line(s::PromptState, repeats::Int, mod::Module; hint::Bool=fal # Replace word by completion prev_pos = position(s) push_undo(s) - edit_splice!(s, (prev_pos - sizeof(partial)) => prev_pos, completions[1]) + edit_splice!(s, (prev_pos - sizeof(partial)) => prev_pos, completions[1].completion) else p = common_prefix(completions) if !isempty(p) && p != partial diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index 50f610ff3b3e8..6c3f4bd4ba73a 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -843,7 +843,7 @@ function complete_line(c::REPLCompletionProvider, s::PromptState, mod::Module; h full = LineEdit.input_string(s) ret, range, should_complete = completions(full, lastindex(partial), mod, c.modifiers.shift, hint) c.modifiers = LineEdit.Modifiers() - return unique!(String[completion_text(x) for x in ret]), partial[range], should_complete + return unique!(LineEdit.NamedCompletion[named_completion(x) for x in ret]), partial[range], should_complete end function complete_line(c::ShellCompletionProvider, s::PromptState; hint::Bool=false) @@ -851,14 +851,14 @@ function complete_line(c::ShellCompletionProvider, s::PromptState; hint::Bool=fa partial = beforecursor(s.input_buffer) full = LineEdit.input_string(s) ret, range, should_complete = shell_completions(full, lastindex(partial), hint) - return unique!(String[completion_text(x) for x in ret]), partial[range], should_complete + return unique!(LineEdit.NamedCompletion[named_completion(x) for x in ret]), partial[range], should_complete end function complete_line(c::LatexCompletions, s; hint::Bool=false) partial = beforecursor(LineEdit.buffer(s)) full = LineEdit.input_string(s)::String ret, range, should_complete = bslash_completions(full, lastindex(partial), hint)[2] - return unique!(String[completion_text(x) for x in ret]), partial[range], should_complete + return unique!(LineEdit.NamedCompletion[named_completion(x) for x in ret]), partial[range], should_complete end with_repl_linfo(f, repl) = f(outstream(repl)) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 1f2c0cabbdb38..0bffb1a1015cd 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -2,7 +2,7 @@ module REPLCompletions -export completions, shell_completions, bslash_completions, completion_text +export completions, shell_completions, bslash_completions, completion_text, named_completion using Core: Const # We want to insulate the REPLCompletion module from any changes the user may @@ -13,6 +13,8 @@ using Base.Meta using Base: propertynames, something, IdSet using Base.Filesystem: _readdirx +using ..REPL.LineEdit: NamedCompletion + abstract type Completion end struct TextCompletion <: Completion @@ -57,8 +59,10 @@ struct MethodCompletion <: Completion end struct BslashCompletion <: Completion - bslash::String + completion::String # what is actually completed, for example "\trianglecdot" + name::String # what is displayed, for example "◬ \trianglecdot" end +BslashCompletion(completion::String) = BslashCompletion(completion, completion) struct ShellCompletion <: Completion text::String @@ -114,13 +118,21 @@ _completion_text(c::PackageCompletion) = c.package _completion_text(c::PropertyCompletion) = sprint(Base.show_sym, c.property) _completion_text(c::FieldCompletion) = sprint(Base.show_sym, c.field) _completion_text(c::MethodCompletion) = repr(c.method) -_completion_text(c::BslashCompletion) = c.bslash _completion_text(c::ShellCompletion) = c.text _completion_text(c::DictCompletion) = c.key _completion_text(c::KeywordArgumentCompletion) = c.kwarg*'=' completion_text(c) = _completion_text(c)::String +named_completion(c::BslashCompletion) = NamedCompletion(c.completion, c.name) + +function named_completion(c) + text = completion_text(c)::String + return NamedCompletion(text, text) +end + +named_completion_completion(c) = named_completion(c).completion::String + const Completions = Tuple{Vector{Completion}, UnitRange{Int}, Bool} function completes_global(x, name) @@ -984,12 +996,10 @@ function bslash_completions(string::String, pos::Int, hint::Bool=false) end # return possible matches; these cannot be mixed with regular # Julian completions as only latex / emoji symbols contain the leading \ - if startswith(s, "\\:") # emoji - namelist = Iterators.filter(k -> startswith(k, s), keys(emoji_symbols)) - else # latex - namelist = Iterators.filter(k -> startswith(k, s), keys(latex_symbols)) - end - return (true, (Completion[BslashCompletion(name) for name in sort!(collect(namelist))], slashpos:pos, true)) + symbol_dict = startswith(s, "\\:") ? emoji_symbols : latex_symbols + namelist = Iterators.filter(k -> startswith(k, s), keys(symbol_dict)) + completions = Completion[BslashCompletion(name, "$(symbol_dict[name]) $name") for name in sort!(collect(namelist))] + return (true, (completions, slashpos:pos, true)) end return (false, (Completion[], 0:-1, false)) end @@ -1099,7 +1109,7 @@ function complete_keyword_argument(partial::String, last_idx::Int, context_modul complete_keyval!(suggestions, last_word) end - return sort!(suggestions, by=completion_text), wordrange + return sort!(suggestions, by=named_completion_completion), wordrange end function get_loading_candidates(pkgstarts::String, project_file::String) @@ -1298,7 +1308,7 @@ function completions(string::String, pos::Int, context_module::Module=Main, shif complete_identifiers!(suggestions, context_module, string, name, pos, separatorpos, startpos; shift) - return sort!(unique!(completion_text, suggestions), by=completion_text), (separatorpos+1):pos, true + return sort!(unique!(named_completion, suggestions), by=named_completion_completion), (separatorpos+1):pos, true elseif inc_tag === :cmd # TODO: should this call shell_completions instead of partially reimplementing it? let m = match(r"[\t\n\r\"`><=*?|]| (?!\\)", reverse(partial)) # fuzzy shell_parse in reverse @@ -1496,7 +1506,7 @@ function completions(string::String, pos::Int, context_module::Module=Main, shif complete_identifiers!(suggestions, context_module, string, name, pos, separatorpos, startpos; comp_keywords, complete_modules_only, shift) - return sort!(unique!(completion_text, suggestions), by=completion_text), namepos:pos, true + return sort!(unique!(named_completion, suggestions), by=named_completion_completion), namepos:pos, true end function shell_completions(string, pos, hint::Bool=false) diff --git a/stdlib/REPL/test/replcompletions.jl b/stdlib/REPL/test/replcompletions.jl index b259567884486..2c8d48cc232cf 100644 --- a/stdlib/REPL/test/replcompletions.jl +++ b/stdlib/REPL/test/replcompletions.jl @@ -170,17 +170,23 @@ end function map_completion_text(completions) c, r, res = completions - return map(completion_text, c), r, res + return map(x -> named_completion(x).completion, c), r, res +end + +function map_named_completion(completions) + c, r, res = completions + return map(named_completion, c), r, res end test_complete(s) = map_completion_text(@inferred(completions(s, lastindex(s)))) test_scomplete(s) = map_completion_text(@inferred(shell_completions(s, lastindex(s)))) -test_bslashcomplete(s) = map_completion_text(@inferred(bslash_completions(s, lastindex(s)))[2]) test_complete_context(s, m=@__MODULE__; shift::Bool=true) = map_completion_text(@inferred(completions(s,lastindex(s), m, shift))) test_complete_foo(s) = test_complete_context(s, Main.CompletionFoo) test_complete_noshift(s) = map_completion_text(@inferred(completions(s, lastindex(s), Main, false))) +test_bslashcomplete(s) = map_named_completion(@inferred(bslash_completions(s, lastindex(s)))[2]) + test_methods_list(@nospecialize(f), tt) = map(x -> string(x.method), Base._methods_by_ftype(Base.signature_type(f, tt), 10, Base.get_world_counter())) @@ -350,7 +356,8 @@ end # test latex symbol completions let s = "\\alpha" c, r = test_bslashcomplete(s) - @test c[1] == "α" + @test c[1].completion == "α" + @test c[1].name == "α" @test r == 1:lastindex(s) @test length(c) == 1 end @@ -358,7 +365,8 @@ end # test latex symbol completions after unicode #9209 let s = "α\\alpha" c, r = test_bslashcomplete(s) - @test c[1] == "α" + @test c[1].completion == "α" + @test c[1].name == "α" @test r == 3:sizeof(s) @test length(c) == 1 end @@ -366,20 +374,25 @@ end # test emoji symbol completions let s = "\\:koala:" c, r = test_bslashcomplete(s) - @test c[1] == "🐨" + @test c[1].completion == "🐨" + @test c[1].name == "🐨" @test r == 1:sizeof(s) @test length(c) == 1 end let s = "\\:ko" c, r = test_bslashcomplete(s) - @test "\\:koala:" in c + ko = only(filter(c) do namedcompletion + namedcompletion.completion == "\\:koala:" + end) + @test ko.name == "🐨 \\:koala:" end # test emoji symbol completions after unicode #9209 let s = "α\\:koala:" c, r = test_bslashcomplete(s) - @test c[1] == "🐨" + @test c[1].name == "🐨" + @test c[1].completion == "🐨" @test r == 3:sizeof(s) @test length(c) == 1 end @@ -1069,8 +1082,8 @@ let s, c, r # Issue #8047 s = "@show \"/dev/nul\"" c,r = completions(s, 15) - c = map(completion_text, c) - @test "null\"" in c + c = map(named_completion, c) + @test "null\"" in [_c.completion for _c in c] @test r == 13:15 @test s[r] == "nul" @@ -1476,7 +1489,7 @@ function test_dict_completion(dict_name) @test c == Any["\"abcd\"]"] s = "$dict_name[\"abcd]" # trailing close bracket c, r = completions(s, lastindex(s) - 1) - c = map(completion_text, c) + c = map(x -> named_completion(x).completion, c) @test c == Any["\"abcd\""] s = "$dict_name[:b" c, r = test_complete(s) From 2590e675885b97579a7531c343a546f6f5bbcbe5 Mon Sep 17 00:00:00 2001 From: Daniel Wennberg Date: Tue, 3 Dec 2024 05:36:39 -0800 Subject: [PATCH 014/198] Update annotated.jl docstrings according to #55741 (#56736) Annotations now use a NamedTuple --- base/strings/annotated.jl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/base/strings/annotated.jl b/base/strings/annotated.jl index c5c330fe0dfcd..814ee2afa9d55 100644 --- a/base/strings/annotated.jl +++ b/base/strings/annotated.jl @@ -55,9 +55,9 @@ like [`string`](@ref) but preserves any annotations present in the arguments. # Examples -```julia-repl +```jldoctest; setup=:(using Base: AnnotatedString) julia> AnnotatedString("this is an example annotated string", - [(1:18, :A => 1), (12:28, :B => 2), (18:35, :C => 3)]) + [(1:18, :A, 1), (12:28, :B, 2), (18:35, :C, 3)]) "this is an example annotated string" ``` """ @@ -87,8 +87,8 @@ AnnotatedChar(s::S, annotations::Vector{$Annotation}) # Examples -```julia-repl -julia> AnnotatedChar('j', :label => 1) +```jldoctest; setup=:(using Base: AnnotatedChar) +julia> AnnotatedChar('j', [(:label, 1)]) 'j': ASCII/Unicode U+006A (category Ll: Letter, lowercase) ``` """ @@ -232,11 +232,11 @@ See also [`AnnotatedString`](@ref) and [`AnnotatedChar`](@ref). ## Examples -```julia-repl +```jldoctest; setup=:(using Base: AnnotatedString, annotatedstring) julia> annotatedstring("now a AnnotatedString") "now a AnnotatedString" -julia> annotatedstring(AnnotatedString("annotated", [(1:9, :label => 1)]), ", and unannotated") +julia> annotatedstring(AnnotatedString("annotated", [(1:9, :label, 1)]), ", and unannotated") "annotated, and unannotated" ``` """ @@ -344,7 +344,7 @@ end annotate!(str::AnnotatedString, [range::UnitRange{Int}], label::Symbol, value) annotate!(str::SubString{AnnotatedString}, [range::UnitRange{Int}], label::Symbol, value) -Annotate a `range` of `str` (or the entire string) with a labeled value (`label` => `value`). +Annotate a `range` of `str` (or the entire string) with a labeled value `(label, value)`. To remove existing `label` annotations, use a value of `nothing`. The order in which annotations are applied to `str` is semantically meaningful, @@ -365,7 +365,7 @@ annotate!(s::SubString{<:AnnotatedString}, label::Symbol, @nospecialize(val::Any """ annotate!(char::AnnotatedChar, label::Symbol, value::Any) -Annotate `char` with the pair `label => value`. +Annotate `char` with the labeled value `(label, value)`. """ annotate!(c::AnnotatedChar, label::Symbol, @nospecialize(val::Any)) = (push!(c.annotations, Annotation((; label, val))); c) From 5ae26276c1a1834f7b2ebdaf03696278df59b11b Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 3 Dec 2024 19:50:25 -0500 Subject: [PATCH 015/198] effects: pack bits better (#56737) There is no reason to preserve duplicates of the bits for the value before and after inference, and many of the numbers in the comments had gotten incorrect. Now we are able to pack all 16 bits of currently defined bitflags into 20 bits, instead of 25 bits (although either case still rounds up to 32). There was also no reason for InferenceState to be mutating of CodeInfo during execution, so remove that mutation. --- Compiler/src/inferencestate.jl | 25 +++++++++---------- Compiler/src/optimize.jl | 45 +++++++++++++++++++--------------- Compiler/src/typeinfer.jl | 3 ++- src/julia.h | 13 +++------- 4 files changed, 42 insertions(+), 44 deletions(-) diff --git a/Compiler/src/inferencestate.jl b/Compiler/src/inferencestate.jl index 9eb929b725fbf..6988e74310fc5 100644 --- a/Compiler/src/inferencestate.jl +++ b/Compiler/src/inferencestate.jl @@ -267,6 +267,7 @@ mutable struct InferenceState bb_vartables::Vector{Union{Nothing,VarTable}} # nothing if not analyzed yet bb_saw_latestworld::Vector{Bool} ssavaluetypes::Vector{Any} + ssaflags::Vector{UInt32} edges::Vector{Any} stmt_info::Vector{CallInfo} @@ -343,6 +344,7 @@ mutable struct InferenceState bb_vartable1[i] = VarState(argtyp, i > nargtypes) end src.ssavaluetypes = ssavaluetypes = Any[ NOT_FOUND for i = 1:nssavalues ] + ssaflags = copy(src.ssaflags) unreachable = BitSet() pclimitations = IdSet{InferenceState}() @@ -374,7 +376,7 @@ mutable struct InferenceState this = new( mi, WorldWithRange(world, valid_worlds), mod, sptypes, slottypes, src, cfg, spec_info, - currbb, currpc, ip, handler_info, ssavalue_uses, bb_vartables, bb_saw_latestworld, ssavaluetypes, edges, stmt_info, + currbb, currpc, ip, handler_info, ssavalue_uses, bb_vartables, bb_saw_latestworld, ssavaluetypes, ssaflags, edges, stmt_info, tasks, pclimitations, limitations, cycle_backedges, callstack, parentid, frameid, cycleid, result, unreachable, bestguess, exc_bestguess, ipo_effects, restrict_abstract_call_sites, cache_mode, insert_coverage, @@ -1004,25 +1006,22 @@ function callers_in_cycle(sv::InferenceState) end callers_in_cycle(sv::IRInterpretationState) = AbsIntCycle(sv.callstack::Vector{AbsIntState}, 0, 0) -get_curr_ssaflag(sv::InferenceState) = sv.src.ssaflags[sv.currpc] +get_curr_ssaflag(sv::InferenceState) = sv.ssaflags[sv.currpc] get_curr_ssaflag(sv::IRInterpretationState) = sv.ir.stmts[sv.curridx][:flag] -has_curr_ssaflag(sv::InferenceState, flag::UInt32) = has_flag(sv.src.ssaflags[sv.currpc], flag) +has_curr_ssaflag(sv::InferenceState, flag::UInt32) = has_flag(sv.ssaflags[sv.currpc], flag) has_curr_ssaflag(sv::IRInterpretationState, flag::UInt32) = has_flag(sv.ir.stmts[sv.curridx][:flag], flag) function set_curr_ssaflag!(sv::InferenceState, flag::UInt32, mask::UInt32=typemax(UInt32)) - curr_flag = sv.src.ssaflags[sv.currpc] - sv.src.ssaflags[sv.currpc] = (curr_flag & ~mask) | flag -end -function set_curr_ssaflag!(sv::IRInterpretationState, flag::UInt32, mask::UInt32=typemax(UInt32)) - curr_flag = sv.ir.stmts[sv.curridx][:flag] - sv.ir.stmts[sv.curridx][:flag] = (curr_flag & ~mask) | flag + curr_flag = sv.ssaflags[sv.currpc] + sv.ssaflags[sv.currpc] = (curr_flag & ~mask) | flag + nothing end -add_curr_ssaflag!(sv::InferenceState, flag::UInt32) = sv.src.ssaflags[sv.currpc] |= flag +add_curr_ssaflag!(sv::InferenceState, flag::UInt32) = sv.ssaflags[sv.currpc] |= flag add_curr_ssaflag!(sv::IRInterpretationState, flag::UInt32) = add_flag!(sv.ir.stmts[sv.curridx], flag) -sub_curr_ssaflag!(sv::InferenceState, flag::UInt32) = sv.src.ssaflags[sv.currpc] &= ~flag +sub_curr_ssaflag!(sv::InferenceState, flag::UInt32) = sv.ssaflags[sv.currpc] &= ~flag sub_curr_ssaflag!(sv::IRInterpretationState, flag::UInt32) = sub_flag!(sv.ir.stmts[sv.curridx], flag) function merge_effects!(::AbstractInterpreter, caller::InferenceState, effects::Effects) @@ -1035,8 +1034,8 @@ function merge_effects!(::AbstractInterpreter, caller::InferenceState, effects:: end merge_effects!(::AbstractInterpreter, ::IRInterpretationState, ::Effects) = return -decode_statement_effects_override(sv::AbsIntState) = - decode_statement_effects_override(get_curr_ssaflag(sv)) +decode_statement_effects_override(sv::InferenceState) = decode_statement_effects_override(sv.src.ssaflags[sv.currpc]) +decode_statement_effects_override(sv::IRInterpretationState) = decode_statement_effects_override(UInt32(0)) struct InferenceLoopState rt diff --git a/Compiler/src/optimize.jl b/Compiler/src/optimize.jl index 856e64e404388..1c02bd67b5bd4 100644 --- a/Compiler/src/optimize.jl +++ b/Compiler/src/optimize.jl @@ -17,37 +17,41 @@ const SLOT_USEDUNDEF = 32 # slot has uses that might raise UndefVarError const IR_FLAG_NULL = zero(UInt32) # This statement is marked as @inbounds by user. -# Ff replaced by inlining, any contained boundschecks may be removed. +# If replaced by inlining, any contained boundschecks may be removed. const IR_FLAG_INBOUNDS = one(UInt32) << 0 # This statement is marked as @inline by user const IR_FLAG_INLINE = one(UInt32) << 1 # This statement is marked as @noinline by user const IR_FLAG_NOINLINE = one(UInt32) << 2 -# An optimization pass has updated this statement in a way that may -# have exposed information that inference did not see. Re-running -# inference on this statement may be profitable. -const IR_FLAG_REFINED = one(UInt32) << 3 # This statement is proven :consistent -const IR_FLAG_CONSISTENT = one(UInt32) << 4 +const IR_FLAG_CONSISTENT = one(UInt32) << 3 # This statement is proven :effect_free -const IR_FLAG_EFFECT_FREE = one(UInt32) << 5 +const IR_FLAG_EFFECT_FREE = one(UInt32) << 4 # This statement is proven :nothrow -const IR_FLAG_NOTHROW = one(UInt32) << 6 -# This statement is proven :terminates -const IR_FLAG_TERMINATES = one(UInt32) << 7 -# This statement is proven :noub -const IR_FLAG_NOUB = one(UInt32) << 8 -# TODO: Both of these should eventually go away once -# This statement is :effect_free == EFFECT_FREE_IF_INACCESSIBLEMEMONLY -const IR_FLAG_EFIIMO = one(UInt32) << 9 -# This statement is :inaccessiblememonly == INACCESSIBLEMEM_OR_ARGMEMONLY -const IR_FLAG_INACCESSIBLEMEM_OR_ARGMEM = one(UInt32) << 10 +const IR_FLAG_NOTHROW = one(UInt32) << 5 +# This statement is proven :terminates_globally +const IR_FLAG_TERMINATES = one(UInt32) << 6 +#const IR_FLAG_TERMINATES_LOCALLY = one(UInt32) << 7 +#const IR_FLAG_NOTASKSTATE = one(UInt32) << 8 +#const IR_FLAG_INACCESSIBLEMEM = one(UInt32) << 9 +const IR_FLAG_NOUB = one(UInt32) << 10 +#const IR_FLAG_NOUBINIB = one(UInt32) << 11 +#const IR_FLAG_CONSISTENTOVERLAY = one(UInt32) << 12 # This statement is :nortcall -const IR_FLAG_NORTCALL = one(UInt32) << 11 +const IR_FLAG_NORTCALL = one(UInt32) << 13 +# An optimization pass has updated this statement in a way that may +# have exposed information that inference did not see. Re-running +# inference on this statement may be profitable. +const IR_FLAG_REFINED = one(UInt32) << 16 # This statement has no users and may be deleted if flags get refined to IR_FLAGS_REMOVABLE -const IR_FLAG_UNUSED = one(UInt32) << 12 +const IR_FLAG_UNUSED = one(UInt32) << 17 +# TODO: Both of these next two should eventually go away once +# This statement is :effect_free == EFFECT_FREE_IF_INACCESSIBLEMEMONLY +const IR_FLAG_EFIIMO = one(UInt32) << 18 +# This statement is :inaccessiblememonly == INACCESSIBLEMEM_OR_ARGMEMONLY +const IR_FLAG_INACCESSIBLEMEM_OR_ARGMEM = one(UInt32) << 19 -const NUM_IR_FLAGS = 13 # sync with julia.h +const NUM_IR_FLAGS = 3 # sync with julia.h const IR_FLAGS_EFFECTS = IR_FLAG_CONSISTENT | IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW | @@ -815,6 +819,7 @@ function scan_non_dataflow_flags!(inst::Instruction, sv::PostOptAnalysisState) sv.nortcall = false end end + nothing end function scan_inconsistency!(inst::Instruction, sv::PostOptAnalysisState) diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index 83ec0271ea474..20c0a5000bd39 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -413,6 +413,7 @@ function finishinfer!(me::InferenceState, interp::AbstractInterpreter) ipo_effects = result.ipo_effects = me.ipo_effects = adjust_effects(me) result.exc_result = me.exc_bestguess = refine_exception_type(me.exc_bestguess, ipo_effects) me.src.rettype = widenconst(ignorelimited(bestguess)) + me.src.ssaflags = me.ssaflags me.src.min_world = first(me.world.valid_worlds) me.src.max_world = last(me.world.valid_worlds) istoplevel = !(me.linfo.def isa Method) @@ -936,7 +937,7 @@ function codeinfo_for_const(interp::AbstractInterpreter, mi::MethodInstance, @no tree.slotflags = fill(0x00, nargs) tree.ssavaluetypes = 1 tree.debuginfo = DebugInfo(mi) - tree.ssaflags = UInt32[0] + tree.ssaflags = [IR_FLAG_NULL] tree.rettype = Core.Typeof(val) tree.edges = Core.svec() set_inlineable!(tree, true) diff --git a/src/julia.h b/src/julia.h index 944fd3c43a297..6c0dd700f9472 100644 --- a/src/julia.h +++ b/src/julia.h @@ -279,7 +279,7 @@ typedef union __jl_purity_overrides_t { } _jl_purity_overrides_t; #define NUM_EFFECTS_OVERRIDES 11 -#define NUM_IR_FLAGS 13 +#define NUM_IR_FLAGS 3 // This type describes a single function body typedef struct _jl_code_info_t { @@ -292,15 +292,8 @@ typedef struct _jl_code_info_t { // 1 << 0 = inbounds region // 1 << 1 = callsite inline region // 1 << 2 = callsite noinline region - // 1 << 3 = refined statement - // 1 << 4 = :consistent - // 1 << 5 = :effect_free - // 1 << 6 = :nothrow - // 1 << 7 = :terminates - // 1 << 8 = :noub - // 1 << 9 = :effect_free_if_inaccessiblememonly - // 1 << 10 = :inaccessiblemem_or_argmemonly - // 1 << 11-19 = callsite effects overrides + // 1 << 3-14 = purity + // 1 << 16+ = reserved for inference // miscellaneous data: jl_array_t *slotnames; // names of local variables jl_array_t *slotflags; // local var bit flags From e48bf8cba9a9305050704e3f21b53431ae123e93 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Wed, 4 Dec 2024 07:04:39 -0500 Subject: [PATCH 016/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?Pkg=20stdlib=20from=207b759d7f0=20to=20d84a1a38b=20(#56743)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: Pkg URL: https://github.com/JuliaLang/Pkg.jl.git Stdlib branch: master Julia branch: master Old commit: 7b759d7f0 New commit: d84a1a38b Julia version: 1.12.0-DEV Pkg version: 1.12.0 Bump invoked by: @KristofferC Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaLang/Pkg.jl/compare/7b759d7f0af56c5ad01f2289bbad71284a556970...d84a1a38b6466fa7400e9ad2874a0ef963a10456 ``` $ git log --oneline 7b759d7f0..d84a1a38b d84a1a38b Allow use of a url and subdir in [sources] (#4039) cd75456a8 Fix heading (#4102) b61066120 rename FORMER_STDLIBS -> UPGRADABLE_STDLIBS (#4070) 814949ed2 Increase version of `StaticArrays` in `why` tests (#4077) 83e13631e Run CI on backport branch too (#4094) ``` Co-authored-by: Dilum Aluthge --- .../Pkg-7b759d7f0af56c5ad01f2289bbad71284a556970.tar.gz/md5 | 1 - .../Pkg-7b759d7f0af56c5ad01f2289bbad71284a556970.tar.gz/sha512 | 1 - .../Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 | 1 + .../Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 | 1 + stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Pkg-7b759d7f0af56c5ad01f2289bbad71284a556970.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-7b759d7f0af56c5ad01f2289bbad71284a556970.tar.gz/sha512 create mode 100644 deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 create mode 100644 deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 diff --git a/deps/checksums/Pkg-7b759d7f0af56c5ad01f2289bbad71284a556970.tar.gz/md5 b/deps/checksums/Pkg-7b759d7f0af56c5ad01f2289bbad71284a556970.tar.gz/md5 deleted file mode 100644 index e55e74562d717..0000000000000 --- a/deps/checksums/Pkg-7b759d7f0af56c5ad01f2289bbad71284a556970.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -20d63322fc5b547d4c2464c27e9a6a0e diff --git a/deps/checksums/Pkg-7b759d7f0af56c5ad01f2289bbad71284a556970.tar.gz/sha512 b/deps/checksums/Pkg-7b759d7f0af56c5ad01f2289bbad71284a556970.tar.gz/sha512 deleted file mode 100644 index 5094dddb8142a..0000000000000 --- a/deps/checksums/Pkg-7b759d7f0af56c5ad01f2289bbad71284a556970.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -93dd178af474c76cce9368416d34570b66cc44c7c311e4dc14569d3f9deed70afcae8a2b1976535ed0732ed305c6d8d1b0ef04cbeeaa3af2891e97650d51467d diff --git a/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 b/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 new file mode 100644 index 0000000000000..f5f87b3f2fa9e --- /dev/null +++ b/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 @@ -0,0 +1 @@ +1a5c995237815e0d7d5ee1ec50006c1c diff --git a/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 b/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 new file mode 100644 index 0000000000000..839cd4704a135 --- /dev/null +++ b/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 @@ -0,0 +1 @@ +2e0b984c8272fe4468e0b527698a58d5010ef3f18d38d862665902e5a0e0b7ba65d3085b3d9de367a7b48a216e71d1611687804254503b3905b7b4d217a00f2f diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 8b40c45c4366f..9ef9ca4b04376 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = master -PKG_SHA1 = 7b759d7f0af56c5ad01f2289bbad71284a556970 +PKG_SHA1 = d84a1a38b6466fa7400e9ad2874a0ef963a10456 PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From 8aac4cc282004e5f4c7fc70810207956fde98164 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Thu, 5 Dec 2024 00:33:33 -0700 Subject: [PATCH 017/198] Hide IRShow include from Revise (#56756) Revise in theory wants to re-evaluate this include, but it fails at doing so, because the include call no longer works after bootstrap. It happens to work right now on master, because the lowering of `Compiler.include` happens to hide the include call from Revise, but that's a Revise bug I'm about to fix. Address this by moving the include call into the package and using an absolute include if necessary. --- Compiler/src/Compiler.jl | 16 +++++++++++++++- base/show.jl | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Compiler/src/Compiler.jl b/Compiler/src/Compiler.jl index 2cf7e5508196c..ddcea8a6c5cbb 100644 --- a/Compiler/src/Compiler.jl +++ b/Compiler/src/Compiler.jl @@ -181,12 +181,26 @@ include("bootstrap.jl") include("reflection_interface.jl") include("opaque_closure.jl") +macro __SOURCE_FILE__() + __source__.file === nothing && return nothing + return __source__.file::Symbol +end + module IRShow end +function load_irshow!() + if isdefined(Base, :end_base_include) + # This code path is exclusively for Revise, which may want to re-run this + # after bootstrap. + include(IRShow, Base.joinpath(Base.dirname(Base.String(@__SOURCE_FILE__)), "ssair/show.jl")) + else + include(IRShow, "ssair/show.jl") + end +end if !isdefined(Base, :end_base_include) # During bootstrap, skip including this file and defer it to base/show.jl to include later else # When this module is loaded as the standard library, include this file as usual - include(IRShow, "ssair/show.jl") + load_irshow!() end end # baremodule Compiler diff --git a/base/show.jl b/base/show.jl index 23957d6e29b2d..cb36488b92bc1 100644 --- a/base/show.jl +++ b/base/show.jl @@ -2821,7 +2821,7 @@ function show(io::IO, vm::Core.TypeofVararg) end end -Compiler.include(Compiler.IRShow, "ssair/show.jl") # define `show` for the compiler types +Compiler.load_irshow!() const IRShow = Compiler.IRShow # an alias for compatibility function show(io::IO, src::CodeInfo; debuginfo::Symbol=:source) From e572d2316fb5bd6cb5e57c0d4300edddb4eb2062 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Thu, 5 Dec 2024 18:12:23 +0900 Subject: [PATCH 018/198] fixup!: JuliaLang/julia#56756 (#56758) We need to quote it, otherwise it would result in `UnderVarError`. --- Compiler/src/Compiler.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Compiler/src/Compiler.jl b/Compiler/src/Compiler.jl index ddcea8a6c5cbb..8dd15462ed998 100644 --- a/Compiler/src/Compiler.jl +++ b/Compiler/src/Compiler.jl @@ -183,7 +183,7 @@ include("opaque_closure.jl") macro __SOURCE_FILE__() __source__.file === nothing && return nothing - return __source__.file::Symbol + return QuoteNode(__source__.file::Symbol) end module IRShow end From 5835c3b69e4e0f47eeb9a512d91622b50ad3423c Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Thu, 5 Dec 2024 17:38:12 +0530 Subject: [PATCH 019/198] Accept more general Integer sizes in reshape (#55521) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR generalizes the `reshape` methods to accept `Integer`s instead of `Int`s, and adds a `_reshape_uncolon` method for `Integer` arguments. The current `_reshape_uncolon` method that accepts `Int`s is left unchanged to ensure that the inferred types are not impacted. I've also tried to ensure that most `Integer` subtypes in `Base` that may be safely converted to `Int`s pass through that method. The call sequence would now go like this: ```julia reshape(A, ::Tuple{Vararg{Union{Integer, Colon}}}) -> reshape(A, ::Tuple{Vararg{Integer}}) -> reshape(A, ::Tuple{Vararg{Int}}) (fallback) ``` This lets packages define `reshape(A::CustomArray, ::Tuple{Integer, Vararg{Integer}})` without having to implement `_reshape_uncolon` by themselves (or having to call internal `Base` functions, as in https://github.com/JuliaArrays/FillArrays.jl/issues/373). `reshape` calls involving a `Colon` would convert this to an `Integer` in `Base`, and then pass the `Integer` sizes to the custom method defined in the package. This PR does not resolve issues like https://github.com/JuliaLang/julia/issues/40076 because this still converts `Integer`s to `Int`s in the actual reshaping step. However, `BigInt` sizes that may be converted to `Int`s will work now: ```julia julia> reshape(1:4, big(2), big(2)) 2×2 reshape(::UnitRange{Int64}, 2, 2) with eltype Int64: 1 3 2 4 julia> reshape(1:4, big(1), :) 1×4 reshape(::UnitRange{Int64}, 1, 4) with eltype Int64: 1 2 3 4 ``` Note that the reshape method with `Integer` sizes explicitly converts these to `Int`s to avoid self-recursion (as opposed to calling `to_shape` to carry out the conversion implicitly). In the future, we may want to decide what to do with types or values that can't be converted to an `Int`. --------- Co-authored-by: Neven Sajko --- base/reshapedarray.jl | 57 +++++++++++++++++++++----------- test/abstractarray.jl | 20 +++++++++++ test/offsetarray.jl | 11 ++++++ test/testhelpers/OffsetArrays.jl | 4 ++- 4 files changed, 72 insertions(+), 20 deletions(-) diff --git a/base/reshapedarray.jl b/base/reshapedarray.jl index 07f608588837b..f65a7d8c9561a 100644 --- a/base/reshapedarray.jl +++ b/base/reshapedarray.jl @@ -121,37 +121,56 @@ reshape reshape(parent::AbstractArray, dims::IntOrInd...) = reshape(parent, dims) reshape(parent::AbstractArray, shp::Tuple{Union{Integer,OneTo}, Vararg{Union{Integer,OneTo}}}) = reshape(parent, to_shape(shp)) +reshape(parent::AbstractArray, dims::Tuple{Integer, Vararg{Integer}}) = reshape(parent, map(Int, dims)) reshape(parent::AbstractArray, dims::Dims) = _reshape(parent, dims) # Allow missing dimensions with Colon(): reshape(parent::AbstractVector, ::Colon) = parent reshape(parent::AbstractVector, ::Tuple{Colon}) = parent reshape(parent::AbstractArray, dims::Int...) = reshape(parent, dims) -reshape(parent::AbstractArray, dims::Union{Int,Colon}...) = reshape(parent, dims) -reshape(parent::AbstractArray, dims::Tuple{Vararg{Union{Int,Colon}}}) = reshape(parent, _reshape_uncolon(parent, dims)) -@inline function _reshape_uncolon(A, dims) - @noinline throw1(dims) = throw(DimensionMismatch(string("new dimensions $(dims) ", - "may have at most one omitted dimension specified by `Colon()`"))) - @noinline throw2(A, dims) = throw(DimensionMismatch(string("array size $(length(A)) ", - "must be divisible by the product of the new dimensions $dims"))) - pre = _before_colon(dims...)::Tuple{Vararg{Int}} +reshape(parent::AbstractArray, dims::Integer...) = reshape(parent, dims) +reshape(parent::AbstractArray, dims::Union{Integer,Colon}...) = reshape(parent, dims) +reshape(parent::AbstractArray, dims::Tuple{Vararg{Union{Integer,Colon}}}) = reshape(parent, _reshape_uncolon(parent, dims)) + +@noinline throw1(dims) = throw(DimensionMismatch(LazyString("new dimensions ", dims, + " may have at most one omitted dimension specified by `Colon()`"))) +@noinline throw2(lenA, dims) = throw(DimensionMismatch(string("array size ", lenA, + " must be divisible by the product of the new dimensions ", dims))) + +@inline function _reshape_uncolon(A, _dims::Tuple{Vararg{Union{Integer, Colon}}}) + # promote the dims to `Int` at least + dims = map(x -> x isa Colon ? x : promote_type(typeof(x), Int)(x), _dims) + pre = _before_colon(dims...) post = _after_colon(dims...) _any_colon(post...) && throw1(dims) - post::Tuple{Vararg{Int}} len = length(A) - sz, is_exact = if iszero(len) - (0, true) + _reshape_uncolon_computesize(len, dims, pre, post) +end +@inline function _reshape_uncolon_computesize(len::Int, dims, pre::Tuple{Vararg{Int}}, post::Tuple{Vararg{Int}}) + sz = if iszero(len) + 0 else let pr = Core.checked_dims(pre..., post...) # safe product - if iszero(pr) - throw2(A, dims) - end - (quo, rem) = divrem(len, pr) - (Int(quo), iszero(rem)) + quo = _reshape_uncolon_computesize_nonempty(len, dims, pr) + convert(Int, quo) end - end::Tuple{Int,Bool} - is_exact || throw2(A, dims) - (pre..., sz, post...)::Tuple{Int,Vararg{Int}} + end + (pre..., sz, post...) +end +@inline function _reshape_uncolon_computesize(len, dims, pre, post) + pr = prod((pre..., post...)) + sz = if iszero(len) + promote(len, pr)[1] # zero of the correct type + else + _reshape_uncolon_computesize_nonempty(len, dims, pr) + end + (pre..., sz, post...) +end +@inline function _reshape_uncolon_computesize_nonempty(len, dims, pr) + iszero(pr) && throw2(len, dims) + (quo, rem) = divrem(len, pr) + iszero(rem) || throw2(len, dims) + quo end @inline _any_colon() = false @inline _any_colon(dim::Colon, tail...) = true diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 2a2ec8e8e432c..4af4099eced45 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -2186,3 +2186,23 @@ end copyto!(A, 1, x, 1) @test A == axes(A,1) end + +@testset "reshape with Integer sizes" begin + @test reshape(1:4, big(2), big(2)) == reshape(1:4, 2, 2) + a = [1 2 3; 4 5 6] + reshaped_arrays = ( + reshape(a, 3, 2), + reshape(a, (3, 2)), + reshape(a, big(3), big(2)), + reshape(a, (big(3), big(2))), + reshape(a, :, big(2)), + reshape(a, (:, big(2))), + reshape(a, big(3), :), + reshape(a, (big(3), :)), + ) + @test allequal(reshaped_arrays) + for b ∈ reshaped_arrays + @test b isa Matrix{Int} + @test b.ref === a.ref + end +end diff --git a/test/offsetarray.jl b/test/offsetarray.jl index fb5855dfbaa0d..8e2ee33c49ed6 100644 --- a/test/offsetarray.jl +++ b/test/offsetarray.jl @@ -914,3 +914,14 @@ end b = sum(a, dims=1) @test b[begin] == sum(r) end + +@testset "reshape" begin + A0 = [1 3; 2 4] + A = reshape(A0, 2:3, 4:5) + @test axes(A) == Base.IdentityUnitRange.((2:3, 4:5)) + + B = reshape(A0, -10:-9, 9:10) + @test isa(B, OffsetArray{Int,2}) + @test parent(B) == A0 + @test axes(B) == Base.IdentityUnitRange.((-10:-9, 9:10)) +end diff --git a/test/testhelpers/OffsetArrays.jl b/test/testhelpers/OffsetArrays.jl index 17b2d8c28680a..e895372a34974 100644 --- a/test/testhelpers/OffsetArrays.jl +++ b/test/testhelpers/OffsetArrays.jl @@ -529,7 +529,7 @@ _similar_axes_or_length(AT, ax::I, ::I) where {I} = similar(AT, map(_indexlength # reshape accepts a single colon Base.reshape(A::AbstractArray, inds::OffsetAxis...) = reshape(A, inds) -function Base.reshape(A::AbstractArray, inds::Tuple{OffsetAxis,Vararg{OffsetAxis}}) +function Base.reshape(A::AbstractArray, inds::Tuple{Vararg{OffsetAxis}}) AR = reshape(no_offset_view(A), map(_indexlength, inds)) O = OffsetArray(AR, map(_offset, axes(AR), inds)) return _popreshape(O, axes(AR), _filterreshapeinds(inds)) @@ -557,6 +557,8 @@ Base.reshape(A::OffsetArray, inds::Tuple{OffsetAxis,Vararg{OffsetAxis}}) = OffsetArray(_reshape(parent(A), inds), map(_toaxis, inds)) # And for non-offset axes, we can just return a reshape of the parent directly Base.reshape(A::OffsetArray, inds::Tuple{Union{Integer,Base.OneTo},Vararg{Union{Integer,Base.OneTo}}}) = _reshape_nov(A, inds) +Base.reshape(A::OffsetArray, inds::Tuple{Integer,Vararg{Integer}}) = _reshape_nov(A, inds) +Base.reshape(A::OffsetArray, inds::Tuple{Union{Colon, Integer}, Vararg{Union{Colon, Integer}}}) = _reshape_nov(A, inds) Base.reshape(A::OffsetArray, inds::Dims) = _reshape_nov(A, inds) Base.reshape(A::OffsetVector, ::Colon) = A Base.reshape(A::OffsetVector, ::Tuple{Colon}) = A From b8230c02c6e015cc5fd8e33811474ff1b82299bc Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 6 Dec 2024 06:17:24 -0500 Subject: [PATCH 020/198] drop llvm 16 support (#56751) Co-authored-by: Valentin Churavy --- doc/src/devdocs/build/build.md | 2 +- src/APInt-C.cpp | 54 -------- src/APInt-C.h | 15 --- src/Makefile | 6 +- src/aotcompile.cpp | 30 +---- src/ccall.cpp | 3 - src/cgutils.cpp | 66 +--------- src/codegen.cpp | 81 +----------- src/disasm.cpp | 10 +- src/jitlayers.cpp | 156 +---------------------- src/jitlayers.h | 20 +-- src/llvm-codegen-shared.h | 22 +--- src/llvm-cpufeatures.cpp | 2 +- src/llvm-julia-licm.cpp | 4 - src/llvm-late-gc-lowering.cpp | 21 --- src/llvm-lower-handlers.cpp | 4 - src/llvm-multiversioning.cpp | 8 +- src/llvm-pass-helpers.cpp | 14 -- src/llvm-propagate-addrspaces.cpp | 18 --- src/llvm-ptls.cpp | 8 -- src/llvm-remove-addrspaces.cpp | 28 ---- src/llvm-simdloop.cpp | 4 - src/llvm-version.h | 8 +- src/pipeline.cpp | 36 +----- src/processor.cpp | 8 -- src/runtime_ccall.cpp | 4 - src/runtime_intrinsics.c | 11 -- src/support/win32-clang-ABI-bug/optional | 10 -- 28 files changed, 19 insertions(+), 634 deletions(-) diff --git a/doc/src/devdocs/build/build.md b/doc/src/devdocs/build/build.md index 553f7c2e815cf..966ef3d102d1c 100644 --- a/doc/src/devdocs/build/build.md +++ b/doc/src/devdocs/build/build.md @@ -249,7 +249,7 @@ The most complicated dependency is LLVM, for which we require additional patches For packaging Julia with LLVM, we recommend either: - bundling a Julia-only LLVM library inside the Julia package, or - adding the patches to the LLVM package of the distribution. - * A complete list of patches is available in on [Github](https://github.com/JuliaLang/llvm-project) see the `julia-release/15.x` branch. + * A complete list of patches is available in on [Github](https://github.com/JuliaLang/llvm-project) see the `julia-release/18.x` branch. * The only Julia-specific patch is the lib renaming (`llvm7-symver-jlprefix.patch`), which should _not_ be applied to a system LLVM. * The remaining patches are all upstream bug fixes, and have been contributed into upstream LLVM. diff --git a/src/APInt-C.cpp b/src/APInt-C.cpp index e73399c2ecde4..86b0bdb27638b 100644 --- a/src/APInt-C.cpp +++ b/src/APInt-C.cpp @@ -475,7 +475,6 @@ void LLVMTrunc(jl_datatype_t *ty, integerPart *pa, jl_datatype_t *otys, integerP memcpy(pr, pa, onumbytes); } -#if JL_LLVM_VERSION >= 170000 extern "C" JL_DLLEXPORT unsigned countr_zero_8(uint8_t Val) { return countr_zero(Val); @@ -495,27 +494,6 @@ extern "C" JL_DLLEXPORT unsigned countr_zero_64(uint64_t Val) { return countr_zero(Val); } -#else -extern "C" JL_DLLEXPORT -unsigned countTrailingZeros_8(uint8_t Val) { - return countTrailingZeros(Val); -} - -extern "C" JL_DLLEXPORT -unsigned countTrailingZeros_16(uint16_t Val) { - return countTrailingZeros(Val); -} - -extern "C" JL_DLLEXPORT -unsigned countTrailingZeros_32(uint32_t Val) { - return countTrailingZeros(Val); -} - -extern "C" JL_DLLEXPORT -unsigned countTrailingZeros_64(uint64_t Val) { - return countTrailingZeros(Val); -} -#endif extern "C" JL_DLLEXPORT void jl_LLVMSMod(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr) { @@ -545,7 +523,6 @@ void jl_LLVMFlipSign(unsigned numbits, integerPart *pa, integerPart *pb, integer memcpy(pr, pa, numbytes); } -#if JL_LLVM_VERSION >= 170000 extern "C" JL_DLLEXPORT unsigned LLVMPopcount(unsigned numbits, integerPart *pa) { CREATE(a) @@ -575,34 +552,3 @@ unsigned LLVMCountl_zero(unsigned numbits, integerPart *pa) { CREATE(a) return a.countl_zero(); } -#else -extern "C" JL_DLLEXPORT -unsigned LLVMCountPopulation(unsigned numbits, integerPart *pa) { - CREATE(a) - return a.countPopulation(); -} - -extern "C" JL_DLLEXPORT -unsigned LLVMCountTrailingOnes(unsigned numbits, integerPart *pa) { - CREATE(a) - return a.countTrailingOnes(); -} - -extern "C" JL_DLLEXPORT -unsigned LLVMCountTrailingZeros(unsigned numbits, integerPart *pa) { - CREATE(a) - return a.countTrailingZeros(); -} - -extern "C" JL_DLLEXPORT -unsigned LLVMCountLeadingOnes(unsigned numbits, integerPart *pa) { - CREATE(a) - return a.countLeadingOnes(); -} - -extern "C" JL_DLLEXPORT -unsigned LLVMCountLeadingZeros(unsigned numbits, integerPart *pa) { - CREATE(a) - return a.countLeadingZeros(); -} -#endif diff --git a/src/APInt-C.h b/src/APInt-C.h index a44d922a40d24..59ce3c765eeec 100644 --- a/src/APInt-C.h +++ b/src/APInt-C.h @@ -54,19 +54,11 @@ JL_DLLEXPORT int LLVMDiv_uov(unsigned numbits, integerPart *pa, integerPart *pb, JL_DLLEXPORT int LLVMRem_sov(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr); JL_DLLEXPORT int LLVMRem_uov(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr); -#if JL_LLVM_VERSION >= 170000 JL_DLLEXPORT unsigned LLVMPopcount(unsigned numbits, integerPart *pa); JL_DLLEXPORT unsigned LLVMCountr_one(unsigned numbits, integerPart *pa); JL_DLLEXPORT unsigned LLVMCountr_zero(unsigned numbits, integerPart *pa); JL_DLLEXPORT unsigned LLVMCountl_one(unsigned numbits, integerPart *pa); JL_DLLEXPORT unsigned LLVMCountl_zero(unsigned numbits, integerPart *pa); -#else -JL_DLLEXPORT unsigned LLVMCountPopulation(unsigned numbits, integerPart *pa); -JL_DLLEXPORT unsigned LLVMCountTrailingOnes(unsigned numbits, integerPart *pa); -JL_DLLEXPORT unsigned LLVMCountTrailingZeros(unsigned numbits, integerPart *pa); -JL_DLLEXPORT unsigned LLVMCountLeadingOnes(unsigned numbits, integerPart *pa); -JL_DLLEXPORT unsigned LLVMCountLeadingZeros(unsigned numbits, integerPart *pa); -#endif JL_DLLEXPORT void LLVMFPtoSI(jl_datatype_t *ty, integerPart *pa, jl_datatype_t *oty, integerPart *pr); JL_DLLEXPORT void LLVMFPtoUI(jl_datatype_t *ty, integerPart *pa, jl_datatype_t *oty, integerPart *pr); @@ -82,17 +74,10 @@ JL_DLLEXPORT int LLVMFPtoUI_exact(jl_datatype_t *ty, integerPart *pa, jl_datatyp JL_DLLEXPORT void jl_LLVMSMod(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr); JL_DLLEXPORT void jl_LLVMFlipSign(unsigned numbits, integerPart *pa, integerPart *pb, integerPart *pr); -#if JL_LLVM_VERSION >= 170000 JL_DLLEXPORT unsigned countr_zero_8(uint8_t Val); JL_DLLEXPORT unsigned countr_zero_16(uint16_t Val); JL_DLLEXPORT unsigned countr_zero_32(uint32_t Val); JL_DLLEXPORT unsigned countr_zero_64(uint64_t Val); -#else -JL_DLLEXPORT unsigned countTrailingZeros_8(uint8_t Val); -JL_DLLEXPORT unsigned countTrailingZeros_16(uint16_t Val); -JL_DLLEXPORT unsigned countTrailingZeros_32(uint32_t Val); -JL_DLLEXPORT unsigned countTrailingZeros_64(uint64_t Val); -#endif //uint8_t getSwappedBytes_8(uint8_t Value); // no-op //uint16_t getSwappedBytes_16(uint16_t Value); diff --git a/src/Makefile b/src/Makefile index 3458f51fa5548..9355ca2c4c675 100644 --- a/src/Makefile +++ b/src/Makefile @@ -77,11 +77,7 @@ else # JULIACODEGEN != LLVM endif -RT_LLVM_LIBS := support - -ifeq ($(shell test $(LLVM_VER_MAJ) -ge 16 && echo true),true) -RT_LLVM_LIBS += targetparser -endif +RT_LLVM_LIBS := support targetparser ifeq ($(OS),WINNT) SRCS += win32_ucontext diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index 1d1e48efc8c6c..ba9a3c05e41ff 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -4,11 +4,7 @@ #include "platform.h" // target support -#if JL_LLVM_VERSION >= 170000 #include -#else -#include -#endif #include "llvm/Support/CodeGen.h" #include #include @@ -963,11 +959,7 @@ static FunctionInfo getFunctionWeight(const Function &F) auto val = F.getFnAttribute("julia.mv.clones").getValueAsString(); // base16, so must be at most 4 * length bits long // popcount gives number of clones - #if JL_LLVM_VERSION >= 170000 info.clones = APInt(val.size() * 4, val, 16).popcount() + 1; - #else - info.clones = APInt(val.size() * 4, val, 16).countPopulation() + 1; - #endif } info.weight += info.insts; // more basic blocks = more complex than just sum of insts, @@ -1372,7 +1364,7 @@ static AOTOutputs add_output_impl(Module &M, TargetMachine &SourceTM, ShardTimer // So for now we inject a definition of these functions that calls our runtime // functions. We do so after optimization to avoid cloning these functions. // Float16 conversion routines -#if defined(_CPU_X86_64_) && defined(_OS_DARWIN_) && JL_LLVM_VERSION >= 160000 +#if defined(_CPU_X86_64_) && defined(_OS_DARWIN_) // LLVM 16 reverted to soft-float ABI for passing half on x86_64 Darwin // https://github.com/llvm/llvm-project/commit/2bcf51c7f82ca7752d1bba390a2e0cb5fdd05ca9 injectCRTAlias(M, "__gnu_h2f_ieee", "julia_half_to_float", @@ -1721,9 +1713,6 @@ static SmallVector add_output(Module &M, TargetMachine &TM, Stri std::function func = [&, i]() { LLVMContext ctx; ctx.setDiscardValueNames(true); - #if JL_LLVM_VERSION < 170000 - SetOpaquePointer(ctx); - #endif // Lazily deserialize the entire module timers[i].deserialize.startTimer(); auto EM = getLazyBitcodeModule(MemoryBufferRef(StringRef(serialized.data(), serialized.size()), "Optimized"), ctx); @@ -1888,7 +1877,7 @@ void jl_dump_native_impl(void *native_code, Str += "10.14.0"; TheTriple.setOSName(Str); } - Optional RelocModel; + std::optional RelocModel; if (TheTriple.isOSLinux() || TheTriple.isOSFreeBSD() || TheTriple.isOSOpenBSD()) { RelocModel = Reloc::PIC_; } @@ -1933,9 +1922,6 @@ void jl_dump_native_impl(void *native_code, JL_TIMING(NATIVE_AOT, NATIVE_Sysimg); LLVMContext Context; Context.setDiscardValueNames(true); - #if JL_LLVM_VERSION < 170000 - SetOpaquePointer(Context); - #endif Module sysimgM("sysimg", Context); sysimgM.setTargetTriple(TheTriple.str()); sysimgM.setDataLayout(DL); @@ -2081,9 +2067,6 @@ void jl_dump_native_impl(void *native_code, JL_TIMING(NATIVE_AOT, NATIVE_Metadata); LLVMContext Context; Context.setDiscardValueNames(true); - #if JL_LLVM_VERSION < 170000 - SetOpaquePointer(Context); - #endif Module metadataM("metadata", Context); metadataM.setTargetTriple(TheTriple.str()); metadataM.setDataLayout(DL); @@ -2299,16 +2282,7 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, jl_ } else { auto p = literal_static_pointer_val(global.first, global.second->getValueType()); - #if JL_LLVM_VERSION >= 170000 Type *elty = PointerType::get(output.getContext(), 0); - #else - Type *elty; - if (p->getType()->isOpaquePointerTy()) { - elty = PointerType::get(output.getContext(), 0); - } else { - elty = p->getType()->getNonOpaquePointerElementType(); - } - #endif // For pretty printing, when LLVM inlines the global initializer into its loads auto alias = GlobalAlias::create(elty, 0, GlobalValue::PrivateLinkage, global.second->getName() + ".jit", p, global.second->getParent()); global.second->setInitializer(ConstantExpr::getBitCast(alias, global.second->getValueType())); diff --git a/src/ccall.cpp b/src/ccall.cpp index 52f8f807132e5..9aa1c56e2e78f 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -264,9 +264,6 @@ static GlobalVariable *emit_plt_thunk( SmallVector args; for (auto &arg : plt->args()) args.push_back(&arg); - #if JL_LLVM_VERSION < 170000 - assert(cast(ptr->getType())->isOpaqueOrPointeeTypeMatches(functype)); - #endif CallInst *ret = irbuilder.CreateCall( functype, ptr, ArrayRef(args)); diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 7d4bd917eff30..9e170555e6149 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -60,11 +60,7 @@ static Value *decay_derived(jl_codectx_t &ctx, Value *V) if (T->getPointerAddressSpace() == AddressSpace::Derived) return V; // Once llvm deletes pointer element types, we won't need it here any more either. - #if JL_LLVM_VERSION >= 170000 Type *NewT = PointerType::get(T, AddressSpace::Derived); - #else - Type *NewT = PointerType::getWithSamePointeeType(cast(T), AddressSpace::Derived); - #endif return ctx.builder.CreateAddrSpaceCast(V, NewT); } @@ -74,11 +70,7 @@ static Value *maybe_decay_tracked(jl_codectx_t &ctx, Value *V) Type *T = V->getType(); if (T->getPointerAddressSpace() != AddressSpace::Tracked) return V; - #if JL_LLVM_VERSION >= 170000 Type *NewT = PointerType::get(T, AddressSpace::Derived); - #else - Type *NewT = PointerType::getWithSamePointeeType(cast(T), AddressSpace::Derived); - #endif return ctx.builder.CreateAddrSpaceCast(V, NewT); } @@ -1010,54 +1002,6 @@ static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, jl_aliasinfo_t const { if (sz == 0) return; - #if JL_LLVM_VERSION < 170000 - // If the types are small and simple, use load and store directly. - // Going through memcpy can cause LLVM (e.g. SROA) to create bitcasts between float and int - // that interferes with other optimizations. - // TODO: Restore this for opaque pointers? Needs extra type information from the caller. - if (ctx.builder.getContext().supportsTypedPointers() && sz <= 64) { - // The size limit is arbitrary but since we mainly care about floating points and - // machine size vectors this should be enough. - const DataLayout &DL = jl_Module->getDataLayout(); - auto srcty = cast(src->getType()); - //TODO unsafe nonopaque pointer - auto srcel = srcty->getNonOpaquePointerElementType(); - auto dstty = cast(dst->getType()); - //TODO unsafe nonopaque pointer - auto dstel = dstty->getNonOpaquePointerElementType(); - while (srcel->isArrayTy() && srcel->getArrayNumElements() == 1) { - src = ctx.builder.CreateConstInBoundsGEP2_32(srcel, src, 0, 0); - srcel = srcel->getArrayElementType(); - srcty = srcel->getPointerTo(); - } - while (dstel->isArrayTy() && dstel->getArrayNumElements() == 1) { - dst = ctx.builder.CreateConstInBoundsGEP2_32(dstel, dst, 0, 0); - dstel = dstel->getArrayElementType(); - dstty = dstel->getPointerTo(); - } - - llvm::Type *directel = nullptr; - if (srcel->isSized() && srcel->isSingleValueType() && DL.getTypeStoreSize(srcel) == sz) { - directel = srcel; - dst = emit_bitcast(ctx, dst, srcty); - } - else if (dstel->isSized() && dstel->isSingleValueType() && - DL.getTypeStoreSize(dstel) == sz) { - directel = dstel; - src = emit_bitcast(ctx, src, dstty); - } - if (directel) { - if (isa(src) && !src->hasName()) - setName(ctx.emission_context, src, "memcpy_refined_src"); - if (isa(dst) && !dst->hasName()) - setName(ctx.emission_context, dst, "memcpy_refined_dst"); - auto val = src_ai.decorateInst(ctx.builder.CreateAlignedLoad(directel, src, MaybeAlign(align_src), is_volatile)); - dst_ai.decorateInst(ctx.builder.CreateAlignedStore(val, dst, align_dst, is_volatile)); - ++SkippedMemcpys; - return; - } - } - #endif ++EmittedMemcpys; // the memcpy intrinsic does not allow to specify different alias tags @@ -1940,7 +1884,7 @@ static std::pair emit_isa(jl_codectx_t &ctx, const jl_cgval_t &x, // actual `isa` calls, this optimization should already have been performed upstream // anyway, but having this optimization in codegen might still be beneficial for // `typeassert`s if we can make it correct. - Optional known_isa; + std::optional known_isa; jl_value_t *intersected_type = type; if (x.constant) known_isa = jl_isa(x.constant, type); @@ -3786,11 +3730,7 @@ static void recursively_adjust_ptr_type(llvm::Value *Val, unsigned FromAS, unsig for (auto *User : Val->users()) { if (isa(User)) { GetElementPtrInst *Inst = cast(User); - #if JL_LLVM_VERSION >= 170000 Inst->mutateType(PointerType::get(Inst->getType(), ToAS)); - #else - Inst->mutateType(PointerType::getWithSamePointeeType(cast(Inst->getType()), ToAS)); - #endif recursively_adjust_ptr_type(Inst, FromAS, ToAS); } else if (isa(User)) { @@ -3799,11 +3739,7 @@ static void recursively_adjust_ptr_type(llvm::Value *Val, unsigned FromAS, unsig } else if (isa(User)) { BitCastInst *Inst = cast(User); - #if JL_LLVM_VERSION >= 170000 Inst->mutateType(PointerType::get(Inst->getType(), ToAS)); - #else - Inst->mutateType(PointerType::getWithSamePointeeType(cast(Inst->getType()), ToAS)); - #endif recursively_adjust_ptr_type(Inst, FromAS, ToAS); } } diff --git a/src/codegen.cpp b/src/codegen.cpp index b8bed0793730b..b9d42b9b5af16 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -23,11 +23,7 @@ #include #include #include -#if JL_LLVM_VERSION >= 170000 #include -#else -#include -#endif #include #include @@ -637,11 +633,7 @@ static AttributeList get_func_attrs(LLVMContext &C) static AttributeList get_donotdelete_func_attrs(LLVMContext &C) { AttrBuilder FnAttrs(C); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly()); -#else - FnAttrs.addAttribute(Attribute::InaccessibleMemOnly); -#endif FnAttrs.addAttribute(Attribute::WillReturn); FnAttrs.addAttribute(Attribute::NoUnwind); return AttributeList::get(C, @@ -671,11 +663,7 @@ static AttributeList get_attrs_box_float(LLVMContext &C, unsigned nbytes) auto FnAttrs = AttrBuilder(C); FnAttrs.addAttribute(Attribute::WillReturn); FnAttrs.addAttribute(Attribute::NoUnwind); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly()); -#else - FnAttrs.addAttribute(Attribute::InaccessibleMemOnly); -#endif auto RetAttrs = AttrBuilder(C); RetAttrs.addAttribute(Attribute::NonNull); RetAttrs.addDereferenceableAttr(nbytes); @@ -691,11 +679,7 @@ static AttributeList get_attrs_box_sext(LLVMContext &C, unsigned nbytes) auto FnAttrs = AttrBuilder(C); FnAttrs.addAttribute(Attribute::WillReturn); FnAttrs.addAttribute(Attribute::NoUnwind); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly()); -#else - FnAttrs.addAttribute(Attribute::InaccessibleMemOnly); -#endif auto RetAttrs = AttrBuilder(C); RetAttrs.addAttribute(Attribute::NonNull); RetAttrs.addAttribute(Attribute::getWithDereferenceableBytes(C, nbytes)); @@ -712,11 +696,7 @@ static AttributeList get_attrs_box_zext(LLVMContext &C, unsigned nbytes) auto FnAttrs = AttrBuilder(C); FnAttrs.addAttribute(Attribute::WillReturn); FnAttrs.addAttribute(Attribute::NoUnwind); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly()); -#else - FnAttrs.addAttribute(Attribute::InaccessibleMemOnly); -#endif auto RetAttrs = AttrBuilder(C); RetAttrs.addAttribute(Attribute::NonNull); RetAttrs.addDereferenceableAttr(nbytes); @@ -1141,12 +1121,7 @@ static const auto jlegalx_func = new JuliaFunction{ return FunctionType::get(getInt32Ty(C), {T, T, T_size}, false); }, [](LLVMContext &C) { AttrBuilder FnAttrs(C); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleOrArgMemOnly()); -#else - FnAttrs.addAttribute(Attribute::ReadOnly); - FnAttrs.addAttribute(Attribute::ArgMemOnly); -#endif FnAttrs.addAttribute(Attribute::NoUnwind); return AttributeList::get(C, AttributeSet::get(C, FnAttrs), @@ -1166,9 +1141,7 @@ static const auto jl_alloc_obj_func = new JuliaFunction{ auto FnAttrs = AttrBuilder(C); FnAttrs.addAllocSizeAttr(1, None); // returns %1 bytes FnAttrs.addAllocKindAttr(AllocFnKind::Alloc); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Ref) | MemoryEffects::inaccessibleMemOnly(ModRefInfo::ModRef)); -#endif FnAttrs.addAttribute(Attribute::WillReturn); FnAttrs.addAttribute(Attribute::NoUnwind); auto RetAttrs = AttrBuilder(C); @@ -1204,11 +1177,7 @@ static const auto jl_typeof_func = new JuliaFunction<>{ }, [](LLVMContext &C) { AttrBuilder FnAttrs(C); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::none()); -#else - FnAttrs.addAttribute(Attribute::ReadNone); -#endif FnAttrs.addAttribute(Attribute::NoUnwind); FnAttrs.addAttribute(Attribute::NoRecurse); return AttributeList::get(C, @@ -1223,11 +1192,7 @@ static const auto jl_write_barrier_func = new JuliaFunction<>{ {JuliaType::get_prjlvalue_ty(C)}, true); }, [](LLVMContext &C) { AttrBuilder FnAttrs(C); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly()); -#else - FnAttrs.addAttribute(Attribute::InaccessibleMemOnly); -#endif FnAttrs.addAttribute(Attribute::NoUnwind); FnAttrs.addAttribute(Attribute::NoRecurse); return AttributeList::get(C, @@ -1300,12 +1265,7 @@ static const auto memcmp_func = new JuliaFunction{ {getPointerTy(C), getPointerTy(C), T_size}, false); }, [](LLVMContext &C) { AttrBuilder FnAttrs(C); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Ref)); -#else - FnAttrs.addAttribute(Attribute::ArgMemOnly); - FnAttrs.addAttribute(Attribute::ReadOnly); -#endif FnAttrs.addAttribute(Attribute::NoUnwind); return AttributeList::get(C, AttributeSet::get(C, FnAttrs), @@ -1355,11 +1315,7 @@ static const auto jlfieldindex_func = new JuliaFunction<>{ }, [](LLVMContext &C) { AttrBuilder FnAttrs(C); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::readOnly()); -#else - FnAttrs.addAttribute(Attribute::ReadOnly); -#endif FnAttrs.addAttribute(Attribute::NoUnwind); FnAttrs.addAttribute(Attribute::WillReturn); return AttributeList::get(C, @@ -1425,9 +1381,7 @@ static const auto jl_allocgenericmemory = new JuliaFunction= 160000 FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly(ModRefInfo::ModRef) | MemoryEffects::argMemOnly(ModRefInfo::Ref)); -#endif FnAttrs.addAttribute(Attribute::WillReturn); RetAttrs.addAlignmentAttr(Align(16)); RetAttrs.addAttribute(Attribute::NonNull); @@ -1505,11 +1459,7 @@ static const auto pointer_from_objref_func = new JuliaFunction<>{ {PointerType::get(JuliaType::get_jlvalue_ty(C), AddressSpace::Derived)}, false); }, [](LLVMContext &C) { AttrBuilder FnAttrs(C); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::none()); -#else - FnAttrs.addAttribute(Attribute::ReadNone); -#endif FnAttrs.addAttribute(Attribute::NoUnwind); return AttributeList::get(C, AttributeSet::get(C, FnAttrs), @@ -1532,11 +1482,7 @@ static const auto gc_loaded_func = new JuliaFunction<>{ FnAttrs.addAttribute(Attribute::Speculatable); FnAttrs.addAttribute(Attribute::WillReturn); FnAttrs.addAttribute(Attribute::NoRecurse); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::none()); -#else - FnAttrs.addAttribute(Attribute::ReadNone); -#endif AttrBuilder RetAttrs(C); RetAttrs.addAttribute(Attribute::NonNull); RetAttrs.addAttribute(Attribute::NoUndef); @@ -2440,11 +2386,7 @@ static Value *emit_inttoptr(jl_codectx_t &ctx, Value *v, Type *ty) auto ptr = I->getOperand(0); if (ty->getPointerAddressSpace() == ptr->getType()->getPointerAddressSpace()) return ptr; - #if JL_LLVM_VERSION >= 170000 else - #else - else if (cast(ty)->hasSameElementTypeAs(cast(ptr->getType()))) - #endif return ctx.builder.CreateAddrSpaceCast(ptr, ty); } ++EmittedIntToPtrs; @@ -10343,10 +10285,6 @@ char jl_using_perf_jitevents = 0; int jl_is_timing_passes = 0; -#if JL_LLVM_VERSION < 170000 -int jl_opaque_ptrs_set = 0; -#endif - extern "C" void jl_init_llvm(void) { jl_page_size = jl_getpagesize(); @@ -10365,12 +10303,8 @@ extern "C" void jl_init_llvm(void) initializeAnalysis(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); -#if JL_LLVM_VERSION >= 160000 - // TODO -#else - initializeAggressiveInstCombine(Registry); - initializeInstrumentation(Registry); -#endif + // TODO: initializeAggressiveInstCombine(Registry); + // TODO: initializeInstrumentation(Registry); initializeTarget(Registry); #ifdef USE_POLLY polly::initializePollyPasses(Registry); @@ -10396,17 +10330,6 @@ extern "C" void jl_init_llvm(void) if (clopt && clopt->getNumOccurrences() == 0) cl::ProvidePositionalOption(clopt, "4", 1); - #if JL_LLVM_VERSION < 170000 - // we want the opaque-pointers to be opt-in, per LLVMContext, for this release - // so change the default value back to pre-14.x, without changing the NumOccurrences flag for it - clopt = llvmopts.lookup("opaque-pointers"); - if (clopt && clopt->getNumOccurrences() == 0) { - clopt->addOccurrence(1, clopt->ArgStr, "false", true); - } else { - jl_opaque_ptrs_set = 1; - } - #endif - clopt = llvmopts.lookup("time-passes"); if (clopt && clopt->getNumOccurrences() > 0) jl_is_timing_passes = 1; diff --git a/src/disasm.cpp b/src/disasm.cpp index b944e48430c29..6a7985bd7ec1b 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -58,11 +58,7 @@ #include "llvm-version.h" // for outputting disassembly -#if JL_LLVM_VERSION >= 170000 #include -#else -#include -#endif #include #include #include @@ -505,7 +501,7 @@ jl_value_t *jl_dump_function_ir_impl(jl_llvmf_dump_t *dump, char strip_ir_metada auto TSM = std::unique_ptr(unwrap(dump->TSM)); //If TSM is not passed in, then the context MUST be locked externally. //RAII will release the lock - Optional lock; + std::optional lock; if (TSM) { lock.emplace(TSM->getContext().getLock()); } @@ -1107,11 +1103,7 @@ static void jl_dump_asm_internal( const MCOperand &OpI = Inst.getOperand(Op); if (OpI.isImm()) { int64_t imm = OpI.getImm(); - #if JL_LLVM_VERSION >= 170000 if (opinfo.operands()[Op].OperandType == MCOI::OPERAND_PCREL) - #else - if (opinfo.OpInfo[Op].OperandType == MCOI::OPERAND_PCREL) - #endif imm += Fptr + Index; const char *name = DisInfo.lookupSymbolName(imm); if (name) diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 42ddfb688af39..80867daade267 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -37,11 +37,7 @@ #include #include #include -#if JL_LLVM_VERSION >= 170000 #include -#else -#include -#endif #include #include @@ -1103,22 +1099,13 @@ class JLDebuginfoPlugin : public ObjectLinkingLayer::Plugin { return Error::success(); } -#if JL_LLVM_VERSION >= 160000 Error notifyRemovingResources(JITDylib &JD, orc::ResourceKey K) override -#else - Error notifyRemovingResources(orc::ResourceKey K) override -#endif { return Error::success(); } -#if JL_LLVM_VERSION >= 160000 void notifyTransferringResources(JITDylib &JD, orc::ResourceKey DstKey, orc::ResourceKey SrcKey) override {} -#else - void notifyTransferringResources(orc::ResourceKey DstKey, - orc::ResourceKey SrcKey) override {} -#endif void modifyPassConfig(MaterializationResponsibility &MR, jitlink::LinkGraph &, jitlink::PassConfiguration &PassConfig) override @@ -1168,21 +1155,12 @@ class JLMemoryUsagePlugin : public ObjectLinkingLayer::Plugin { Error notifyFailed(orc::MaterializationResponsibility &MR) override { return Error::success(); } -#if JL_LLVM_VERSION >= 160000 Error notifyRemovingResources(JITDylib &JD, orc::ResourceKey K) override -#else - Error notifyRemovingResources(orc::ResourceKey K) override -#endif { return Error::success(); } -#if JL_LLVM_VERSION >= 160000 void notifyTransferringResources(JITDylib &JD, orc::ResourceKey DstKey, orc::ResourceKey SrcKey) override {} -#else - void notifyTransferringResources(orc::ResourceKey DstKey, - orc::ResourceKey SrcKey) override {} -#endif void modifyPassConfig(orc::MaterializationResponsibility &, jitlink::LinkGraph &, @@ -1199,11 +1177,7 @@ class JLMemoryUsagePlugin : public ObjectLinkingLayer::Plugin { for (auto block : section.blocks()) { secsize += block->getSize(); } -#if JL_LLVM_VERSION >= 160000 if ((section.getMemProt() & orc::MemProt::Exec) == orc::MemProt::None) { -#else - if ((section.getMemProt() & jitlink::MemProt::Exec) == jitlink::MemProt::None) { -#endif data_size += secsize; } else { code_size += secsize; @@ -1235,11 +1209,7 @@ class JLMemoryUsagePlugin : public ObjectLinkingLayer::Plugin { // TODO: Port our memory management optimisations to JITLink instead of using the // default InProcessMemoryManager. std::unique_ptr createJITLinkMemoryManager() JL_NOTSAFEPOINT { -#if JL_LLVM_VERSION < 160000 - return cantFail(orc::MapperJITLinkMemoryManager::CreateWithMapper()); -#else return cantFail(orc::MapperJITLinkMemoryManager::CreateWithMapper(/*Reservation Granularity*/ 16 * 1024 * 1024)); -#endif } #ifdef _COMPILER_CLANG_ @@ -1288,21 +1258,11 @@ class ForwardingMemoryManager : public RuntimeDyld::MemoryManager { bool IsReadOnly) override { return MemMgr->allocateDataSection(Size, Alignment, SectionID, SectionName, IsReadOnly); } -#if JL_LLVM_VERSION >= 160000 virtual void reserveAllocationSpace(uintptr_t CodeSize, Align CodeAlign, uintptr_t RODataSize, Align RODataAlign, uintptr_t RWDataSize, Align RWDataAlign) override { return MemMgr->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign, RWDataSize, RWDataAlign); } -#else - virtual void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, - uintptr_t RODataSize, - uint32_t RODataAlign, - uintptr_t RWDataSize, - uint32_t RWDataAlign) override { - return MemMgr->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign, RWDataSize, RWDataAlign); - } -#endif virtual bool needsToReserveAllocationSpace() override { return MemMgr->needsToReserveAllocationSpace(); } @@ -1415,7 +1375,7 @@ namespace { FeaturesStr = Features.getString(); } // Allocate a target... - Optional codemodel = + std::optional codemodel = #ifdef _P64 // Make sure we are using the large code model on 64bit // Let LLVM pick a default suitable for jitting on 32bit @@ -1830,11 +1790,6 @@ struct JuliaOJIT::DLSymOptimizer { if (named) { auto T = GV.getValueType(); assert(T->isPointerTy()); - #if JL_LLVM_VERSION < 170000 - if (!T->isOpaquePointerTy()) { - T = T->getNonOpaquePointerElementType(); - } - #endif init = GlobalAlias::create(T, 0, GlobalValue::PrivateLinkage, GV.getName() + ".jit", init, &M); } GV.setInitializer(init); @@ -1885,11 +1840,6 @@ struct JuliaOJIT::DLSymOptimizer { if (named) { auto T = CI->getType(); assert(T->isPointerTy()); - #if JL_LLVM_VERSION < 170000 - if (!T->isOpaquePointerTy()) { - T = T->getNonOpaquePointerElementType(); - } - #endif init = GlobalAlias::create(T, 0, GlobalValue::PrivateLinkage, CI->getName() + ".jit", init, &M); } // DCE and SimplifyCFG will kill the branching structure around @@ -1933,19 +1883,6 @@ void fixupTM(TargetMachine &TM) { } } -#if JL_LLVM_VERSION < 170000 -extern int jl_opaque_ptrs_set; -void SetOpaquePointer(LLVMContext &ctx) { - if (jl_opaque_ptrs_set) - return; -#ifndef JL_LLVM_OPAQUE_POINTERS - ctx.setOpaquePointers(false); -#else - ctx.setOpaquePointers(true); -#endif -} -#endif - llvm::DataLayout jl_create_datalayout(TargetMachine &TM) { // Mark our address spaces as non-integral auto jl_data_layout = TM.createDataLayout(); @@ -2053,7 +1990,7 @@ JuliaOJIT::JuliaOJIT() orc::SymbolAliasMap jl_crt = { // Float16 conversion routines -#if defined(_CPU_X86_64_) && defined(_OS_DARWIN_) && JL_LLVM_VERSION >= 160000 +#if defined(_CPU_X86_64_) && defined(_OS_DARWIN_) // LLVM 16 reverted to soft-float ABI for passing half on x86_64 Darwin // https://github.com/llvm/llvm-project/commit/2bcf51c7f82ca7752d1bba390a2e0cb5fdd05ca9 { mangle("__gnu_h2f_ieee"), { mangle("julia_half_to_float"), JITSymbolFlags::Exported } }, @@ -2087,7 +2024,6 @@ JuliaOJIT::JuliaOJIT() #ifdef MSAN_EMUTLS_WORKAROUND orc::SymbolMap msan_crt; - #if JL_LLVM_VERSION >= 170000 msan_crt[mangle("__emutls_get_address")] = {ExecutorAddr::fromPtr(msan_workaround::getTLSAddress), JITSymbolFlags::Exported}; msan_crt[mangle("__emutls_v.__msan_param_tls")] = {ExecutorAddr::fromPtr( reinterpret_cast(static_cast(msan_workaround::MSanTLS::param))), JITSymbolFlags::Exported}; @@ -2105,25 +2041,6 @@ JuliaOJIT::JuliaOJIT() reinterpret_cast(static_cast(msan_workaround::MSanTLS::va_arg_overflow_size))), JITSymbolFlags::Exported}; msan_crt[mangle("__emutls_v.__msan_origin_tls")] = {ExecutorAddr::fromPtr( reinterpret_cast(static_cast(msan_workaround::MSanTLS::origin))), JITSymbolFlags::Exported}; - #else - msan_crt[mangle("__emutls_get_address")] = JITEvaluatedSymbol::fromPointer(msan_workaround::getTLSAddress, JITSymbolFlags::Exported); - msan_crt[mangle("__emutls_v.__msan_param_tls")] = JITEvaluatedSymbol::fromPointer( - reinterpret_cast(static_cast(msan_workaround::MSanTLS::param)), JITSymbolFlags::Exported); - msan_crt[mangle("__emutls_v.__msan_param_origin_tls")] = JITEvaluatedSymbol::fromPointer( - reinterpret_cast(static_cast(msan_workaround::MSanTLS::param_origin)), JITSymbolFlags::Exported); - msan_crt[mangle("__emutls_v.__msan_retval_tls")] = JITEvaluatedSymbol::fromPointer( - reinterpret_cast(static_cast(msan_workaround::MSanTLS::retval)), JITSymbolFlags::Exported); - msan_crt[mangle("__emutls_v.__msan_retval_origin_tls")] = JITEvaluatedSymbol::fromPointer( - reinterpret_cast(static_cast(msan_workaround::MSanTLS::retval_origin)), JITSymbolFlags::Exported); - msan_crt[mangle("__emutls_v.__msan_va_arg_tls")] = JITEvaluatedSymbol::fromPointer( - reinterpret_cast(static_cast(msan_workaround::MSanTLS::va_arg)), JITSymbolFlags::Exported); - msan_crt[mangle("__emutls_v.__msan_va_arg_origin_tls")] = JITEvaluatedSymbol::fromPointer( - reinterpret_cast(static_cast(msan_workaround::MSanTLS::va_arg_origin)), JITSymbolFlags::Exported); - msan_crt[mangle("__emutls_v.__msan_va_arg_overflow_size_tls")] = JITEvaluatedSymbol::fromPointer( - reinterpret_cast(static_cast(msan_workaround::MSanTLS::va_arg_overflow_size)), JITSymbolFlags::Exported); - msan_crt[mangle("__emutls_v.__msan_origin_tls")] = JITEvaluatedSymbol::fromPointer( - reinterpret_cast(static_cast(msan_workaround::MSanTLS::origin)), JITSymbolFlags::Exported); - #endif cantFail(GlobalJD.define(orc::absoluteSymbols(msan_crt))); #endif #if JL_LLVM_VERSION < 190000 @@ -2133,11 +2050,7 @@ JuliaOJIT::JuliaOJIT() // hopefully fixed upstream by e7698a13e319a9919af04d3d693a6f6ea7168a44 static int64_t jl___asan_globals_registered; orc::SymbolMap asan_crt; - #if JL_LLVM_VERSION >= 170000 asan_crt[mangle("___asan_globals_registered")] = {ExecutorAddr::fromPtr(&jl___asan_globals_registered), JITSymbolFlags::Common | JITSymbolFlags::Exported}; - #else - asan_crt[mangle("___asan_globals_registered")] = JITEvaluatedSymbol::fromPointer(&jl___asan_globals_registered, JITSymbolFlags::Common | JITSymbolFlags::Exported); - #endif cantFail(JD.define(orc::absoluteSymbols(asan_crt))); #endif #endif @@ -2148,9 +2061,6 @@ JuliaOJIT::~JuliaOJIT() = default; ThreadSafeContext JuliaOJIT::makeContext() { auto ctx = std::make_unique(); - #if JL_LLVM_VERSION < 170000 - SetOpaquePointer(*ctx); - #endif return orc::ThreadSafeContext(std::move(ctx)); } @@ -2162,11 +2072,7 @@ orc::SymbolStringPtr JuliaOJIT::mangle(StringRef Name) void JuliaOJIT::addGlobalMapping(StringRef Name, uint64_t Addr) { - #if JL_LLVM_VERSION >= 170000 cantFail(JD.define(orc::absoluteSymbols({{mangle(Name), {ExecutorAddr::fromPtr((void*)Addr), JITSymbolFlags::Exported}}}))); - #else - cantFail(JD.define(orc::absoluteSymbols({{mangle(Name), JITEvaluatedSymbol::fromPointer((void*)Addr)}}))); - #endif } void JuliaOJIT::addModule(orc::ThreadSafeModule TSM) @@ -2245,7 +2151,6 @@ SmallVector JuliaOJIT::findSymbols(ArrayRef Names) return Addrs; } -#if JL_LLVM_VERSION >= 170000 Expected JuliaOJIT::findSymbol(StringRef Name, bool ExportedSymbolsOnly) { orc::JITDylib* SearchOrders[3] = {&JD, &GlobalJD, &ExternalJD}; @@ -2286,50 +2191,6 @@ uint64_t JuliaOJIT::getFunctionAddress(StringRef Name) } return addr->getAddress().getValue(); } -#else -JL_JITSymbol JuliaOJIT::findSymbol(StringRef Name, bool ExportedSymbolsOnly) -{ - orc::JITDylib* SearchOrders[3] = {&JD, &GlobalJD, &ExternalJD}; - ArrayRef SearchOrder = ArrayRef(&SearchOrders[0], ExportedSymbolsOnly ? 3 : 1); - auto Sym = ES.lookup(SearchOrder, Name); - if (Sym) - return *Sym; - return Sym.takeError(); -} - -JL_JITSymbol JuliaOJIT::findUnmangledSymbol(StringRef Name) -{ - return findSymbol(getMangledName(Name), true); -} - -Expected JuliaOJIT::findExternalJDSymbol(StringRef Name, bool ExternalJDOnly) -{ - orc::JITDylib* SearchOrders[3] = {&ExternalJD, &GlobalJD, &JD}; - ArrayRef SearchOrder = ArrayRef(&SearchOrders[0], ExternalJDOnly ? 1 : 3); - auto Sym = ES.lookup(SearchOrder, getMangledName(Name)); - return Sym; -} - -uint64_t JuliaOJIT::getGlobalValueAddress(StringRef Name) -{ - auto addr = findSymbol(getMangledName(Name), false); - if (!addr) { - consumeError(addr.takeError()); - return 0; - } - return cantFail(addr).getAddress(); -} - -uint64_t JuliaOJIT::getFunctionAddress(StringRef Name) -{ - auto addr = findSymbol(getMangledName(Name), false); - if (!addr) { - consumeError(addr.takeError()); - return 0; - } - return cantFail(addr).getAddress(); -} -#endif StringRef JuliaOJIT::getFunctionAtAddress(uint64_t Addr, jl_callptr_t invoke, jl_code_instance_t *codeinst) { @@ -2361,13 +2222,8 @@ StringRef JuliaOJIT::getFunctionAtAddress(uint64_t Addr, jl_callptr_t invoke, jl } #ifdef JL_USE_JITLINK -#if JL_LLVM_VERSION >= 170000 #define addAbsoluteToMap(map,name) \ (map[mangle(#name)] = {ExecutorAddr::fromPtr(&name), JITSymbolFlags::Exported | JITSymbolFlags::Callable}, orc::ExecutorAddr::fromPtr(&name)) -#else -#define addAbsoluteToMap(map,name) \ - (map[mangle(#name)] = JITEvaluatedSymbol::fromPointer(&name, JITSymbolFlags::Exported | JITSymbolFlags::Callable), orc::ExecutorAddr::fromPtr(&name)) -#endif void JuliaOJIT::enableJITDebuggingSupport() { @@ -2552,11 +2408,7 @@ void jl_merge_module(orc::ThreadSafeModule &destTSM, orc::ThreadSafeModule srcTS } // Reparent the global variable: SG.removeFromParent(); - #if JL_LLVM_VERSION >= 170000 dest.insertGlobalVariable(&SG); - #else - dest.getGlobalList().push_back(&SG); - #endif // Comdat is owned by the Module SG.setComdat(nullptr); } @@ -2603,11 +2455,7 @@ void jl_merge_module(orc::ThreadSafeModule &destTSM, orc::ThreadSafeModule srcTS } } SG.removeFromParent(); - #if JL_LLVM_VERSION >= 170000 dest.insertAlias(&SG); - #else - dest.getAliasList().push_back(&SG); - #endif } // metadata nodes need to be explicitly merged not just copied diff --git a/src/jitlayers.h b/src/jitlayers.h index baba5412226e3..6665be6a33faa 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -363,14 +363,6 @@ class MaxAlignedAllocImpl }; using MaxAlignedAlloc = MaxAlignedAllocImpl<>; -#if JL_LLVM_VERSION < 170000 -typedef JITSymbol JL_JITSymbol; -// The type that is similar to SymbolInfo on LLVM 4.0 is actually -// `JITEvaluatedSymbol`. However, we only use this type when a JITSymbol -// is expected. -typedef JITSymbol JL_SymbolInfo; -#endif - using CompilerResultT = Expected>; using OptimizerResultT = Expected; using SharedBytesT = StringSet::MapEntryTy)>>; @@ -472,7 +464,7 @@ class JuliaOJIT { } private: ResourcePool &pool; - Optional resource; + std::optional resource; }; OwningResource operator*() JL_NOTSAFEPOINT { @@ -558,16 +550,10 @@ class JuliaOJIT { orc::ExecutionSession &getExecutionSession() JL_NOTSAFEPOINT { return ES; } orc::JITDylib &getExternalJITDylib() JL_NOTSAFEPOINT { return ExternalJD; } - #if JL_LLVM_VERSION >= 170000 Expected findSymbol(StringRef Name, bool ExportedSymbolsOnly) JL_NOTSAFEPOINT; Expected findUnmangledSymbol(StringRef Name) JL_NOTSAFEPOINT; Expected findExternalJDSymbol(StringRef Name, bool ExternalJDOnly) JL_NOTSAFEPOINT; SmallVector findSymbols(ArrayRef Names) JL_NOTSAFEPOINT; - #else - JITEvaluatedSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) JL_NOTSAFEPOINT; - JITEvaluatedSymbol findUnmangledSymbol(StringRef Name) JL_NOTSAFEPOINT; - Expected findExternalJDSymbol(StringRef Name, bool ExternalJDOnly) JL_NOTSAFEPOINT; - #endif uint64_t getGlobalValueAddress(StringRef Name) JL_NOTSAFEPOINT; uint64_t getFunctionAddress(StringRef Name) JL_NOTSAFEPOINT; StringRef getFunctionAtAddress(uint64_t Addr, jl_callptr_t invoke, jl_code_instance_t *codeinst) JL_NOTSAFEPOINT; @@ -660,10 +646,6 @@ Module &jl_codegen_params_t::shared_module() JL_NOTSAFEPOINT { } void fixupTM(TargetMachine &TM) JL_NOTSAFEPOINT; -#if JL_LLVM_VERSION < 170000 -void SetOpaquePointer(LLVMContext &ctx) JL_NOTSAFEPOINT; -#endif - void optimizeDLSyms(Module &M); // NewPM diff --git a/src/llvm-codegen-shared.h b/src/llvm-codegen-shared.h index a99e18f3e3762..d9551e0552f9c 100644 --- a/src/llvm-codegen-shared.h +++ b/src/llvm-codegen-shared.h @@ -1,5 +1,6 @@ // This file is a part of Julia. License is MIT: https://julialang.org/license +#include #include #include #include @@ -8,30 +9,15 @@ #include #include #include - -#if JL_LLVM_VERSION >= 160000 #include -#endif #include "julia.h" #define STR(csym) #csym #define XSTR(csym) STR(csym) -#if JL_LLVM_VERSION >= 160000 - -#include - -template -using Optional = std::optional; static constexpr std::nullopt_t None = std::nullopt; -#else - -#include - -#endif - enum AddressSpace { Generic = 0, Tracked = 10, @@ -180,7 +166,7 @@ static inline llvm::Instruction *tbaa_decorate(llvm::MDNode *md, llvm::Instructi using namespace llvm; inst->setMetadata(llvm::LLVMContext::MD_tbaa, md); if (llvm::isa(inst) && md && md == get_tbaa_const(md->getContext())) { - inst->setMetadata(llvm::LLVMContext::MD_invariant_load, llvm::MDNode::get(md->getContext(), None)); + inst->setMetadata(llvm::LLVMContext::MD_invariant_load, llvm::MDNode::get(md->getContext(), std::nullopt)); } return inst; } @@ -245,11 +231,7 @@ static inline void emit_gc_safepoint(llvm::IRBuilder<> &builder, llvm::Type *T_s if (!F) { FunctionType *FT = FunctionType::get(Type::getVoidTy(C), {T_size->getPointerTo()}, false); F = Function::Create(FT, Function::ExternalLinkage, "julia.safepoint", M); -#if JL_LLVM_VERSION >= 160000 F->setMemoryEffects(MemoryEffects::inaccessibleOrArgMemOnly()); -#else - F->addFnAttr(Attribute::InaccessibleMemOrArgMemOnly); -#endif } builder.CreateCall(F, {signal_page}); } diff --git a/src/llvm-cpufeatures.cpp b/src/llvm-cpufeatures.cpp index 05d62adc57926..a6e963664b0f3 100644 --- a/src/llvm-cpufeatures.cpp +++ b/src/llvm-cpufeatures.cpp @@ -37,7 +37,7 @@ STATISTIC(LoweredWithoutFMA, "Number of have_fma's that were lowered to false"); extern JuliaOJIT *jl_ExecutionEngine; // whether this platform unconditionally (i.e. without needing multiversioning) supports FMA -Optional always_have_fma(Function &intr, const Triple &TT) JL_NOTSAFEPOINT { +std::optional always_have_fma(Function &intr, const Triple &TT) JL_NOTSAFEPOINT { if (TT.isAArch64()) { auto intr_name = intr.getName(); auto typ = intr_name.substr(strlen("julia.cpu.have_fma.")); diff --git a/src/llvm-julia-licm.cpp b/src/llvm-julia-licm.cpp index 8d80f7fd54877..baf844dffa89c 100644 --- a/src/llvm-julia-licm.cpp +++ b/src/llvm-julia-licm.cpp @@ -342,11 +342,7 @@ struct JuliaLICM : public JuliaPassContext { } } if (changed && SE) { -#if JL_LLVM_VERSION >= 160000 SE->forgetLoopDispositions(); -#else - SE->forgetLoopDispositions(L); -#endif } #ifdef JL_VERIFY_PASSES assert(!verifyLLVMIR(*L)); diff --git a/src/llvm-late-gc-lowering.cpp b/src/llvm-late-gc-lowering.cpp index d95cc9c49b698..ff2cac6e49406 100644 --- a/src/llvm-late-gc-lowering.cpp +++ b/src/llvm-late-gc-lowering.cpp @@ -1163,9 +1163,6 @@ State LateLowerGCFrame::LocalScan(Function &F) { } if (CI->hasStructRetAttr()) { Type *ElT = getAttributeAtIndex(CI->getAttributes(), 1, Attribute::StructRet).getValueAsType(); - #if JL_LLVM_VERSION < 170000 - assert(cast(CI->getArgOperand(0)->getType())->isOpaqueOrPointeeTypeMatches(getAttributeAtIndex(CI->getAttributes(), 1, Attribute::StructRet).getValueAsType())); - #endif auto tracked = CountTrackedPointers(ElT, true); if (tracked.count) { AllocaInst *SRet = dyn_cast((CI->arg_begin()[0])->stripInBoundsOffsets()); @@ -1252,38 +1249,20 @@ State LateLowerGCFrame::LocalScan(Function &F) { callee->getName() == "memcmp") { continue; } -#if JL_LLVM_VERSION >= 160000 if (callee->getMemoryEffects().onlyReadsMemory() || callee->getMemoryEffects().onlyAccessesArgPointees()) { continue; } -#else - if (callee->hasFnAttribute(Attribute::ReadNone) || - callee->hasFnAttribute(Attribute::ReadOnly) || - callee->hasFnAttribute(Attribute::ArgMemOnly)) { - continue; - } -#endif if (MemTransferInst *MI = dyn_cast(CI)) { MaybeTrackDst(S, MI); } } -#if JL_LLVM_VERSION >= 160000 if (isa(CI) || CI->getMemoryEffects().onlyAccessesArgPointees() || CI->getMemoryEffects().onlyReadsMemory()) { // Intrinsics are never safepoints. continue; } -#else - if (isa(CI) || - CI->hasFnAttr(Attribute::ArgMemOnly) || - CI->hasFnAttr(Attribute::ReadNone) || - CI->hasFnAttr(Attribute::ReadOnly)) { - // Intrinsics are never safepoints. - continue; - } -#endif SmallVector CalleeRoots; for (Use &U : CI->args()) { // Find all callee rooted arguments. diff --git a/src/llvm-lower-handlers.cpp b/src/llvm-lower-handlers.cpp index e09ea892ee488..c359bf6c117ce 100644 --- a/src/llvm-lower-handlers.cpp +++ b/src/llvm-lower-handlers.cpp @@ -8,11 +8,7 @@ #include #include -#if JL_LLVM_VERSION >= 170000 #include -#else -#include -#endif #include #include #include diff --git a/src/llvm-multiversioning.cpp b/src/llvm-multiversioning.cpp index 22ef973decfe9..a76d076ebd6f3 100644 --- a/src/llvm-multiversioning.cpp +++ b/src/llvm-multiversioning.cpp @@ -15,11 +15,7 @@ #include #include #include -#if JL_LLVM_VERSION >= 170000 #include -#else -#include -#endif #include #include #include @@ -51,7 +47,7 @@ using namespace llvm; -extern Optional always_have_fma(Function&, const Triple &TT); +extern std::optional always_have_fma(Function&, const Triple &TT); namespace { constexpr uint32_t clone_mask = @@ -185,7 +181,7 @@ struct TargetSpec { } }; -static Optional> get_target_specs(Module &M) { +static std::optional> get_target_specs(Module &M) { auto md = M.getModuleFlag("julia.mv.specs"); if (!md) return None; diff --git a/src/llvm-pass-helpers.cpp b/src/llvm-pass-helpers.cpp index 4e9e4826b4f75..ca25251040fb2 100644 --- a/src/llvm-pass-helpers.cpp +++ b/src/llvm-pass-helpers.cpp @@ -129,9 +129,7 @@ namespace jl_intrinsics { static Function *addGCAllocAttributes(Function *target) { auto FnAttrs = AttrBuilder(target->getContext()); -#if JL_LLVM_VERSION >= 160000 FnAttrs.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Ref) | MemoryEffects::inaccessibleMemOnly(ModRefInfo::ModRef)); -#endif FnAttrs.addAllocKindAttr(AllocFnKind::Alloc); FnAttrs.addAttribute(Attribute::WillReturn); FnAttrs.addAttribute(Attribute::NoUnwind); @@ -228,11 +226,7 @@ namespace jl_intrinsics { false), Function::ExternalLinkage, QUEUE_GC_ROOT_NAME); -#if JL_LLVM_VERSION >= 160000 intrinsic->setMemoryEffects(MemoryEffects::inaccessibleOrArgMemOnly()); -#else - intrinsic->addFnAttr(Attribute::InaccessibleMemOrArgMemOnly); -#endif return intrinsic; }); @@ -248,11 +242,7 @@ namespace jl_intrinsics { false), Function::ExternalLinkage, SAFEPOINT_NAME); -#if JL_LLVM_VERSION >= 160000 intrinsic->setMemoryEffects(MemoryEffects::inaccessibleOrArgMemOnly()); -#else - intrinsic->addFnAttr(Attribute::InaccessibleMemOrArgMemOnly); -#endif return intrinsic; }); } @@ -309,11 +299,7 @@ namespace jl_well_known { false), Function::ExternalLinkage, GC_QUEUE_ROOT_NAME); -#if JL_LLVM_VERSION >= 160000 func->setMemoryEffects(MemoryEffects::inaccessibleOrArgMemOnly()); -#else - func->addFnAttr(Attribute::InaccessibleMemOrArgMemOnly); -#endif return func; }); diff --git a/src/llvm-propagate-addrspaces.cpp b/src/llvm-propagate-addrspaces.cpp index 4e5a2ee5e0d54..06a52ad3dcb43 100644 --- a/src/llvm-propagate-addrspaces.cpp +++ b/src/llvm-propagate-addrspaces.cpp @@ -163,22 +163,14 @@ Value *PropagateJuliaAddrspacesVisitor::LiftPointer(Module *M, Value *V, Instruc Instruction *InstV = cast(V); Instruction *NewV = InstV->clone(); ToInsert.push_back(std::make_pair(NewV, InstV)); - #if JL_LLVM_VERSION >= 170000 Type *NewRetTy = PointerType::get(InstV->getType(), allocaAddressSpace); - #else - Type *NewRetTy = PointerType::getWithSamePointeeType(cast(InstV->getType()), allocaAddressSpace); - #endif NewV->mutateType(NewRetTy); LiftingMap[InstV] = NewV; ToRevisit.push_back(NewV); } } auto CollapseCastsAndLift = [&](Value *CurrentV, Instruction *InsertPt) -> Value * { - #if JL_LLVM_VERSION >= 170000 PointerType *TargetType = PointerType::get(CurrentV->getType(), allocaAddressSpace); - #else - PointerType *TargetType = PointerType::getWithSamePointeeType(cast(CurrentV->getType()), allocaAddressSpace); - #endif while (!LiftingMap.count(CurrentV)) { if (isa(CurrentV)) CurrentV = cast(CurrentV)->getOperand(0); @@ -192,17 +184,7 @@ Value *PropagateJuliaAddrspacesVisitor::LiftPointer(Module *M, Value *V, Instruc } if (LiftingMap.count(CurrentV)) CurrentV = LiftingMap[CurrentV]; - #if JL_LLVM_VERSION >= 170000 assert(CurrentV->getType() == TargetType); - #else - if (CurrentV->getType() != TargetType) { - // Shouldn't get here when using opaque pointers, so the new BitCastInst is fine - assert(CurrentV->getContext().supportsTypedPointers()); - auto *BCI = new BitCastInst(CurrentV, TargetType); - ToInsert.push_back(std::make_pair(BCI, InsertPt)); - CurrentV = BCI; - } - #endif return CurrentV; }; diff --git a/src/llvm-ptls.cpp b/src/llvm-ptls.cpp index 614ed15f840e6..e36136859517a 100644 --- a/src/llvm-ptls.cpp +++ b/src/llvm-ptls.cpp @@ -9,11 +9,7 @@ #include #include -#if JL_LLVM_VERSION >= 170000 #include -#else -#include -#endif #include #include #include @@ -67,11 +63,7 @@ struct LowerPTLS { void LowerPTLS::set_pgcstack_attrs(CallInst *pgcstack) const { -#if JL_LLVM_VERSION >= 160000 pgcstack->addFnAttr(Attribute::getWithMemoryEffects(pgcstack->getContext(), MemoryEffects::none())); -#else - addFnAttr(pgcstack, Attribute::ReadNone); -#endif addFnAttr(pgcstack, Attribute::NoUnwind); } diff --git a/src/llvm-remove-addrspaces.cpp b/src/llvm-remove-addrspaces.cpp index 89ae1d292d108..bb492f467e74c 100644 --- a/src/llvm-remove-addrspaces.cpp +++ b/src/llvm-remove-addrspaces.cpp @@ -44,19 +44,7 @@ class AddrspaceRemoveTypeRemapper : public ValueMapTypeRemapper { DstTy = SrcTy; if (auto Ty = dyn_cast(SrcTy)) { - #if JL_LLVM_VERSION >= 170000 DstTy = PointerType::get(Ty->getContext(), ASRemapper(Ty->getAddressSpace())); - #else - if (Ty->isOpaque()) { - DstTy = PointerType::get(Ty->getContext(), ASRemapper(Ty->getAddressSpace())); - } - else { - //Remove once opaque pointer transition is complete - DstTy = PointerType::get( - remapType(Ty->getNonOpaquePointerElementType()), - ASRemapper(Ty->getAddressSpace())); - } - #endif } else if (auto Ty = dyn_cast(SrcTy)) { SmallVector Params; @@ -157,24 +145,8 @@ class AddrspaceRemoveValueMaterializer : public ValueMaterializer { Ops.push_back(NewOp ? cast(NewOp) : Op); } - #if JL_LLVM_VERSION >= 170000 if (CE->getOpcode() != Instruction::GetElementPtr) DstV = CE->getWithOperands(Ops, Ty); - #else - if (CE->getOpcode() == Instruction::GetElementPtr) { - // GEP const exprs need to know the type of the source. - // asserts remapType(typeof arg0) == typeof mapValue(arg0). - Constant *Src = CE->getOperand(0); - auto ptrty = cast(Src->getType()->getScalarType()); - //Remove once opaque pointer transition is complete - if (!ptrty->isOpaque()) { - Type *SrcTy = remapType(ptrty->getNonOpaquePointerElementType()); - DstV = CE->getWithOperands(Ops, Ty, false, SrcTy); - } - } - else - DstV = CE->getWithOperands(Ops, Ty); - #endif } } diff --git a/src/llvm-simdloop.cpp b/src/llvm-simdloop.cpp index e12b30e3db466..3faa9d9728e67 100644 --- a/src/llvm-simdloop.cpp +++ b/src/llvm-simdloop.cpp @@ -297,11 +297,7 @@ static bool processLoop(Loop &L, OptimizationRemarkEmitter &ORE, ScalarEvolution } if (SE) -#if JL_LLVM_VERSION >= 160000 SE->forgetLoopDispositions(); -#else - SE->forgetLoopDispositions(&L); -#endif } #ifdef JL_VERIFY_PASSES diff --git a/src/llvm-version.h b/src/llvm-version.h index 984e918d480cc..061d80deb02f9 100644 --- a/src/llvm-version.h +++ b/src/llvm-version.h @@ -10,12 +10,8 @@ #define JL_LLVM_VERSION (LLVM_VERSION_MAJOR * 10000 + LLVM_VERSION_MINOR * 100 \ + LLVM_VERSION_PATCH) -#if JL_LLVM_VERSION < 150000 - #error Only LLVM versions >= 15.0.0 are supported by Julia -#endif - -#if JL_LLVM_VERSION >= 160000 - #define JL_LLVM_OPAQUE_POINTERS 1 +#if JL_LLVM_VERSION < 170000 + #error Only LLVM versions >= 17.0.0 are supported by Julia #endif #if JL_LLVM_VERSION < 19000 && defined(_CPU_RISCV64_) diff --git a/src/pipeline.cpp b/src/pipeline.cpp index f8976099ee53c..8c9054c0d65ff 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -150,15 +150,9 @@ namespace { // Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn(); // MPM.addPass(RequireAnalysisPass()); //Let's assume the defaults are actually fine for our purposes - #if JL_LLVM_VERSION < 160000 - // MPM.addPass(ModuleAddressSanitizerPass( - // Opts, UseGlobalGC, UseOdrIndicator, DestructorKind)); - MPM.addPass(ModuleAddressSanitizerPass(AddressSanitizerOptions())); - #else // LLVM 16+ // MPM.addPass(AddressSanitizerPass( // Opts, UseGlobalGC, UseOdrIndicator, DestructorKind)); MPM.addPass(AddressSanitizerPass(AddressSanitizerOptions(), true, false)); - #endif // } }; ASanPass(/*SanitizerKind::Address, */false); @@ -347,12 +341,8 @@ static void buildEarlySimplificationPipeline(ModulePassManager &MPM, PassBuilder FPM.addPass(DCEPass()); FPM.addPass(SimplifyCFGPass(basicSimplifyCFGOptions())); if (O.getSpeedupLevel() >= 1) { -#if JL_LLVM_VERSION >= 160000 // TODO check the LLVM 15 default. FPM.addPass(SROAPass(SROAOptions::PreserveCFG)); -#else - FPM.addPass(SROAPass()); -#endif } MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); } @@ -389,12 +379,8 @@ static void buildEarlyOptimizerPipeline(ModulePassManager &MPM, PassBuilder *PB, if (O.getSpeedupLevel() >= 1) { FunctionPassManager FPM; if (O.getSpeedupLevel() >= 2) { -#if JL_LLVM_VERSION >= 160000 // TODO check the LLVM 15 default. FPM.addPass(SROAPass(SROAOptions::PreserveCFG)); -#else - FPM.addPass(SROAPass()); -#endif // SROA can duplicate PHI nodes which can block LowerSIMD FPM.addPass(InstCombinePass()); FPM.addPass(JumpThreadingPass()); @@ -468,12 +454,8 @@ static void buildScalarOptimizerPipeline(FunctionPassManager &FPM, PassBuilder * if (options.enable_scalar_optimizations) { if (O.getSpeedupLevel() >= 2) { JULIA_PASS(FPM.addPass(AllocOptPass())); - #if JL_LLVM_VERSION >= 160000 // TODO check the LLVM 15 default. FPM.addPass(SROAPass(SROAOptions::PreserveCFG)); - #else - FPM.addPass(SROAPass()); - #endif FPM.addPass(InstSimplifyPass()); FPM.addPass(GVNPass()); FPM.addPass(MemCpyOptPass()); @@ -737,12 +719,7 @@ void NewPM::run(Module &M) { //We must recreate the analysis managers every time //so that analyses from previous runs of the pass manager //do not hang around for the next run -#if JL_LLVM_VERSION >= 160000 StandardInstrumentations SI(M.getContext(),false); -#else - StandardInstrumentations SI(false); -#endif -#if JL_LLVM_VERSION >= 170000 PassInstrumentationCallbacks PIC; adjustPIC(PIC); TimePasses.registerCallbacks(PIC); @@ -752,17 +729,6 @@ void NewPM::run(Module &M) { ModuleAnalysisManager MAM; SI.registerCallbacks(PIC, &MAM); SI.getTimePasses().setOutStream(nulls()); //TODO: figure out a better way of doing this -#else - FunctionAnalysisManager FAM(createFAM(O, *TM.get())); - PassInstrumentationCallbacks PIC; - adjustPIC(PIC); - TimePasses.registerCallbacks(PIC); - SI.registerCallbacks(PIC, &FAM); - SI.getTimePasses().setOutStream(nulls()); //TODO: figure out a better way of doing this - LoopAnalysisManager LAM; - CGSCCAnalysisManager CGAM; - ModuleAnalysisManager MAM; -#endif PassBuilder PB(TM.get(), PipelineTuningOptions(), None, &PIC); PB.registerLoopAnalyses(LAM); PB.registerFunctionAnalyses(FAM); @@ -794,7 +760,7 @@ OptimizationLevel getOptLevel(int optlevel) { } //This part is also basically stolen from LLVM's PassBuilder.cpp file -static Optional> parseJuliaPipelineOptions(StringRef name) { +static std::optional> parseJuliaPipelineOptions(StringRef name) { if (name.consume_front("julia")) { auto O = OptimizationLevel::O2; auto options = OptimizationOptions::defaults(); diff --git a/src/processor.cpp b/src/processor.cpp index bc12f5b54be19..3edebcc2f3ae6 100644 --- a/src/processor.cpp +++ b/src/processor.cpp @@ -7,11 +7,7 @@ #include #include #include -#if JL_LLVM_VERSION >= 170000 #include -#else -#include -#endif #include #include @@ -162,11 +158,7 @@ struct FeatureList { { int cnt = 0; for (size_t i = 0; i < n; i++) - #if JL_LLVM_VERSION >= 170000 cnt += llvm::popcount(eles[i]); - #else - cnt += llvm::countPopulation(eles[i]); - #endif return cnt; } inline bool empty() const diff --git a/src/runtime_ccall.cpp b/src/runtime_ccall.cpp index 56f8487d8fb73..2a6cb00961594 100644 --- a/src/runtime_ccall.cpp +++ b/src/runtime_ccall.cpp @@ -4,11 +4,7 @@ #include #include #include -#if JL_LLVM_VERSION >= 170000 #include -#else -#include -#endif #include #include "julia.h" diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index 450096eef5b01..80281b733bf44 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -1574,7 +1574,6 @@ bi_iintrinsic_cnvtb_fast(LLVMAShr, ashr_op, ashr_int, , 1) //un_iintrinsic_fast(LLVMByteSwap, bswap_op, bswap_int, u) un_iintrinsic_slow(LLVMByteSwap, bswap_int, u) //#define ctpop_op(a) __builtin_ctpop(a) -#if JL_LLVM_VERSION >= 170000 //uu_iintrinsic_fast(LLVMPopcount, ctpop_op, ctpop_int, u) uu_iintrinsic_slow(LLVMPopcount, ctpop_int, u) //#define ctlz_op(a) __builtin_ctlz(a) @@ -1583,16 +1582,6 @@ uu_iintrinsic_slow(LLVMCountl_zero, ctlz_int, u) //#define cttz_op(a) __builtin_cttz(a) //uu_iintrinsic_fast(LLVMCountr_zero, cttz_op, cttz_int, u) uu_iintrinsic_slow(LLVMCountr_zero, cttz_int, u) -#else -//uu_iintrinsic_fast(LLVMCountPopulation, ctpop_op, ctpop_int, u) -uu_iintrinsic_slow(LLVMCountPopulation, ctpop_int, u) -//#define ctlz_op(a) __builtin_ctlz(a) -//uu_iintrinsic_fast(LLVMCountLeadingZeros, ctlz_op, ctlz_int, u) -uu_iintrinsic_slow(LLVMCountLeadingZeros, ctlz_int, u) -//#define cttz_op(a) __builtin_cttz(a) -//uu_iintrinsic_fast(LLVMCountTrailingZeros, cttz_op, cttz_int, u) -uu_iintrinsic_slow(LLVMCountTrailingZeros, cttz_int, u) -#endif #define not_op(a) ~a un_iintrinsic_fast(LLVMFlipAllBits, not_op, not_int, u) diff --git a/src/support/win32-clang-ABI-bug/optional b/src/support/win32-clang-ABI-bug/optional index a2ecdad1e33ce..fd2f7646e1766 100644 --- a/src/support/win32-clang-ABI-bug/optional +++ b/src/support/win32-clang-ABI-bug/optional @@ -57,7 +57,6 @@ namespace optional_detail { // // The move constructible / assignable conditions emulate the remaining behavior // of std::is_trivially_copyable. -#if JL_LLVM_VERSION >= 170000 template ::value && std::is_trivially_copy_assignable::value && @@ -65,15 +64,6 @@ template ::value) && (std::is_trivially_move_assignable::value || !std::is_move_assignable::value))> -#else -template ::value && - std::is_trivially_copy_assignable::value && - (llvm::is_trivially_move_constructible::value || - !std::is_move_constructible::value) && - (std::is_trivially_move_assignable::value || - !std::is_move_assignable::value))> -#endif class OptionalStorage { union { char empty; From fe2617378cb6ea56a1b5e41ff33b7ad34bfa71ac Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 6 Dec 2024 05:32:45 -0700 Subject: [PATCH 021/198] Address some post-commit review from #56660 (#56747) Some more questions still to be answered, but this should address the immediate actionable review items. --- .../extras/CompilerDevTools/src/CompilerDevTools.jl | 12 ++---------- Compiler/src/abstractinterpretation.jl | 9 +++++---- Compiler/src/stmtinfo.jl | 2 +- base/docs/basedocs.jl | 4 ++-- base/optimized_generics.jl | 2 +- src/builtins.c | 10 ++++++---- 6 files changed, 17 insertions(+), 22 deletions(-) diff --git a/Compiler/extras/CompilerDevTools/src/CompilerDevTools.jl b/Compiler/extras/CompilerDevTools/src/CompilerDevTools.jl index cd3f7b7b4bdac..5d0df5ccaa4e4 100644 --- a/Compiler/extras/CompilerDevTools/src/CompilerDevTools.jl +++ b/Compiler/extras/CompilerDevTools/src/CompilerDevTools.jl @@ -34,19 +34,11 @@ import Core.OptimizedGenerics.CompilerPlugins: typeinf, typeinf_edge Compiler.typeinf_edge(interp, mi.def, mi.specTypes, Core.svec(), parent_frame, false, false) end -# TODO: This needs special compiler support to properly case split for multiple -# method matches, etc. -@noinline function mi_for_tt(tt, world=Base.tls_world_age()) - interp = SplitCacheInterp(; world) - match, _ = Compiler.findsup(tt, Compiler.method_table(interp)) - Base.specialize_method(match) -end - function with_new_compiler(f, args...) - tt = Base.signature_type(f, typeof(args)) + mi = @ccall jl_method_lookup(Any[f, args...]::Ptr{Any}, (1+length(args))::Csize_t, Base.tls_world_age()::Csize_t)::Ref{Core.MethodInstance} world = Base.tls_world_age() new_compiler_ci = Core.OptimizedGenerics.CompilerPlugins.typeinf( - SplitCacheOwner(), mi_for_tt(tt), Compiler.SOURCE_MODE_ABI + SplitCacheOwner(), mi, Compiler.SOURCE_MODE_ABI ) invoke(f, new_compiler_ci, args...) end diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 24daaf1e6f626..2efd8a2b7264f 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -2223,11 +2223,12 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt if isa(method_or_ci, CodeInstance) our_world = sv.world.this argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft)) - sig = method_or_ci.def.specTypes + specsig = method_or_ci.def.specTypes + defdef = method_or_ci.def.def exct = method_or_ci.exctype - if !hasintersect(argtype, sig) + if !hasintersect(argtype, specsig) return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())) - elseif !(argtype <: sig) + elseif !(argtype <: specsig) || (isa(defdef, Method) && !(argtype <: defdef.sig)) exct = Union{exct, TypeError} end callee_valid_range = WorldRange(method_or_ci.min_world, method_or_ci.max_world) @@ -2257,7 +2258,7 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt # Fall through to generic invoke handling end else - widenconst(types) >: Union{Method, CodeInstance} && return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) + hasintersect(widenconst(types), Union{Method, CodeInstance}) && return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) (types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3), false) isexact || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) unwrapped = unwrap_unionall(types) diff --git a/Compiler/src/stmtinfo.jl b/Compiler/src/stmtinfo.jl index 9f0f1f38d4c8a..4f55f068e9456 100644 --- a/Compiler/src/stmtinfo.jl +++ b/Compiler/src/stmtinfo.jl @@ -277,7 +277,7 @@ struct InvokeCICallInfo <: CallInfo edge::CodeInstance end add_edges_impl(edges::Vector{Any}, info::InvokeCICallInfo) = - add_one_edge!(edges, info.edge) + add_inlining_edge!(edges, info.edge) """ info::InvokeCallInfo diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index 141950f5e92ff..c62c980fae1e1 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -2064,8 +2064,8 @@ to `invoke(f, method.sig, args...)`. The `argtypes` argument may be a `CodeInstance`, bypassing both method lookup and specialization. The semantics of this invocation are similar to a function pointer call of the `CodeInstance`'s `invoke` pointer. It is an error to invoke a `CodeInstance` with arguments that do not match its -parent MethodInstance or from a world age not included in the `min_world`/`max_world` range. -It is undefined behavior to invoke a CodeInstance whose behavior does not match the constraints +parent `MethodInstance` or from a world age not included in the `min_world`/`max_world` range. +It is undefined behavior to invoke a `CodeInstance` whose behavior does not match the constraints specified in its fields. For some code instances with `owner !== nothing` (i.e. those generated by external compilers), it may be an error to invoke them after passing through precompilation. This is an advanced interface intended for use with external compiler plugins. diff --git a/base/optimized_generics.jl b/base/optimized_generics.jl index c0b953777ca94..6b1d146b6172b 100644 --- a/base/optimized_generics.jl +++ b/base/optimized_generics.jl @@ -61,7 +61,7 @@ end Implements a pair of functions `typeinf`/`typeinf_edge`. When the optimizer sees a call to `typeinf`, it has license to instead call `typeinf_edge`, supplying the current inference stack in `parent_frame` (but otherwise supplying the arguments -to `typeinf`). typeinf_edge will return the `CodeInstance` that `typeinf` would +to `typeinf`). `typeinf_edge` will return the `CodeInstance` that `typeinf` would have returned at runtime. The optimizer may perform a non-IPO replacement of the call to `typeinf` by the result of `typeinf_edge`. In addition, the IPO-safe fields of the `CodeInstance` may be propagated in IPO mode. diff --git a/src/builtins.c b/src/builtins.c index 3f555da9d2a83..4b9c1ad6043c2 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1590,8 +1590,10 @@ JL_CALLABLE(jl_f_invoke) } else if (jl_is_code_instance(argtypes)) { jl_code_instance_t *codeinst = (jl_code_instance_t*)args[1]; jl_callptr_t invoke = jl_atomic_load_acquire(&codeinst->invoke); - if (jl_tuple1_isa(args[0], &args[2], nargs - 2, (jl_datatype_t*)codeinst->def->specTypes)) { - jl_type_error("invoke: argument type error", codeinst->def->specTypes, arg_tuple(args[0], &args[2], nargs - 2)); + // N.B.: specTypes need not be a subtype of the method signature. We need to check both. + if (!jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)codeinst->def->specTypes) || + (jl_is_method(codeinst->def->def.value) && !jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)codeinst->def->def.method->sig))) { + jl_type_error("invoke: argument type error", codeinst->def->specTypes, arg_tuple(args[0], &args[2], nargs - 1)); } if (jl_atomic_load_relaxed(&codeinst->min_world) > jl_current_task->world_age || jl_current_task->world_age > jl_atomic_load_relaxed(&codeinst->max_world)) { @@ -1604,10 +1606,10 @@ JL_CALLABLE(jl_f_invoke) if (invoke) { return invoke(args[0], &args[2], nargs - 2, codeinst); } else { - if (codeinst->owner != jl_nothing || !jl_is_method(codeinst->def->def.value)) { + if (codeinst->owner != jl_nothing) { jl_error("Failed to invoke or compile external codeinst"); } - return jl_gf_invoke_by_method(codeinst->def->def.method, args[0], &args[2], nargs - 1); + return jl_invoke(args[0], &args[2], nargs - 1, codeinst->def); } } if (!jl_is_tuple_type(jl_unwrap_unionall(argtypes))) From 184ad5bcc955a86638cbc4cc3147b12f0eafb513 Mon Sep 17 00:00:00 2001 From: Nick Robinson Date: Fri, 6 Dec 2024 22:09:44 +0000 Subject: [PATCH 022/198] Add per-task metrics (#56320) Close https://github.com/JuliaLang/julia/issues/47351 (builds on top of https://github.com/JuliaLang/julia/pull/48416) Adds two per-task metrics: - running time = amount of time the task was actually running (according to our scheduler). Note: currently inclusive of GC time, but would be good to be able to separate that out (in a future PR) - wall time = amount of time between the scheduler becoming aware of this task and the task entering a terminal state (i.e. done or failed). We record running time in `wait()`, where the scheduler stops running the task as well as in `yield(t)`, `yieldto(t)` and `throwto(t)`, which bypass the scheduler. Other places where a task stops running (for `Channel`, `ReentrantLock`, `Event`, `Timer` and `Semaphore` are all implemented in terms of `wait(Condition)`, which in turn calls `wait()`. `LibuvStream` similarly calls `wait()`. This should capture everything (albeit, slightly over-counting task CPU time by including any enqueuing work done before we hit `wait()`). The various metrics counters could be a separate inlined struct if we think that's a useful abstraction, but for now i've just put them directly in `jl_task_t`. They are all atomic, except the `metrics_enabled` flag itself (which we now have to check on task start/switch/done even if metrics are not enabled) which is set on task construction and marked `const` on the julia side. In future PRs we could add more per-task metrics, e.g. compilation time, GC time, allocations, potentially a wait-time breakdown (time waiting on locks, channels, in the scheduler run queue, etc.), potentially the number of yields. Perhaps in future there could be ways to enable this on a per-thread and per-task basis. And potentially in future these same timings could be used by `@time` (e.g. writing this same timing data to a ScopedValue like in https://github.com/JuliaLang/julia/pull/55103 but only for tasks lexically scoped to inside the `@time` block). Timings are off by default but can be turned on globally via starting Julia with `--task-metrics=yes` or calling `Base.Experimental.task_metrics(true)`. Metrics are collected for all tasks created when metrics are enabled. In other words, enabling/disabling timings via `Base.Experimental.task_metrics` does not affect existing `Task`s, only new `Task`s. The other new APIs are `Base.Experimental.task_running_time_ns(::Task)` and `Base.Experimental.task_wall_time_ns(::Task)` for retrieving the new metrics. These are safe to call on any task (including the current task, or a task running on another thread). All these are in `Base.Experimental` to give us room to change up the APIs as we add more metrics in future PRs (without worrying about release timelines). cc @NHDaly @kpamnany @d-netto --------- Co-authored-by: Pete Vilter Co-authored-by: K Pamnany Co-authored-by: Nathan Daly Co-authored-by: Valentin Churavy --- NEWS.md | 5 + base/boot.jl | 26 ++- base/experimental.jl | 74 ++++++++ base/options.jl | 1 + base/task.jl | 53 +++++- doc/man/julia.1 | 4 + doc/src/base/multi-threading.md | 8 + doc/src/manual/command-line-interface.md | 1 + src/init.c | 4 + src/jlapi.c | 22 +++ src/jloptions.c | 12 ++ src/jloptions.h | 1 + src/jltypes.c | 46 ++++- src/julia.h | 26 ++- src/julia_internal.h | 3 + src/task.c | 31 ++++ src/threading.c | 2 + test/cmdlineargs.jl | 9 + test/core.jl | 3 +- test/threads_exec.jl | 224 +++++++++++++++++++++++ 20 files changed, 529 insertions(+), 26 deletions(-) diff --git a/NEWS.md b/NEWS.md index b77a786c24823..641b84b480bb4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -17,6 +17,11 @@ New language features - atomic set once (`@atomiconce v[3] = 2`), - atomic swap (`x = @atomicswap v[3] = 2`), and - atomic replace (`x = @atomicreplace v[3] 2=>5`). +- New option `--task-metrics=yes` to enable the collection of per-task timing information, + which can also be enabled/disabled at runtime with `Base.Experimental.task_metrics(::Bool)`. ([#56320]) + The available metrics are: + - actual running time for the task (`Base.Experimental.task_running_time_ns`), and + - wall-time for the task (`Base.Experimental.task_wall_time_ns`). Language changes ---------------- diff --git a/base/boot.jl b/base/boot.jl index f66ee69780193..4badedae3cfb7 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -175,15 +175,33 @@ #end #mutable struct Task -# parent::Task +# next::Any +# queue::Any # storage::Any -# state::Symbol # donenotify::Any # result::Any -# exception::Any -# backtrace::Any # scope::Any # code::Any +# @atomic _state::UInt8 +# sticky::UInt8 +# priority::UInt16 +# @atomic _isexception::UInt8 +# pad00::UInt8 +# pad01::UInt8 +# pad02::UInt8 +# rngState0::UInt64 +# rngState1::UInt64 +# rngState2::UInt64 +# rngState3::UInt64 +# rngState4::UInt64 +# const metrics_enabled::Bool +# pad10::UInt8 +# pad11::UInt8 +# pad12::UInt8 +# @atomic first_enqueued_at::UInt64 +# @atomic last_started_running_at::UInt64 +# @atomic running_time_ns::UInt64 +# @atomic finished_at::UInt64 #end export diff --git a/base/experimental.jl b/base/experimental.jl index 411bb2407cdc5..17871b4f346d6 100644 --- a/base/experimental.jl +++ b/base/experimental.jl @@ -503,4 +503,78 @@ usage, by eliminating the tracking of those possible invalidation. """ disable_new_worlds() = ccall(:jl_disable_new_worlds, Cvoid, ()) +### Task metrics + +""" + Base.Experimental.task_metrics(::Bool) + +Enable or disable the collection of per-task metrics. +A `Task` created when `Base.Experimental.task_metrics(true)` is in effect will have +[`Base.Experimental.task_running_time_ns`](@ref) and [`Base.Experimental.task_wall_time_ns`](@ref) +timing information available. + +!!! note + Task metrics can be enabled at start-up via the `--task-metrics=yes` command line option. +""" +function task_metrics(b::Bool) + if b + ccall(:jl_task_metrics_enable, Cvoid, ()) + else + ccall(:jl_task_metrics_disable, Cvoid, ()) + end + return nothing end + +""" + Base.Experimental.task_running_time_ns(t::Task) -> Union{UInt64, Nothing} + +Return the total nanoseconds that the task `t` has spent running. +This metric is only updated when `t` yields or completes unless `t` is the current task, in +which it will be updated continuously. +See also [`Base.Experimental.task_wall_time_ns`](@ref). + +Returns `nothing` if task timings are not enabled. +See [`Base.Experimental.task_metrics`](@ref). + +!!! note "This metric is from the Julia scheduler" + A task may be running on an OS thread that is descheduled by the OS + scheduler, this time still counts towards the metric. + +!!! compat "Julia 1.12" + This method was added in Julia 1.12. +""" +function task_running_time_ns(t::Task=current_task()) + t.metrics_enabled || return nothing + if t == current_task() + # These metrics fields can't update while we're running. + # But since we're running we need to include the time since we last started running! + return t.running_time_ns + (time_ns() - t.last_started_running_at) + else + return t.running_time_ns + end +end + +""" + Base.Experimental.task_wall_time_ns(t::Task) -> Union{UInt64, Nothing} + +Return the total nanoseconds that the task `t` was runnable. +This is the time since the task first entered the run queue until the time at which it +completed, or until the current time if the task has not yet completed. +See also [`Base.Experimental.task_running_time_ns`](@ref). + +Returns `nothing` if task timings are not enabled. +See [`Base.Experimental.task_metrics`](@ref). + +!!! compat "Julia 1.12" + This method was added in Julia 1.12. +""" +function task_wall_time_ns(t::Task=current_task()) + t.metrics_enabled || return nothing + start_at = t.first_enqueued_at + start_at == 0 && return UInt64(0) + end_at = t.finished_at + end_at == 0 && return time_ns() - start_at + return end_at - start_at +end + +end # module diff --git a/base/options.jl b/base/options.jl index 07baa3b51f65b..7e7808bd5c047 100644 --- a/base/options.jl +++ b/base/options.jl @@ -61,6 +61,7 @@ struct JLOptions heap_size_hint::UInt64 trace_compile_timing::Int8 trim::Int8 + task_metrics::Int8 end # This runs early in the sysimage != is not defined yet diff --git a/base/task.jl b/base/task.jl index 2a922c4b85f24..951e980ee903c 100644 --- a/base/task.jl +++ b/base/task.jl @@ -977,7 +977,11 @@ function enq_work(t::Task) return t end -schedule(t::Task) = enq_work(t) +function schedule(t::Task) + # [task] created -scheduled-> wait_time + maybe_record_enqueued!(t) + enq_work(t) +end """ schedule(t::Task, [val]; error=false) @@ -1031,6 +1035,8 @@ function schedule(t::Task, @nospecialize(arg); error=false) t.queue === nothing || Base.error("schedule: Task not runnable") setfield!(t, :result, arg) end + # [task] created -scheduled-> wait_time + maybe_record_enqueued!(t) enq_work(t) return t end @@ -1064,11 +1070,15 @@ immediately yields to `t` before calling the scheduler. Throws a `ConcurrencyViolationError` if `t` is the currently running task. """ function yield(t::Task, @nospecialize(x=nothing)) - current = current_task() - t === current && throw(ConcurrencyViolationError("Cannot yield to currently running task!")) + ct = current_task() + t === ct && throw(ConcurrencyViolationError("Cannot yield to currently running task!")) (t._state === task_state_runnable && t.queue === nothing) || throw(ConcurrencyViolationError("yield: Task not runnable")) + # [task] user_time -yield-> wait_time + record_running_time!(ct) + # [task] created -scheduled-> wait_time + maybe_record_enqueued!(t) t.result = x - enq_work(current) + enq_work(ct) set_next_task(t) return try_yieldto(ensure_rescheduled) end @@ -1082,6 +1092,7 @@ call to `yieldto`. This is a low-level call that only switches tasks, not consid or scheduling in any way. Its use is discouraged. """ function yieldto(t::Task, @nospecialize(x=nothing)) + ct = current_task() # TODO: these are legacy behaviors; these should perhaps be a scheduler # state error instead. if t._state === task_state_done @@ -1089,6 +1100,10 @@ function yieldto(t::Task, @nospecialize(x=nothing)) elseif t._state === task_state_failed throw(t.result) end + # [task] user_time -yield-> wait_time + record_running_time!(ct) + # [task] created -scheduled-unfairly-> wait_time + maybe_record_enqueued!(t) t.result = x set_next_task(t) return try_yieldto(identity) @@ -1102,6 +1117,10 @@ function try_yieldto(undo) rethrow() end ct = current_task() + # [task] wait_time -(re)started-> user_time + if ct.metrics_enabled + @atomic :monotonic ct.last_started_running_at = time_ns() + end if ct._isexception exc = ct.result ct.result = nothing @@ -1115,6 +1134,11 @@ end # yield to a task, throwing an exception in it function throwto(t::Task, @nospecialize exc) + ct = current_task() + # [task] user_time -yield-> wait_time + record_running_time!(ct) + # [task] created -scheduled-unfairly-> wait_time + maybe_record_enqueued!(t) t.result = exc t._isexception = true set_next_task(t) @@ -1167,6 +1191,9 @@ checktaskempty = Partr.multiq_check_empty end function wait() + ct = current_task() + # [task] user_time -yield-or-done-> wait_time + record_running_time!(ct) GC.safepoint() W = workqueue_for(Threads.threadid()) poptask(W) @@ -1181,3 +1208,21 @@ if Sys.iswindows() else pause() = ccall(:pause, Cvoid, ()) end + +# update the `running_time_ns` field of `t` to include the time since it last started running. +function record_running_time!(t::Task) + if t.metrics_enabled && !istaskdone(t) + @atomic :monotonic t.running_time_ns += time_ns() - t.last_started_running_at + end + return t +end + +# if this is the first time `t` has been added to the run queue +# (or the first time it has been unfairly yielded to without being added to the run queue) +# then set the `first_enqueued_at` field to the current time. +function maybe_record_enqueued!(t::Task) + if t.metrics_enabled && t.first_enqueued_at == 0 + @atomic :monotonic t.first_enqueued_at = time_ns() + end + return t +end diff --git a/doc/man/julia.1 b/doc/man/julia.1 index 56cb690d66eeb..2da11ae1b3f18 100644 --- a/doc/man/julia.1 +++ b/doc/man/julia.1 @@ -294,6 +294,10 @@ If --trace-compile is enabled show how long each took to compile in ms --trace-dispatch={stderr|name} Print precompile statements for methods dispatched during execution or save to stderr or a path. +.TP +--task-metrics={yes|no*} +Enable the collection of per-task metrics. + .TP -image-codegen Force generate code in imaging mode diff --git a/doc/src/base/multi-threading.md b/doc/src/base/multi-threading.md index 9e3bc49acf6dc..81d1d83d765ac 100644 --- a/doc/src/base/multi-threading.md +++ b/doc/src/base/multi-threading.md @@ -65,3 +65,11 @@ These building blocks are used to create the regular synchronization objects. ```@docs Base.Threads.SpinLock ``` + +## Task metrics (Experimental) + +```@docs +Base.Experimental.task_metrics +Base.Experimental.task_running_time_ns +Base.Experimental.task_wall_time_ns +``` diff --git a/doc/src/manual/command-line-interface.md b/doc/src/manual/command-line-interface.md index 734d7031db5e8..9b06deaf0ea8a 100644 --- a/doc/src/manual/command-line-interface.md +++ b/doc/src/manual/command-line-interface.md @@ -203,6 +203,7 @@ The following is a complete list of command-line switches available when launchi |`--code-coverage=tracefile.info` |Append coverage information to the LCOV tracefile (filename supports format tokens).| |`--track-allocation[={none*\|user\|all}]` |Count bytes allocated by each source line (omitting setting is equivalent to "user")| |`--track-allocation=@` |Count bytes but only in files that fall under the given file path/directory. The `@` prefix is required to select this option. A `@` with no path will track the current directory.| +|`--task-metrics={yes\|no*}` |Enable the collection of per-task metrics| |`--bug-report=KIND` |Launch a bug report session. It can be used to start a REPL, run a script, or evaluate expressions. It first tries to use BugReporting.jl installed in current environment and falls back to the latest compatible BugReporting.jl if not. For more information, see `--bug-report=help`.| |`--heap-size-hint=` |Forces garbage collection if memory usage is higher than the given value. The value may be specified as a number of bytes, optionally in units of KB, MB, GB, or TB, or as a percentage of physical memory with %.| |`--compile={yes*\|no\|all\|min}` |Enable or disable JIT compiler, or request exhaustive or minimal compilation| diff --git a/src/init.c b/src/init.c index 1cd14e8556cc6..7b41e63e98455 100644 --- a/src/init.c +++ b/src/init.c @@ -849,6 +849,10 @@ JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel) #if defined(_COMPILER_GCC_) && __GNUC__ >= 12 #pragma GCC diagnostic ignored "-Wdangling-pointer" #endif + if (jl_options.task_metrics == JL_OPTIONS_TASK_METRICS_ON) { + // enable before creating the root task so it gets timings too. + jl_atomic_fetch_add(&jl_task_metrics_enabled, 1); + } // warning: this changes `jl_current_task`, so be careful not to call that from this function jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi); #pragma GCC diagnostic pop diff --git a/src/jlapi.c b/src/jlapi.c index a3621385a437e..defb2db6ac911 100644 --- a/src/jlapi.c +++ b/src/jlapi.c @@ -809,6 +809,28 @@ JL_DLLEXPORT uint64_t jl_cumulative_recompile_time_ns(void) return jl_atomic_load_relaxed(&jl_cumulative_recompile_time); } +/** + * @brief Enable per-task timing. + */ +JL_DLLEXPORT void jl_task_metrics_enable(void) +{ + // Increment the flag to allow reentrant callers. + jl_atomic_fetch_add(&jl_task_metrics_enabled, 1); +} + +/** + * @brief Disable per-task timing. + */ +JL_DLLEXPORT void jl_task_metrics_disable(void) +{ + // Prevent decrementing the counter below zero + uint8_t enabled = jl_atomic_load_relaxed(&jl_task_metrics_enabled); + while (enabled > 0) { + if (jl_atomic_cmpswap(&jl_task_metrics_enabled, &enabled, enabled-1)) + break; + } +} + /** * @brief Retrieve floating-point environment constants. * diff --git a/src/jloptions.c b/src/jloptions.c index f81cf0453db21..c68b5ce193d98 100644 --- a/src/jloptions.c +++ b/src/jloptions.c @@ -152,6 +152,7 @@ JL_DLLEXPORT void jl_init_options(void) 0, // heap-size-hint 0, // trace_compile_timing JL_TRIM_NO, // trim + 0, // task_metrics }; jl_options_initialized = 1; } @@ -316,6 +317,7 @@ static const char opts_hidden[] = " comment if color is not supported\n" " --trace-compile-timing If --trace-compile is enabled show how long each took to\n" " compile in ms\n" + " --task-metrics={yes|no*} Enable collection of per-task timing data.\n" " --image-codegen Force generate code in imaging mode\n" " --permalloc-pkgimg={yes|no*} Copy the data section of package images into memory\n" " --trim={no*|safe|unsafe|unsafe-warn}\n" @@ -347,6 +349,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) opt_trace_compile, opt_trace_compile_timing, opt_trace_dispatch, + opt_task_metrics, opt_math_mode, opt_worker, opt_bind_to, @@ -427,6 +430,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) { "trace-compile", required_argument, 0, opt_trace_compile }, { "trace-compile-timing", no_argument, 0, opt_trace_compile_timing }, { "trace-dispatch", required_argument, 0, opt_trace_dispatch }, + { "task-metrics", required_argument, 0, opt_task_metrics }, { "math-mode", required_argument, 0, opt_math_mode }, { "handle-signals", required_argument, 0, opt_handle_signals }, // hidden command line options @@ -978,6 +982,14 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) else jl_errorf("julia: invalid argument to --trim={safe|no|unsafe|unsafe-warn} (%s)", optarg); break; + case opt_task_metrics: + if (!strcmp(optarg, "no")) + jl_options.task_metrics = JL_OPTIONS_TASK_METRICS_OFF; + else if (!strcmp(optarg, "yes")) + jl_options.task_metrics = JL_OPTIONS_TASK_METRICS_ON; + else + jl_errorf("julia: invalid argument to --task-metrics={yes|no} (%s)", optarg); + break; default: jl_errorf("julia: unhandled option -- %c\n" "This is a bug, please report it.", c); diff --git a/src/jloptions.h b/src/jloptions.h index b9910702f3f9b..211122242cbbd 100644 --- a/src/jloptions.h +++ b/src/jloptions.h @@ -65,6 +65,7 @@ typedef struct { uint64_t heap_size_hint; int8_t trace_compile_timing; int8_t trim; + int8_t task_metrics; } jl_options_t; #endif diff --git a/src/jltypes.c b/src/jltypes.c index 6c6325d84a5ff..abd1f62092035 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -3746,7 +3746,7 @@ void jl_init_types(void) JL_GC_DISABLED NULL, jl_any_type, jl_emptysvec, - jl_perm_symsvec(16, + jl_perm_symsvec(27, "next", "queue", "storage", @@ -3754,16 +3754,27 @@ void jl_init_types(void) JL_GC_DISABLED "result", "scope", "code", + "_state", + "sticky", + "priority", + "_isexception", + "pad00", + "pad01", + "pad02", "rngState0", "rngState1", "rngState2", "rngState3", "rngState4", - "_state", - "sticky", - "_isexception", - "priority"), - jl_svec(16, + "metrics_enabled", + "pad10", + "pad11", + "pad12", + "first_enqueued_at", + "last_started_running_at", + "running_time_ns", + "finished_at"), + jl_svec(27, jl_any_type, jl_any_type, jl_any_type, @@ -3771,21 +3782,36 @@ void jl_init_types(void) JL_GC_DISABLED jl_any_type, jl_any_type, jl_any_type, + jl_uint8_type, + jl_bool_type, + jl_uint16_type, + jl_bool_type, + jl_uint8_type, + jl_uint8_type, + jl_uint8_type, jl_uint64_type, jl_uint64_type, jl_uint64_type, jl_uint64_type, jl_uint64_type, - jl_uint8_type, jl_bool_type, - jl_bool_type, - jl_uint16_type), + jl_uint8_type, + jl_uint8_type, + jl_uint8_type, + jl_uint64_type, + jl_uint64_type, + jl_uint64_type, + jl_uint64_type), jl_emptysvec, 0, 1, 6); XX(task); jl_value_t *listt = jl_new_struct(jl_uniontype_type, jl_task_type, jl_nothing_type); jl_svecset(jl_task_type->types, 0, listt); - const static uint32_t task_atomicfields[1] = {0x00001000}; // Set fields 13 as atomic + // Set field 20 (metrics_enabled) as const + // Set fields 8 (_state) and 24-27 (metric counters) as atomic + const static uint32_t task_constfields[1] = { 0b00000000000010000000000000000000 }; + const static uint32_t task_atomicfields[1] = { 0b00000111100000000000000010000000 }; + jl_task_type->name->constfields = task_constfields; jl_task_type->name->atomicfields = task_atomicfields; tv = jl_svec2(tvar("A"), tvar("R")); diff --git a/src/julia.h b/src/julia.h index 6c0dd700f9472..a9864aad16ccc 100644 --- a/src/julia.h +++ b/src/julia.h @@ -2276,16 +2276,25 @@ typedef struct _jl_task_t { jl_value_t *result; jl_value_t *scope; jl_function_t *start; - // 4 byte padding on 32-bit systems - // uint32_t padding0; - uint64_t rngState[JL_RNG_SIZE]; _Atomic(uint8_t) _state; uint8_t sticky; // record whether this Task can be migrated to a new thread - _Atomic(uint8_t) _isexception; // set if `result` is an exception to throw or that we exited with - // 1 byte padding - // uint8_t padding1; - // multiqueue priority uint16_t priority; + _Atomic(uint8_t) _isexception; // set if `result` is an exception to throw or that we exited with + uint8_t pad0[3]; + // === 64 bytes (cache line) + uint64_t rngState[JL_RNG_SIZE]; + // flag indicating whether or not to record timing metrics for this task + uint8_t metrics_enabled; + uint8_t pad1[3]; + // timestamp this task first entered the run queue + _Atomic(uint64_t) first_enqueued_at; + // timestamp this task was most recently scheduled to run + _Atomic(uint64_t) last_started_running_at; + // time this task has spent running; updated when it yields or finishes. + _Atomic(uint64_t) running_time_ns; + // === 64 bytes (cache line) + // timestamp this task finished (i.e. entered state DONE or FAILED). + _Atomic(uint64_t) finished_at; // hidden state: // cached floating point environment @@ -2612,6 +2621,9 @@ JL_DLLEXPORT int jl_generating_output(void) JL_NOTSAFEPOINT; #define JL_TRIM_UNSAFE 2 #define JL_TRIM_UNSAFE_WARN 3 +#define JL_OPTIONS_TASK_METRICS_OFF 0 +#define JL_OPTIONS_TASK_METRICS_ON 1 + // Version information #include // Generated file diff --git a/src/julia_internal.h b/src/julia_internal.h index 2178f603441e0..4741316093f95 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -316,6 +316,9 @@ extern JL_DLLEXPORT _Atomic(uint8_t) jl_measure_compile_time_enabled; extern JL_DLLEXPORT _Atomic(uint64_t) jl_cumulative_compile_time; extern JL_DLLEXPORT _Atomic(uint64_t) jl_cumulative_recompile_time; +// Global *atomic* integer controlling *process-wide* task timing. +extern JL_DLLEXPORT _Atomic(uint8_t) jl_task_metrics_enabled; + #define jl_return_address() ((uintptr_t)__builtin_return_address(0)) STATIC_INLINE uint32_t jl_int32hash_fast(uint32_t a) diff --git a/src/task.c b/src/task.c index 5e1172a96a409..1a50d6fcbcf65 100644 --- a/src/task.c +++ b/src/task.c @@ -313,6 +313,13 @@ void JL_NORETURN jl_finish_task(jl_task_t *ct) { JL_PROBE_RT_FINISH_TASK(ct); JL_SIGATOMIC_BEGIN(); + if (ct->metrics_enabled) { + // [task] user_time -finished-> wait_time + assert(jl_atomic_load_relaxed(&ct->first_enqueued_at) != 0); + uint64_t now = jl_hrtime(); + jl_atomic_store_relaxed(&ct->finished_at, now); + jl_atomic_fetch_add_relaxed(&ct->running_time_ns, now - jl_atomic_load_relaxed(&ct->last_started_running_at)); + } if (jl_atomic_load_relaxed(&ct->_isexception)) jl_atomic_store_release(&ct->_state, JL_TASK_STATE_FAILED); else @@ -1146,6 +1153,11 @@ JL_DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, jl_value_t *completion t->ptls = NULL; t->world_age = ct->world_age; t->reentrant_timing = 0; + t->metrics_enabled = jl_atomic_load_relaxed(&jl_task_metrics_enabled) != 0; + jl_atomic_store_relaxed(&t->first_enqueued_at, 0); + jl_atomic_store_relaxed(&t->last_started_running_at, 0); + jl_atomic_store_relaxed(&t->running_time_ns, 0); + jl_atomic_store_relaxed(&t->finished_at, 0); jl_timing_task_init(t); if (t->ctx.copy_stack) @@ -1245,6 +1257,12 @@ CFI_NORETURN fesetenv(&ct->fenv); ct->ctx.started = 1; + if (ct->metrics_enabled) { + // [task] wait_time -started-> user_time + assert(jl_atomic_load_relaxed(&ct->first_enqueued_at) != 0); + assert(jl_atomic_load_relaxed(&ct->last_started_running_at) == 0); + jl_atomic_store_relaxed(&ct->last_started_running_at, jl_hrtime()); + } JL_PROBE_RT_START_TASK(ct); jl_timing_block_task_enter(ct, ptls, NULL); if (jl_atomic_load_relaxed(&ct->_isexception)) { @@ -1596,6 +1614,19 @@ jl_task_t *jl_init_root_task(jl_ptls_t ptls, void *stack_lo, void *stack_hi) ct->ptls = ptls; ct->world_age = 1; // OK to run Julia code on this task ct->reentrant_timing = 0; + jl_atomic_store_relaxed(&ct->running_time_ns, 0); + jl_atomic_store_relaxed(&ct->finished_at, 0); + ct->metrics_enabled = jl_atomic_load_relaxed(&jl_task_metrics_enabled) != 0; + if (ct->metrics_enabled) { + // [task] created -started-> user_time + uint64_t now = jl_hrtime(); + jl_atomic_store_relaxed(&ct->first_enqueued_at, now); + jl_atomic_store_relaxed(&ct->last_started_running_at, now); + } + else { + jl_atomic_store_relaxed(&ct->first_enqueued_at, 0); + jl_atomic_store_relaxed(&ct->last_started_running_at, 0); + } ptls->root_task = ct; jl_atomic_store_relaxed(&ptls->current_task, ct); JL_GC_PROMISE_ROOTED(ct); diff --git a/src/threading.c b/src/threading.c index 8f0dfb3330885..ac9cc276d613a 100644 --- a/src/threading.c +++ b/src/threading.c @@ -49,6 +49,8 @@ JL_DLLEXPORT _Atomic(uint8_t) jl_measure_compile_time_enabled = 0; JL_DLLEXPORT _Atomic(uint64_t) jl_cumulative_compile_time = 0; JL_DLLEXPORT _Atomic(uint64_t) jl_cumulative_recompile_time = 0; +JL_DLLEXPORT _Atomic(uint8_t) jl_task_metrics_enabled = 0; + JL_DLLEXPORT void *jl_get_ptls_states(void) { // mostly deprecated: use current_task instead diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index cc3f8950f0dc0..5df174694049d 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -783,6 +783,15 @@ let exename = `$(Base.julia_cmd()) --startup-file=no --color=no` "Int(Base.JLOptions().fast_math)"`)) == JL_OPTIONS_FAST_MATH_DEFAULT end + let JL_OPTIONS_TASK_METRICS_OFF = 0, JL_OPTIONS_TASK_METRICS_ON = 1 + @test parse(Int,readchomp(`$exename -E + "Int(Base.JLOptions().task_metrics)"`)) == JL_OPTIONS_TASK_METRICS_OFF + @test parse(Int, readchomp(`$exename --task-metrics=yes -E + "Int(Base.JLOptions().task_metrics)"`)) == JL_OPTIONS_TASK_METRICS_ON + @test !parse(Bool, readchomp(`$exename -E "current_task().metrics_enabled"`)) + @test parse(Bool, readchomp(`$exename --task-metrics=yes -E "current_task().metrics_enabled"`)) + end + # --worker takes default / custom as argument (default/custom arguments # tested in test/parallel.jl) @test errors_not_signals(`$exename --worker=true`) diff --git a/test/core.jl b/test/core.jl index 63952e8728e1e..ba1803a137392 100644 --- a/test/core.jl +++ b/test/core.jl @@ -25,6 +25,7 @@ for (T, c) in ( (TypeVar, [:name, :ub, :lb]), (Core.Memory, [:length, :ptr]), (Core.GenericMemoryRef, [:mem, :ptr_or_offset]), + (Task, [:metrics_enabled]), ) @test Set((fieldname(T, i) for i in 1:fieldcount(T) if isconst(T, i))) == Set(c) end @@ -42,7 +43,7 @@ for (T, c) in ( (DataType, [:types, :layout]), (Core.Memory, []), (Core.GenericMemoryRef, []), - (Task, [:_state]) + (Task, [:_state, :running_time_ns, :finished_at, :first_enqueued_at, :last_started_running_at]), ) @test Set((fieldname(T, i) for i in 1:fieldcount(T) if Base.isfieldatomic(T, i))) == Set(c) end diff --git a/test/threads_exec.jl b/test/threads_exec.jl index ac54dd009390c..d77cf06905f44 100644 --- a/test/threads_exec.jl +++ b/test/threads_exec.jl @@ -3,6 +3,7 @@ using Test using Base.Threads using Base.Threads: SpinLock, threadpoolsize +using LinearAlgebra: peakflops # for cfunction_closure include("testenv.jl") @@ -1312,4 +1313,227 @@ end end end end + +@testset "Base.Experimental.task_metrics" begin + t = Task(() -> nothing) + @test_throws "const field" t.metrics_enabled = true + is_task_metrics_enabled() = fetch(Threads.@spawn current_task().metrics_enabled) + @test !is_task_metrics_enabled() + try + @testset "once" begin + Base.Experimental.task_metrics(true) + @test is_task_metrics_enabled() + Base.Experimental.task_metrics(false) + @test !is_task_metrics_enabled() + end + @testset "multiple" begin + Base.Experimental.task_metrics(true) # 1 + Base.Experimental.task_metrics(true) # 2 + Base.Experimental.task_metrics(true) # 3 + @test is_task_metrics_enabled() + Base.Experimental.task_metrics(false) # 2 + @test is_task_metrics_enabled() + Base.Experimental.task_metrics(false) # 1 + @test is_task_metrics_enabled() + @sync for i in 1:5 # 0 (not negative) + Threads.@spawn Base.Experimental.task_metrics(false) + end + @test !is_task_metrics_enabled() + Base.Experimental.task_metrics(true) # 1 + @test is_task_metrics_enabled() + end + finally + while is_task_metrics_enabled() + Base.Experimental.task_metrics(false) + end + end +end + +@testset "task time counters" begin + @testset "enabled" begin + try + Base.Experimental.task_metrics(true) + start_time = time_ns() + t = Threads.@spawn peakflops() + wait(t) + end_time = time_ns() + wall_time_delta = end_time - start_time + @test t.metrics_enabled + @test Base.Experimental.task_running_time_ns(t) > 0 + @test Base.Experimental.task_wall_time_ns(t) > 0 + @test Base.Experimental.task_wall_time_ns(t) >= Base.Experimental.task_running_time_ns(t) + @test wall_time_delta > Base.Experimental.task_wall_time_ns(t) + finally + Base.Experimental.task_metrics(false) + end + end + @testset "disabled" begin + t = Threads.@spawn peakflops() + wait(t) + @test !t.metrics_enabled + @test isnothing(Base.Experimental.task_running_time_ns(t)) + @test isnothing(Base.Experimental.task_wall_time_ns(t)) + end + @testset "task not run" begin + t1 = Task(() -> nothing) + @test !t1.metrics_enabled + @test isnothing(Base.Experimental.task_running_time_ns(t1)) + @test isnothing(Base.Experimental.task_wall_time_ns(t1)) + try + Base.Experimental.task_metrics(true) + t2 = Task(() -> nothing) + @test t2.metrics_enabled + @test Base.Experimental.task_running_time_ns(t2) == 0 + @test Base.Experimental.task_wall_time_ns(t2) == 0 + finally + Base.Experimental.task_metrics(false) + end + end + @testset "task failure" begin + try + Base.Experimental.task_metrics(true) + t = Threads.@spawn error("this task failed") + @test_throws "this task failed" wait(t) + @test Base.Experimental.task_running_time_ns(t) > 0 + @test Base.Experimental.task_wall_time_ns(t) > 0 + @test Base.Experimental.task_wall_time_ns(t) >= Base.Experimental.task_running_time_ns(t) + finally + Base.Experimental.task_metrics(false) + end + end + @testset "direct yield(t)" begin + try + Base.Experimental.task_metrics(true) + start = time_ns() + t_outer = Threads.@spawn begin + t_inner = Task(() -> peakflops()) + t_inner.sticky = false + # directly yield to `t_inner` rather calling `schedule(t_inner)` + yield(t_inner) + wait(t_inner) + @test Base.Experimental.task_running_time_ns(t_inner) > 0 + @test Base.Experimental.task_wall_time_ns(t_inner) > 0 + @test Base.Experimental.task_wall_time_ns(t_inner) >= Base.Experimental.task_running_time_ns(t_inner) + end + wait(t_outer) + delta = time_ns() - start + @test Base.Experimental.task_running_time_ns(t_outer) > 0 + @test Base.Experimental.task_wall_time_ns(t_outer) > 0 + @test Base.Experimental.task_wall_time_ns(t_outer) >= Base.Experimental.task_running_time_ns(t_outer) + @test Base.Experimental.task_wall_time_ns(t_outer) < delta + finally + Base.Experimental.task_metrics(false) + end + end + @testset "bad schedule" begin + try + Base.Experimental.task_metrics(true) + t1 = Task((x) -> 1) + schedule(t1) # MethodError + yield() + @assert istaskfailed(t1) + @test Base.Experimental.task_running_time_ns(t1) > 0 + @test Base.Experimental.task_wall_time_ns(t1) > 0 + foo(a, b) = a + b + t2 = Task(() -> (peakflops(); foo(wait()))) + schedule(t2) + yield() + @assert istaskstarted(t1) && !istaskdone(t2) + schedule(t2, 1) + yield() + @assert istaskfailed(t2) + @test Base.Experimental.task_running_time_ns(t2) > 0 + @test Base.Experimental.task_wall_time_ns(t2) > 0 + finally + Base.Experimental.task_metrics(false) + end + end + @testset "continuously update until task done" begin + try + Base.Experimental.task_metrics(true) + last_running_time = Ref(typemax(Int)) + last_wall_time = Ref(typemax(Int)) + t = Threads.@spawn begin + running_time = Base.Experimental.task_running_time_ns() + wall_time = Base.Experimental.task_wall_time_ns() + for _ in 1:5 + x = time_ns() + while time_ns() < x + 100 + end + new_running_time = Base.Experimental.task_running_time_ns() + new_wall_time = Base.Experimental.task_wall_time_ns() + @test new_running_time > running_time + @test new_wall_time > wall_time + running_time = new_running_time + wall_time = new_wall_time + end + last_running_time[] = running_time + last_wall_time[] = wall_time + end + wait(t) + final_running_time = Base.Experimental.task_running_time_ns(t) + final_wall_time = Base.Experimental.task_wall_time_ns(t) + @test last_running_time[] < final_running_time + @test last_wall_time[] < final_wall_time + # ensure many more tasks are run to make sure the counters are + # not being updated after a task is done e.g. only when a new task is found + @sync for _ in 1:Threads.nthreads() + Threads.@spawn rand() + end + @test final_running_time == Base.Experimental.task_running_time_ns(t) + @test final_wall_time == Base.Experimental.task_wall_time_ns(t) + finally + Base.Experimental.task_metrics(false) + end + end +end + +@testset "task time counters: lots of spawns" begin + using Dates + try + Base.Experimental.task_metrics(true) + # create more tasks than we have threads. + # - all tasks must have: cpu time <= wall time + # - some tasks must have: cpu time < wall time + # - summing across all tasks we must have: total cpu time <= available cpu time + n_tasks = 2 * Threads.nthreads(:default) + cpu_times = Vector{UInt64}(undef, n_tasks) + wall_times = Vector{UInt64}(undef, n_tasks) + start_time = time_ns() + @sync begin + for i in 1:n_tasks + start_time_i = time_ns() + task_i = Threads.@spawn peakflops() + Threads.@spawn begin + wait(task_i) + end_time_i = time_ns() + wall_time_delta_i = end_time_i - start_time_i + cpu_times[$i] = cpu_time_i = Base.Experimental.task_running_time_ns(task_i) + wall_times[$i] = wall_time_i = Base.Experimental.task_wall_time_ns(task_i) + # task should have recorded some cpu-time and some wall-time + @test cpu_time_i > 0 + @test wall_time_i > 0 + # task cpu-time cannot be greater than its wall-time + @test wall_time_i >= cpu_time_i + # task wall-time must be less than our manually measured wall-time + # between calling `@spawn` and returning from `wait`. + @test wall_time_delta_i > wall_time_i + end + end + end + end_time = time_ns() + wall_time_delta = (end_time - start_time) + available_cpu_time = wall_time_delta * Threads.nthreads(:default) + summed_cpu_time = sum(cpu_times) + # total CPU time from all tasks can't exceed what was actually available. + @test available_cpu_time > summed_cpu_time + # some tasks must have cpu-time less than their wall-time, because we had more tasks + # than threads. + summed_wall_time = sum(wall_times) + @test summed_wall_time > summed_cpu_time + finally + Base.Experimental.task_metrics(false) + end +end + end # main testset From 3a68b035ccbc4837448119099e059defaa6d5b98 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 6 Dec 2024 21:58:52 -0700 Subject: [PATCH 023/198] Fully outline all GlobalRefs (#56746) This is an alternative to #56714 that goes in the opposite direction - just outline all GlobalRefs during lowering. It is a lot simpler that #56714 at the cost of some size increase. Numbers: sys.so .ldata size: This PR: 159.8 MB Master: 158.9 MB I don't have numbers of #56714, because it's not fully complete. Additionally, it's possible that restricting GlobalRefs from arguments position would let us use a more efficient encoding in the future. --- Compiler/test/inference.jl | 9 +++--- doc/src/base/reflection.md | 10 ++++--- src/ast.c | 37 ----------------------- src/jlfrontend.scm | 1 - src/julia-syntax.scm | 1 - stdlib/Test/src/Test.jl | 5 ++-- test/core.jl | 61 ++++++++++++++++++++++++-------------- test/staged.jl | 12 ++++---- 8 files changed, 57 insertions(+), 79 deletions(-) diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index b3099897faf51..c8b599adb1323 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -3031,14 +3031,13 @@ end # issue #28279 # ensure that lowering doesn't move these into statement position, which would require renumbering -using Base: +, - -function f28279(b::Bool) +@eval function f28279(b::Bool) let i = 1 - while i > b - i -= 1 + while $(>)(i, b) + i = $(-)(i, 1) end if b end - return i + 1 + return $(+)(i, 1) end end code28279 = code_lowered(f28279, (Bool,))[1].code diff --git a/doc/src/base/reflection.md b/doc/src/base/reflection.md index 9228fb38322df..d88c3c8b0d0cf 100644 --- a/doc/src/base/reflection.md +++ b/doc/src/base/reflection.md @@ -100,10 +100,12 @@ as assignments, branches, and calls: ```jldoctest; setup = (using Base: +, sin) julia> Meta.lower(@__MODULE__, :( [1+2, sin(0.5)] )) :($(Expr(:thunk, CodeInfo( -1 ─ %1 = dynamic 1 + 2 -│ %2 = dynamic sin(0.5) -│ %3 = dynamic Base.vect(%1, %2) -└── return %3 +1 ─ %1 = :+ +│ %2 = dynamic (%1)(1, 2) +│ %3 = sin +│ %4 = dynamic (%3)(0.5) +│ %5 = dynamic Base.vect(%2, %4) +└── return %5 )))) ``` diff --git a/src/ast.c b/src/ast.c index 474c0661f5230..959bac26c2c15 100644 --- a/src/ast.c +++ b/src/ast.c @@ -181,42 +181,6 @@ static value_t fl_defined_julia_global(fl_context_t *fl_ctx, value_t *args, uint return (bpart != NULL && decode_restriction_kind(jl_atomic_load_relaxed(&bpart->restriction)) == BINDING_KIND_GLOBAL) ? fl_ctx->T : fl_ctx->F; } -static value_t fl_nothrow_julia_global(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) -{ - // tells whether a var is defined, in the sense that accessing it is nothrow - // can take either a symbol or a module and a symbol - jl_ast_context_t *ctx = jl_ast_ctx(fl_ctx); - jl_module_t *mod = ctx->module; - jl_sym_t *var = NULL; - if (nargs == 1) { - (void)tosymbol(fl_ctx, args[0], "nothrow-julia-global"); - var = scmsym_to_julia(fl_ctx, args[0]); - } - else { - argcount(fl_ctx, "nothrow-julia-global", nargs, 2); - value_t argmod = args[0]; - if (iscvalue(argmod) && cv_class((cvalue_t*)ptr(argmod)) == jl_ast_ctx(fl_ctx)->jvtype) { - mod = *(jl_module_t**)cv_data((cvalue_t*)ptr(argmod)); - JL_GC_PROMISE_ROOTED(mod); - } else { - if (!iscons(argmod) || !issymbol(car_(argmod)) || scmsym_to_julia(fl_ctx, car_(argmod)) != jl_thismodule_sym) { - lerrorf(fl_ctx, fl_ctx->ArgError, "nothrow-julia-global: Unknown globalref module kind"); - } - } - (void)tosymbol(fl_ctx, args[1], "nothrow-julia-global"); - var = scmsym_to_julia(fl_ctx, args[1]); - } - jl_binding_t *b = jl_get_module_binding(mod, var, 0); - jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age); - jl_ptr_kind_union_t pku = jl_walk_binding_inplace(&b, &bpart, jl_current_task->world_age); - if (!bpart) - return fl_ctx->F; - if (jl_bkind_is_some_guard(decode_restriction_kind(pku))) - return fl_ctx->F; - return (jl_bkind_is_some_constant(decode_restriction_kind(pku)) ? - decode_restriction_value(pku) : jl_atomic_load_relaxed(&b->value)) != NULL ? fl_ctx->T : fl_ctx->F; -} - // Used to generate a unique suffix for a given symbol (e.g. variable or type name) // first argument contains a stack of method definitions seen so far by `closure-convert` in flisp. // if the top of the stack is non-NIL, we use it to augment the suffix so that it becomes @@ -288,7 +252,6 @@ static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *m static const builtinspec_t julia_flisp_ast_ext[] = { { "defined-julia-global", fl_defined_julia_global }, // TODO: can we kill this safepoint - { "nothrow-julia-global", fl_nothrow_julia_global }, { "current-julia-module-counter", fl_module_unique_name }, { "julia-scalar?", fl_julia_scalar }, { NULL, NULL } diff --git a/src/jlfrontend.scm b/src/jlfrontend.scm index 3d46940d6fcbb..9c69da199c0cd 100644 --- a/src/jlfrontend.scm +++ b/src/jlfrontend.scm @@ -31,7 +31,6 @@ ;; this is overwritten when we run in actual julia (define (defined-julia-global v) #f) -(define (nothrow-julia-global v) #f) ;; parser entry points diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index c7ca5d553bb31..c522a565f462a 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -4356,7 +4356,6 @@ f(x) = yt(x) (define (valid-ir-argument? e) (or (simple-atom? e) - (and (globalref? e) (nothrow-julia-global (cadr e) (caddr e))) (and (pair? e) (memq (car e) '(quote inert top core slot static_parameter))))) diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index 7c985828d47f2..464cb2ac9de9c 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -1965,8 +1965,9 @@ Arguments #self#::Core.Const(f) a::Int64 Body::UNION{FLOAT64, INT64} -1 ─ %1 = (a > 1)::Bool -└── goto #3 if not %1 +1 ─ %1 = :>::Core.Const(>) +│ %2 = (%1)(a, 1)::Bool +└── goto #3 if not %2 2 ─ return 1 3 ─ return 1.0 diff --git a/test/core.jl b/test/core.jl index ba1803a137392..7e4f655222ea5 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7435,6 +7435,7 @@ end @test isa(Core.eval(@__MODULE__, :(Bar31062(()))), Bar31062) @test precompile(identity, (Foo31062,)) +using Core: SSAValue ftype_eval = Ref(0) FieldTypeA = String FieldTypeE = UInt32 @@ -7458,27 +7459,41 @@ let fc = FieldConvert(1.0, [2.0], 0x3, 0x4, 0x5) end @test ftype_eval[] == 1 let code = code_lowered(FieldConvert)[1].code - local fc_global_ssa, sp1_ssa, apply_type_ssa, field_type_ssa, - field_type2_ssa, field_type4_ssa, field_type5_ssa, - slot_read_1, slot_read_2, slot_read_3, slot_read_4, - new_ssa - @test code[(fc_global_ssa = 1;)] == GlobalRef(@__MODULE__, :FieldConvert) - @test code[(sp1_ssa = 2;)] == Expr(:static_parameter, 1) - @test code[(apply_type_ssa = 3;)] == Expr(:call, GlobalRef(Core, :apply_type), Core.SSAValue(fc_global_ssa), GlobalRef(@__MODULE__, :FieldTypeA), Core.SSAValue(sp1_ssa)) - @test code[(field_type_ssa = 4;)] == Expr(:call, GlobalRef(Core, :fieldtype), Core.SSAValue(apply_type_ssa), 1) - @test code[10] == Expr(:(=), Core.SlotNumber(10), Expr(:call, GlobalRef(Base, :convert), Core.SSAValue(field_type_ssa), Core.SlotNumber(10))) - @test code[(slot_read_1 = 11;)] == Core.SlotNumber(10) - @test code[(field_type2_ssa = 12;)] == Expr(:call, GlobalRef(Core, :fieldtype), Core.SSAValue(apply_type_ssa), 2) - @test code[18] == Expr(:(=), Core.SlotNumber(9), Expr(:call, GlobalRef(Base, :convert), Core.SSAValue(field_type2_ssa), Core.SlotNumber(9))) - @test code[(slot_read_2 = 19;)] == Core.SlotNumber(9) - @test code[(field_type4_ssa = 20;)] == Expr(:call, GlobalRef(Core, :fieldtype), Core.SSAValue(apply_type_ssa), 4) - @test code[26] == Expr(:(=), Core.SlotNumber(8), Expr(:call, GlobalRef(Base, :convert), Core.SSAValue(field_type4_ssa), Core.SlotNumber(8))) - @test code[(slot_read_3 = 27;)] == Core.SlotNumber(8) - @test code[(field_type5_ssa = 28;)] == Expr(:call, GlobalRef(Core, :fieldtype), Core.SSAValue(apply_type_ssa), 5) - @test code[34] == Expr(:(=), Core.SlotNumber(7), Expr(:call, GlobalRef(Base, :convert), Core.SSAValue(field_type5_ssa), Core.SlotNumber(7))) - @test code[(slot_read_4 = 35;)] == Core.SlotNumber(7) - @test code[(new_ssa = 36;)] == Expr(:new, Core.SSAValue(apply_type_ssa), Core.SSAValue(slot_read_1), Core.SSAValue(slot_read_2), Core.SlotNumber(4), Core.SSAValue(slot_read_3), Core.SSAValue(slot_read_4)) - @test code[37] == Core.ReturnNode(Core.SSAValue(new_ssa)) + calls = Vector{Pair{SSAValue, Expr}}(undef, 0) + for i = 1:length(code) + expr = code[i] + if Meta.isexpr(expr, :call) || (Meta.isexpr(expr, :(=)) && Meta.isexpr(expr.args[2], :call)) + push!(calls, SSAValue(i)=>expr) + end + end + + function is_globalref(arg, gr) + while isa(arg, SSAValue) + arg = code[arg.id] + end + arg == gr + end + + # calls[1] + @test all(is_globalref.(calls[1][2].args[1:3], (GlobalRef(Core, :apply_type), GlobalRef(@__MODULE__, :FieldConvert), GlobalRef(@__MODULE__, :FieldTypeA)))) + + # calls[2] + @test all(is_globalref.(calls[2][2].args[1:1], (GlobalRef(Core, :fieldtype),))) + @test all(calls[2][2].args[2:3] .== (calls[1][1], 1)) + + # calls[3] - isa + + # calls[4] + let calle = calls[4][2] + @test Meta.isexpr(calle, :(=)) + call = calle.args[2] + @test is_globalref(call.args[1], GlobalRef(Base, :convert)) + @test call.args[2] == calls[2][1] + end + + # calls[5] + @test all(is_globalref.(calls[5][2].args[1:1], (GlobalRef(Core, :fieldtype),))) + @test all(calls[5][2].args[2:3] .== (calls[1][1], 2)) end # Issue #32820 @@ -8156,7 +8171,7 @@ end @test Core.Compiler.is_foldable(Base.infer_effects(length, (Core.SimpleVector,))) @test Core.Compiler.is_foldable(Base.infer_effects(getindex, (Core.SimpleVector,Int))) -# Test that a nothrow-globalref doesn't get outlined during lowering +# Test that a the lowering of nothrow globalref module WellKnownGlobal global well_known = 1 end @@ -8165,7 +8180,7 @@ macro insert_global() end check_globalref_lowering() = @insert_global let src = code_lowered(check_globalref_lowering)[1] - @test length(src.code) == 2 + @test length(src.code) == 4 end # Test correctness of widen_diagonal diff --git a/test/staged.jl b/test/staged.jl index 1b28144639f97..6cb99950a7bb2 100644 --- a/test/staged.jl +++ b/test/staged.jl @@ -270,12 +270,12 @@ end # PR #23168 -function f23168(a, x) +@eval function f23168(a, x) push!(a, 1) if @generated - :(y = x + x) + :(y = $(+)(x, x)) else - y = 2x + y = $(*)(2, x) end push!(a, y) if @generated @@ -290,9 +290,9 @@ end let a = Any[] @test f23168(a, 3) == (6, Int) @test a == [1, 6, 3] - @test occursin(" + ", string(code_lowered(f23168, (Vector{Any},Int)))) - @test occursin("2 * ", string(Base.uncompressed_ir(first(methods(f23168))))) - @test occursin("2 * ", string(code_lowered(f23168, (Vector{Any},Int), generated=false))) + @test occursin("(+)(", string(code_lowered(f23168, (Vector{Any},Int)))) + @test occursin("(*)(2", string(Base.uncompressed_ir(first(methods(f23168))))) + @test occursin("(*)(2", string(code_lowered(f23168, (Vector{Any},Int), generated=false))) @test occursin("Base.add_int", string(code_typed(f23168, (Vector{Any},Int)))) end From 6cb9f04c1ec562f800669ba13a9a096203aea7cf Mon Sep 17 00:00:00 2001 From: Julius Krumbiegel <22495855+jkrumbiegel@users.noreply.github.com> Date: Sat, 7 Dec 2024 19:56:09 +0100 Subject: [PATCH 024/198] Add #54800 to NEWS (#56774) Show glyphs for latex or emoji shortcodes being suggested in the REPL --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 641b84b480bb4..2ad92701dd638 100644 --- a/NEWS.md +++ b/NEWS.md @@ -171,6 +171,7 @@ Standard library changes in the REPL will now issue a warning the first time occurs. ([#54872]) - When an object is printed automatically (by being returned in the REPL), its display is now truncated after printing 20 KiB. This does not affect manual calls to `show`, `print`, and so forth. ([#53959]) +- Backslash completions now print the respective glyph or emoji next to each matching backslash shortcode. ([#54800]) #### SuiteSparse From c897a13c45c1222b4b16cf941348beef25f97ee0 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Sat, 7 Dec 2024 19:43:15 -0300 Subject: [PATCH 025/198] Add the actual datatype to the heapsnapshot. This groups objects of the same type together (#56596) --- src/gc-heap-snapshot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gc-heap-snapshot.cpp b/src/gc-heap-snapshot.cpp index 72eb17115f4c7..f3793939610b5 100644 --- a/src/gc-heap-snapshot.cpp +++ b/src/gc-heap-snapshot.cpp @@ -380,7 +380,7 @@ size_t record_node_to_gc_snapshot(jl_value_t *a) JL_NOTSAFEPOINT ios_mem(&str_, 0); JL_STREAM* str = (JL_STREAM*)&str_; jl_static_show(str, (jl_value_t*)type); - + node_type = StringRef((const char*)str_.buf, str_.size); name = StringRef((const char*)str_.buf, str_.size); } From 54755adb1d96539fdd125ea9c442d0fcf206d5cc Mon Sep 17 00:00:00 2001 From: clonefetch <166312854+clonefetch@users.noreply.github.com> Date: Sun, 8 Dec 2024 21:21:58 +0800 Subject: [PATCH 026/198] Fix typos in docstring, comments, and news (#56778) --- NEWS.md | 2 +- base/deprecated.jl | 2 +- base/pointer.jl | 2 +- base/sysimg.jl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index 2ad92701dd638..78d1d9b4bc7b8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -36,7 +36,7 @@ Language changes may pave the way for inference to be able to intelligently re-use the old results, once the new method is deleted. ([#53415]) - - Macro expansion will no longer eagerly recurse into into `Expr(:toplevel)` + - Macro expansion will no longer eagerly recurse into `Expr(:toplevel)` expressions returned from macros. Instead, macro expansion of `:toplevel` expressions will be delayed until evaluation time. This allows a later expression within a given `:toplevel` expression to make use of macros diff --git a/base/deprecated.jl b/base/deprecated.jl index 84ef89e44b473..cffff05d954d1 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -4,7 +4,7 @@ # Instructions for Julia Core Developers: # 1. When making a breaking change that is known to be depnedet upon by an # important and closely coupled package, decide on a unique `change_name` -# for your PR and add it to the list below. In general, is is better to +# for your PR and add it to the list below. In general, it is better to # err on the side of caution and assign a `change_name` even if it is not # clear that it is required. `change_name`s may also be assigned after the # fact in a separate PR. (Note that this may cause packages to misbehave diff --git a/base/pointer.jl b/base/pointer.jl index b1580ef17d562..de2f413d8f881 100644 --- a/base/pointer.jl +++ b/base/pointer.jl @@ -169,7 +169,7 @@ The `unsafe` prefix on this function indicates that no validation is performed o pointer `p` to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program. Unlike C, storing memory region allocated as -different type may be valid provided that that the types are compatible. +different type may be valid provided that the types are compatible. !!! compat "Julia 1.10" The `order` argument is available as of Julia 1.10. diff --git a/base/sysimg.jl b/base/sysimg.jl index e57ec1c99bfe6..42f54a849f157 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -# Can be be loaded on top of either an existing system image built from +# Can be loaded on top of either an existing system image built from # `Base_compiler.jl` or standalone, in which case we will build it now. let had_compiler = isdefined(Main, :Base) if had_compiler; else From e0656ac017a427f739f985809017a33c269b3af1 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Sun, 8 Dec 2024 15:48:54 -0600 Subject: [PATCH 027/198] Add sort for NTuples (#54494) This is partially a reland of #46104, but without the controversial `sort(x) = sort!(copymutable(x))` and with some extensibility improvements. Implements #54489. --- NEWS.md | 1 + base/sort.jl | 43 ++++++++++++++++++++++++++++++++++++++++--- test/sorting.jl | 30 ++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 78d1d9b4bc7b8..3c893566c7219 100644 --- a/NEWS.md +++ b/NEWS.md @@ -110,6 +110,7 @@ New library features * `invoke` now supports passing a Method instead of a type signature making this interface somewhat more flexible for certain uncommon use cases ([#56692]). * `invoke` now supports passing a CodeInstance instead of a type, which can enable certain compiler plugin workflows ([#56660]). +* `sort` now supports `NTuple`s ([#54494]) Standard library changes ------------------------ diff --git a/base/sort.jl b/base/sort.jl index 29e67a3eb8d8c..f9d74f626fe58 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -4,7 +4,7 @@ module Sort using Base.Order -using Base: copymutable, midpoint, require_one_based_indexing, uinttype, +using Base: copymutable, midpoint, require_one_based_indexing, uinttype, tail, sub_with_overflow, add_with_overflow, OneTo, BitSigned, BitIntegerType, top_set_bit import Base: @@ -1482,8 +1482,9 @@ InitialOptimizations(next) = SubArrayOptimization( `DefaultStable` is an algorithm which indicates that a fast, general purpose sorting algorithm should be used, but does not specify exactly which algorithm. -Currently, it is composed of two parts: the [`InitialOptimizations`](@ref) and a hybrid of -Radix, Insertion, Counting, Quick sorts. +Currently, when sorting short NTuples, this is an unrolled mergesort, and otherwise it is +composed of two parts: the [`InitialOptimizations`](@ref) and a hybrid of Radix, Insertion, +Counting, Quick sorts. We begin with MissingOptimization because it has no runtime cost when it is not triggered and can enable other optimizations to be applied later. For example, @@ -1619,6 +1620,7 @@ defalg(v::AbstractArray) = DEFAULT_STABLE defalg(v::AbstractArray{<:Union{Number, Missing}}) = DEFAULT_UNSTABLE defalg(v::AbstractArray{Missing}) = DEFAULT_UNSTABLE # for method disambiguation defalg(v::AbstractArray{Union{}}) = DEFAULT_UNSTABLE # for method disambiguation +defalg(v::NTuple) = DEFAULT_STABLE """ sort!(v; alg::Base.Sort.Algorithm=Base.Sort.defalg(v), lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward) @@ -1757,6 +1759,41 @@ julia> v """ sort(v::AbstractVector; kws...) = sort!(copymutable(v); kws...) +function sort(x::NTuple; + alg::Algorithm=defalg(x), + lt=isless, + by=identity, + rev::Union{Bool,Nothing}=nothing, + order::Ordering=Forward, + scratch::Union{Vector, Nothing}=nothing) + # Can't do this check with type parameters because of https://github.com/JuliaLang/julia/issues/56698 + scratch === nothing || eltype(x) == eltype(scratch) || throw(ArgumentError("scratch has the wrong eltype")) + _sort(x, alg, ord(lt,by,rev,order), (;scratch))::typeof(x) +end +# Folks who want to hack internals can define a new _sort(x::NTuple, ::TheirAlg, o::Ordering) +# or _sort(x::NTuple{N, TheirType}, ::DefaultStable, o::Ordering) where N +function _sort(x::NTuple, a::Union{DefaultStable, DefaultUnstable}, o::Ordering, kw) + # The unrolled tuple sort is prohibitively slow to compile for length > 9. + # See https://github.com/JuliaLang/julia/pull/46104#issuecomment-1435688502 for benchmarks + if length(x) > 9 + v = copymutable(x) + _sort!(v, a, o, kw) + typeof(x)(v) + else + _mergesort(x, o) + end +end +_mergesort(x::Union{NTuple{0}, NTuple{1}}, o::Ordering) = x +function _mergesort(x::NTuple, o::Ordering) + a, b = Base.IteratorsMD.split(x, Val(length(x)>>1)) + merge(_mergesort(a, o), _mergesort(b, o), o) +end +merge(x::NTuple, y::NTuple{0}, o::Ordering) = x +merge(x::NTuple{0}, y::NTuple, o::Ordering) = y +merge(x::NTuple{0}, y::NTuple{0}, o::Ordering) = x # Method ambiguity +merge(x::NTuple, y::NTuple, o::Ordering) = + (lt(o, y[1], x[1]) ? (y[1], merge(x, tail(y), o)...) : (x[1], merge(tail(x), y, o)...)) + ## partialsortperm: the permutation to sort the first k elements of an array ## """ diff --git a/test/sorting.jl b/test/sorting.jl index 71af50429027a..e16b30de5bfc8 100644 --- a/test/sorting.jl +++ b/test/sorting.jl @@ -94,6 +94,22 @@ end vcat(2000, (x:x+99 for x in 1900:-100:100)..., 1:99) end +function tuple_sort_test(x) + @test issorted(sort(x)) + length(x) > 9 && return # length > 9 uses a vector fallback + @test 0 == @allocated sort(x) +end +@testset "sort(::NTuple)" begin + @test sort(()) == () + @test sort((9,8,3,3,6,2,0,8)) == (0,2,3,3,6,8,8,9) + @test sort((9,8,3,3,6,2,0,8), by=x->x÷3) == (2,0,3,3,8,6,8,9) + for i in 1:40 + tuple_sort_test(rand(NTuple{i, Float64})) + end + @test_throws MethodError sort((1,2,3.0)) + @test Base.infer_return_type(sort, Tuple{Tuple{Vararg{Int}}}) == Tuple{Vararg{Int}} +end + @testset "partialsort" begin @test partialsort([3,6,30,1,9],3) == 6 @test partialsort([3,6,30,1,9],3:4) == [6,9] @@ -913,6 +929,20 @@ end end @test sort([1,2,3], alg=MySecondAlg()) == [9,9,9] @test all(sort(v, alg=Base.Sort.InitialOptimizations(MySecondAlg())) .=== vcat(fill(9, 100), fill(missing, 10))) + + # Tuple extensions (custom alg) + @test_throws MethodError sort((1,2,3), alg=MyFirstAlg()) + Base.Sort._sort(v::NTuple, ::MyFirstAlg, o::Base.Order.Ordering, kw) = (17,2,9) + @test sort((1,2,3), alg=MyFirstAlg()) == (17,2,9) + + struct TupleFoo + x::Int + end + + # Tuple extensions (custom type) + @test_throws MethodError sort(TupleFoo.((3,1,2))) + Base.Sort._sort(v::NTuple{N, TupleFoo}, ::Base.Sort.DefaultStable, o::Base.Order.Ordering, kw) where N = v + @test sort(TupleFoo.((3,1,2))) === TupleFoo.((3,1,2)) end @testset "sort!(v, lo, hi, alg, order)" begin From dfe6a13e5038c8cbe0f1720d190629225ec1a19b Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Mon, 9 Dec 2024 16:41:30 -0500 Subject: [PATCH 028/198] precompile: don't waste memory on useless inferred code (#56749) We never have a reason to reference this data again since we already have native code generated for it, so it is simply wasting memory and download space. $ du -sh {old,new}/usr/share/julia/compiled 256M old 227M new --- Compiler/src/effects.jl | 1 + src/codegen.cpp | 8 ++++---- src/staticdata.c | 30 ++++++++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Compiler/src/effects.jl b/Compiler/src/effects.jl index e521166fd61fa..9aea4cb204ec6 100644 --- a/Compiler/src/effects.jl +++ b/Compiler/src/effects.jl @@ -335,6 +335,7 @@ is_inaccessiblemem_or_argmemonly(effects::Effects) = effects.inaccessiblememonly is_consistent_overlay(effects::Effects) = effects.nonoverlayed === CONSISTENT_OVERLAY +# (sync this with codegen.cpp and staticdata.c effects_foldable functions) function encode_effects(e::Effects) return ((e.consistent % UInt32) << 0) | ((e.effect_free % UInt32) << 3) | diff --git a/src/codegen.cpp b/src/codegen.cpp index b9d42b9b5af16..21591acedc632 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -10124,10 +10124,10 @@ jl_llvm_functions_t jl_emit_codeinst( else if (jl_is_method(def) && // don't delete toplevel code def->source != NULL && // don't delete code from optimized opaque closures that can't be reconstructed inferred != jl_nothing && // and there is something to delete (test this before calling jl_ir_inlining_cost) - !effects_foldable(jl_atomic_load_relaxed(&codeinst->ipo_purity_bits)) && // don't delete code we may want for irinterp - ((jl_ir_inlining_cost(inferred) == UINT16_MAX) || // don't delete inlineable code - jl_atomic_load_relaxed(&codeinst->invoke) == jl_fptr_const_return_addr) && // unless it is constant - !(params.imaging_mode || jl_options.incremental)) { // don't delete code when generating a precompile file + ((!effects_foldable(jl_atomic_load_relaxed(&codeinst->ipo_purity_bits)) && // don't delete code we may want for irinterp + (jl_ir_inlining_cost(inferred) == UINT16_MAX) && // don't delete inlineable code + !jl_generating_output()) || // don't delete code when generating a precompile file, trading memory in the short term for avoiding likely duplicating inference work for aotcompile + jl_atomic_load_relaxed(&codeinst->invoke) == jl_fptr_const_return_addr)) { // unless it is constant (although this shouldn't have had code in the first place) // Never end up in a situation where the codeinst has no invoke, but also no source, so we never fall // through the cracks of SOURCE_MODE_ABI. jl_callptr_t expected = NULL; diff --git a/src/staticdata.c b/src/staticdata.c index 65584c015e228..1665b5be4ed0f 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -769,6 +769,16 @@ static uintptr_t jl_fptr_id(void *fptr) return *(uintptr_t*)pbp; } +static int effects_foldable(uint32_t effects) +{ + // N.B.: This needs to be kept in sync with Core.Compiler.is_foldable(effects, true) + return ((effects & 0x7) == 0) && // is_consistent(effects) + (((effects >> 10) & 0x03) == 0) && // is_noub(effects) + (((effects >> 3) & 0x03) == 0) && // is_effect_free(effects) + ((effects >> 6) & 0x01); // is_terminates(effects) +} + + // `jl_queue_for_serialization` adds items to `serialization_order` #define jl_queue_for_serialization(s, v) jl_queue_for_serialization_((s), (jl_value_t*)(v), 1, 0) static void jl_queue_for_serialization_(jl_serializer_state *s, jl_value_t *v, int recursive, int immediate) JL_GC_DISABLED; @@ -908,8 +918,24 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_ // TODO: if (ci in ci->defs->cache) record_field_change((jl_value_t**)&ci->next, NULL); } - if (jl_atomic_load_relaxed(&ci->inferred) && !is_relocatable_ci(&relocatable_ext_cis, ci)) - record_field_change((jl_value_t**)&ci->inferred, jl_nothing); + jl_value_t *inferred = jl_atomic_load_relaxed(&ci->inferred); + if (inferred && inferred != jl_nothing) { // disregard if there is nothing here to delete (e.g. builtins, unspecialized) + if (!is_relocatable_ci(&relocatable_ext_cis, ci)) + record_field_change((jl_value_t**)&ci->inferred, jl_nothing); + else if (jl_is_method(ci->def->def.method) && // don't delete toplevel code + ci->def->def.method->source) { // don't delete code from optimized opaque closures that can't be reconstructed (and builtins) + if (jl_atomic_load_relaxed(&ci->max_world) != ~(size_t)0 || // delete all code that cannot run + jl_atomic_load_relaxed(&ci->invoke) == jl_fptr_const_return) { // delete all code that just returns a constant + record_field_change((jl_value_t**)&ci->inferred, jl_nothing); + } + else if (native_functions && // don't delete any code if making a ji file + !effects_foldable(jl_atomic_load_relaxed(&ci->ipo_purity_bits)) && // don't delete code we may want for irinterp + jl_ir_inlining_cost(inferred) == UINT16_MAX) { // don't delete inlineable code + // delete the code now: if we thought it was worth keeping, it would have been converted to object code + record_field_change((jl_value_t**)&ci->inferred, jl_nothing); + } + } + } } if (immediate) // must be things that can be recursively handled, and valid as type parameters From 7192df7e900a6e4562e1670f544b8be8878ee359 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Mon, 9 Dec 2024 16:42:27 -0500 Subject: [PATCH 029/198] various globals cleanups (#56750) While doing some work on analyzing what code runs at toplevel, I found a few things to simplify or fix: - simplify float.jl loop not to call functions just defined to get back the value just stored there - add method to the correct checkbounds function (instead of a local) - missing world push/pop around jl_interpret_toplevel_thunk after #56509 - jl_lineno use maybe missed in #53799 - add some debugging dump for scm_to_julia_ mistakes --- base/float.jl | 13 ++++++++----- base/range.jl | 2 +- src/ast.c | 2 ++ src/interpreter.c | 3 --- src/toplevel.c | 25 ++++++++++++------------- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/base/float.jl b/base/float.jl index c7230459d0822..faded5cd5978c 100644 --- a/base/float.jl +++ b/base/float.jl @@ -122,13 +122,16 @@ significand_mask(::Type{Float16}) = 0x03ff mantissa(x::T) where {T} = reinterpret(Unsigned, x) & significand_mask(T) for T in (Float16, Float32, Float64) - @eval significand_bits(::Type{$T}) = $(trailing_ones(significand_mask(T))) - @eval exponent_bits(::Type{$T}) = $(sizeof(T)*8 - significand_bits(T) - 1) - @eval exponent_bias(::Type{$T}) = $(Int(exponent_one(T) >> significand_bits(T))) + sb = trailing_ones(significand_mask(T)) + em = exponent_mask(T) + eb = Int(exponent_one(T) >> sb) + @eval significand_bits(::Type{$T}) = $(sb) + @eval exponent_bits(::Type{$T}) = $(sizeof(T)*8 - sb - 1) + @eval exponent_bias(::Type{$T}) = $(eb) # maximum float exponent - @eval exponent_max(::Type{$T}) = $(Int(exponent_mask(T) >> significand_bits(T)) - exponent_bias(T) - 1) + @eval exponent_max(::Type{$T}) = $(Int(em >> sb) - eb - 1) # maximum float exponent without bias - @eval exponent_raw_max(::Type{$T}) = $(Int(exponent_mask(T) >> significand_bits(T))) + @eval exponent_raw_max(::Type{$T}) = $(Int(em >> sb)) end """ diff --git a/base/range.jl b/base/range.jl index b05dddb025a7c..39428ab741955 100644 --- a/base/range.jl +++ b/base/range.jl @@ -954,7 +954,7 @@ function _getindex(v::UnitRange{T}, i::Integer) where {T<:OverflowSafe} end let BitInteger64 = Union{Int8,Int16,Int32,Int64,UInt8,UInt16,UInt32,UInt64} # for bootstrapping - function checkbounds(::Type{Bool}, v::StepRange{<:BitInteger64, <:BitInteger64}, i::BitInteger64) + global function checkbounds(::Type{Bool}, v::StepRange{<:BitInteger64, <:BitInteger64}, i::BitInteger64) res = widemul(step(v), i-oneunit(i)) + first(v) (0 < i) & ifelse(0 < step(v), res <= last(v), res >= last(v)) end diff --git a/src/ast.c b/src/ast.c index 959bac26c2c15..0f24d96393f2f 100644 --- a/src/ast.c +++ b/src/ast.c @@ -669,6 +669,8 @@ static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *m if (iscvalue(e) && cv_class((cvalue_t*)ptr(e)) == jl_ast_ctx(fl_ctx)->jvtype) { return *(jl_value_t**)cv_data((cvalue_t*)ptr(e)); } + fl_print(fl_ctx, ios_stderr, e); + ios_putc('\n', ios_stderr); jl_error("malformed tree"); } diff --git a/src/interpreter.c b/src/interpreter.c index fa4fba94a60a5..a465fe27f5084 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -893,10 +893,7 @@ jl_value_t *NOINLINE jl_interpret_toplevel_thunk(jl_module_t *m, jl_code_info_t s->mi = NULL; s->ci = NULL; JL_GC_ENABLEFRAME(s); - jl_task_t *ct = jl_current_task; - size_t last_age = ct->world_age; jl_value_t *r = eval_body(stmts, s, 0, 1); - ct->world_age = last_age; JL_GC_POP(); return r; } diff --git a/src/toplevel.c b/src/toplevel.c index 21737119af9a6..44b503d4e1463 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -1065,7 +1065,10 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val if (has_opaque) { jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0); } + size_t world = jl_atomic_load_acquire(&jl_world_counter); + ct->world_age = world; result = jl_interpret_toplevel_thunk(m, thk); + ct->world_age = last_age; } JL_GC_POP(); @@ -1075,8 +1078,8 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val JL_DLLEXPORT jl_value_t *jl_toplevel_eval(jl_module_t *m, jl_value_t *v) { const char *filename = jl_filename; - int lieno = jl_lineno; - return jl_toplevel_eval_flex(m, v, 1, 0, &filename, &lieno); + int lineno = jl_lineno; + return jl_toplevel_eval_flex(m, v, 1, 0, &filename, &lineno); } // Check module `m` is open for `eval/include`, or throw an error. @@ -1177,14 +1180,13 @@ static jl_value_t *jl_parse_eval_all(jl_module_t *module, jl_value_t *text, jl_task_t *ct = jl_current_task; int last_lineno = jl_lineno; const char *last_filename = jl_filename; - size_t last_age = ct->world_age; int lineno = 0; jl_lineno = 0; const char *filename_str = jl_string_data(filename); jl_filename = filename_str; - int err = 0; JL_TRY { + size_t last_age = ct->world_age; ct->world_age = jl_atomic_load_acquire(&jl_world_counter); for (size_t i = 0; i < jl_expr_nargs(ast); i++) { expression = jl_exprarg(ast, i); @@ -1200,23 +1202,20 @@ static jl_value_t *jl_parse_eval_all(jl_module_t *module, jl_value_t *text, ct->world_age = jl_atomic_load_relaxed(&jl_world_counter); result = jl_toplevel_eval_flex(module, expression, 1, 1, &filename_str, &lineno); } + ct->world_age = last_age; } JL_CATCH { - result = jl_box_long(jl_lineno); // (ab)use result to root error line - err = 1; - goto finally; // skip jl_restore_excstack - } -finally: - ct->world_age = last_age; - jl_lineno = last_lineno; - jl_filename = last_filename; - if (err) { + result = jl_box_long(lineno); // (ab)use result to root error line + jl_lineno = last_lineno; + jl_filename = last_filename; if (jl_loaderror_type == NULL) jl_rethrow(); else jl_rethrow_other(jl_new_struct(jl_loaderror_type, filename, result, jl_current_exception(ct))); } + jl_lineno = last_lineno; + jl_filename = last_filename; JL_GC_POP(); return result; } From 32ea18ecfb545c6abae8013d133d683987b9e323 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Tue, 10 Dec 2024 03:51:46 -0500 Subject: [PATCH 030/198] Fix test report alignment (#56789) --- stdlib/Test/src/Test.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index 464cb2ac9de9c..3a60527a26e11 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -1194,7 +1194,7 @@ function print_test_results(ts::AbstractTestSet, depth_pad=0) duration_width = max(textwidth("Time"), textwidth(tc.duration)) # Calculate the alignment of the test result counts by # recursively walking the tree of test sets - align = max(get_alignment(ts, 0), textwidth("Test Summary:")) + align = max(get_alignment(ts, depth_pad), textwidth("Test Summary:")) # Print the outer test set header once printstyled(rpad("Test Summary:", align, " "), " |", " "; bold=true) if pass_width > 0 From 42bd79144ea5363ce7cd4c2d5b3785aaecb60f4b Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Tue, 10 Dec 2024 03:53:16 -0500 Subject: [PATCH 031/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?Pkg=20stdlib=20from=20d84a1a38b=20to=20e7c37f342=20(#56786)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 | 1 - .../Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 | 1 - .../Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/md5 | 1 + .../Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/sha512 | 1 + stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 create mode 100644 deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/md5 create mode 100644 deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/sha512 diff --git a/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 b/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 deleted file mode 100644 index f5f87b3f2fa9e..0000000000000 --- a/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -1a5c995237815e0d7d5ee1ec50006c1c diff --git a/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 b/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 deleted file mode 100644 index 839cd4704a135..0000000000000 --- a/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -2e0b984c8272fe4468e0b527698a58d5010ef3f18d38d862665902e5a0e0b7ba65d3085b3d9de367a7b48a216e71d1611687804254503b3905b7b4d217a00f2f diff --git a/deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/md5 b/deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/md5 new file mode 100644 index 0000000000000..6627dc3683c65 --- /dev/null +++ b/deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/md5 @@ -0,0 +1 @@ +7024326f0c033e3da419ed217754fbed diff --git a/deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/sha512 b/deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/sha512 new file mode 100644 index 0000000000000..cfc9d5f30f0e8 --- /dev/null +++ b/deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/sha512 @@ -0,0 +1 @@ +bef19838be850f027fb3dedadce0efa762cd64797809030210ec95830f538ced1b2aede3bd2ca5f32d489e2dc517b7c8e38307adcba194db417ce792437cfb56 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 9ef9ca4b04376..50105c42c642c 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = master -PKG_SHA1 = d84a1a38b6466fa7400e9ad2874a0ef963a10456 +PKG_SHA1 = e7c37f34293ab12051258828884755ea116b77df PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From 9d28a0604a3bfb4c3838ec9ac4ca0997c2b0834c Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Tue, 10 Dec 2024 06:20:39 -0700 Subject: [PATCH 032/198] Bump JuliaSyntax to 0.4.10 (#56110) --- deps/JuliaSyntax.version | 2 +- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + test/syntax.jl | 2 +- 6 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/sha512 create mode 100644 deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/sha512 diff --git a/deps/JuliaSyntax.version b/deps/JuliaSyntax.version index 7f124715024ce..86f94135884a0 100644 --- a/deps/JuliaSyntax.version +++ b/deps/JuliaSyntax.version @@ -1,4 +1,4 @@ JULIASYNTAX_BRANCH = main -JULIASYNTAX_SHA1 = 4f1731d6ce7c2465fc21ea245110b7a39f34658a +JULIASYNTAX_SHA1 = dfd1d69b153eb119873035e62993a109b27192f0 JULIASYNTAX_GIT_URL := https://github.com/JuliaLang/JuliaSyntax.jl.git JULIASYNTAX_TAR_URL = https://api.github.com/repos/JuliaLang/JuliaSyntax.jl/tarball/$1 diff --git a/deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/md5 b/deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/md5 deleted file mode 100644 index c2663955ec773..0000000000000 --- a/deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -8c9d9579eeab1ba40f978a32c9db9900 diff --git a/deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/sha512 b/deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/sha512 deleted file mode 100644 index 46647cb3e432b..0000000000000 --- a/deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -1bdad624f61482b55deba8727fea1c087bfaea9e1f8afa3b44b984441fb7e663dac067baa4a96ae2d4cbd4a46ae8c87e9d20d2dfcd17046ad194711304184e57 diff --git a/deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/md5 b/deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/md5 new file mode 100644 index 0000000000000..51b30461d3905 --- /dev/null +++ b/deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/md5 @@ -0,0 +1 @@ +e58559668aabb0fa96d598970c4d648e diff --git a/deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/sha512 b/deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/sha512 new file mode 100644 index 0000000000000..63a513ec9ae63 --- /dev/null +++ b/deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/sha512 @@ -0,0 +1 @@ +59e22f7db63a383beadf96a68d4db6ae173d61be6d766ea1792b3a3bd70125f73dd4df9e55bad4c66363aa0b6ff6ea5259d3c91abf42f5fe34446e3fa076cc87 diff --git a/test/syntax.jl b/test/syntax.jl index 315f2d8b0f38b..fca8b9e8ccdf5 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -476,7 +476,7 @@ let err = try catch e e end - @test err.line == 7 + @test err.line in (5, 7) end # PR #17393 From da43f11022e394009758379491bcb4de71ef321f Mon Sep 17 00:00:00 2001 From: CY Han Date: Tue, 10 Dec 2024 22:12:54 +0800 Subject: [PATCH 033/198] libgit2: update enums from v1.8.0 (#56764) --- stdlib/LibGit2/src/callbacks.jl | 8 ++++---- stdlib/LibGit2/src/error.jl | 15 ++++++++++++--- stdlib/LibGit2/test/libgit2-tests.jl | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/stdlib/LibGit2/src/callbacks.jl b/stdlib/LibGit2/src/callbacks.jl index 043e04e0dfad6..c4156d4a44c71 100644 --- a/stdlib/LibGit2/src/callbacks.jl +++ b/stdlib/LibGit2/src/callbacks.jl @@ -43,7 +43,7 @@ end function user_abort() ensure_initialized() # Note: Potentially it could be better to just throw a Julia error. - ccall((:giterr_set_str, libgit2), Cvoid, + ccall((:git_error_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), "Aborting, user cancelled credential request.") return Cint(Error.EUSER) @@ -51,7 +51,7 @@ end function prompt_limit() ensure_initialized() - ccall((:giterr_set_str, libgit2), Cvoid, + ccall((:git_error_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), "Aborting, maximum number of prompts reached.") return Cint(Error.EAUTH) @@ -59,7 +59,7 @@ end function exhausted_abort() ensure_initialized() - ccall((:giterr_set_str, libgit2), Cvoid, + ccall((:git_error_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), "All authentication methods have failed.") return Cint(Error.EAUTH) @@ -339,7 +339,7 @@ function credentials_callback(libgit2credptr::Ptr{Ptr{Cvoid}}, url_ptr::Cstring, if err == 0 if p.explicit !== nothing ensure_initialized() - ccall((:giterr_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), + ccall((:git_error_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), "The explicitly provided credential is incompatible with the requested " * "authentication methods.") end diff --git a/stdlib/LibGit2/src/error.jl b/stdlib/LibGit2/src/error.jl index 1a493006ea1b5..6647d803d3193 100644 --- a/stdlib/LibGit2/src/error.jl +++ b/stdlib/LibGit2/src/error.jl @@ -19,7 +19,7 @@ export GitError EUNMERGED = Cint(-10), # merge in progress prevented op ENONFASTFORWARD = Cint(-11), # ref not fast-forwardable EINVALIDSPEC = Cint(-12), # name / ref not in valid format - EMERGECONFLICT = Cint(-13), # merge conflict prevented op + ECONFLICT = Cint(-13), # Checkout conflicts prevented operation ELOCKED = Cint(-14), # lock file prevented op EMODIFIED = Cint(-15), # ref value does not match expected EAUTH = Cint(-16), # authentication error @@ -27,6 +27,11 @@ export GitError EAPPLIED = Cint(-18), # patch/merge has already been applied EPEEL = Cint(-19), # the requested peel operation is not possible EEOF = Cint(-20), # unexpected EOF + EINVALID = Cint(-21), # Invalid operation or input + EUNCOMMITTED = Cint(-22), # Uncommitted changes in index prevented operation + EDIRECTORY = Cint(-23), # The operation is not valid for a directory + EMERGECONFLICT = Cint(-24), # A merge conflict exists and cannot continue + PASSTHROUGH = Cint(-30), # internal only ITEROVER = Cint(-31), # signals end of iteration RETRY = Cint(-32), # internal only @@ -34,7 +39,11 @@ export GitError EINDEXDIRTY = Cint(-34), # unsaved changes in the index would be overwritten EAPPLYFAIL = Cint(-35), # patch application failed EOWNER = Cint(-36), # the object is not owned by the current user - TIMEOUT = Cint(-37)) # The operation timed out + TIMEOUT = Cint(-37), # The operation timed out + EUNCHANGED = Cint(-38), # There were no changes + ENOTSUPPORTED = Cint(-39), # An option is not supported + EREADONLY = Cint(-40), # The subject is read-only +) @enum(Class, None, NoMemory, @@ -88,7 +97,7 @@ Base.show(io::IO, err::GitError) = print(io, "GitError(Code:$(err.code), Class:$ function last_error() ensure_initialized() - err = ccall((:giterr_last, libgit2), Ptr{ErrorStruct}, ()) + err = ccall((:git_error_last, libgit2), Ptr{ErrorStruct}, ()) if err != C_NULL err_obj = unsafe_load(err) err_class = Class(err_obj.class) diff --git a/stdlib/LibGit2/test/libgit2-tests.jl b/stdlib/LibGit2/test/libgit2-tests.jl index 9ab75ed1dc39b..1dfa5429368b6 100644 --- a/stdlib/LibGit2/test/libgit2-tests.jl +++ b/stdlib/LibGit2/test/libgit2-tests.jl @@ -1070,7 +1070,7 @@ mktempdir() do dir # test workaround for git_tree_walk issue # https://github.com/libgit2/libgit2/issues/4693 - ccall((:giterr_set_str, libgit2), Cvoid, (Cint, Cstring), + ccall((:git_error_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(LibGit2.Error.Invalid), "previous error") try # file needs to exist in tree in order to trigger the stop walk condition From 19e06d39141e1e2f0f9c4664ba9b88867b587a6e Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Tue, 10 Dec 2024 09:33:41 -0500 Subject: [PATCH 034/198] fix `exp(weirdNaN)` (#56784) Fixes https://github.com/JuliaLang/julia/issues/56782 Fix `exp(reinterpret(Float64, 0x7ffbb14880000000))` returning non-NaN value. This should have minimal performance impact since it's already in the fallback branch. --- base/special/exp.jl | 2 ++ test/math.jl | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/base/special/exp.jl b/base/special/exp.jl index 312197339a086..38d7509807aed 100644 --- a/base/special/exp.jl +++ b/base/special/exp.jl @@ -216,6 +216,7 @@ end small_part = muladd(jU, expm1b_kernel(base, r), jL) + jU if !(abs(x) <= SUBNORM_EXP(base, T)) + isnan(x) && return x x >= MAX_EXP(base, T) && return Inf x <= MIN_EXP(base, T) && return 0.0 if k <= -53 @@ -243,6 +244,7 @@ end hi, lo = Base.canonicalize2(1.0, kern) small_part = fma(jU, hi, muladd(jU, (lo+xlo), very_small)) if !(abs(x) <= SUBNORM_EXP(base, T)) + isnan(x) && return x x >= MAX_EXP(base, T) && return Inf x <= MIN_EXP(base, T) && return 0.0 if k <= -53 diff --git a/test/math.jl b/test/math.jl index d794facb02d25..7070fe63ba931 100644 --- a/test/math.jl +++ b/test/math.jl @@ -382,6 +382,10 @@ end end end +@testset "https://github.com/JuliaLang/julia/issues/56782" begin + @test isnan(exp(reinterpret(Float64, 0x7ffbb14880000000))) +end + @testset "test abstractarray trig functions" begin TAA = rand(2,2) TAA = (TAA + TAA')/2. From 9160e048b343d34aaab64d816c52087ba24f24fc Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:39:03 -0500 Subject: [PATCH 035/198] Add note to Vararg/UnionAll warning about making it an error (#56662) This warning message ``` WARNING: Wrapping `Vararg` directly in UnionAll is deprecated (wrap the tuple instead). You may need to write `f(x::Vararg{T})` rather than `f(x::Vararg{<:T})` or `f(x::Vararg{T}) where T` instead of `f(x::Vararg{T} where T)`. ``` (last extended in #49558) seems clear enough if you wrote the code. But if it's coming from 10 packages deep, there's no information to track down the origin. Turns out you can do this with `--depwarn=error`. But the message doesn't tell you that, and doesn't call itself a deprecation warning at all. --- src/jltypes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jltypes.c b/src/jltypes.c index abd1f62092035..52b993cd5aa4d 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -910,7 +910,7 @@ JL_DLLEXPORT jl_value_t *jl_type_unionall(jl_tvar_t *v, jl_value_t *body) if (jl_options.depwarn) { if (jl_options.depwarn == JL_OPTIONS_DEPWARN_ERROR) jl_error("Wrapping `Vararg` directly in UnionAll is deprecated (wrap the tuple instead).\nYou may need to write `f(x::Vararg{T})` rather than `f(x::Vararg{<:T})` or `f(x::Vararg{T}) where T` instead of `f(x::Vararg{T} where T)`."); - jl_printf(JL_STDERR, "WARNING: Wrapping `Vararg` directly in UnionAll is deprecated (wrap the tuple instead).\nYou may need to write `f(x::Vararg{T})` rather than `f(x::Vararg{<:T})` or `f(x::Vararg{T}) where T` instead of `f(x::Vararg{T} where T)`.\n"); + jl_printf(JL_STDERR, "WARNING: Wrapping `Vararg` directly in UnionAll is deprecated (wrap the tuple instead).\nYou may need to write `f(x::Vararg{T})` rather than `f(x::Vararg{<:T})` or `f(x::Vararg{T}) where T` instead of `f(x::Vararg{T} where T)`.\nTo make this warning an error, and hence obtain a stack trace, use `julia --depwarn=error`.\n"); } jl_vararg_t *vm = (jl_vararg_t*)body; int T_has_tv = vm->T && jl_has_typevar(vm->T, v); From 29a7ce403fb1ed302183c5f87ebd859e98dc6ed4 Mon Sep 17 00:00:00 2001 From: Paul Melis Date: Tue, 10 Dec 2024 15:42:33 +0100 Subject: [PATCH 036/198] Add a note clearifying option parsing (#56285) To help with #56274 --- doc/src/manual/command-line-interface.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/src/manual/command-line-interface.md b/doc/src/manual/command-line-interface.md index 9b06deaf0ea8a..3477f61164c50 100644 --- a/doc/src/manual/command-line-interface.md +++ b/doc/src/manual/command-line-interface.md @@ -222,6 +222,10 @@ The following is a complete list of command-line switches available when launchi |`--permalloc-pkgimg={yes\|no*}` |Copy the data section of package images into memory| |`--trim={no*\|safe\|unsafe\|unsafe-warn}` |Build a sysimage including only code provably reachable from methods marked by calling `entrypoint`. The three non-default options differ in how they handle dynamic call sites. In safe mode, such sites result in compile-time errors. In unsafe mode, such sites are allowed but the resulting binary might be missing needed code and can throw runtime errors. With unsafe-warn, such sites will trigger warnings at compile-time and might error at runtime.| +Options that have the form `--option={...}` can be specified either as `--option=value` or as `--option value`. For example, `julia --banner=no` is equivalent to `julia --banner no`. This is especially relevant for options that take a filename for output, because forgetting to specifying the argument for (say) `--trace-compile` will cause the option following it to be interpreted as the filename, possibly unintentionally overwriting it. + +Note that options of the form `--option[=...]` can **not** be specified as `--option value`, but only as `--option=value` (or simply `--option`, when no argument is provided). + !!! compat "Julia 1.1" In Julia 1.0, the default `--project=@.` option did not search up from the root directory of a Git repository for the `Project.toml` file. From Julia 1.1 forward, it From d269d7d375827a0279dc1fee7bb24c9418f06f03 Mon Sep 17 00:00:00 2001 From: Zentrik Date: Wed, 11 Dec 2024 08:31:11 +0000 Subject: [PATCH 037/198] Fix undefined symbol error in version script (#55363) lld 17 and above by default error if symbols listed in the version script are undefined. Julia has a few of these, as some symbols are defined conditionally in Julia (e.g. based on OS), others perhaps have been removed from Julia and other seem to be defined in other libraries. Further the version script is used in linking three times, each time linking together different objects and so having different symbols defined. Adding `-Wl,--undefined-version` is not a great solution as passing that to ld < 2.40 errors and there doesn't seem to be a great way to check if a linker supports this flag. I don't know how to get around these errors for symbols like `_IO_stdin_used` which Julia doesn't define and it seems to matter whether or not they are exported, see https://libc-alpha.sourceware.narkive.com/SevIQmU3/io-stdin-used-stripped-by-version-scripts. So I've converted all undefined symbols into wildcards to work around the error. Fixes #50414, fixes #54533 and replaces #55319. --------- Co-authored-by: Zentrik --- Make.inc | 2 +- src/julia.expmap.in | 38 +++++++++++++++++++------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Make.inc b/Make.inc index 29512bbbe7f45..a60a95d21c3db 100644 --- a/Make.inc +++ b/Make.inc @@ -1470,7 +1470,7 @@ ifeq (,$(findstring aarch64,$(ARCH))) OSLIBS += -lgcc_s endif -OSLIBS += -Wl,--export-dynamic -Wl,--undefined-version -Wl,--version-script=$(BUILDROOT)/src/julia.expmap \ +OSLIBS += -Wl,--export-dynamic -Wl,--version-script=$(BUILDROOT)/src/julia.expmap \ $(NO_WHOLE_ARCHIVE) endif diff --git a/src/julia.expmap.in b/src/julia.expmap.in index 29366f6296a85..b28a714e75f69 100644 --- a/src/julia.expmap.in +++ b/src/julia.expmap.in @@ -2,7 +2,7 @@ global: pthread*; __stack_chk_*; - asprintf; + asprintf*; bitvector_*; ios_*; arraylist_*; @@ -10,33 +10,33 @@ jl_*; ijl_*; _jl_mutex_*; - rec_backtrace; + rec_backtrace*; julia_*; - libsupport_init; - localtime_r; - memhash; - memhash32; - memhash32_seed; - memhash_seed; - restore_signals; + libsupport_init*; + localtime_r*; + memhash*; + memhash32*; + memhash32_seed*; + memhash_seed*; + restore_signals*; u8_*; uv_*; - add_library_mapping; + add_library_mapping*; utf8proc_*; - jlbacktrace; - jlbacktracet; - _IO_stdin_used; - _Z24jl_coverage_data_pointerN4llvm9StringRefEi; - _Z22jl_coverage_alloc_lineN4llvm9StringRefEi; - _Z22jl_malloc_data_pointerN4llvm9StringRefEi; + jlbacktrace*; + jlbacktracet*; + _IO_stdin_used*; /* glibc expects this to be exported to detect which version of glibc is being used, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109 for further details */ + _Z24jl_coverage_data_pointerN4llvm9StringRefEi*; + _Z22jl_coverage_alloc_lineN4llvm9StringRefEi*; + _Z22jl_malloc_data_pointerN4llvm9StringRefEi*; _jl_timing_*; LLVMExtra*; JLJIT*; - llvmGetPassPluginInfo; + llvmGetPassPluginInfo*; /* freebsd */ - environ; - __progname; + environ*; + __progname*; local: *; From 92d37025fd2c49abbdabd16bc6308b75e978e4d6 Mon Sep 17 00:00:00 2001 From: Nathan Boyer <65452054+nathanrboyer@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:47:43 -0500 Subject: [PATCH 038/198] Update repr docstring to hint what it stands for. (#56761) - Change `repr` docstring from "Create a string from any value ..." to "Create a string representation of any value ...". - Document that it typically emits parseable Julia code --------- Co-authored-by: Ian Butterworth --- base/strings/io.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/base/strings/io.jl b/base/strings/io.jl index 116bcf71eeb7a..b4a3c7ad3e0c2 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -250,7 +250,9 @@ print(io::IO, s::Union{String,SubString{String}}) = (write(io, s); nothing) """ repr(x; context=nothing) -Create a string from any value using the 2-argument `show(io, x)` function. +Create a string representation of any value using the 2-argument `show(io, x)` function, +which aims to produce a string that is parseable Julia code, where possible. +i.e. `eval(Meta.parse(repr(x))) == x` should hold true. You should not add methods to `repr`; define a [`show`](@ref) method instead. The optional keyword argument `context` can be set to a `:key=>value` pair, a From 582585bfb0a5494d41fd28b47a9774d498c608d9 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Wed, 11 Dec 2024 16:59:25 -0500 Subject: [PATCH 039/198] Fix generate_precompile statement grouping & avoid defining new func (#56317) --- contrib/generate_precompile.jl | 100 ++++++++++++++++----------------- 1 file changed, 48 insertions(+), 52 deletions(-) diff --git a/contrib/generate_precompile.jl b/contrib/generate_precompile.jl index ffbbfd620997f..b075223d9c7e4 100644 --- a/contrib/generate_precompile.jl +++ b/contrib/generate_precompile.jl @@ -136,60 +136,56 @@ for match = Base._methods(+, (Int, Int), -1, Base.get_world_counter()) m = match.method delete!(push!(Set{Method}(), m), m) copy(Core.Compiler.retrieve_code_info(Core.Compiler.specialize_method(match), typemax(UInt))) - - empty!(Set()) - push!(push!(Set{Union{GlobalRef,Symbol}}(), :two), GlobalRef(Base, :two)) - (setindex!(Dict{String,Base.PkgId}(), Base.PkgId(Base), "file.jl"))["file.jl"] - (setindex!(Dict{Symbol,Vector{Int}}(), [1], :two))[:two] - (setindex!(Dict{Base.PkgId,String}(), "file.jl", Base.PkgId(Base)))[Base.PkgId(Base)] - (setindex!(Dict{Union{GlobalRef,Symbol}, Vector{Int}}(), [1], :two))[:two] - (setindex!(IdDict{Type, Union{Missing, Vector{Tuple{LineNumberNode, Expr}}}}(), missing, Int))[Int] - Dict{Symbol, Union{Nothing, Bool, Symbol}}(:one => false)[:one] - Dict(Base => [:(1+1)])[Base] - Dict(:one => [1])[:one] - Dict("abc" => Set())["abc"] - pushfirst!([], sum) - get(Base.pkgorigins, Base.PkgId(Base), nothing) - sort!([1,2,3]) - unique!([1,2,3]) - cumsum([1,2,3]) - append!(Int[], BitSet()) - isempty(BitSet()) - delete!(BitSet([1,2]), 3) - deleteat!(Int32[1,2,3], [1,3]) - deleteat!(Any[1,2,3], [1,3]) - Core.svec(1, 2) == Core.svec(3, 4) - any(t->t[1].line > 1, [(LineNumberNode(2,:none), :(1+1))]) - - # Code loading uses this - sortperm(mtime.(readdir(".")), rev=true) - # JLLWrappers uses these - Dict{Base.UUID,Set{String}}()[Base.UUID("692b3bcd-3c85-4b1f-b108-f13ce0eb3210")] = Set{String}() - get!(Set{String}, Dict{Base.UUID,Set{String}}(), Base.UUID("692b3bcd-3c85-4b1f-b108-f13ce0eb3210")) - eachindex(IndexLinear(), Expr[]) - push!(Expr[], Expr(:return, false)) - vcat(String[], String[]) - k, v = (:hello => nothing) - Base.print_time_imports_report(Base) - Base.print_time_imports_report_init(Base) - - # Preferences uses these - get(Dict{String,Any}(), "missing", nothing) - delete!(Dict{String,Any}(), "missing") - for (k, v) in Dict{String,Any}() - println(k) - end - - # interactive startup uses this - write(IOBuffer(), "") - - # Not critical, but helps hide unrelated compilation from @time when using --trace-compile. - f55729() = Base.Experimental.@force_compile - @time @eval f55729() - @time @eval f55729() - break # only actually need to do this once end +empty!(Set()) +push!(push!(Set{Union{GlobalRef,Symbol}}(), :two), GlobalRef(Base, :two)) +(setindex!(Dict{String,Base.PkgId}(), Base.PkgId(Base), "file.jl"))["file.jl"] +(setindex!(Dict{Symbol,Vector{Int}}(), [1], :two))[:two] +(setindex!(Dict{Base.PkgId,String}(), "file.jl", Base.PkgId(Base)))[Base.PkgId(Base)] +(setindex!(Dict{Union{GlobalRef,Symbol}, Vector{Int}}(), [1], :two))[:two] +(setindex!(IdDict{Type, Union{Missing, Vector{Tuple{LineNumberNode, Expr}}}}(), missing, Int))[Int] +Dict{Symbol, Union{Nothing, Bool, Symbol}}(:one => false)[:one] +Dict(Base => [:(1+1)])[Base] +Dict(:one => [1])[:one] +Dict("abc" => Set())["abc"] +pushfirst!([], sum) +get(Base.pkgorigins, Base.PkgId(Base), nothing) +sort!([1,2,3]) +unique!([1,2,3]) +cumsum([1,2,3]) +append!(Int[], BitSet()) +isempty(BitSet()) +delete!(BitSet([1,2]), 3) +deleteat!(Int32[1,2,3], [1,3]) +deleteat!(Any[1,2,3], [1,3]) +Core.svec(1, 2) == Core.svec(3, 4) +any(t->t[1].line > 1, [(LineNumberNode(2,:none), :(1+1))]) + +# Code loading uses this +sortperm(mtime.(readdir(".")), rev=true) +# JLLWrappers uses these +Dict{Base.UUID,Set{String}}()[Base.UUID("692b3bcd-3c85-4b1f-b108-f13ce0eb3210")] = Set{String}() +get!(Set{String}, Dict{Base.UUID,Set{String}}(), Base.UUID("692b3bcd-3c85-4b1f-b108-f13ce0eb3210")) +eachindex(IndexLinear(), Expr[]) +push!(Expr[], Expr(:return, false)) +vcat(String[], String[]) +k, v = (:hello => nothing) +Base.print_time_imports_report(Base) +Base.print_time_imports_report_init(Base) + +# Preferences uses these +get(Dict{String,Any}(), "missing", nothing) +delete!(Dict{String,Any}(), "missing") +for (k, v) in Dict{String,Any}() + println(k) +end + +# interactive startup uses this +write(IOBuffer(), "") + +# precompile @time report generation and printing +@time @eval Base.Experimental.@force_compile """ julia_exepath() = joinpath(Sys.BINDIR, Base.julia_exename()) From 48be7ca438dd607e47936660b5dbc38145e6399e Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Thu, 12 Dec 2024 12:40:00 +0100 Subject: [PATCH 040/198] remove LinearAlgebra specific bitarray tests since they have moved to the external LinearAlgebra.jl repo (#56800) Moved in https://github.com/JuliaLang/LinearAlgebra.jl/pull/1148. --- test/bitarray.jl | 69 +++--------------------------------------------- 1 file changed, 4 insertions(+), 65 deletions(-) diff --git a/test/bitarray.jl b/test/bitarray.jl index 67d8fae0eda6d..fd5c1421a256f 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -1,7 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using Base: findprevnot, findnextnot -using Random, LinearAlgebra, Test +using Random, Test, LinearAlgebra # Ideally, these tests should not depend on LinearAlgebra isdefined(Main, :SizedArrays) || @eval Main include("testhelpers/SizedArrays.jl") using .Main.SizedArrays @@ -15,7 +15,6 @@ tc(r1,r2) = false bitcheck(b::BitArray) = Test._check_bitarray_consistency(b) bitcheck(x) = true -bcast_setindex!(b, x, I...) = (b[I...] .= x; b) function check_bitop_call(ret_type, func, args...; kwargs...) r2 = func(map(x->(isa(x, BitArray) ? Array(x) : x), args)...; kwargs...) @@ -34,6 +33,9 @@ macro check_bit_operation(ex) Expr(:call, :check_bitop_call, nothing, map(esc, ex.args)...) end +bcast_setindex!(b, x, I...) = (b[I...] .= x; b) + + let t0 = time_ns() global timesofar function timesofar(str) @@ -1641,69 +1643,6 @@ end timesofar("cat") -@testset "Linear algebra" begin - b1 = bitrand(v1) - b2 = bitrand(v1) - @check_bit_operation dot(b1, b2) Int - - b1 = bitrand(n1, n2) - @test_throws ArgumentError tril(b1, -n1 - 2) - @test_throws ArgumentError tril(b1, n2) - @test_throws ArgumentError triu(b1, -n1) - @test_throws ArgumentError triu(b1, n2 + 2) - for k in (-n1 - 1):(n2 - 1) - @check_bit_operation tril(b1, k) BitMatrix - end - for k in (-n1 + 1):(n2 + 1) - @check_bit_operation triu(b1, k) BitMatrix - end - - for sz = [(n1,n1), (n1,n2), (n2,n1)], (f,isf) = [(tril,istril), (triu,istriu)] - b1 = bitrand(sz...) - @check_bit_operation isf(b1) Bool - b1 = f(bitrand(sz...)) - @check_bit_operation isf(b1) Bool - end - - b1 = bitrand(n1,n1) - b1 .|= copy(b1') - @check_bit_operation issymmetric(b1) Bool - @check_bit_operation ishermitian(b1) Bool - - b1 = bitrand(n1) - b2 = bitrand(n2) - @check_bit_operation kron(b1, b2) BitVector - - b1 = bitrand(s1, s2) - b2 = bitrand(s3, s4) - @check_bit_operation kron(b1, b2) BitMatrix - - b1 = bitrand(v1) - @check_bit_operation diff(b1) Vector{Int} - - b1 = bitrand(n1, n2) - @check_bit_operation diff(b1, dims=1) Matrix{Int} - @check_bit_operation diff(b1, dims=2) Matrix{Int} - - b1 = bitrand(n1, n1) - @test ((svdb1, svdb1A) = (svd(b1), svd(Array(b1))); - svdb1.U == svdb1A.U && svdb1.S == svdb1A.S && svdb1.V == svdb1A.V) - @test ((qrb1, qrb1A) = (qr(b1), qr(Array(b1))); - Matrix(qrb1.Q) == Matrix(qrb1A.Q) && qrb1.R == qrb1A.R) - - b1 = bitrand(v1) - @check_bit_operation diagm(0 => b1) BitMatrix - - b1 = bitrand(v1) - b2 = bitrand(v1) - @check_bit_operation diagm(-1 => b1, 1 => b2) BitMatrix - - b1 = bitrand(n1, n1) - @check_bit_operation diag(b1) -end - -timesofar("linalg") - @testset "findmax, findmin" begin b1 = trues(0) @test_throws ArgumentError findmax(b1) From 9118ea7565feae13d5b47654a3c245c0df36e753 Mon Sep 17 00:00:00 2001 From: William Moses Date: Thu, 12 Dec 2024 07:46:25 -0600 Subject: [PATCH 041/198] Fix partially_inline for unreachable (#56787) --- base/meta.jl | 5 +++++ test/meta.jl | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/base/meta.jl b/base/meta.jl index bcf4fbf632ab2..0078e15bcd98b 100644 --- a/base/meta.jl +++ b/base/meta.jl @@ -363,10 +363,15 @@ function _partially_inline!(@nospecialize(x), slot_replacements::Vector{Any}, return x end if isa(x, Core.ReturnNode) + # Unreachable doesn't have val defined + if !isdefined(x, :val) + return x + else return Core.ReturnNode( _partially_inline!(x.val, slot_replacements, type_signature, static_param_values, slot_offset, statement_offset, boundscheck), ) + end end if isa(x, Core.GotoIfNot) return Core.GotoIfNot( diff --git a/test/meta.jl b/test/meta.jl index 5fb1ebc0d3647..2b235d3cc1b0d 100644 --- a/test/meta.jl +++ b/test/meta.jl @@ -276,6 +276,11 @@ ci = code_lowered(g, Tuple{Val{true}})[1] @test Meta.partially_inline!(copy(ci.code), Any[isdefined_globalref, 1], Tuple{typeof(isdefined_globalref), Int}, [], 0, 0, :propagate)[1] == Expr(:isdefined, GlobalRef(Base, :foo)) + withunreachable(s::String) = sin(s) + ci = code_lowered(withunreachable, Tuple{String})[1] + ci.code[end] = Core.ReturnNode() + @test Meta.partially_inline!(copy(ci.code), Any[withunreachable, "foo"], Tuple{typeof(withunreachable), String}, + [], 0, 0, :propagate)[end] == Core.ReturnNode() end @testset "Base.Meta docstrings" begin From cea6a9a6b7a605bb58798eee4ba1b068d7f893eb Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 12 Dec 2024 16:19:43 -0500 Subject: [PATCH 042/198] codegen: reduce recursion in cfunction generation (#56806) The regular code-path for this was only missing the age_ok handling, so add in that handling so we can delete the custom path here for the test and some of the brokenness that implied. --- src/aotcompile.cpp | 2 +- src/cgutils.cpp | 4 +- src/codegen.cpp | 240 ++++++++++++++--------------------------- src/gf.c | 6 +- src/jitlayers.cpp | 83 ++++++++------ src/jitlayers.h | 7 +- src/julia_internal.h | 2 +- src/precompile_utils.c | 4 +- test/llvmcall.jl | 2 +- 9 files changed, 146 insertions(+), 204 deletions(-) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index ba9a3c05e41ff..198d7490cb092 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -505,7 +505,7 @@ static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root size_t nrealargs = jl_nparams(mi->specTypes); // number of actual arguments being passed bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure; // TODO: maybe this can be cached in codeinst->specfptr? - emit_specsig_to_fptr1(proto.decl, proto.cc, proto.return_roots, mi->specTypes, codeinst->rettype, is_opaque_closure, nrealargs, params, pinvoke, 0, 0); + emit_specsig_to_fptr1(proto.decl, proto.cc, proto.return_roots, mi->specTypes, codeinst->rettype, is_opaque_closure, nrealargs, params, pinvoke); preal_decl = ""; // no need to fixup the name } if (!preal_decl.empty()) { diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 9e170555e6149..dd6ced04673e6 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -2279,7 +2279,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, const jl_cgval_t argv[3] = { cmp, lhs, rhs }; jl_cgval_t ret; if (modifyop) { - ret = emit_invoke(ctx, *modifyop, argv, 3, (jl_value_t*)jl_any_type); + ret = emit_invoke(ctx, *modifyop, argv, 3, (jl_value_t*)jl_any_type, nullptr); } else { if (trim_may_error(ctx.params->trim)) { @@ -4018,7 +4018,7 @@ static jl_cgval_t union_store(jl_codectx_t &ctx, emit_lockstate_value(ctx, needlock, false); const jl_cgval_t argv[3] = { cmp, oldval, rhs }; if (modifyop) { - rhs = emit_invoke(ctx, *modifyop, argv, 3, (jl_value_t*)jl_any_type); + rhs = emit_invoke(ctx, *modifyop, argv, 3, (jl_value_t*)jl_any_type, nullptr); } else { if (trim_may_error(ctx.params->trim)) { diff --git a/src/codegen.cpp b/src/codegen.cpp index 21591acedc632..fbd990857dd94 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2074,7 +2074,7 @@ static CallInst *emit_jlcall(jl_codectx_t &ctx, JuliaFunction<> *theFptr, Value static Value *emit_f_is(jl_codectx_t &ctx, const jl_cgval_t &arg1, const jl_cgval_t &arg2, Value *nullcheck1 = nullptr, Value *nullcheck2 = nullptr); static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t nargs, ArrayRef argv, bool is_promotable=false); -static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayRef argv, size_t nargs, jl_value_t *rt); +static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayRef argv, size_t nargs, jl_value_t *rt, Value *age_ok); static Value *literal_pointer_val(jl_codectx_t &ctx, jl_value_t *p); static unsigned julia_alignment(jl_value_t *jt); @@ -2141,18 +2141,18 @@ static jl_value_t *StackFrame( return frame; } -static void push_frames(jl_codectx_t &ctx, jl_method_instance_t *caller, jl_method_instance_t *callee, int no_debug=false) +static void push_frames(jl_codectx_t &ctx, jl_method_instance_t *caller, jl_method_instance_t *callee) { CallFrames frames; auto it = ctx.emission_context.enqueuers.find(callee); if (it != ctx.emission_context.enqueuers.end()) return; - if (no_debug) { // Used in tojlinvoke + auto DL = ctx.builder.getCurrentDebugLocation(); + if (caller == nullptr || !DL) { // Used in various places frames.push_back({ctx.funcName, "", 0}); ctx.emission_context.enqueuers.insert({callee, {caller, std::move(frames)}}); return; } - auto DL = ctx.builder.getCurrentDebugLocation(); auto filename = std::string(DL->getFilename()); auto line = DL->getLine(); auto fname = std::string(DL->getScope()->getSubprogram()->getName()); @@ -5205,14 +5205,12 @@ static CallInst *emit_jlcall(jl_codectx_t &ctx, JuliaFunction<> *theFptr, Value return emit_jlcall(ctx, prepare_call(theFptr), theF, argv, nargs, trampoline); } -static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_closure, jl_value_t *specTypes, jl_value_t *jlretty, jl_returninfo_t &returninfo, jl_code_instance_t *fromexternal, - ArrayRef argv, size_t nargs) +static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_closure, jl_value_t *specTypes, jl_value_t *jlretty, jl_returninfo_t &returninfo, ArrayRef argv, size_t nargs) { ++EmittedSpecfunCalls; // emit specialized call site bool gcstack_arg = JL_FEAT_TEST(ctx, gcstack_arg); - FunctionType *cft = returninfo.decl.getFunctionType(); - size_t nfargs = cft->getNumParams(); + size_t nfargs = returninfo.decl.getFunctionType()->getNumParams(); SmallVector argvals(nfargs); unsigned idx = 0; AllocaInst *result = nullptr; @@ -5304,23 +5302,7 @@ static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_clos idx++; } assert(idx == nfargs); - Value *TheCallee = returninfo.decl.getCallee(); - if (fromexternal) { - std::string namep("p"); - namep += cast(returninfo.decl.getCallee())->getName(); - GlobalVariable *GV = cast_or_null(jl_Module->getNamedValue(namep)); - if (GV == nullptr) { - GV = new GlobalVariable(*jl_Module, TheCallee->getType(), false, - GlobalVariable::ExternalLinkage, - Constant::getNullValue(TheCallee->getType()), - namep); - ctx.emission_context.external_fns[std::make_tuple(fromexternal, true)] = GV; - } - jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); - TheCallee = ai.decorateInst(ctx.builder.CreateAlignedLoad(TheCallee->getType(), GV, Align(sizeof(void*)))); - setName(ctx.emission_context, TheCallee, namep); - } - CallInst *call = ctx.builder.CreateCall(cft, TheCallee, argvals); + CallInst *call = ctx.builder.CreateCall(returninfo.decl, argvals); call->setAttributes(returninfo.attrs); if (gcstack_arg && ctx.emission_context.use_swiftcc) call->setCallingConv(CallingConv::Swift); @@ -5362,7 +5344,7 @@ static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_clos } static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_closure, jl_value_t *specTypes, jl_value_t *jlretty, llvm::Value *callee, StringRef specFunctionObject, jl_code_instance_t *fromexternal, - ArrayRef argv, size_t nargs, jl_returninfo_t::CallingConv *cc, unsigned *nreturn_roots, jl_value_t *inferred_retty) + ArrayRef argv, size_t nargs, jl_returninfo_t::CallingConv *cc, unsigned *nreturn_roots, jl_value_t *inferred_retty, Value *age_ok) { ++EmittedSpecfunCalls; // emit specialized call site @@ -5370,21 +5352,52 @@ static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_clos jl_returninfo_t returninfo = get_specsig_function(ctx, jl_Module, callee, specFunctionObject, specTypes, jlretty, is_opaque_closure, gcstack_arg); *cc = returninfo.cc; *nreturn_roots = returninfo.return_roots; - jl_cgval_t retval = emit_call_specfun_other(ctx, is_opaque_closure, specTypes, jlretty, returninfo, fromexternal, argv, nargs); + if (fromexternal) { + std::string namep("p"); + Value *TheCallee = returninfo.decl.getCallee(); + namep += cast(TheCallee)->getName(); + GlobalVariable *GV = cast_or_null(jl_Module->getNamedValue(namep)); + if (GV == nullptr) { + GV = new GlobalVariable(*jl_Module, TheCallee->getType(), false, + GlobalVariable::ExternalLinkage, + Constant::getNullValue(TheCallee->getType()), + namep); + ctx.emission_context.external_fns[std::make_tuple(fromexternal, true)] = GV; + } + jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); + TheCallee = ai.decorateInst(ctx.builder.CreateAlignedLoad(TheCallee->getType(), GV, Align(sizeof(void*)))); + setName(ctx.emission_context, TheCallee, namep); + returninfo.decl = FunctionCallee(returninfo.decl.getFunctionType(), TheCallee); + } + if (age_ok) { + std::string funcName(specFunctionObject); + funcName += "_gfthunk"; + Function *gf_thunk = Function::Create(returninfo.decl.getFunctionType(), + GlobalVariable::InternalLinkage, funcName, jl_Module); + jl_init_function(gf_thunk, ctx.emission_context.TargetTriple); + gf_thunk->setAttributes(AttributeList::get(gf_thunk->getContext(), {returninfo.attrs, gf_thunk->getAttributes()})); + // build a specsig -> jl_apply_generic converter thunk + // this builds a method that calls jl_apply_generic (as a closure over a singleton function pointer), + // but which has the signature of a specsig + emit_specsig_to_fptr1(gf_thunk, returninfo.cc, returninfo.return_roots, specTypes, jlretty, is_opaque_closure, nargs, ctx.emission_context, + prepare_call(jlapplygeneric_func)); + returninfo.decl = FunctionCallee(returninfo.decl.getFunctionType(), ctx.builder.CreateSelect(age_ok, returninfo.decl.getCallee(), gf_thunk)); + } + jl_cgval_t retval = emit_call_specfun_other(ctx, is_opaque_closure, specTypes, jlretty, returninfo, argv, nargs); // see if inference has a different / better type for the call than the lambda return update_julia_type(ctx, retval, inferred_retty); } static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, jl_method_instance_t *mi, jl_value_t *jlretty, StringRef specFunctionObject, jl_code_instance_t *fromexternal, - ArrayRef argv, size_t nargs, jl_returninfo_t::CallingConv *cc, unsigned *return_roots, jl_value_t *inferred_retty) + ArrayRef argv, size_t nargs, jl_returninfo_t::CallingConv *cc, unsigned *return_roots, jl_value_t *inferred_retty, Value *age_ok) { bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure; return emit_call_specfun_other(ctx, is_opaque_closure, mi->specTypes, jlretty, NULL, - specFunctionObject, fromexternal, argv, nargs, cc, return_roots, inferred_retty); + specFunctionObject, fromexternal, argv, nargs, cc, return_roots, inferred_retty, age_ok); } static jl_cgval_t emit_call_specfun_boxed(jl_codectx_t &ctx, jl_value_t *jlretty, StringRef specFunctionObject, jl_code_instance_t *fromexternal, - ArrayRef argv, size_t nargs, jl_value_t *inferred_retty) + ArrayRef argv, size_t nargs, jl_value_t *inferred_retty, Value *age_ok) { Value *theFptr; if (fromexternal) { @@ -5407,6 +5420,8 @@ static jl_cgval_t emit_call_specfun_boxed(jl_codectx_t &ctx, jl_value_t *jlretty theFptr = jl_Module->getOrInsertFunction(specFunctionObject, ctx.types().T_jlfunc).getCallee(); addRetAttr(cast(theFptr), Attribute::NonNull); } + if (age_ok) + theFptr = ctx.builder.CreateSelect(age_ok, theFptr, prepare_call(jlapplygeneric_func)); Value *ret = emit_jlcall(ctx, FunctionCallee(ctx.types().T_jlfunc, theFptr), nullptr, argv, nargs, julia_call); return update_julia_type(ctx, mark_julia_type(ctx, ret, true, jlretty), inferred_retty); } @@ -5425,10 +5440,10 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt) if (argv[i].typ == jl_bottom_type) return jl_cgval_t(); } - return emit_invoke(ctx, lival, argv, nargs, rt); + return emit_invoke(ctx, lival, argv, nargs, rt, nullptr); } -static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayRef argv, size_t nargs, jl_value_t *rt) +static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayRef argv, size_t nargs, jl_value_t *rt, Value *age_ok) { ++EmittedInvokes; bool handled = false; @@ -5451,12 +5466,12 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR FunctionType *ft = ctx.f->getFunctionType(); StringRef protoname = ctx.f->getName(); if (ft == ctx.types().T_jlfunc) { - result = emit_call_specfun_boxed(ctx, ctx.rettype, protoname, nullptr, argv, nargs, rt); + result = emit_call_specfun_boxed(ctx, ctx.rettype, protoname, nullptr, argv, nargs, rt, age_ok); handled = true; } else if (ft != ctx.types().T_jlfuncparams) { unsigned return_roots = 0; - result = emit_call_specfun_other(ctx, mi, ctx.rettype, protoname, nullptr, argv, nargs, &cc, &return_roots, rt); + result = emit_call_specfun_other(ctx, mi, ctx.rettype, protoname, nullptr, argv, nargs, &cc, &return_roots, rt, age_ok); handled = true; } } @@ -5516,9 +5531,9 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; unsigned return_roots = 0; if (specsig) - result = emit_call_specfun_other(ctx, mi, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt); + result = emit_call_specfun_other(ctx, mi, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt, age_ok); else - result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, rt); + result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, rt, age_ok); handled = true; if (need_to_emit) { Function *trampoline_decl = cast(jl_Module->getNamedValue(protoname)); @@ -5542,8 +5557,8 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR print_stacktrace(ctx, ctx.params->trim); } } - Value *r = emit_jlcall(ctx, jlinvoke_func, boxed(ctx, lival), argv, nargs, julia_call2); - result = mark_julia_type(ctx, r, true, rt); + Value *r = age_ok ? emit_jlcall(ctx, jlapplygeneric_func, nullptr, argv, nargs, julia_call) : emit_jlcall(ctx, jlinvoke_func, boxed(ctx, lival), argv, nargs, julia_call2); + result = mark_julia_type(ctx, r, true, age_ok ? (jl_value_t*)jl_any_type : rt); } if (result.typ == jl_bottom_type) { #ifndef JL_NDEBUG @@ -5636,7 +5651,7 @@ static jl_cgval_t emit_specsig_oc_call(jl_codectx_t &ctx, jl_value_t *oc_type, j Value *specptr = emit_unbox(ctx, ctx.types().T_size, closure_specptr, (jl_value_t*)jl_long_type); JL_GC_PUSH1(&sigtype); jl_cgval_t r = emit_call_specfun_other(ctx, true, sigtype, oc_rett, specptr, "", NULL, argv, nargs, - &cc, &return_roots, oc_rett); + &cc, &return_roots, oc_rett, nullptr); JL_GC_POP(); return r; } @@ -7189,8 +7204,7 @@ Function *emit_tojlinvoke(jl_code_instance_t *codeinst, StringRef theFptrName, M name, M); jl_init_function(f, params.TargetTriple); if (trim_may_error(params.params->trim)) { - // TODO: Debuginfo! - push_frames(ctx, ctx.linfo, codeinst->def, 1); + push_frames(ctx, ctx.linfo, codeinst->def); } jl_name_jlfunc_args(params, f); //f->setAlwaysInline(); @@ -7232,11 +7246,10 @@ void emit_specsig_to_fptr1( jl_value_t *calltype, jl_value_t *rettype, bool is_for_opaque_closure, size_t nargs, jl_codegen_params_t ¶ms, - Function *target, - size_t min_world, size_t max_world) + Function *target) { ++EmittedCFuncInvalidates; - jl_codectx_t ctx(gf_thunk->getParent()->getContext(), params, min_world, max_world); + jl_codectx_t ctx(gf_thunk->getParent()->getContext(), params, 0, 0); ctx.f = gf_thunk; BasicBlock *b0 = BasicBlock::Create(ctx.builder.getContext(), "top", gf_thunk); @@ -7353,12 +7366,11 @@ void emit_specsig_to_fptr1( } } -static Function* gen_cfun_wrapper( +static Function *gen_cfun_wrapper( Module *into, jl_codegen_params_t ¶ms, const function_sig_t &sig, jl_value_t *ff, const char *aliasname, jl_value_t *declrt, jl_method_instance_t *lam, - jl_unionall_t *unionall_env, jl_svec_t *sparam_vals, jl_array_t **closure_types, - size_t min_world, size_t max_world) + jl_unionall_t *unionall_env, jl_svec_t *sparam_vals, jl_array_t **closure_types) { ++GeneratedCFuncWrappers; // Generate a c-callable wrapper @@ -7366,36 +7378,17 @@ static Function* gen_cfun_wrapper( size_t nargs = sig.nccallargs; const char *name = "cfunction"; size_t world = jl_atomic_load_acquire(&jl_world_counter); - jl_code_instance_t *codeinst = NULL; bool nest = (!ff || unionall_env); jl_value_t *astrt = (jl_value_t*)jl_any_type; - void *callptr = NULL; - jl_callptr_t invoke = NULL; - int calltype = 0; if (aliasname) name = aliasname; else if (lam) name = jl_symbol_name(lam->def.method->name); - if (lam && params.cache) { + + jl_code_instance_t *codeinst = NULL; + if (lam) { // TODO: this isn't ideal to be unconditionally calling type inference (and compile) from here - codeinst = jl_compile_method_internal(lam, world); - uint8_t specsigflags; - void *fptr; - jl_read_codeinst_invoke(codeinst, &specsigflags, &invoke, &fptr, 0); - assert(invoke); - if (invoke == jl_fptr_args_addr) { - callptr = fptr; - calltype = 1; - } - else if (invoke == jl_fptr_const_return_addr) { - // don't need the fptr - callptr = (void*)codeinst->rettype_const; - calltype = 2; - } - else if (specsigflags & 0b1) { - callptr = fptr; - calltype = 3; - } + codeinst = jl_type_infer(lam, world, SOURCE_MODE_NOT_REQUIRED); astrt = codeinst->rettype; if (astrt != (jl_value_t*)jl_bottom_type && jl_type_intersection(astrt, declrt) == jl_bottom_type) { @@ -7471,7 +7464,7 @@ static Function* gen_cfun_wrapper( jl_init_function(cw, params.TargetTriple); cw->setAttributes(AttributeList::get(M->getContext(), {attributes, cw->getAttributes()})); - jl_codectx_t ctx(M->getContext(), params, min_world, max_world); + jl_codectx_t ctx(M->getContext(), params, 0, 0); ctx.f = cw; ctx.name = name; ctx.funcName = name; @@ -7490,8 +7483,8 @@ static Function* gen_cfun_wrapper( prepare_global_in(jl_Module, jlgetworld_global), ctx.types().alignof_ptr); cast(world_v)->setOrdering(AtomicOrdering::Acquire); - Value *age_ok = NULL; - if (calltype) { + Value *age_ok = nullptr; + if (codeinst) { LoadInst *lam_max = ctx.builder.CreateAlignedLoad( ctx.types().T_size, emit_ptrgep(ctx, literal_pointer_val(ctx, (jl_value_t*)codeinst), offsetof(jl_code_instance_t, max_world)), @@ -7655,79 +7648,9 @@ static Function* gen_cfun_wrapper( // Create the call bool jlfunc_sret; jl_cgval_t retval; - if (calltype == 2) { - nargs = 0; // arguments not needed -- TODO: not really true, should emit an age_ok test and jlcall - (void)nargs; // silence unused variable warning - jlfunc_sret = false; - retval = mark_julia_const(ctx, (jl_value_t*)callptr); - } - else if (calltype == 0 || calltype == 1) { - // emit a jlcall - jlfunc_sret = false; - Function *theFptr = NULL; - if (calltype == 1) { - StringRef fname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)callptr, invoke, codeinst); - theFptr = cast_or_null(jl_Module->getNamedValue(fname)); - if (!theFptr) { - theFptr = Function::Create(ctx.types().T_jlfunc, GlobalVariable::ExternalLinkage, - fname, jl_Module); - jl_init_function(theFptr, ctx.emission_context.TargetTriple); - jl_name_jlfunc_args(ctx.emission_context, theFptr); - addRetAttr(theFptr, Attribute::NonNull); - } - else { - assert(theFptr->getFunctionType() == ctx.types().T_jlfunc); - } - } - BasicBlock *b_generic, *b_jlcall, *b_after; - Value *ret_jlcall; - if (age_ok) { - assert(theFptr); - b_generic = BasicBlock::Create(ctx.builder.getContext(), "generic", cw); - b_jlcall = BasicBlock::Create(ctx.builder.getContext(), "apply", cw); - b_after = BasicBlock::Create(ctx.builder.getContext(), "after", cw); - ctx.builder.CreateCondBr(age_ok, b_jlcall, b_generic); - ctx.builder.SetInsertPoint(b_jlcall); - // for jlcall, we need to pass the function object even if it is a ghost. - Value *theF = boxed(ctx, inputargs[0]); - assert(theF); - ret_jlcall = emit_jlcall(ctx, theFptr, theF, ArrayRef(inputargs).drop_front(), nargs, julia_call); - ctx.builder.CreateBr(b_after); - ctx.builder.SetInsertPoint(b_generic); - } - Value *ret = emit_jlcall(ctx, jlapplygeneric_func, NULL, inputargs, nargs + 1, julia_call); - if (age_ok) { - ctx.builder.CreateBr(b_after); - ctx.builder.SetInsertPoint(b_after); - PHINode *retphi = ctx.builder.CreatePHI(ctx.types().T_prjlvalue, 2); - retphi->addIncoming(ret_jlcall, b_jlcall); - retphi->addIncoming(ret, b_generic); - ret = retphi; - } - retval = mark_julia_type(ctx, ret, true, astrt); - } - else { - bool is_opaque_closure = jl_is_method(lam->def.value) && lam->def.method->is_for_opaque_closure; - assert(calltype == 3); - // emit a specsig call - StringRef protoname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)callptr, invoke, codeinst); - bool gcstack_arg = JL_FEAT_TEST(ctx, gcstack_arg); - jl_returninfo_t returninfo = get_specsig_function(ctx, M, NULL, protoname, lam->specTypes, astrt, is_opaque_closure, gcstack_arg); - if (age_ok) { - funcName += "_gfthunk"; - Function *gf_thunk = Function::Create(returninfo.decl.getFunctionType(), - GlobalVariable::InternalLinkage, funcName, M); - jl_init_function(gf_thunk, ctx.emission_context.TargetTriple); - gf_thunk->setAttributes(AttributeList::get(M->getContext(), {returninfo.attrs, gf_thunk->getAttributes()})); - // build a specsig -> jl_apply_generic converter thunk - // this builds a method that calls jl_apply_generic (as a closure over a singleton function pointer), - // but which has the signature of a specsig - emit_specsig_to_fptr1(gf_thunk, returninfo.cc, returninfo.return_roots, lam->specTypes, codeinst->rettype, is_opaque_closure, nargs + 1, ctx.emission_context, - prepare_call_in(gf_thunk->getParent(), jlapplygeneric_func), min_world, max_world); - returninfo.decl = FunctionCallee(returninfo.decl.getFunctionType(), ctx.builder.CreateSelect(age_ok, returninfo.decl.getCallee(), gf_thunk)); - } - retval = emit_call_specfun_other(ctx, is_opaque_closure, lam->specTypes, codeinst->rettype, returninfo, nullptr, inputargs, nargs + 1); - jlfunc_sret = (returninfo.cc == jl_returninfo_t::SRet); + if (codeinst) { + retval = emit_invoke(ctx, mark_julia_const(ctx, (jl_value_t*)codeinst), inputargs, nargs + 1, astrt, age_ok); + jlfunc_sret = retval.V && isa(retval.V) && !retval.TIndex && retval.inline_roots.empty(); if (jlfunc_sret && sig.sret) { // fuse the two sret together assert(retval.ispointer()); @@ -7737,6 +7660,12 @@ static Function* gen_cfun_wrapper( result->eraseFromParent(); } } + else { + // emit a dispatch + jlfunc_sret = false; + Value *ret = emit_jlcall(ctx, jlapplygeneric_func, NULL, inputargs, nargs + 1, julia_call); + retval = mark_julia_type(ctx, ret, true, astrt); + } // inline a call to typeassert here, if required emit_typecheck(ctx, retval, declrt, "cfunction"); @@ -7909,15 +7838,13 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con } } size_t world = jl_atomic_load_acquire(&jl_world_counter); - size_t min_valid = 0; - size_t max_valid = ~(size_t)0; // try to look up this function for direct invoking - jl_method_instance_t *lam = sigt ? jl_get_specialization1((jl_tupletype_t*)sigt, world, &min_valid, &max_valid, 0) : NULL; + jl_method_instance_t *lam = sigt ? jl_get_specialization1((jl_tupletype_t*)sigt, world, 0) : NULL; Value *F = gen_cfun_wrapper( jl_Module, ctx.emission_context, sig, fexpr_rt.constant, NULL, declrt, lam, - unionall_env, sparam_vals, &closure_types, min_valid, max_valid); + unionall_env, sparam_vals, &closure_types); bool outboxed; if (nest) { // F is actually an init_trampoline function that returns the real address @@ -7977,7 +7904,7 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con // do codegen to create a C-callable alias/wrapper, or if sysimg_handle is set, // restore one from a loaded system image. -const char *jl_generate_ccallable(LLVMOrcThreadSafeModuleRef llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t ¶ms) +const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t ¶ms) { ++GeneratedCCallables; jl_datatype_t *ft = (jl_datatype_t*)jl_tparam0(sigt); @@ -8006,8 +7933,6 @@ const char *jl_generate_ccallable(LLVMOrcThreadSafeModuleRef llvmmod, void *sysi argtypes, NULL, false, CallingConv::C, false, ¶ms); if (sig.err_msg.empty()) { size_t world = jl_atomic_load_acquire(&jl_world_counter); - size_t min_valid = 0; - size_t max_valid = ~(size_t)0; if (sysimg_handle) { // restore a ccallable from the system image void *addr; @@ -8020,9 +7945,9 @@ const char *jl_generate_ccallable(LLVMOrcThreadSafeModuleRef llvmmod, void *sysi } } else { - jl_method_instance_t *lam = jl_get_specialization1((jl_tupletype_t*)sigt, world, &min_valid, &max_valid, 0); + jl_method_instance_t *lam = jl_get_specialization1((jl_tupletype_t*)sigt, world, 0); //Safe b/c params holds context lock - gen_cfun_wrapper(unwrap(llvmmod)->getModuleUnlocked(), params, sig, ff, name, declrt, lam, NULL, NULL, NULL, min_valid, max_valid); + gen_cfun_wrapper(llvmmod, params, sig, ff, name, declrt, lam, NULL, NULL, NULL); } JL_GC_POP(); return name; @@ -8084,7 +8009,7 @@ static void gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *jlretty, j } argv[i] = mark_julia_type(ctx, theArg, true, ty); } - jl_cgval_t retval = emit_call_specfun_other(ctx, is_opaque_closure, lam->specTypes, jlretty, f, nullptr, argv, nargs); + jl_cgval_t retval = emit_call_specfun_other(ctx, is_opaque_closure, lam->specTypes, jlretty, f, argv, nargs); if (retarg != -1) { Value *theArg; if (retarg == 0) @@ -10040,8 +9965,7 @@ static jl_llvm_functions_t jl_emit_oc_wrapper(orc::ThreadSafeModule &m, jl_codeg size_t nrealargs = jl_nparams(mi->specTypes); emit_specsig_to_fptr1(gf_thunk, returninfo.cc, returninfo.return_roots, mi->specTypes, rettype, true, nrealargs, ctx.emission_context, - prepare_call_in(gf_thunk->getParent(), jlopaque_closure_call_func), // TODO: this could call emit_oc_call directly - ctx.min_world, ctx.max_world); + prepare_call_in(gf_thunk->getParent(), jlopaque_closure_call_func)); // TODO: this could call emit_oc_call directly declarations.specFunctionObject = funcName; } return declarations; diff --git a/src/gf.c b/src/gf.c index bbf065a4fac0d..a5ba309784557 100644 --- a/src/gf.c +++ b/src/gf.c @@ -3084,7 +3084,7 @@ JL_DLLEXPORT jl_method_instance_t *jl_method_match_to_mi(jl_method_match_t *matc } // compile-time method lookup -jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types JL_PROPAGATES_ROOT, size_t world, size_t *min_valid, size_t *max_valid, int mt_cache) +jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types JL_PROPAGATES_ROOT, size_t world, int mt_cache) { if (jl_has_free_typevars((jl_value_t*)types)) return NULL; // don't poison the cache due to a malformed query @@ -3096,10 +3096,6 @@ jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types JL_PROPAGATES size_t max_valid2 = ~(size_t)0; int ambig = 0; jl_value_t *matches = jl_matching_methods(types, jl_nothing, 1, 1, world, &min_valid2, &max_valid2, &ambig); - if (*min_valid < min_valid2) - *min_valid = min_valid2; - if (*max_valid > max_valid2) - *max_valid = max_valid2; if (matches == jl_nothing || jl_array_nrows(matches) != 1 || ambig) return NULL; JL_GC_PUSH1(&matches); diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 80867daade267..25494ba57d257 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -382,7 +382,7 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t jl_method_instance_t *mi = codeinst->def; size_t nrealargs = jl_nparams(mi->specTypes); // number of actual arguments being passed bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure; - emit_specsig_to_fptr1(proto.decl, proto.cc, proto.return_roots, mi->specTypes, codeinst->rettype, is_opaque_closure, nrealargs, params, pinvoke, 0, 0); + emit_specsig_to_fptr1(proto.decl, proto.cc, proto.return_roots, mi->specTypes, codeinst->rettype, is_opaque_closure, nrealargs, params, pinvoke); jl_gc_unsafe_leave(ct->ptls, gc_state); preal_decl = ""; // no need to fixup the name } @@ -713,7 +713,7 @@ static void jl_emit_codeinst_to_jit( int waiting = jl_analyze_workqueue(codeinst, params); if (waiting) { auto release = std::move(params.tsctx_lock); // unlock again before moving from it - incompletemodules.insert(std::pair(codeinst, std::make_tuple(std::move(params), waiting))); + incompletemodules.try_emplace(codeinst, std::move(params), waiting); } else { finish_params(result_m.getModuleUnlocked(), params); @@ -760,7 +760,7 @@ static void _jl_compile_codeinst( } -const char *jl_generate_ccallable(LLVMOrcThreadSafeModuleRef llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t ¶ms); +const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t ¶ms); // compile a C-callable alias extern "C" JL_DLLEXPORT_CODEGEN @@ -774,45 +774,68 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void * uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); if (measure_compile_time_enabled) compiler_start_time = jl_hrtime(); + jl_codegen_params_t *pparams = (jl_codegen_params_t*)p; + DataLayout DL = pparams ? pparams->DL : jl_ExecutionEngine->getDataLayout(); + Triple TargetTriple = pparams ? pparams->TargetTriple : jl_ExecutionEngine->getTargetTriple(); orc::ThreadSafeContext ctx; auto into = unwrap(llvmmod); - jl_codegen_params_t *pparams = (jl_codegen_params_t*)p; orc::ThreadSafeModule backing; + bool success = true; + const char *name = ""; + SmallVector dependencies; if (into == NULL) { - if (!pparams) { - ctx = jl_ExecutionEngine->makeContext(); - } - backing = jl_create_ts_module("cextern", pparams ? pparams->tsctx : ctx, pparams ? pparams->DL : jl_ExecutionEngine->getDataLayout(), pparams ? pparams->TargetTriple : jl_ExecutionEngine->getTargetTriple()); + ctx = pparams ? pparams->tsctx : jl_ExecutionEngine->makeContext(); + backing = jl_create_ts_module("cextern", ctx, DL, TargetTriple); into = &backing; } - bool success = true; - { - auto Lock = into->getContext().getLock(); - Module *M = into->getModuleUnlocked(); - jl_codegen_params_t params(into->getContext(), M->getDataLayout(), Triple(M->getTargetTriple())); - params.imaging_mode = imaging_default(); + { // params scope + jl_codegen_params_t params(into->getContext(), DL, TargetTriple); if (pparams == NULL) { - M->getContext().setDiscardValueNames(true); + params.cache = p == NULL; + params.imaging_mode = imaging_default(); + params.tsctx.getContext()->setDiscardValueNames(true); pparams = ¶ms; } - assert(pparams->tsctx.getContext() == into->getContext().getContext()); - const char *name = jl_generate_ccallable(wrap(into), sysimg, declrt, sigt, *pparams); - if (!sysimg) { - jl_unique_gcsafe_lock lock(extern_c_lock); - if (jl_ExecutionEngine->getGlobalValueAddress(name)) { - success = false; + Module &M = *into->getModuleUnlocked(); + assert(pparams->tsctx.getContext() == &M.getContext()); + name = jl_generate_ccallable(&M, sysimg, declrt, sigt, *pparams); + if (!sysimg && !p) { + { // drop lock to keep analyzer happy (since it doesn't know we have the only reference to it) + auto release = std::move(params.tsctx_lock); } - if (success && p == NULL) { - jl_jit_globals(params.global_targets); - assert(params.workqueue.empty()); - if (params._shared_module) { - jl_ExecutionEngine->optimizeDLSyms(*params._shared_module); // safepoint - jl_ExecutionEngine->addModule(orc::ThreadSafeModule(std::move(params._shared_module), params.tsctx)); + { // lock scope + jl_unique_gcsafe_lock lock(extern_c_lock); + if (jl_ExecutionEngine->getGlobalValueAddress(name)) + success = false; + } + params.tsctx_lock = params.tsctx.getLock(); // re-acquire lock + if (success && params.cache) { + for (auto &it : params.workqueue) { + jl_code_instance_t *codeinst = it.first; + JL_GC_PROMISE_ROOTED(codeinst); + dependencies.push_back(codeinst); + recursive_compile_graph(codeinst, nullptr); } + jl_analyze_workqueue(nullptr, params, true); + assert(params.workqueue.empty()); + finish_params(&M, params); } - if (success && llvmmod == NULL) { - jl_ExecutionEngine->optimizeDLSyms(*M); // safepoint - jl_ExecutionEngine->addModule(std::move(*into)); + } + pparams = nullptr; + } + if (!sysimg && success && llvmmod == NULL) { + { // lock scope + jl_unique_gcsafe_lock lock(extern_c_lock); + if (!jl_ExecutionEngine->getGlobalValueAddress(name)) { + for (auto dep : dependencies) + jl_compile_codeinst_now(dep); + { + auto Lock = backing.getContext().getLock(); + jl_ExecutionEngine->optimizeDLSyms(*backing.getModuleUnlocked()); // safepoint + } + jl_ExecutionEngine->addModule(std::move(backing)); + success = jl_ExecutionEngine->getGlobalValueAddress(name); + assert(success); } } } diff --git a/src/jitlayers.h b/src/jitlayers.h index 6665be6a33faa..b6f1e9ec20c6b 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -260,7 +260,7 @@ struct jl_codegen_params_t { bool external_linkage = false; bool imaging_mode; bool use_swiftcc = true; - jl_codegen_params_t(orc::ThreadSafeContext ctx, DataLayout DL, Triple triple) + jl_codegen_params_t(orc::ThreadSafeContext ctx, DataLayout DL, Triple triple) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_ENTER : tsctx(std::move(ctx)), tsctx_lock(tsctx.getLock()), DL(std::move(DL)), @@ -271,6 +271,8 @@ struct jl_codegen_params_t { if (TargetTriple.isRISCV()) use_swiftcc = false; } + jl_codegen_params_t(jl_codegen_params_t &&) JL_NOTSAFEPOINT = default; + ~jl_codegen_params_t() JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE = default; }; jl_llvm_functions_t jl_emit_code( @@ -299,8 +301,7 @@ void emit_specsig_to_fptr1( jl_value_t *calltype, jl_value_t *rettype, bool is_for_opaque_closure, size_t nargs, jl_codegen_params_t ¶ms, - Function *target, - size_t min_world, size_t max_world) JL_NOTSAFEPOINT; + Function *target) JL_NOTSAFEPOINT; Function *get_or_emit_fptr1(StringRef Name, Module *M) JL_NOTSAFEPOINT; void jl_init_function(Function *F, const Triple &TT) JL_NOTSAFEPOINT; diff --git a/src/julia_internal.h b/src/julia_internal.h index 4741316093f95..e0e8158f8e0d9 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -1195,7 +1195,7 @@ _Atomic(jl_value_t*) *jl_table_peek_bp(jl_genericmemory_t *a, jl_value_t *key) J JL_DLLEXPORT jl_method_t *jl_new_method_uninit(jl_module_t*); JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *module); -JL_DLLEXPORT jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types, size_t world, size_t *min_valid, size_t *max_valid, int mt_cache); +JL_DLLEXPORT jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types, size_t world, int mt_cache); jl_method_instance_t *jl_get_specialized(jl_method_t *m, jl_value_t *types, jl_svec_t *sp); JL_DLLEXPORT jl_value_t *jl_rettype_inferred(jl_value_t *owner, jl_method_instance_t *li JL_PROPAGATES_ROOT, size_t min_world, size_t max_world); JL_DLLEXPORT jl_value_t *jl_rettype_inferred_native(jl_method_instance_t *mi, size_t min_world, size_t max_world) JL_NOTSAFEPOINT; diff --git a/src/precompile_utils.c b/src/precompile_utils.c index 81c60ba70d29f..4717351d499b0 100644 --- a/src/precompile_utils.c +++ b/src/precompile_utils.c @@ -264,10 +264,8 @@ static void *jl_precompile_(jl_array_t *m, int external_linkage) jl_value_t *item = jl_array_ptr_ref(m, i); if (jl_is_method_instance(item)) { mi = (jl_method_instance_t*)item; - size_t min_world = 0; - size_t max_world = ~(size_t)0; if (mi != jl_atomic_load_relaxed(&mi->def.method->unspecialized) && !jl_isa_compileable_sig((jl_tupletype_t*)mi->specTypes, mi->sparam_vals, mi->def.method)) - mi = jl_get_specialization1((jl_tupletype_t*)mi->specTypes, jl_atomic_load_acquire(&jl_world_counter), &min_world, &max_world, 0); + mi = jl_get_specialization1((jl_tupletype_t*)mi->specTypes, jl_atomic_load_acquire(&jl_world_counter), 0); if (mi) jl_array_ptr_1d_push(m2, (jl_value_t*)mi); } diff --git a/test/llvmcall.jl b/test/llvmcall.jl index c83ac05b1ec48..ddf66ca680d45 100644 --- a/test/llvmcall.jl +++ b/test/llvmcall.jl @@ -157,7 +157,7 @@ module ObjLoadTest nothing end @test_throws(ErrorException("@ccallable was already defined for this method name"), - @eval @ccallable Cvoid jl_the_callback(not_the_method::Int) = "other") + @eval @ccallable String jl_the_callback(not_the_method::Int) = "other") # Make sure everything up until here gets compiled @test jl_the_callback() === nothing @test jl_the_callback(1) == "other" From 309021d138b16156b969f59bb2c33742b62a4c31 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 12 Dec 2024 16:20:06 -0500 Subject: [PATCH 043/198] gc: simplify sweep_weak_refs logic (#56816) [NFCI] --- src/gc-stock.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/gc-stock.c b/src/gc-stock.c index 61a013f347975..2c285d9a6d369 100644 --- a/src/gc-stock.c +++ b/src/gc-stock.c @@ -388,24 +388,18 @@ static void sweep_weak_refs(void) jl_ptls_t ptls2 = gc_all_tls_states[i]; if (ptls2 != NULL) { size_t n = 0; - size_t ndel = 0; + size_t i = 0; size_t l = ptls2->gc_tls_common.heap.weak_refs.len; void **lst = ptls2->gc_tls_common.heap.weak_refs.items; - if (l == 0) - continue; - while (1) { - jl_weakref_t *wr = (jl_weakref_t*)lst[n]; - if (gc_marked(jl_astaggedvalue(wr)->bits.gc)) + // filter with preserving order + for (i = 0; i < l; i++) { + jl_weakref_t *wr = (jl_weakref_t*)lst[i]; + if (gc_marked(jl_astaggedvalue(wr)->bits.gc)) { + lst[n] = wr; n++; - else - ndel++; - if (n >= l - ndel) - break; - void *tmp = lst[n]; - lst[n] = lst[n + ndel]; - lst[n + ndel] = tmp; + } } - ptls2->gc_tls_common.heap.weak_refs.len -= ndel; + ptls2->gc_tls_common.heap.weak_refs.len = n; } } } From 03a0247eb04bda17d34518b59c61ab1bcacfb6b5 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 12 Dec 2024 21:54:30 -0500 Subject: [PATCH 044/198] gc: improve mallocarrays locality (#56801) --- src/gc-common.c | 13 ++----------- src/gc-common.h | 6 ------ src/gc-debug.c | 10 ++++------ src/gc-stock.c | 36 ++++++++++++++++-------------------- src/gc-tls-common.h | 5 ++--- src/mtarraylist.c | 4 ++-- src/support/arraylist.h | 10 +++++----- 7 files changed, 31 insertions(+), 53 deletions(-) diff --git a/src/gc-common.c b/src/gc-common.c index c751b54f059f5..3d578b81578b1 100644 --- a/src/gc-common.c +++ b/src/gc-common.c @@ -557,17 +557,8 @@ size_t jl_genericmemory_nbytes(jl_genericmemory_t *m) JL_NOTSAFEPOINT // tracking Memorys with malloc'd storage void jl_gc_track_malloced_genericmemory(jl_ptls_t ptls, jl_genericmemory_t *m, int isaligned){ // This is **NOT** a GC safe point. - mallocmemory_t *ma; - if (ptls->gc_tls_common.heap.mafreelist == NULL) { - ma = (mallocmemory_t*)malloc_s(sizeof(mallocmemory_t)); - } - else { - ma = ptls->gc_tls_common.heap.mafreelist; - ptls->gc_tls_common.heap.mafreelist = ma->next; - } - ma->a = (jl_genericmemory_t*)((uintptr_t)m | !!isaligned); - ma->next = ptls->gc_tls_common.heap.mallocarrays; - ptls->gc_tls_common.heap.mallocarrays = ma; + void *a = (void*)((uintptr_t)m | !!isaligned); + small_arraylist_push(&ptls->gc_tls_common.heap.mallocarrays, a); } // =========================================================================== // diff --git a/src/gc-common.h b/src/gc-common.h index 3007151009f7d..1745df17950f9 100644 --- a/src/gc-common.h +++ b/src/gc-common.h @@ -61,12 +61,6 @@ extern jl_gc_callback_list_t *gc_cblist_notify_gc_pressure; // malloc wrappers, aligned allocation // =========================================================================== // -// data structure for tracking malloc'd genericmemory. -typedef struct _mallocmemory_t { - jl_genericmemory_t *a; // lowest bit is tagged if this is aligned memory - struct _mallocmemory_t *next; -} mallocmemory_t; - #if defined(_OS_WINDOWS_) STATIC_INLINE void *jl_malloc_aligned(size_t sz, size_t align) { diff --git a/src/gc-debug.c b/src/gc-debug.c index 7c479484cde45..6e51064035b7b 100644 --- a/src/gc-debug.c +++ b/src/gc-debug.c @@ -1025,12 +1025,11 @@ void gc_stats_big_obj(void) v = v->next; } - mallocmemory_t *ma = ptls2->gc_tls.heap.mallocarrays; - while (ma != NULL) { - uint8_t bits =jl_astaggedvalue(ma->a)->bits.gc; + void **lst = ptls2->gc_tls.heap.mallocarrays.items; + for (size_t i = 0, l = ptls2->gc_tls.heap.mallocarrays.len; i < l; i++) { + jl_genericmemory_t *m = (jl_genericmemory_t*)((uintptr_t)lst[i] & ~(uintptr_t)1); + uint8_t bits = jl_astaggedvalue(m)->bits.gc; if (gc_marked(bits)) { - jl_genericmemory_t *m = (jl_genericmemory_t*)ma->a; - m = (jl_genericmemory_t*)((uintptr_t)m & ~(uintptr_t)1); size_t sz = jl_genericmemory_nbytes(m); if (gc_old(bits)) { assert(bits == GC_OLD_MARKED); @@ -1042,7 +1041,6 @@ void gc_stats_big_obj(void) stat.nbytes_used += sz; } } - ma = ma->next; } } jl_safe_printf("%lld kB (%lld%% old) in %lld large objects (%lld%% old)\n", diff --git a/src/gc-stock.c b/src/gc-stock.c index 2c285d9a6d369..c1bc1d64ae199 100644 --- a/src/gc-stock.c +++ b/src/gc-stock.c @@ -623,10 +623,9 @@ void jl_gc_reset_alloc_count(void) JL_NOTSAFEPOINT reset_thread_gc_counts(); } -static void jl_gc_free_memory(jl_value_t *v, int isaligned) JL_NOTSAFEPOINT +static void jl_gc_free_memory(jl_genericmemory_t *m, int isaligned) JL_NOTSAFEPOINT { - assert(jl_is_genericmemory(v)); - jl_genericmemory_t *m = (jl_genericmemory_t*)v; + assert(jl_is_genericmemory(m)); assert(jl_genericmemory_how(m) == 1 || jl_genericmemory_how(m) == 2); char *d = (char*)m->ptr; size_t freed_bytes = memory_block_usable_size(d, isaligned); @@ -648,25 +647,23 @@ static void sweep_malloced_memory(void) JL_NOTSAFEPOINT for (int t_i = 0; t_i < gc_n_threads; t_i++) { jl_ptls_t ptls2 = gc_all_tls_states[t_i]; if (ptls2 != NULL) { - mallocmemory_t *ma = ptls2->gc_tls_common.heap.mallocarrays; - mallocmemory_t **pma = &ptls2->gc_tls_common.heap.mallocarrays; - while (ma != NULL) { - mallocmemory_t *nxt = ma->next; - jl_value_t *a = (jl_value_t*)((uintptr_t)ma->a & ~1); - int bits = jl_astaggedvalue(a)->bits.gc; - if (gc_marked(bits)) { - pma = &ma->next; + size_t n = 0; + size_t l = ptls2->gc_tls_common.heap.mallocarrays.len; + void **lst = ptls2->gc_tls_common.heap.mallocarrays.items; + // filter without preserving order + while (n < l) { + jl_genericmemory_t *m = (jl_genericmemory_t*)((uintptr_t)lst[n] & ~1); + if (gc_marked(jl_astaggedvalue(m)->bits.gc)) { + n++; } else { - *pma = nxt; - int isaligned = (uintptr_t)ma->a & 1; - jl_gc_free_memory(a, isaligned); - ma->next = ptls2->gc_tls_common.heap.mafreelist; - ptls2->gc_tls_common.heap.mafreelist = ma; + int isaligned = (uintptr_t)lst[n] & 1; + jl_gc_free_memory(m, isaligned); + l--; + lst[n] = lst[l]; } - gc_time_count_mallocd_memory(bits); - ma = nxt; } + ptls2->gc_tls_common.heap.mallocarrays.len = l; } } gc_time_mallocd_memory_end(); @@ -3433,8 +3430,7 @@ void jl_init_thread_heap(jl_ptls_t ptls) small_arraylist_new(&common_heap->live_tasks, 0); for (int i = 0; i < JL_N_STACK_POOLS; i++) small_arraylist_new(&common_heap->free_stacks[i], 0); - common_heap->mallocarrays = NULL; - common_heap->mafreelist = NULL; + small_arraylist_new(&common_heap->mallocarrays, 0); heap->young_generation_of_bigvals = (bigval_t*)calloc_s(sizeof(bigval_t)); // sentinel assert(gc_bigval_sentinel_tag != 0); // make sure the sentinel is initialized heap->young_generation_of_bigvals->header = gc_bigval_sentinel_tag; diff --git a/src/gc-tls-common.h b/src/gc-tls-common.h index ba36f5c1c238e..473668d648294 100644 --- a/src/gc-tls-common.h +++ b/src/gc-tls-common.h @@ -21,9 +21,8 @@ typedef struct { // that are holding onto a stack from the pool small_arraylist_t live_tasks; - // variables for tracking malloc'd arrays - struct _mallocmemory_t *mallocarrays; - struct _mallocmemory_t *mafreelist; + // variable for tracking malloc'd arrays + small_arraylist_t mallocarrays; #define JL_N_STACK_POOLS 16 small_arraylist_t free_stacks[JL_N_STACK_POOLS]; diff --git a/src/mtarraylist.c b/src/mtarraylist.c index 7af265a86ab63..0a0f3fe867e39 100644 --- a/src/mtarraylist.c +++ b/src/mtarraylist.c @@ -14,8 +14,8 @@ extern "C" { // but there can be any number of observers typedef struct { - _Atomic(uint32_t) len; - uint32_t max; + _Atomic(size_t) len; + size_t max; _Atomic(_Atomic(void*)*) items; _Atomic(void*) _space[SMALL_AL_N_INLINE]; } small_mtarraylist_t; diff --git a/src/support/arraylist.h b/src/support/arraylist.h index a83bd2808756c..8d4ef61ba251c 100644 --- a/src/support/arraylist.h +++ b/src/support/arraylist.h @@ -5,7 +5,7 @@ #define AL_N_INLINE 29 -#define SMALL_AL_N_INLINE 6 +#define SMALL_AL_N_INLINE 5 #ifdef __cplusplus extern "C" { @@ -13,7 +13,7 @@ extern "C" { #include "analyzer_annotations.h" -typedef struct { +typedef struct { // 32 words size_t len; size_t max; void **items; @@ -27,9 +27,9 @@ JL_DLLEXPORT void arraylist_push(arraylist_t *a, void *elt) JL_NOTSAFEPOINT; JL_DLLEXPORT void *arraylist_pop(arraylist_t *a) JL_NOTSAFEPOINT; JL_DLLEXPORT void arraylist_grow(arraylist_t *a, size_t n) JL_NOTSAFEPOINT; -typedef struct { - uint32_t len; - uint32_t max; +typedef struct { // 8 words + size_t len; + size_t max; void **items; void *_space[SMALL_AL_N_INLINE]; } small_arraylist_t; From ece1c70184022341439a774eb27915daf377b02c Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Fri, 13 Dec 2024 11:09:19 -0300 Subject: [PATCH 045/198] Fix codegen not handling invoke exprs with Codeinstances iwith jl_fptr_sparam_addr invoke types. (#56817) fixes https://github.com/JuliaLang/julia/issues/56739 I didn't succeed in making a test for this. The sole trigger seems to be ```julia using HMMGradients T = Float32 A = T[0.0 1.0 0.0; 0.0 0.5 0.5; 1.0 0.0 0.0] t2tr = Dict{Int,Vector{Int}}[Dict(1 => [2]),] t2IJ= HMMGradients.t2tr2t2IJ(t2tr) Nt = length(t2tr)+1 Ns = size(A,1) y = rand(T,Nt,Ns) c = rand(Float32, Nt) beta = backward(Nt,A,c,t2IJ,y) gamma = posterior(Nt,t2IJ,A,y) ``` in @oscardssmith memorynew PR One other option is to have the builtin handle receiving a CI. That might make the code cleaner and does handle the case where we receive a dynamic CI (is that even a thing) --- Compiler/test/codegen.jl | 9 ++++ src/codegen.cpp | 106 +++++++++++++++++++++------------------ 2 files changed, 66 insertions(+), 49 deletions(-) diff --git a/Compiler/test/codegen.jl b/Compiler/test/codegen.jl index b6805a77124ca..9ba268fe95be8 100644 --- a/Compiler/test/codegen.jl +++ b/Compiler/test/codegen.jl @@ -1027,3 +1027,12 @@ for a in ((@noinline Ref{Int}(2)), @test ex === a end end + +# Make sure that code that has unbound sparams works +#https://github.com/JuliaLang/julia/issues/56739 + +f56739(a) where {T} = a + +@test f56739(1) == 1 +g56739(x) = @noinline f56739(x) +@test g56739(1) == 1 diff --git a/src/codegen.cpp b/src/codegen.cpp index fbd990857dd94..5656fb594044b 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5484,62 +5484,70 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR result = mark_julia_const(ctx, codeinst->rettype_const); handled = true; } - else if (invoke != jl_fptr_sparam_addr) { + else { bool specsig, needsparams; std::tie(specsig, needsparams) = uses_specsig(mi, codeinst->rettype, ctx.params->prefer_specsig); - std::string name; - StringRef protoname; - bool need_to_emit = true; - bool cache_valid = ctx.use_cache || ctx.external_linkage; - bool external = false; - - // Check if we already queued this up - auto it = ctx.call_targets.find(codeinst); - if (need_to_emit && it != ctx.call_targets.end()) { - assert(it->second.specsig == specsig); - protoname = it->second.decl->getName(); - need_to_emit = cache_valid = false; - } + if (needsparams) { + if (trim_may_error(ctx.params->trim)) + push_frames(ctx, ctx.linfo, mi); + Value *r = emit_jlcall(ctx, jlinvoke_func, track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)mi)), argv, nargs, julia_call2); + result = mark_julia_type(ctx, r, true, rt); + handled = true; + } else { + std::string name; + StringRef protoname; + bool need_to_emit = true; + bool cache_valid = ctx.use_cache || ctx.external_linkage; + bool external = false; + + // Check if we already queued this up + auto it = ctx.call_targets.find(codeinst); + if (need_to_emit && it != ctx.call_targets.end()) { + assert(it->second.specsig == specsig); + protoname = it->second.decl->getName(); + need_to_emit = cache_valid = false; + } - // Check if it is already compiled (either JIT or externally) - if (need_to_emit && cache_valid) { - // optimization: emit the correct name immediately, if we know it - // TODO: use `emitted` map here too to try to consolidate names? - uint8_t specsigflags; - jl_callptr_t invoke; - void *fptr; - jl_read_codeinst_invoke(codeinst, &specsigflags, &invoke, &fptr, 0); - if (specsig ? specsigflags & 0b1 : invoke == jl_fptr_args_addr) { - protoname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, invoke, codeinst); - if (ctx.external_linkage) { - // TODO: Add !specsig support to aotcompile.cpp - // Check that the codeinst is containing native code - if (specsig && (specsigflags & 0b100)) { - external = true; + // Check if it is already compiled (either JIT or externally) + if (need_to_emit && cache_valid) { + // optimization: emit the correct name immediately, if we know it + // TODO: use `emitted` map here too to try to consolidate names? + uint8_t specsigflags; + jl_callptr_t invoke; + void *fptr; + jl_read_codeinst_invoke(codeinst, &specsigflags, &invoke, &fptr, 0); + if (specsig ? specsigflags & 0b1 : invoke == jl_fptr_args_addr) { + protoname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, invoke, codeinst); + if (ctx.external_linkage) { + // TODO: Add !specsig support to aotcompile.cpp + // Check that the codeinst is containing native code + if (specsig && (specsigflags & 0b100)) { + external = true; + need_to_emit = false; + } + } + else { // ctx.use_cache need_to_emit = false; } } - else { // ctx.use_cache - need_to_emit = false; - } } - } - if (need_to_emit) { - raw_string_ostream(name) << (specsig ? "j_" : "j1_") << name_from_method_instance(mi) << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1); - protoname = StringRef(name); - } - jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; - unsigned return_roots = 0; - if (specsig) - result = emit_call_specfun_other(ctx, mi, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt, age_ok); - else - result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, rt, age_ok); - handled = true; - if (need_to_emit) { - Function *trampoline_decl = cast(jl_Module->getNamedValue(protoname)); - ctx.call_targets[codeinst] = {cc, return_roots, trampoline_decl, nullptr, specsig}; - if (trim_may_error(ctx.params->trim)) - push_frames(ctx, ctx.linfo, mi); + if (need_to_emit) { + raw_string_ostream(name) << (specsig ? "j_" : "j1_") << name_from_method_instance(mi) << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1); + protoname = StringRef(name); + } + jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; + unsigned return_roots = 0; + if (specsig) + result = emit_call_specfun_other(ctx, mi, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt, age_ok); + else + result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, rt, age_ok); + handled = true; + if (need_to_emit) { + Function *trampoline_decl = cast(jl_Module->getNamedValue(protoname)); + ctx.call_targets[codeinst] = {cc, return_roots, trampoline_decl, nullptr, specsig}; + if (trim_may_error(ctx.params->trim)) + push_frames(ctx, ctx.linfo, mi); + } } } } From fe5ed171ade0795902f21f05ef9defb60e25c4ff Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Sat, 14 Dec 2024 07:41:42 -0500 Subject: [PATCH 046/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?SparseArrays=20stdlib=20from=201b4933c=20to=204fd3aad=20(#56830?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: SparseArrays URL: https://github.com/JuliaSparse/SparseArrays.jl.git Stdlib branch: main Julia branch: master Old commit: 1b4933c New commit: 4fd3aad Julia version: 1.12.0-DEV SparseArrays version: 1.12.0 Bump invoked by: @DilumAluthge Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaSparse/SparseArrays.jl/compare/1b4933ccc7b1f97427ff88bd7ba58950021f2c60...4fd3aad5735e3b80eefe7b068f3407d7dd0c0924 ``` $ git log --oneline 1b4933c..4fd3aad 4fd3aad Generalize `istriu`/`istril` to accept a band index (#590) 780c4de Bump codecov/codecov-action from 4 to 5 (#589) 1beb0e4 Update LICENSE.md (#587) 268d390 QR: handle xtype/dtype returned from LibSuiteSparse that don't match matrix element type (#586) 9731aef get rid of UUID changing stuff (#582) ``` Co-authored-by: Dilum Aluthge --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/SparseArrays.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/md5 delete mode 100644 deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/sha512 create mode 100644 deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/md5 create mode 100644 deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/sha512 diff --git a/deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/md5 b/deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/md5 deleted file mode 100644 index 41d78a15f2ddb..0000000000000 --- a/deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -a643f01ee101a274d86d6469dd6a9d48 diff --git a/deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/sha512 b/deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/sha512 deleted file mode 100644 index 1868f9a865af5..0000000000000 --- a/deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -09a86606b28b17f1066d608374f4f8b2fcdcd17d08a8fa37b08edea7b27a9e6becadc8e8e93b1dcc1477dc247255d6a8ded4f8e678f46d80c9fd0ad72a7f3973 diff --git a/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/md5 b/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/md5 new file mode 100644 index 0000000000000..4c75f5c1f619a --- /dev/null +++ b/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/md5 @@ -0,0 +1 @@ +308e26cc6171656caaa7f6ba07e83d1c diff --git a/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/sha512 b/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/sha512 new file mode 100644 index 0000000000000..ad389d6e42048 --- /dev/null +++ b/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/sha512 @@ -0,0 +1 @@ +62b94ad0dca0d62e5753f50aef806ebdb5c8b56b241a285957190845be21fc6b8c8f93089b6f627795f6d7f2b1b01118bcff87c21102a3f3bae6d4c408362681 diff --git a/stdlib/SparseArrays.version b/stdlib/SparseArrays.version index af6fac41ddf84..0ff7a761bffa3 100644 --- a/stdlib/SparseArrays.version +++ b/stdlib/SparseArrays.version @@ -1,4 +1,4 @@ SPARSEARRAYS_BRANCH = main -SPARSEARRAYS_SHA1 = 1b4933ccc7b1f97427ff88bd7ba58950021f2c60 +SPARSEARRAYS_SHA1 = 4fd3aad5735e3b80eefe7b068f3407d7dd0c0924 SPARSEARRAYS_GIT_URL := https://github.com/JuliaSparse/SparseArrays.jl.git SPARSEARRAYS_TAR_URL = https://api.github.com/repos/JuliaSparse/SparseArrays.jl/tarball/$1 From f84d0c4014decb2607c7a54285bb028311e22c77 Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Sat, 14 Dec 2024 16:07:22 -0500 Subject: [PATCH 047/198] Missing tests for IdSet (#56258) Co-authored-by: CY Han --- test/sets.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/sets.jl b/test/sets.jl index b78d2f15dd989..4d52cb243620c 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -1037,6 +1037,8 @@ end @test !isempty(A) A = empty!(A) @test isempty(A) + @test isnothing(sizehint!(A, 10)) + @test Base.copymutable(A) == copy(A) end @testset "⊊, ⊋" begin From 06f988b74150367ac7000f2db25e4864cf9cb036 Mon Sep 17 00:00:00 2001 From: Jakob Nybo Nissen Date: Sat, 14 Dec 2024 22:20:31 +0100 Subject: [PATCH 048/198] Fix eltype of flatten of tuple with non-2 length (#56802) In 4c076c80af, eltype of flatten of tuple was improved by computing a refined eltype at compile time. However, this implementation only worked for length-2 tuples, and errored for all others. Generalize this to all tuples. Closes #56783 --------- Co-authored-by: Neven Sajko --- base/iterators.jl | 12 +++++++++--- test/iterators.jl | 8 ++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/base/iterators.jl b/base/iterators.jl index 6b8d9fe75e302..c6278e6284d70 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -15,7 +15,8 @@ using .Base: AbstractRange, AbstractUnitRange, UnitRange, LinearIndices, TupleOrBottom, (:), |, +, -, *, !==, !, ==, !=, <=, <, >, >=, =>, missing, any, _counttuple, eachindex, ntuple, zero, prod, reduce, in, firstindex, lastindex, - tail, fieldtypes, min, max, minimum, zero, oneunit, promote, promote_shape, LazyString + tail, fieldtypes, min, max, minimum, zero, oneunit, promote, promote_shape, LazyString, + afoldl using Core: @doc using .Base: @@ -1202,8 +1203,13 @@ julia> [(x,y) for x in 0:1 for y in 'a':'c'] # collects generators involving It flatten(itr) = Flatten(itr) eltype(::Type{Flatten{I}}) where {I} = eltype(eltype(I)) -eltype(::Type{Flatten{I}}) where {I<:Union{Tuple,NamedTuple}} = promote_typejoin(map(eltype, fieldtypes(I))...) -eltype(::Type{Flatten{Tuple{}}}) = eltype(Tuple{}) + +# For tuples, we statically know the element type of each index, so we can compute +# this at compile time. +function eltype(::Type{Flatten{I}}) where {I<:Union{Tuple,NamedTuple}} + afoldl((T, i) -> promote_typejoin(T, eltype(i)), Union{}, fieldtypes(I)...) +end + IteratorEltype(::Type{Flatten{I}}) where {I} = _flatteneltype(I, IteratorEltype(I)) IteratorEltype(::Type{Flatten{Tuple{}}}) = IteratorEltype(Tuple{}) _flatteneltype(I, ::HasEltype) = IteratorEltype(eltype(I)) diff --git a/test/iterators.jl b/test/iterators.jl index d1e7525c43465..1feccf5fb1d3e 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -515,6 +515,14 @@ end @test eltype(flatten(UnitRange{Int8}[1:2, 3:4])) == Int8 @test eltype(flatten(([1, 2], [3.0, 4.0]))) == Real @test eltype(flatten((a = [1, 2], b = Int8[3, 4]))) == Signed +@test eltype(flatten((Int[], Nothing[], Int[]))) == Union{Int, Nothing} +@test eltype(flatten((String[],))) == String +@test eltype(flatten((Int[], UInt[], Int8[],))) == Integer +@test eltype(flatten((; a = Int[], b = Nothing[], c = Int[]))) == Union{Int, Nothing} +@test eltype(flatten((; a = String[],))) == String +@test eltype(flatten((; a = Int[], b = UInt[], c = Int8[],))) == Integer +@test eltype(flatten(())) == Union{} +@test eltype(flatten((;))) == Union{} @test length(flatten(zip(1:3, 4:6))) == 6 @test length(flatten(1:6)) == 6 @test collect(flatten(Any[])) == Any[] From 006f19c33ccb5563bff06168c7a952fbc4154279 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sat, 14 Dec 2024 19:42:17 -0500 Subject: [PATCH 049/198] Skip or loosen two `errorshow` tests on 32-bit Windows (#56837) Ref #55900. --- test/errorshow.jl | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/test/errorshow.jl b/test/errorshow.jl index 7a3d50d599f2e..f83bbe31b7cc4 100644 --- a/test/errorshow.jl +++ b/test/errorshow.jl @@ -791,8 +791,22 @@ backtrace() @test occursin("g28442", output[3]) @test lstrip(output[5])[1:3] == "[2]" @test occursin("f28442", output[5]) - @test occursin("the above 2 lines are repeated 5000 more times", output[7]) - @test lstrip(output[8])[1:7] == "[10003]" + is_windows_32_bit = Sys.iswindows() && (Sys.WORD_SIZE == 32) + if is_windows_32_bit + # These tests are currently broken (intermittently/non-determistically) on 32-bit Windows. + # https://github.com/JuliaLang/julia/issues/55900 + # Instead of skipping them entirely, we skip one, and we loosen the other. + + # Broken test: @test occursin("the above 2 lines are repeated 5000 more times", output[7]) + @test occursin("the above 2 lines are repeated ", output[7]) + @test occursin(" more times", output[7]) + + # Broken test: @test lstrip(output[8])[1:7] == "[10003]" + @test_broken false + else + @test occursin("the above 2 lines are repeated 5000 more times", output[7]) + @test lstrip(output[8])[1:7] == "[10003]" + end end @testset "Line number correction" begin From 5eb07d54e95ba58a595d51fd0b6d36d3c2472684 Mon Sep 17 00:00:00 2001 From: Priynsh <119518987+Priynsh@users.noreply.github.com> Date: Sun, 15 Dec 2024 09:40:56 +0530 Subject: [PATCH 050/198] Adding tests for AbstractArrayMath.jl (#56773) added tests for lines 7, 137-154 (insertdims function) from base/abstractarraymath.jl --------- Co-authored-by: Lilith Orion Hafner Co-authored-by: Dilum Aluthge --- test/abstractarray.jl | 21 +++++++++++++++ test/arrayops.jl | 62 ++++++++++++++++++++++++------------------- 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 4af4099eced45..c7ec61704c1bc 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -2206,3 +2206,24 @@ end @test b.ref === a.ref end end +@testset "AbstractArrayMath" begin + @testset "IsReal" begin + A = [1, 2, 3, 4] + @test isreal(A) == true + B = [1.1, 2.2, 3.3, 4.4] + @test isreal(B) == true + C = [1, 2.2, 3] + @test isreal(C) == true + D = Real[] + @test isreal(D) == true + E = [1 + 1im, 2 - 2im] + @test isreal(E) == false + struct MyReal <: Real + value::Float64 + end + F = [MyReal(1.0), MyReal(2.0)] + @test isreal(F) == true + G = ["a", "b", "c"] + @test_throws MethodError isreal(G) + end +end diff --git a/test/arrayops.jl b/test/arrayops.jl index ca378c3f3036b..655e14675bfb4 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -307,34 +307,40 @@ end @test_throws ArgumentError dropdims(a, dims=3) @test_throws ArgumentError dropdims(a, dims=4) @test_throws ArgumentError dropdims(a, dims=6) - - - a = rand(8, 7) - @test @inferred(insertdims(a, dims=1)) == @inferred(insertdims(a, dims=(1,))) == reshape(a, (1, 8, 7)) - @test @inferred(insertdims(a, dims=3)) == @inferred(insertdims(a, dims=(3,))) == reshape(a, (8, 7, 1)) - @test @inferred(insertdims(a, dims=(1, 3))) == reshape(a, (1, 8, 1, 7)) - @test @inferred(insertdims(a, dims=(1, 2, 3))) == reshape(a, (1, 1, 1, 8, 7)) - @test @inferred(insertdims(a, dims=(1, 4))) == reshape(a, (1, 8, 7, 1)) - @test @inferred(insertdims(a, dims=(1, 3, 5))) == reshape(a, (1, 8, 1, 7, 1)) - @test @inferred(insertdims(a, dims=(1, 2, 4, 6))) == reshape(a, (1, 1, 8, 1, 7, 1)) - @test @inferred(insertdims(a, dims=(1, 3, 4, 6))) == reshape(a, (1, 8, 1, 1, 7, 1)) - @test @inferred(insertdims(a, dims=(1, 4, 6, 3))) == reshape(a, (1, 8, 1, 1, 7, 1)) - @test @inferred(insertdims(a, dims=(1, 3, 5, 6))) == reshape(a, (1, 8, 1, 7, 1, 1)) - - @test_throws ArgumentError insertdims(a, dims=(1, 1, 2, 3)) - @test_throws ArgumentError insertdims(a, dims=(1, 2, 2, 3)) - @test_throws ArgumentError insertdims(a, dims=(1, 2, 3, 3)) - @test_throws UndefKeywordError insertdims(a) - @test_throws ArgumentError insertdims(a, dims=0) - @test_throws ArgumentError insertdims(a, dims=(1, 2, 1)) - @test_throws ArgumentError insertdims(a, dims=4) - @test_throws ArgumentError insertdims(a, dims=6) - - # insertdims and dropdims are inverses - b = rand(1,1,1,5,1,1,7) - for dims in [1, (1,), 2, (2,), 3, (3,), (1,3), (1,2,3), (1,2), (1,3,5), (1,2,5,6), (1,3,5,6), (1,3,5,6), (1,6,5,3)] - @test dropdims(insertdims(a; dims); dims) == a - @test insertdims(dropdims(b; dims); dims) == b + @testset "insertdims" begin + a = rand(8, 7) + @test @inferred(insertdims(a, dims=1)) == @inferred(insertdims(a, dims=(1,))) == reshape(a, (1, 8, 7)) + @test @inferred(insertdims(a, dims=3)) == @inferred(insertdims(a, dims=(3,))) == reshape(a, (8, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 3))) == reshape(a, (1, 8, 1, 7)) + @test @inferred(insertdims(a, dims=(1, 2, 3))) == reshape(a, (1, 1, 1, 8, 7)) + @test @inferred(insertdims(a, dims=(1, 4))) == reshape(a, (1, 8, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 3, 5))) == reshape(a, (1, 8, 1, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 2, 4, 6))) == reshape(a, (1, 1, 8, 1, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 3, 4, 6))) == reshape(a, (1, 8, 1, 1, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 4, 6, 3))) == reshape(a, (1, 8, 1, 1, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 3, 5, 6))) == reshape(a, (1, 8, 1, 7, 1, 1)) + @test_throws ArgumentError insertdims(a, dims=(1, 1, 2, 3)) + @test_throws ArgumentError insertdims(a, dims=(1, 2, 2, 3)) + @test_throws ArgumentError insertdims(a, dims=(1, 2, 3, 3)) + @test_throws UndefKeywordError insertdims(a) + @test_throws ArgumentError insertdims(a, dims=0) + @test_throws ArgumentError insertdims(a, dims=(1, 2, 1)) + @test_throws ArgumentError insertdims(a, dims=4) + @test_throws ArgumentError insertdims(a, dims=6) + A = reshape(1:6, 2, 3) + @test_throws ArgumentError insertdims(A, dims=(2, 2)) + D = insertdims(A, dims=()) + @test size(D) == size(A) + @test D == A + E = ones(2, 3, 4) + F = insertdims(E, dims=(2, 4, 6)) + @test size(F) == (2, 1, 3, 1, 4, 1) + # insertdims and dropdims are inverses + b = rand(1,1,1,5,1,1,7) + for dims in [1, (1,), 2, (2,), 3, (3,), (1,3), (1,2,3), (1,2), (1,3,5), (1,2,5,6), (1,3,5,6), (1,3,5,6), (1,6,5,3)] + @test dropdims(insertdims(a; dims); dims) == a + @test insertdims(dropdims(b; dims); dims) == b + end end sz = (5,8,7) From 98a8ffc18b7df98fcebadfaa2de8281789ad92e9 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Sun, 15 Dec 2024 06:44:02 -0500 Subject: [PATCH 051/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?Downloads=20stdlib=20from=2089d3c7d=20to=20afd04be=20(#56826)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: Downloads URL: https://github.com/JuliaLang/Downloads.jl.git Stdlib branch: master Julia branch: master Old commit: 89d3c7d New commit: afd04be Julia version: 1.12.0-DEV Downloads version: 1.6.0(It's okay that it doesn't match) Bump invoked by: @DilumAluthge Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaLang/Downloads.jl/compare/89d3c7dded535a77551e763a437a6d31e4d9bf84...afd04be8aa94204c075c8aec83fca040ebb4ff98 ``` $ git log --oneline 89d3c7d..afd04be afd04be Bump codecov/codecov-action from 4 to 5 (#264) 39036e1 CI: Use Dependabot to automatically update external GitHub Actions (#263) 78e7c7c Bump CI actions versions (#252) ``` Co-authored-by: Dilum Aluthge --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/Downloads.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/md5 delete mode 100644 deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/sha512 create mode 100644 deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/md5 create mode 100644 deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/sha512 diff --git a/deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/md5 b/deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/md5 deleted file mode 100644 index 611f3dd448d98..0000000000000 --- a/deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -2472bd6434d21c4b3e3199437e6fdcf7 diff --git a/deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/sha512 b/deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/sha512 deleted file mode 100644 index 6937982e838f3..0000000000000 --- a/deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -0a3fa9a09de81aa9676dbc7448408c7503f45e42519a2667540ad890316c7da089c95de5464a2032171f963c6f3cba73d6b3c246f1c7ac6ede283fc8132d5209 diff --git a/deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/md5 b/deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/md5 new file mode 100644 index 0000000000000..f0d72ab470aeb --- /dev/null +++ b/deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/md5 @@ -0,0 +1 @@ +9dbfa6c0a76d20b2ca8de844d08f3af4 diff --git a/deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/sha512 b/deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/sha512 new file mode 100644 index 0000000000000..7abbb06818d75 --- /dev/null +++ b/deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/sha512 @@ -0,0 +1 @@ +f5d2469419f4a083f84c1f23e6e528f4115804e45bdfdbd897110bb346aaa70afc57c24f9166ae20fb4305c1d40f5a77de4cfed7b69aef93f09d0d4eff183e3d diff --git a/stdlib/Downloads.version b/stdlib/Downloads.version index b539771fbdb47..3d1da64bdfe11 100644 --- a/stdlib/Downloads.version +++ b/stdlib/Downloads.version @@ -1,4 +1,4 @@ DOWNLOADS_BRANCH = master -DOWNLOADS_SHA1 = 89d3c7dded535a77551e763a437a6d31e4d9bf84 +DOWNLOADS_SHA1 = afd04be8aa94204c075c8aec83fca040ebb4ff98 DOWNLOADS_GIT_URL := https://github.com/JuliaLang/Downloads.jl.git DOWNLOADS_TAR_URL = https://api.github.com/repos/JuliaLang/Downloads.jl/tarball/$1 From e9c007f1ff76111b463b6096ad0a08519ee6c79f Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Sun, 15 Dec 2024 06:44:54 -0500 Subject: [PATCH 052/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?SHA=20stdlib=20from=20aaf2df6=20to=208fa221d=20(#56834)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: SHA URL: https://github.com/JuliaCrypto/SHA.jl.git Stdlib branch: master Julia branch: master Old commit: aaf2df6 New commit: 8fa221d Julia version: 1.12.0-DEV SHA version: 0.7.0(Does not match) Bump invoked by: @inkydragon Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaCrypto/SHA.jl/compare/aaf2df61ff8c3898196587a375d3cf213bd40b41...8fa221ddc8f3b418d9929084f1644f4c32c9a27e ``` $ git log --oneline aaf2df6..8fa221d 8fa221d ci: update doctest config (#120) 346b359 ci: Update ci config (#115) aba9014 Fix type mismatch for `shake/digest!` and setup x86 ci (#117) 0b76d04 Merge pull request #114 from JuliaCrypto/dependabot/github_actions/codecov/codecov-action-5 5094d9d Update .github/workflows/CI.yml 45596b1 Bump codecov/codecov-action from 4 to 5 230ab51 test: remove outdate tests (#113) 7f25aa8 rm: Duplicated const alias (#111) aa72f73 [SHA3] Fix padding special-case (#108) 3a01401 Delete Manifest.toml (#109) da351bb Remvoe all getproperty funcs (#99) 4eee84f Bump codecov/codecov-action from 3 to 4 (#104) 15f7dbc Bump codecov/codecov-action from 1 to 3 (#102) 860e6b9 Bump actions/checkout from 2 to 4 (#103) 8e5f0ea Add dependabot to auto update github actions (#100) 4ab324c Merge pull request #98 from fork4jl/sha512-t a658829 SHA-512: add ref to NIST standard 11a4c73 Apply suggestions from code review 969f867 Merge pull request #97 from fingolfin/mh/Vector b1401fb SHA-512: add NIST test 4d7091b SHA-512: add to docs 09fef9a SHA-512: test SHA-512/224, SHA-512/256 7201b74 SHA-512: impl SHA-512/224, SHA-512/256 4ab85ad Array -> Vector 8ef91b6 fixed bug in padding for shake, addes testcases for full code coverage (#95) 88e1c83 Remove non-existent property (#75) 068f85d shake128,shake256: fixed typo in export declarations (#93) 176baaa SHA3 xof shake128 and shake256 (#92) e1af7dd Hardcode doc edit backlink ``` Co-authored-by: Dilum Aluthge --- .../SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/md5 | 1 + .../SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/sha512 | 1 + .../SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/md5 | 1 - .../SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/sha512 | 1 - stdlib/SHA.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/md5 create mode 100644 deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/sha512 delete mode 100644 deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/md5 delete mode 100644 deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/sha512 diff --git a/deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/md5 b/deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/md5 new file mode 100644 index 0000000000000..52e05f5e427ae --- /dev/null +++ b/deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/md5 @@ -0,0 +1 @@ +e52615827242aae56422a4f73a8c6878 diff --git a/deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/sha512 b/deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/sha512 new file mode 100644 index 0000000000000..e6b8446587554 --- /dev/null +++ b/deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/sha512 @@ -0,0 +1 @@ +7b1df257616aaa9067f822a88dddf52bc10f9f61e3a0728e33e595455bd7167e680c50371c41cb25f8c8a9fb9cf40225847df1523a6c6f3571a471f7163f563c diff --git a/deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/md5 b/deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/md5 deleted file mode 100644 index 3b51189e187a3..0000000000000 --- a/deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -dec1d21e890c88e57a0d4eb085633d57 diff --git a/deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/sha512 b/deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/sha512 deleted file mode 100644 index cbe1ff2eea29e..0000000000000 --- a/deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -fb611794a539c6725000ff6eda13e0af5dd3f82e22466bdff650ffa0e4edbba5ac4707195035531645a4161ecbb5f873f4f6b1040ce33e9b1adf9c1d34187718 diff --git a/stdlib/SHA.version b/stdlib/SHA.version index f22bb33dc7ea2..4b33964a6dcdb 100644 --- a/stdlib/SHA.version +++ b/stdlib/SHA.version @@ -1,4 +1,4 @@ SHA_BRANCH = master -SHA_SHA1 = aaf2df61ff8c3898196587a375d3cf213bd40b41 +SHA_SHA1 = 8fa221ddc8f3b418d9929084f1644f4c32c9a27e SHA_GIT_URL := https://github.com/JuliaCrypto/SHA.jl.git SHA_TAR_URL = https://api.github.com/repos/JuliaCrypto/SHA.jl/tarball/$1 From 0e7b621e56b8c8f84baf22d02a0106fe8325489b Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Sun, 15 Dec 2024 06:45:58 -0500 Subject: [PATCH 053/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?StyledStrings=20stdlib=20from=20056e843=20to=208985a37=20(#5683?= =?UTF-8?q?2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: StyledStrings URL: https://github.com/JuliaLang/StyledStrings.jl.git Stdlib branch: main Julia branch: master Old commit: 056e843 New commit: 8985a37 Julia version: 1.12.0-DEV StyledStrings version: 1.11.0(Does not match) Bump invoked by: @DilumAluthge Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaLang/StyledStrings.jl/compare/056e843b2d428bb9735b03af0cff97e738ac7e14...8985a37ac054c37d084a03ad2837208244824877 ``` $ git log --oneline 056e843..8985a37 8985a37 Fix interpolation edge case dropping annotations 729f56c Add typeasserts to `convert(::Type{Face}, ::Dict)` ``` Co-authored-by: Dilum Aluthge --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/StyledStrings.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/md5 delete mode 100644 deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/sha512 create mode 100644 deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/md5 create mode 100644 deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/sha512 diff --git a/deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/md5 b/deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/md5 deleted file mode 100644 index 8d78dd7b0a11b..0000000000000 --- a/deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -f053c84279a8920f355f202e605842af diff --git a/deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/sha512 b/deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/sha512 deleted file mode 100644 index 5a8ca888c38f8..0000000000000 --- a/deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -b6f4c1d6c0dc73a520472746c96adff506e5405154e4b93d419e07b577b01804d2fc87d4a6cac48a136777579bebf8388c2c1e54f849b51e233138d482146b4f diff --git a/deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/md5 b/deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/md5 new file mode 100644 index 0000000000000..0fd8e8966e068 --- /dev/null +++ b/deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/md5 @@ -0,0 +1 @@ +411277f3701cc3e286ec8a84ccdf6f11 diff --git a/deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/sha512 b/deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/sha512 new file mode 100644 index 0000000000000..0b495aefef55d --- /dev/null +++ b/deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/sha512 @@ -0,0 +1 @@ +95a7e92389f6fd02d3bec17ec0201ba41316aa2d7c321b14af88ccce8246fd0000ed2c0cc818f87cb81f7134304233db897f656426a00caac1bc7635056260c2 diff --git a/stdlib/StyledStrings.version b/stdlib/StyledStrings.version index 5e58a5456148a..c72f7a8399725 100644 --- a/stdlib/StyledStrings.version +++ b/stdlib/StyledStrings.version @@ -1,4 +1,4 @@ STYLEDSTRINGS_BRANCH = main -STYLEDSTRINGS_SHA1 = 056e843b2d428bb9735b03af0cff97e738ac7e14 +STYLEDSTRINGS_SHA1 = 8985a37ac054c37d084a03ad2837208244824877 STYLEDSTRINGS_GIT_URL := https://github.com/JuliaLang/StyledStrings.jl.git STYLEDSTRINGS_TAR_URL = https://api.github.com/repos/JuliaLang/StyledStrings.jl/tarball/$1 From 8924e6f6c4f61946e72fde783c59a7996d749051 Mon Sep 17 00:00:00 2001 From: Neven Sajko Date: Sun, 15 Dec 2024 13:37:43 +0100 Subject: [PATCH 054/198] xref `UnionAll` in the doc string of `where` (#56411) --- base/docs/basedocs.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index c62c980fae1e1..cef5e12a9e0d8 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -1515,7 +1515,7 @@ kw"new" """ where -The `where` keyword creates a type that is an iterated union of other types, over all +The `where` keyword creates a [`UnionAll`](@ref) type, which may be thought of as an iterated union of other types, over all values of some variable. For example `Vector{T} where T<:Real` includes all [`Vector`](@ref)s where the element type is some kind of `Real` number. From b4c5e58a976cbe48a6e5ec27f4408312d8073218 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Sun, 15 Dec 2024 09:20:44 -0500 Subject: [PATCH 055/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?ArgTools=20stdlib=20from=20997089b=20to=201314758=20(#56839)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: ArgTools URL: https://github.com/JuliaIO/ArgTools.jl.git Stdlib branch: master Julia branch: master Old commit: 997089b New commit: 1314758 Julia version: 1.12.0-DEV ArgTools version: 1.1.2(Does not match) Bump invoked by: @DilumAluthge Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaIO/ArgTools.jl/compare/997089b9cd56404b40ff766759662e16dc1aab4b...1314758ad02ff5e9e5ca718920c6c633b467a84a ``` $ git log --oneline 997089b..1314758 1314758 build(deps): bump codecov/codecov-action from 4 to 5; also, use CODECOV_TOKEN (#40) 68bb888 Fix typo in `arg_write` docstring (#39) 5d56027 build(deps): bump julia-actions/setup-julia from 1 to 2 (#38) b6189c7 build(deps): bump codecov/codecov-action from 3 to 4 (#37) ``` Co-authored-by: Dilum Aluthge --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/ArgTools.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/md5 create mode 100644 deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/sha512 delete mode 100644 deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/md5 delete mode 100644 deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/sha512 diff --git a/deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/md5 b/deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/md5 new file mode 100644 index 0000000000000..e172379604478 --- /dev/null +++ b/deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/md5 @@ -0,0 +1 @@ +d3209f45b8ea01a22ac7e9b265e3b84f diff --git a/deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/sha512 b/deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/sha512 new file mode 100644 index 0000000000000..991a457654113 --- /dev/null +++ b/deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/sha512 @@ -0,0 +1 @@ +314981eee11356f14b6dc9e07389c51432e7862d6c767d87d6679385f5a36faef34902954a5dfa6b37d8f3f25eaa4f23ba9431cc78acd3513377955e7d73f210 diff --git a/deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/md5 b/deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/md5 deleted file mode 100644 index 3e85638390011..0000000000000 --- a/deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -44175a2843f243a8f2e01cd1e781ecc9 diff --git a/deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/sha512 b/deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/sha512 deleted file mode 100644 index f5690055f63f4..0000000000000 --- a/deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -8a9d0f20cd8fa0ed072966debc691597bb09b34836465f52595b9b2525e80b194c7176781495573dd2f9a02b142e832e59f0dccef15afa184543775d58dc7987 diff --git a/stdlib/ArgTools.version b/stdlib/ArgTools.version index 09090a62ce0bf..914746c1a6900 100644 --- a/stdlib/ArgTools.version +++ b/stdlib/ArgTools.version @@ -1,4 +1,4 @@ ARGTOOLS_BRANCH = master -ARGTOOLS_SHA1 = 997089b9cd56404b40ff766759662e16dc1aab4b +ARGTOOLS_SHA1 = 1314758ad02ff5e9e5ca718920c6c633b467a84a ARGTOOLS_GIT_URL := https://github.com/JuliaIO/ArgTools.jl.git ARGTOOLS_TAR_URL = https://api.github.com/repos/JuliaIO/ArgTools.jl/tarball/$1 From dafaa611ec45cbcefb67915ba754f001698869f6 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Sun, 15 Dec 2024 23:21:45 -0500 Subject: [PATCH 056/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?Statistics=20stdlib=20from=2068869af=20to=20d49c2bf=20(#56831)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: Statistics URL: https://github.com/JuliaStats/Statistics.jl.git Stdlib branch: master Julia branch: master Old commit: 68869af New commit: d49c2bf Julia version: 1.12.0-DEV Statistics version: 1.11.2(Does not match) Bump invoked by: @DilumAluthge Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaStats/Statistics.jl/compare/68869af06e8cdeb7aba1d5259de602da7328057f...d49c2bf4f81e1efb4980a35fe39c815ef8396297 ``` $ git log --oneline 68869af..d49c2bf d49c2bf Merge pull request #178 from JuliaStats/dw/ci d10d6a3 Update Project.toml 1b67c17 Merge pull request #168 from JuliaStats/andreasnoack-patch-2 c3721ed Add a coverage badge 8086523 Test earliest supported Julia version and prereleases 12a1976 Update codecov in ci.yml 2caf0eb Merge pull request #177 from JuliaStats/ViralBShah-patch-1 33e6e8b Update ci.yml to use julia-actions/cache a399c19 Merge pull request #176 from JuliaStats/dependabot/github_actions/julia-actions/setup-julia-2 6b8d58a Merge branch 'master' into dependabot/github_actions/julia-actions/setup-julia-2 c2fb201 Merge pull request #175 from JuliaStats/dependabot/github_actions/actions/cache-4 8f808e4 Merge pull request #174 from JuliaStats/dependabot/github_actions/codecov/codecov-action-4 7f82133 Merge pull request #173 from JuliaStats/dependabot/github_actions/actions/checkout-4 046fb6f Update ci.yml c0fc336 Bump julia-actions/setup-julia from 1 to 2 a95a57a Bump actions/cache from 1 to 4 b675501 Bump codecov/codecov-action from 1 to 4 0088c49 Bump actions/checkout from 2 to 4 ad95c08 Create dependabot.yml 40275e2 Merge pull request #167 from JuliaStats/andreasnoack-patch-1 fa5592a Merge pull request #170 from mbauman/patch-1 cf57562 Add more tests of mean and median of ranges 128dc11 Merge pull request #169 from stevengj/patch-1 48d7a02 docfix: abs2, not ^2 2ac5bec correct std docs: sqrt is elementwise 39f6332 Merge pull request #96 from josemanuel22/mean_may_return_incorrect_results db3682b Merge branch 'master' into mean_may_return_incorrect_results 9e96507 Update src/Statistics.jl 58e5986 Test prereleases 6e76739 Implement one-argument cov2cor! b8fee00 Stop testing on nightly 9addbb8 Merge pull request #162 from caleb-allen/patch-1 6e3d223 Merge pull request #164 from aplavin/patch-1 71ebe28 Merge pull request #166 from JuliaStats/dw/cov_cor_optimization 517afa6 add tests aa0f549 Optimize `cov` and `cor` with identical arguments cc11ea9 propagate NaN value in median cf7040f Use non-mobile Wikipedia urls 547bf4d adding docu to mean! explain target should not alias with the source 296650a adding docu to mean! explain target should not alias with the source ``` Co-authored-by: Dilum Aluthge --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/Statistics.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/md5 delete mode 100644 deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/sha512 create mode 100644 deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/md5 create mode 100644 deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/sha512 diff --git a/deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/md5 b/deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/md5 deleted file mode 100644 index 9ba42f555d535..0000000000000 --- a/deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -01b84d67052d1558e51619d5159e7a8b diff --git a/deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/sha512 b/deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/sha512 deleted file mode 100644 index 31c9c6ca42cec..0000000000000 --- a/deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -6ab55ba6f93d2e8b34b19f53cb51a4bfc97b336d451b98f7b95ff81f04fee4fb90a2e4d04aa4bbf3ccffc99c36d9c82c9d00dbae283474308de4a27a91c2e0b7 diff --git a/deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/md5 b/deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/md5 new file mode 100644 index 0000000000000..3956c67f7fd47 --- /dev/null +++ b/deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/md5 @@ -0,0 +1 @@ +acf2bb0ea30132602e172e2f5f6274b4 diff --git a/deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/sha512 b/deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/sha512 new file mode 100644 index 0000000000000..051f2d0a862c3 --- /dev/null +++ b/deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/sha512 @@ -0,0 +1 @@ +5e879fe79bae19b62f81659a102602271c73a424faf4be069ab31fb50e30b536a8c7b3692127763000cc1dbab69c93ac3da7bace5f093d05dce2d652fb221d52 diff --git a/stdlib/Statistics.version b/stdlib/Statistics.version index 1449dcee29b79..3df70d30ba7e6 100644 --- a/stdlib/Statistics.version +++ b/stdlib/Statistics.version @@ -1,4 +1,4 @@ STATISTICS_BRANCH = master -STATISTICS_SHA1 = 68869af06e8cdeb7aba1d5259de602da7328057f +STATISTICS_SHA1 = d49c2bf4f81e1efb4980a35fe39c815ef8396297 STATISTICS_GIT_URL := https://github.com/JuliaStats/Statistics.jl.git STATISTICS_TAR_URL = https://api.github.com/repos/JuliaStats/Statistics.jl/tarball/$1 From 055103901eb486e5b2e8d300ba7c531563beb618 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Mon, 16 Dec 2024 13:32:17 +0900 Subject: [PATCH 057/198] inference: don't allocate `TryCatchFrame` for `compute_trycatch(::IRCode)` (#56835) `TryCatchFrame` is only required for the abstract interpretation and is not necessary in `compute_trycatch` within slot2ssa.jl. @nanosoldier `runbenchmarks("inference", vs=":master")` --- Compiler/src/inferencestate.jl | 45 ++++++++++++++++++++++++---------- Compiler/src/ssair/slot2ssa.jl | 8 +++--- Compiler/test/inference.jl | 2 +- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/Compiler/src/inferencestate.jl b/Compiler/src/inferencestate.jl index 6988e74310fc5..046f98df1f41d 100644 --- a/Compiler/src/inferencestate.jl +++ b/Compiler/src/inferencestate.jl @@ -219,16 +219,29 @@ const CACHE_MODE_GLOBAL = 0x01 << 0 # cached globally, optimization required const CACHE_MODE_LOCAL = 0x01 << 1 # cached locally, optimization required const CACHE_MODE_VOLATILE = 0x01 << 2 # not cached, optimization required -mutable struct TryCatchFrame +abstract type Handler end +get_enter_idx(handler::Handler) = get_enter_idx_impl(handler)::Int + +mutable struct TryCatchFrame <: Handler exct scopet const enter_idx::Int scope_uses::Vector{Int} - TryCatchFrame(@nospecialize(exct), @nospecialize(scopet), enter_idx::Int) = new(exct, scopet, enter_idx) + TryCatchFrame(@nospecialize(exct), @nospecialize(scopet), enter_idx::Int) = + new(exct, scopet, enter_idx) +end +TryCatchFrame(stmt::EnterNode, pc::Int) = + TryCatchFrame(Bottom, isdefined(stmt, :scope) ? Bottom : nothing, pc) +get_enter_idx_impl((; enter_idx)::TryCatchFrame) = enter_idx + +struct SimpleHandler <: Handler + enter_idx::Int end +SimpleHandler(::EnterNode, pc::Int) = SimpleHandler(pc) +get_enter_idx_impl((; enter_idx)::SimpleHandler) = enter_idx -struct HandlerInfo - handlers::Vector{TryCatchFrame} +struct HandlerInfo{T<:Handler} + handlers::Vector{T} handler_at::Vector{Tuple{Int,Int}} # tuple of current (handler, exception stack) value at the pc end @@ -261,7 +274,7 @@ mutable struct InferenceState currbb::Int currpc::Int ip::BitSet#=TODO BoundedMinPrioritySet=# # current active instruction pointers - handler_info::Union{Nothing,HandlerInfo} + handler_info::Union{Nothing,HandlerInfo{TryCatchFrame}} ssavalue_uses::Vector{BitSet} # ssavalue sparsity and restart info # TODO: Could keep this sparsely by doing structural liveness analysis ahead of time. bb_vartables::Vector{Union{Nothing,VarTable}} # nothing if not analyzed yet @@ -318,7 +331,7 @@ mutable struct InferenceState currbb = currpc = 1 ip = BitSet(1) # TODO BitSetBoundedMinPrioritySet(1) - handler_info = compute_trycatch(code) + handler_info = ComputeTryCatch{TryCatchFrame}()(code) nssavalues = src.ssavaluetypes::Int ssavalue_uses = find_ssavalue_uses(code, nssavalues) nstmts = length(code) @@ -421,10 +434,16 @@ is_inferred(result::InferenceResult) = result.result !== nothing was_reached(sv::InferenceState, pc::Int) = sv.ssavaluetypes[pc] !== NOT_FOUND -compute_trycatch(ir::IRCode) = compute_trycatch(ir.stmts.stmt, ir.cfg.blocks) +struct ComputeTryCatch{T<:Handler} end + +const compute_trycatch = ComputeTryCatch{SimpleHandler}() + +(compute_trycatch::ComputeTryCatch{SimpleHandler})(ir::IRCode) = + compute_trycatch(ir.stmts.stmt, ir.cfg.blocks) """ - compute_trycatch(code, [, bbs]) -> handler_info::Union{Nothing,HandlerInfo} + (::ComputeTryCatch{Handler})(code, [, bbs]) -> handler_info::Union{Nothing,HandlerInfo{Handler}} + const compute_trycatch = ComputeTryCatch{SimpleHandler}() Given the code of a function, compute, at every statement, the current try/catch handler, and the current exception stack top. This function returns @@ -433,9 +452,9 @@ a tuple of: 1. `handler_info.handler_at`: A statement length vector of tuples `(catch_handler, exception_stack)`, which are indices into `handlers` - 2. `handler_info.handlers`: A `TryCatchFrame` vector of handlers + 2. `handler_info.handlers`: A `Handler` vector of handlers """ -function compute_trycatch(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothing}=nothing) +function (::ComputeTryCatch{Handler})(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothing}=nothing) where Handler # The goal initially is to record the frame like this for the state at exit: # 1: (enter 3) # == 0 # 3: (expr) # == 1 @@ -454,10 +473,10 @@ function compute_trycatch(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothi stmt = code[pc] if isa(stmt, EnterNode) (;handlers, handler_at) = handler_info = - (handler_info === nothing ? HandlerInfo(TryCatchFrame[], fill((0, 0), n)) : handler_info) + (handler_info === nothing ? HandlerInfo{Handler}(Handler[], fill((0, 0), n)) : handler_info) l = stmt.catch_dest (bbs !== nothing) && (l = first(bbs[l].stmts)) - push!(handlers, TryCatchFrame(Bottom, isdefined(stmt, :scope) ? Bottom : nothing, pc)) + push!(handlers, Handler(stmt, pc)) handler_id = length(handlers) handler_at[pc + 1] = (handler_id, 0) push!(ip, pc + 1) @@ -526,7 +545,7 @@ function compute_trycatch(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothi end cur_hand = cur_stacks[1] for i = 1:l - cur_hand = handler_at[handlers[cur_hand].enter_idx][1] + cur_hand = handler_at[get_enter_idx(handlers[cur_hand])][1] end cur_stacks = (cur_hand, cur_stacks[2]) cur_stacks == (0, 0) && break diff --git a/Compiler/src/ssair/slot2ssa.jl b/Compiler/src/ssair/slot2ssa.jl index 6fc87934d3bc5..80dffdab23243 100644 --- a/Compiler/src/ssair/slot2ssa.jl +++ b/Compiler/src/ssair/slot2ssa.jl @@ -801,9 +801,11 @@ function construct_ssa!(ci::CodeInfo, ir::IRCode, sv::OptimizationState, has_pinode[id] = false enter_idx = idx while (handler = gethandler(handler_info, enter_idx)) !== nothing - (; enter_idx) = handler - leave_block = block_for_inst(cfg, (code[enter_idx]::EnterNode).catch_dest) - cidx = findfirst((; slot)::NewPhiCNode2->slot_id(slot)==id, new_phic_nodes[leave_block]) + enter_idx = get_enter_idx(handler) + enter_node = code[enter_idx]::EnterNode + leave_block = block_for_inst(cfg, enter_node.catch_dest) + cidx = findfirst((; slot)::NewPhiCNode2->slot_id(slot)==id, + new_phic_nodes[leave_block]) if cidx !== nothing node = thisdef ? UpsilonNode(thisval) : UpsilonNode() if incoming_vals[id] === UNDEF_TOKEN diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index c8b599adb1323..e272ff6de8d99 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -4436,7 +4436,7 @@ let x = Tuple{Int,Any}[ #=20=# (0, Core.ReturnNode(Core.SlotNumber(3))) ] (;handler_at, handlers) = Compiler.compute_trycatch(last.(x)) - @test map(x->x[1] == 0 ? 0 : handlers[x[1]].enter_idx, handler_at) == first.(x) + @test map(x->x[1] == 0 ? 0 : Compiler.get_enter_idx(handlers[x[1]]), handler_at) == first.(x) end @test only(Base.return_types((Bool,)) do y From 13f446e9f4d518b20faea68d2e239fcabd462ea9 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Mon, 16 Dec 2024 02:50:44 -0500 Subject: [PATCH 058/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?LazyArtifacts=20stdlib=20from=20e9a3633=20to=20a719c0e=20(#5682?= =?UTF-8?q?7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: LazyArtifacts URL: https://github.com/JuliaPackaging/LazyArtifacts.jl.git Stdlib branch: main Julia branch: master Old commit: e9a3633 New commit: a719c0e Julia version: 1.12.0-DEV LazyArtifacts version: 1.11.0(Does not match) Bump invoked by: @DilumAluthge Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaPackaging/LazyArtifacts.jl/compare/e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c...a719c0e3d68a95c6f3dc9571459428ca8761fa2c ``` $ git log --oneline e9a3633..a719c0e a719c0e Add compat for LazyArtifacts ``` Co-authored-by: Dilum Aluthge --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/LazyArtifacts.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/md5 create mode 100644 deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/sha512 delete mode 100644 deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/md5 delete mode 100644 deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/sha512 diff --git a/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/md5 b/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/md5 new file mode 100644 index 0000000000000..363c289573765 --- /dev/null +++ b/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/md5 @@ -0,0 +1 @@ +ce3754f1d195e1533fc1f3c51e2a2d4c diff --git a/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/sha512 b/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/sha512 new file mode 100644 index 0000000000000..62227971fe7f7 --- /dev/null +++ b/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/sha512 @@ -0,0 +1 @@ +1e1beb6202f089b82f06c1f1fcb129a31d2b438df8a3a49c7367d3df4587d8b9b8fbcf74d3f5ff3c25c241314c71e5dfd72014338b822f01252890e2a14831d1 diff --git a/deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/md5 b/deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/md5 deleted file mode 100644 index 4d14c85460418..0000000000000 --- a/deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -8355c253fadfc3f9222e05cb67845dd6 diff --git a/deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/sha512 b/deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/sha512 deleted file mode 100644 index d44f215e67673..0000000000000 --- a/deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -6d965199ed02446e694789a38f05249ff60ac00f8295fe32bf91a79cca34649829e38eaf46cc0b0b72ff2df7e184c2eaeb610600ebb5158251b331c61e9dfc5d diff --git a/stdlib/LazyArtifacts.version b/stdlib/LazyArtifacts.version index 4246ec3ad5d1a..f740516eb9953 100644 --- a/stdlib/LazyArtifacts.version +++ b/stdlib/LazyArtifacts.version @@ -1,4 +1,4 @@ LAZYARTIFACTS_BRANCH = main -LAZYARTIFACTS_SHA1 = e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c +LAZYARTIFACTS_SHA1 = a719c0e3d68a95c6f3dc9571459428ca8761fa2c LAZYARTIFACTS_GIT_URL := https://github.com/JuliaPackaging/LazyArtifacts.jl.git LAZYARTIFACTS_TAR_URL = https://api.github.com/repos/JuliaPackaging/LazyArtifacts.jl/tarball/$1 From 17857ca0f21eb0aa643fb630644a05cc69bc517b Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Mon, 16 Dec 2024 14:56:41 -0500 Subject: [PATCH 059/198] make `memorynew` intrinsic (#56803) Attempt to split up https://github.com/JuliaLang/julia/pull/55913 into 2 pieces. This piece now only adds the `memorynew` intrinsic without any of the optimizations enabled by https://github.com/JuliaLang/julia/pull/55913. As such, this PR should be ready to merge now. (and will make https://github.com/JuliaLang/julia/pull/55913 smaller and simpler) --------- Co-authored-by: gbaraldi --- Compiler/src/tfuncs.jl | 30 +++++++- Compiler/test/irpasses.jl | 7 +- base/boot.jl | 7 +- doc/src/manual/performance-tips.md | 22 +++--- src/array.c | 13 +--- src/builtin_proto.h | 1 + src/builtins.c | 10 +++ src/ccall.cpp | 27 ------- src/cgutils.cpp | 110 ++++++++++++++++++++++++++++- src/codegen.cpp | 45 ++++++++++++ src/genericmemory.c | 61 ++++++++-------- src/julia.h | 2 + src/rtutils.c | 7 ++ src/staticdata.c | 5 +- test/core.jl | 9 +++ 15 files changed, 264 insertions(+), 92 deletions(-) diff --git a/Compiler/src/tfuncs.jl b/Compiler/src/tfuncs.jl index af8863c1b3a3a..906bc9521adf9 100644 --- a/Compiler/src/tfuncs.jl +++ b/Compiler/src/tfuncs.jl @@ -2017,6 +2017,12 @@ function tuple_tfunc(𝕃::AbstractLattice, argtypes::Vector{Any}) return anyinfo ? PartialStruct(𝕃, typ, argtypes) : typ end +@nospecs function memorynew_tfunc(𝕃::AbstractLattice, memtype, m) + hasintersect(widenconst(m), Int) || return Bottom + return tmeet(𝕃, instanceof_tfunc(memtype, true)[1], GenericMemory) +end +add_tfunc(Core.memorynew, 2, 2, memorynew_tfunc, 10) + @nospecs function memoryrefget_tfunc(𝕃::AbstractLattice, mem, order, boundscheck) memoryref_builtin_common_errorcheck(mem, order, boundscheck) || return Bottom return memoryref_elemtype(mem) @@ -2238,13 +2244,31 @@ end return boundscheck ⊑ Bool && memtype ⊑ GenericMemoryRef && order ⊑ Symbol end +@nospecs function memorynew_nothrow(argtypes::Vector{Any}) + if !(argtypes[1] isa Const && argtypes[2] isa Const) + return false + end + MemT = argtypes[1].val + if !(isconcretetype(MemT) && MemT <: GenericMemory) + return false + end + len = argtypes[2].val + if !(len isa Int && 0 <= len < typemax(Int)) + return false + end + elsz = datatype_layoutsize(MemT) + overflows = checked_smul_int(len, elsz)[2] + return !overflows +end # Query whether the given builtin is guaranteed not to throw given the `argtypes`. # `argtypes` can be assumed not to contain varargs. function _builtin_nothrow(𝕃::AbstractLattice, @nospecialize(f::Builtin), argtypes::Vector{Any}, @nospecialize(rt)) ⊑ = partialorder(𝕃) na = length(argtypes) - if f === memoryrefnew + if f === Core.memorynew + return memorynew_nothrow(argtypes) + elseif f === memoryrefnew return memoryref_builtin_common_nothrow(argtypes) elseif f === memoryrefoffset length(argtypes) == 1 || return false @@ -2347,6 +2371,7 @@ const _EFFECT_FREE_BUILTINS = [ isa, UnionAll, getfield, + Core.memorynew, memoryrefnew, memoryrefoffset, memoryrefget, @@ -2381,6 +2406,7 @@ const _INACCESSIBLEMEM_BUILTINS = Any[ compilerbarrier, Core._typevar, donotdelete, + Core.memorynew, ] const _ARGMEM_BUILTINS = Any[ @@ -2543,7 +2569,7 @@ function builtin_effects(𝕃::AbstractLattice, @nospecialize(f::Builtin), argty consistent = ALWAYS_TRUE elseif f === memoryrefget || f === memoryrefset! || f === memoryref_isassigned consistent = CONSISTENT_IF_INACCESSIBLEMEMONLY - elseif f === Core._typevar + elseif f === Core._typevar || f === Core.memorynew consistent = CONSISTENT_IF_NOTRETURNED else consistent = ALWAYS_FALSE diff --git a/Compiler/test/irpasses.jl b/Compiler/test/irpasses.jl index e9d6f57337530..90d8c9dc6ab3d 100644 --- a/Compiler/test/irpasses.jl +++ b/Compiler/test/irpasses.jl @@ -1083,12 +1083,13 @@ end # test `flags_for_effects` and DCE # ================================ -let # effect-freeness computation for array allocation +@testset "effect-freeness computation for array allocation" begin # should eliminate dead allocations good_dims = [1, 2, 3, 4, 10] Ns = [1, 2, 3, 4, 10] - for dim = good_dims, N = Ns + Ts = Any[Int, Union{Missing,Nothing}, Nothing, Any] + @testset "$dim, $N" for dim in good_dims, N in Ns Int64(dim)^N > typemax(Int) && continue dims = ntuple(i->dim, N) @test @eval fully_eliminated() do @@ -1099,7 +1100,7 @@ let # effect-freeness computation for array allocation # shouldn't eliminate erroneous dead allocations bad_dims = [-1, typemax(Int)] - for dim in bad_dims, N in [1, 2, 3, 4, 10], T in Any[Int, Union{Missing,Nothing}, Nothing, Any] + @testset "$dim, $N, $T" for dim in bad_dims, N in Ns, T in Ts dims = ntuple(i->dim, N) @test @eval !fully_eliminated() do Array{$T,$N}(undef, $(dims...)) diff --git a/base/boot.jl b/base/boot.jl index 4badedae3cfb7..ed0a722c5e562 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -575,12 +575,7 @@ struct UndefInitializer end const undef = UndefInitializer() # type and dimensionality specified -(self::Type{GenericMemory{kind,T,addrspace}})(::UndefInitializer, m::Int) where {T,addrspace,kind} = - if isdefined(self, :instance) && m === 0 - self.instance - else - ccall(:jl_alloc_genericmemory, Ref{GenericMemory{kind,T,addrspace}}, (Any, Int), self, m) - end +(self::Type{GenericMemory{kind,T,addrspace}})(::UndefInitializer, m::Int) where {T,addrspace,kind} = memorynew(self, m) (self::Type{GenericMemory{kind,T,addrspace}})(::UndefInitializer, d::NTuple{1,Int}) where {T,kind,addrspace} = self(undef, getfield(d,1)) # empty vector constructor (self::Type{GenericMemory{kind,T,addrspace}})() where {T,kind,addrspace} = self(undef, 0) diff --git a/doc/src/manual/performance-tips.md b/doc/src/manual/performance-tips.md index 038000f55e761..1166164241c60 100644 --- a/doc/src/manual/performance-tips.md +++ b/doc/src/manual/performance-tips.md @@ -1058,12 +1058,12 @@ the output. As a trivial example, compare ```jldoctest prealloc julia> function xinc(x) - return [x, x+1, x+2] + return [x + i for i in 1:3000] end; julia> function loopinc() y = 0 - for i = 1:10^7 + for i = 1:10^5 ret = xinc(i) y += ret[2] end @@ -1075,16 +1075,16 @@ with ```jldoctest prealloc julia> function xinc!(ret::AbstractVector{T}, x::T) where T - ret[1] = x - ret[2] = x+1 - ret[3] = x+2 + for i in 1:3000 + ret[i] = x+i + end nothing end; julia> function loopinc_prealloc() - ret = Vector{Int}(undef, 3) + ret = Vector{Int}(undef, 3000) y = 0 - for i = 1:10^7 + for i = 1:10^5 xinc!(ret, i) y += ret[2] end @@ -1096,12 +1096,12 @@ Timing results: ```jldoctest prealloc; filter = r"[0-9\.]+ seconds \(.*?\)" julia> @time loopinc() - 0.529894 seconds (40.00 M allocations: 1.490 GiB, 12.14% gc time) -50000015000000 + 0.297454 seconds (200.00 k allocations: 2.239 GiB, 39.80% gc time) +5000250000 julia> @time loopinc_prealloc() - 0.030850 seconds (6 allocations: 288 bytes) -50000015000000 + 0.009410 seconds (2 allocations: 23.477 KiB) +5000250000 ``` Preallocation has other advantages, for example by allowing the caller to control the "output" diff --git a/src/array.c b/src/array.c index f0051ec17565a..da9cb24b4d0e9 100644 --- a/src/array.c +++ b/src/array.c @@ -16,12 +16,6 @@ extern "C" { #endif -#if defined(_P64) && defined(UINT128MAX) -typedef __uint128_t wideint_t; -#else -typedef uint64_t wideint_t; -#endif - #define MAXINTVAL (((size_t)-1)>>1) JL_DLLEXPORT int jl_array_validate_dims(size_t *nel, uint32_t ndims, size_t *dims) @@ -30,10 +24,9 @@ JL_DLLEXPORT int jl_array_validate_dims(size_t *nel, uint32_t ndims, size_t *dim size_t _nel = 1; for (i = 0; i < ndims; i++) { size_t di = dims[i]; - wideint_t prod = (wideint_t)_nel * (wideint_t)di; - if (prod >= (wideint_t) MAXINTVAL || di >= MAXINTVAL) + int overflow = __builtin_mul_overflow(_nel, di, &_nel); + if (overflow || di >= MAXINTVAL) return 1; - _nel = prod; } *nel = _nel; return 0; @@ -204,7 +197,7 @@ JL_DLLEXPORT void jl_array_grow_end(jl_array_t *a, size_t inc) int isbitsunion = jl_genericmemory_isbitsunion(a->ref.mem); size_t newnrows = n + inc; if (!isbitsunion && elsz == 0) { - jl_genericmemory_t *newmem = jl_alloc_genericmemory(mtype, MAXINTVAL - 1); + jl_genericmemory_t *newmem = jl_alloc_genericmemory(mtype, MAXINTVAL - 2); a->ref.mem = newmem; jl_gc_wb(a, newmem); a->dimsize[0] = newnrows; diff --git a/src/builtin_proto.h b/src/builtin_proto.h index 7fbd555758675..70ad67040991d 100644 --- a/src/builtin_proto.h +++ b/src/builtin_proto.h @@ -46,6 +46,7 @@ DECLARE_BUILTIN(is); DECLARE_BUILTIN(isa); DECLARE_BUILTIN(isdefined); DECLARE_BUILTIN(issubtype); +DECLARE_BUILTIN(memorynew); DECLARE_BUILTIN(memoryref); DECLARE_BUILTIN(memoryref_isassigned); DECLARE_BUILTIN(memoryrefget); diff --git a/src/builtins.c b/src/builtins.c index 4b9c1ad6043c2..06dbd84aff6c0 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1675,6 +1675,15 @@ JL_CALLABLE(jl_f__typevar) } // genericmemory --------------------------------------------------------------------- +JL_CALLABLE(jl_f_memorynew) +{ + JL_NARGS(memorynew, 2, 2); + jl_datatype_t *jl_genericmemory_type_type = jl_datatype_type; + JL_TYPECHK(memorynew, genericmemory_type, args[0]); + JL_TYPECHK(memorynew, long, args[1]); + size_t nel = jl_unbox_long(args[1]); + return (jl_value_t*)jl_alloc_genericmemory(args[0], nel); +} JL_CALLABLE(jl_f_memoryref) { @@ -2441,6 +2450,7 @@ void jl_init_primitives(void) JL_GC_DISABLED jl_builtin_setglobalonce = add_builtin_func("setglobalonce!", jl_f_setglobalonce); // memory primitives + jl_builtin_memorynew = add_builtin_func("memorynew", jl_f_memorynew); jl_builtin_memoryref = add_builtin_func("memoryrefnew", jl_f_memoryref); jl_builtin_memoryrefoffset = add_builtin_func("memoryrefoffset", jl_f_memoryrefoffset); jl_builtin_memoryrefget = add_builtin_func("memoryrefget", jl_f_memoryrefget); diff --git a/src/ccall.cpp b/src/ccall.cpp index 9aa1c56e2e78f..3937570896f82 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -1877,33 +1877,6 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) JL_GC_POP(); return mark_julia_type(ctx, obj, true, jl_any_type); } - else if (is_libjulia_func(jl_alloc_genericmemory)) { - ++CCALL_STAT(jl_alloc_genericmemory); - assert(lrt == ctx.types().T_prjlvalue); - assert(!isVa && !llvmcall && nccallargs == 2); - const jl_cgval_t &typ = argv[0]; - const jl_cgval_t &nel = argv[1]; - auto arg_typename = [&] JL_NOTSAFEPOINT { - auto istyp = argv[0].constant; - std::string type_str; - if (istyp && jl_is_datatype(istyp) && jl_is_genericmemory_type(istyp)){ - auto eltype = jl_tparam1(istyp); - if (jl_is_datatype(eltype)) - type_str = jl_symbol_name(((jl_datatype_t*)eltype)->name->name); - else if (jl_is_uniontype(eltype)) - type_str = "Union"; - else - type_str = ""; - } - else - type_str = ""; - return "Memory{" + type_str + "}[]"; - }; - auto alloc = ctx.builder.CreateCall(prepare_call(jl_allocgenericmemory), { boxed(ctx,typ), emit_unbox(ctx, ctx.types().T_size, nel, (jl_value_t*)jl_ulong_type)}); - setName(ctx.emission_context, alloc, arg_typename); - JL_GC_POP(); - return mark_julia_type(ctx, alloc, true, jl_any_type); - } else if (is_libjulia_func(memcpy) && (rt == (jl_value_t*)jl_nothing_type || jl_is_cpointer_type(rt))) { ++CCALL_STAT(memcpy); const jl_cgval_t &dst = argv[0]; diff --git a/src/cgutils.cpp b/src/cgutils.cpp index dd6ced04673e6..6aabc459d2c91 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -1548,19 +1548,24 @@ static void emit_error(jl_codectx_t &ctx, const Twine &txt) } // DO NOT PASS IN A CONST CONDITION! -static void error_unless(jl_codectx_t &ctx, Value *cond, const Twine &msg) +static void error_unless(jl_codectx_t &ctx, Function *F, Value *cond, const Twine &msg) { ++EmittedConditionalErrors; BasicBlock *failBB = BasicBlock::Create(ctx.builder.getContext(), "fail", ctx.f); BasicBlock *passBB = BasicBlock::Create(ctx.builder.getContext(), "pass"); ctx.builder.CreateCondBr(cond, passBB, failBB); ctx.builder.SetInsertPoint(failBB); - just_emit_error(ctx, prepare_call(jlerror_func), msg); + just_emit_error(ctx, F, msg); ctx.builder.CreateUnreachable(); passBB->insertInto(ctx.f); ctx.builder.SetInsertPoint(passBB); } +static void error_unless(jl_codectx_t &ctx, Value *cond, const Twine &msg) +{ + error_unless(ctx, prepare_call(jlerror_func), cond, msg); +} + static void raise_exception(jl_codectx_t &ctx, Value *exc, BasicBlock *contBB=nullptr) { @@ -4427,6 +4432,107 @@ static int compare_cgparams(const jl_cgparams_t *a, const jl_cgparams_t *b) } #endif +static jl_cgval_t emit_memorynew(jl_codectx_t &ctx, jl_datatype_t *typ, jl_cgval_t nel, jl_genericmemory_t *inst) +{ + emit_typecheck(ctx, nel, (jl_value_t*)jl_long_type, "memorynew"); + nel = update_julia_type(ctx, nel, (jl_value_t*)jl_long_type); + if (nel.typ == jl_bottom_type) + return jl_cgval_t(); + + const jl_datatype_layout_t *layout = ((jl_datatype_t*)typ)->layout; + assert(((jl_datatype_t*)typ)->has_concrete_subtype && layout != NULL); + size_t elsz = layout->size; + int isboxed = layout->flags.arrayelem_isboxed; + int isunion = layout->flags.arrayelem_isunion; + int zi = ((jl_datatype_t*)typ)->zeroinit; + if (isboxed) + elsz = sizeof(void*); + + auto ptls = get_current_ptls(ctx); + auto T_size = ctx.types().T_size; + auto int8t = getInt8Ty(ctx.builder.getContext()); + BasicBlock *emptymemBB, *nonemptymemBB, *retvalBB; + emptymemBB = BasicBlock::Create(ctx.builder.getContext(), "emptymem"); + nonemptymemBB = BasicBlock::Create(ctx.builder.getContext(), "nonemptymem"); + retvalBB = BasicBlock::Create(ctx.builder.getContext(), "retval"); + auto nel_unboxed = emit_unbox(ctx, ctx.types().T_size, nel, (jl_value_t*)jl_long_type); + Value *memorynew_empty = ctx.builder.CreateICmpEQ(nel_unboxed, ConstantInt::get(T_size, 0)); + setName(ctx.emission_context, memorynew_empty, "memorynew_empty"); + ctx.builder.CreateCondBr(memorynew_empty, emptymemBB, nonemptymemBB); + // if nel == 0 + emptymemBB->insertInto(ctx.f); + ctx.builder.SetInsertPoint(emptymemBB); + auto emptyalloc = track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)inst)); + ctx.builder.CreateBr(retvalBB); + nonemptymemBB->insertInto(ctx.f); + ctx.builder.SetInsertPoint(nonemptymemBB); + // else actually allocate mem + auto arg_typename = [&] JL_NOTSAFEPOINT { + std::string type_str; + auto eltype = jl_tparam1(typ); + if (jl_is_datatype(eltype)) + type_str = jl_symbol_name(((jl_datatype_t*)eltype)->name->name); + else if (jl_is_uniontype(eltype)) + type_str = "Union"; + else + type_str = ""; + return "Memory{" + type_str + "}[]"; + }; + auto cg_typ = literal_pointer_val(ctx, (jl_value_t*) typ); + auto cg_elsz = ConstantInt::get(T_size, elsz); + + FunctionCallee intr = Intrinsic::getDeclaration(jl_Module, Intrinsic::smul_with_overflow, ArrayRef(T_size)); + // compute nbytes with possible overflow + Value *prod_with_overflow = ctx.builder.CreateCall(intr, {nel_unboxed, cg_elsz}); + Value *nbytes = ctx.builder.CreateExtractValue(prod_with_overflow, 0); + Value *overflow = ctx.builder.CreateExtractValue(prod_with_overflow, 1); + if (isunion) { + // if isunion, we need to allocate the union selector bytes as well + intr = Intrinsic::getDeclaration(jl_Module, Intrinsic::sadd_with_overflow, ArrayRef(T_size)); + Value *add_with_overflow = ctx.builder.CreateCall(intr, {nel_unboxed, nbytes}); + nbytes = ctx.builder.CreateExtractValue(add_with_overflow, 0); + Value *overflow1 = ctx.builder.CreateExtractValue(add_with_overflow, 1); + overflow = ctx.builder.CreateOr(overflow, overflow1); + } + Value *negnel = ctx.builder.CreateICmpSLT(nel_unboxed, ConstantInt::get(T_size, 0)); + overflow = ctx.builder.CreateOr(overflow, negnel); + auto cg_typemax_int = ConstantInt::get(T_size, (((size_t)-1)>>1)-1); + Value *tobignel = ctx.builder.CreateICmpSLT(cg_typemax_int, elsz == 0 ? nel_unboxed: nbytes); + overflow = ctx.builder.CreateOr(overflow, tobignel); + Value *notoverflow = ctx.builder.CreateNot(overflow); + error_unless(ctx, prepare_call(jlargumenterror_func), notoverflow, "invalid GenericMemory size: the number of elements is either negative or too large for system address width"); + // actually allocate + auto call = prepare_call(jl_alloc_genericmemory_unchecked_func); + Value *alloc = ctx.builder.CreateCall(call, { ptls, nbytes, cg_typ}); + // set length (jl_alloc_genericmemory_unchecked_func doesn't have it) + Value *decay_alloc = decay_derived(ctx, alloc); + Value *len_field = ctx.builder.CreateStructGEP(ctx.types().T_jlgenericmemory, decay_alloc, 0); + auto len_store = ctx.builder.CreateAlignedStore(nel_unboxed, len_field, Align(sizeof(void*))); + auto aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memorylen); + aliasinfo.decorateInst(len_store); + //This avoids the length store from being deleted which is illegal + ctx.builder.CreateFence(AtomicOrdering::Release, SyncScope::SingleThread); + // zeroinit pointers and unions + if (zi) { + Value *memory_ptr = ctx.builder.CreateStructGEP(ctx.types().T_jlgenericmemory, decay_alloc, 1); + auto *load = ctx.builder.CreateAlignedLoad(ctx.types().T_ptr, memory_ptr, Align(sizeof(void*))); + aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memoryptr); + aliasinfo.decorateInst(load); + ctx.builder.CreateMemSet(load, ConstantInt::get(int8t, 0), nbytes, Align(sizeof(void*))); + } + + setName(ctx.emission_context, alloc, arg_typename); + ctx.builder.CreateBr(retvalBB); + nonemptymemBB = ctx.builder.GetInsertBlock(); + // phi node to choose which side of branch + retvalBB->insertInto(ctx.f); + ctx.builder.SetInsertPoint(retvalBB); + auto phi = ctx.builder.CreatePHI(ctx.types().T_prjlvalue, 2); + phi->addIncoming(emptyalloc, emptymemBB); + phi->addIncoming(alloc, nonemptymemBB); + return mark_julia_type(ctx, phi, true, typ); +} + static jl_cgval_t _emit_memoryref(jl_codectx_t &ctx, Value *mem, Value *data, const jl_datatype_layout_t *layout, jl_value_t *typ) { //jl_cgval_t argv[] = { diff --git a/src/codegen.cpp b/src/codegen.cpp index 5656fb594044b..86c9afd134d9a 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -801,6 +801,12 @@ static const auto jlerror_func = new JuliaFunction<>{ {getPointerTy(C)}, false); }, get_attrs_noreturn, }; +static const auto jlargumenterror_func = new JuliaFunction<>{ + XSTR(jl_argument_error), + [](LLVMContext &C) { return FunctionType::get(getVoidTy(C), + {getPointerTy(C)}, false); }, + get_attrs_noreturn, +}; static const auto jlatomicerror_func = new JuliaFunction<>{ XSTR(jl_atomic_error), [](LLVMContext &C) { return FunctionType::get(getVoidTy(C), @@ -1153,6 +1159,29 @@ static const auto jl_alloc_obj_func = new JuliaFunction{ None); }, }; +static const auto jl_alloc_genericmemory_unchecked_func = new JuliaFunction{ + XSTR(jl_alloc_genericmemory_unchecked), + [](LLVMContext &C, Type *T_size) { + auto T_jlvalue = JuliaType::get_jlvalue_ty(C); + auto T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked); + auto T_pjlvalue = PointerType::get(T_jlvalue, 0); + return FunctionType::get(T_prjlvalue, + {T_pjlvalue, T_size, T_pjlvalue}, false); + }, + [](LLVMContext &C) { + auto FnAttrs = AttrBuilder(C); + FnAttrs.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Ref) | MemoryEffects::inaccessibleMemOnly(ModRefInfo::ModRef)); + FnAttrs.addAttribute(Attribute::WillReturn); + FnAttrs.addAttribute(Attribute::NoUnwind); + auto RetAttrs = AttrBuilder(C); + RetAttrs.addAttribute(Attribute::NoAlias); + RetAttrs.addAttribute(Attribute::NonNull); + return AttributeList::get(C, + AttributeSet::get(C, FnAttrs), + AttributeSet::get(C, RetAttrs), + None); + }, +}; static const auto jl_newbits_func = new JuliaFunction<>{ XSTR(jl_new_bits), [](LLVMContext &C) { @@ -1574,6 +1603,7 @@ static const auto &builtin_func_map() { { jl_f_nfields_addr, new JuliaFunction<>{XSTR(jl_f_nfields), get_func_sig, get_func_attrs} }, { jl_f__expr_addr, new JuliaFunction<>{XSTR(jl_f__expr), get_func_sig, get_func_attrs} }, { jl_f__typevar_addr, new JuliaFunction<>{XSTR(jl_f__typevar), get_func_sig, get_func_attrs} }, + { jl_f_memorynew_addr, new JuliaFunction<>{XSTR(jl_f_memorynew), get_func_sig, get_func_attrs} }, { jl_f_memoryref_addr, new JuliaFunction<>{XSTR(jl_f_memoryref), get_func_sig, get_func_attrs} }, { jl_f_memoryrefoffset_addr, new JuliaFunction<>{XSTR(jl_f_memoryrefoffset), get_func_sig, get_func_attrs} }, { jl_f_memoryrefset_addr, new JuliaFunction<>{XSTR(jl_f_memoryrefset), get_func_sig, get_func_attrs} }, @@ -4421,6 +4451,20 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return true; } + else if (f == jl_builtin_memorynew && (nargs == 2)) { + const jl_cgval_t &memty = argv[1]; + if (!memty.constant) + return false; + jl_datatype_t *typ = (jl_datatype_t*) memty.constant; + if (!jl_is_concrete_type((jl_value_t*)typ) || !jl_is_genericmemory_type(typ)) + return false; + jl_genericmemory_t *inst = (jl_genericmemory_t*)((jl_datatype_t*)typ)->instance; + if (inst == NULL) + return false; + *ret = emit_memorynew(ctx, typ, argv[2], inst); + return true; + } + else if (f == jl_builtin_memoryref && nargs == 1) { const jl_cgval_t &mem = argv[1]; jl_datatype_t *mty_dt = (jl_datatype_t*)jl_unwrap_unionall(mem.typ); @@ -10152,6 +10196,7 @@ static void init_jit_functions(void) add_named_global(jltypeassert_func, &jl_typeassert); add_named_global(jlapplytype_func, &jl_instantiate_type_in_env); add_named_global(jl_object_id__func, &jl_object_id_); + add_named_global(jl_alloc_genericmemory_unchecked_func, &jl_alloc_genericmemory_unchecked); add_named_global(jl_alloc_obj_func, (void*)NULL); add_named_global(jl_newbits_func, (void*)jl_new_bits); add_named_global(jl_typeof_func, (void*)NULL); diff --git a/src/genericmemory.c b/src/genericmemory.c index 2b02f021ccdd0..e435ec3b63c9f 100644 --- a/src/genericmemory.c +++ b/src/genericmemory.c @@ -24,49 +24,51 @@ JL_DLLEXPORT char *jl_genericmemory_typetagdata(jl_genericmemory_t *m) JL_NOTSAF return (char*)m->ptr + m->length * layout->size; } -#if defined(_P64) && defined(UINT128MAX) -typedef __uint128_t wideint_t; -#else -typedef uint64_t wideint_t; -#endif - #define MAXINTVAL (((size_t)-1)>>1) -jl_genericmemory_t *_new_genericmemory_(jl_value_t *mtype, size_t nel, int8_t isunion, int8_t zeroinit, size_t elsz) +// ONLY USE FROM CODEGEN. It only partially initializes the mem +JL_DLLEXPORT jl_genericmemory_t *jl_alloc_genericmemory_unchecked(jl_ptls_t ptls, size_t nbytes, jl_datatype_t *mtype) { - jl_task_t *ct = jl_current_task; - char *data; - jl_genericmemory_t *m; - if (nel == 0) // zero-sized allocation optimization - return (jl_genericmemory_t*)((jl_datatype_t*)mtype)->instance; - wideint_t prod = (wideint_t)nel * elsz; - if (isunion) { - // an extra byte for each isbits union memory element, stored at m->ptr + m->length - prod += nel; - } - if (nel >= MAXINTVAL || prod >= (wideint_t) MAXINTVAL) - jl_exceptionf(jl_argumenterror_type, "invalid GenericMemory size: the number of elements is either negative or too large for system address width"); - size_t tot = (size_t)prod + LLT_ALIGN(sizeof(jl_genericmemory_t),JL_SMALL_BYTE_ALIGNMENT); + size_t tot = nbytes + LLT_ALIGN(sizeof(jl_genericmemory_t),JL_SMALL_BYTE_ALIGNMENT); int pooled = tot <= GC_MAX_SZCLASS; + char *data; + jl_genericmemory_t *m; if (!pooled) { - data = (char*)jl_gc_managed_malloc(prod); + data = (char*)jl_gc_managed_malloc(nbytes); tot = sizeof(jl_genericmemory_t) + sizeof(void*); } - m = (jl_genericmemory_t*)jl_gc_alloc(ct->ptls, tot, mtype); + m = (jl_genericmemory_t*)jl_gc_alloc(ptls, tot, mtype); if (pooled) { data = (char*)m + JL_SMALL_BYTE_ALIGNMENT; } else { int isaligned = 1; // jl_gc_managed_malloc is always aligned - jl_gc_track_malloced_genericmemory(ct->ptls, m, isaligned); + jl_gc_track_malloced_genericmemory(ptls, m, isaligned); jl_genericmemory_data_owner_field(m) = (jl_value_t*)m; } - m->length = nel; + // length set by codegen m->ptr = data; + return m; +} +jl_genericmemory_t *_new_genericmemory_(jl_value_t *mtype, size_t nel, int8_t isunion, int8_t zeroinit, size_t elsz) +{ + if (nel == 0) // zero-sized allocation optimization + return (jl_genericmemory_t*)((jl_datatype_t*)mtype)->instance; + size_t nbytes; + int overflow = __builtin_mul_overflow(nel, elsz, &nbytes); + if (isunion) { + // an extra byte for each isbits union memory element, stored at m->ptr + m->length + overflow |= __builtin_add_overflow(nel, nbytes, &nbytes); + } + if ((nel >= MAXINTVAL-1) || (nbytes >= MAXINTVAL-1) || overflow) + jl_exceptionf(jl_argumenterror_type, "invalid GenericMemory size: the number of elements is either negative or too large for system address width"); + jl_task_t *ct = jl_current_task; + jl_genericmemory_t *m = jl_alloc_genericmemory_unchecked((jl_ptls_t) ct->ptls, nbytes, (jl_datatype_t*)mtype); + m->length = nel; if (zeroinit) - memset(data, 0, (size_t)prod); + memset((char*)m->ptr, 0, nbytes); return m; } @@ -150,13 +152,14 @@ JL_DLLEXPORT jl_genericmemory_t *jl_ptr_to_genericmemory(jl_value_t *mtype, void if (((uintptr_t)data) & ((align > JL_HEAP_ALIGNMENT ? JL_HEAP_ALIGNMENT : align) - 1)) jl_exceptionf(jl_argumenterror_type, "unsafe_wrap: pointer %p is not properly aligned to %u bytes", data, align); - wideint_t prod = (wideint_t)nel * elsz; + size_t nbytes; + int overflow = __builtin_mul_overflow(nel, elsz, &nbytes); if (isunion) { // an extra byte for each isbits union memory element, stored at m->ptr + m->length - prod += nel; + overflow |= __builtin_add_overflow(nel, nbytes, &nbytes); } - if (nel >= MAXINTVAL || prod >= (wideint_t) MAXINTVAL) - jl_exceptionf(jl_argumenterror_type, "invalid GenericMemory size: too large for system address width"); + if ((nel >= MAXINTVAL) || (nbytes >= MAXINTVAL) || overflow) + jl_exceptionf(jl_argumenterror_type, "invalid GenericMemory size: the number of elements is either negative or too large for system address width"); int tsz = sizeof(jl_genericmemory_t) + sizeof(void*); m = (jl_genericmemory_t*)jl_gc_alloc(ct->ptls, tsz, mtype); m->ptr = data; diff --git a/src/julia.h b/src/julia.h index a9864aad16ccc..049416a33336f 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1949,6 +1949,7 @@ JL_DLLEXPORT jl_genericmemory_t *jl_ptr_to_genericmemory(jl_value_t *mtype, void size_t nel, int own_buffer); JL_DLLEXPORT jl_genericmemory_t *jl_alloc_genericmemory(jl_value_t *mtype, size_t nel); JL_DLLEXPORT jl_genericmemory_t *jl_pchar_to_memory(const char *str, size_t len); +JL_DLLEXPORT jl_genericmemory_t *jl_alloc_genericmemory_unchecked(jl_ptls_t ptls, size_t nbytes, jl_datatype_t *mtype); JL_DLLEXPORT jl_value_t *jl_genericmemory_to_string(jl_genericmemory_t *m, size_t len); JL_DLLEXPORT jl_genericmemory_t *jl_alloc_memory_any(size_t n); JL_DLLEXPORT jl_value_t *jl_genericmemoryref(jl_genericmemory_t *m, size_t i); // 0-indexed @@ -2068,6 +2069,7 @@ JL_DLLEXPORT void JL_NORETURN jl_type_error_rt(const char *fname, jl_value_t *got JL_MAYBE_UNROOTED); JL_DLLEXPORT void JL_NORETURN jl_undefined_var_error(jl_sym_t *var, jl_value_t *scope JL_MAYBE_UNROOTED); JL_DLLEXPORT void JL_NORETURN jl_has_no_field_error(jl_datatype_t *t, jl_sym_t *var); +JL_DLLEXPORT void JL_NORETURN jl_argument_error(char *str); JL_DLLEXPORT void JL_NORETURN jl_atomic_error(char *str); JL_DLLEXPORT void JL_NORETURN jl_bounds_error(jl_value_t *v JL_MAYBE_UNROOTED, jl_value_t *t JL_MAYBE_UNROOTED); diff --git a/src/rtutils.c b/src/rtutils.c index fcc4a489d3f38..00a5b639d8683 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -157,6 +157,13 @@ JL_DLLEXPORT void JL_NORETURN jl_has_no_field_error(jl_datatype_t *t, jl_sym_t * jl_throw(jl_new_struct(jl_fielderror_type, t, var)); } +JL_DLLEXPORT void JL_NORETURN jl_argument_error(char *str) // == jl_exceptionf(jl_argumenterror_type, "%s", str) +{ + jl_value_t *msg = jl_pchar_to_string((char*)str, strlen(str)); + JL_GC_PUSH1(&msg); + jl_throw(jl_new_struct(jl_argumenterror_type, msg)); +} + JL_DLLEXPORT void JL_NORETURN jl_atomic_error(char *str) // == jl_exceptionf(jl_atomicerror_type, "%s", str) { jl_value_t *msg = jl_pchar_to_string((char*)str, strlen(str)); diff --git a/src/staticdata.c b/src/staticdata.c index 1665b5be4ed0f..a0d56f3e38f54 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -101,7 +101,7 @@ extern "C" { // TODO: put WeakRefs on the weak_refs list during deserialization // TODO: handle finalizers -#define NUM_TAGS 193 +#define NUM_TAGS 194 // An array of references that need to be restored from the sysimg // This is a manually constructed dual of the gvars array, which would be produced by codegen for Julia code, for C. @@ -290,6 +290,7 @@ jl_value_t **const*const get_tags(void) { INSERT_TAG(jl_builtin_replacefield); INSERT_TAG(jl_builtin_setfieldonce); INSERT_TAG(jl_builtin_fieldtype); + INSERT_TAG(jl_builtin_memorynew); INSERT_TAG(jl_builtin_memoryref); INSERT_TAG(jl_builtin_memoryrefoffset); INSERT_TAG(jl_builtin_memoryrefget); @@ -508,7 +509,7 @@ static const jl_fptr_args_t id_to_fptrs[] = { &jl_f__call_latest, &jl_f__call_in_world, &jl_f__call_in_world_total, &jl_f_isdefined, &jl_f_tuple, &jl_f_svec, &jl_f_intrinsic_call, &jl_f_getfield, &jl_f_setfield, &jl_f_swapfield, &jl_f_modifyfield, &jl_f_setfieldonce, - &jl_f_replacefield, &jl_f_fieldtype, &jl_f_nfields, &jl_f_apply_type, + &jl_f_replacefield, &jl_f_fieldtype, &jl_f_nfields, &jl_f_apply_type, &jl_f_memorynew, &jl_f_memoryref, &jl_f_memoryrefoffset, &jl_f_memoryrefget, &jl_f_memoryref_isassigned, &jl_f_memoryrefset, &jl_f_memoryrefswap, &jl_f_memoryrefmodify, &jl_f_memoryrefreplace, &jl_f_memoryrefsetonce, &jl_f_applicable, &jl_f_invoke, &jl_f_sizeof, &jl_f__expr, &jl_f__typevar, diff --git a/test/core.jl b/test/core.jl index 7e4f655222ea5..4bbb2ca368019 100644 --- a/test/core.jl +++ b/test/core.jl @@ -4505,6 +4505,15 @@ for T in (Any, ValueWrapper) end end +#test grow_end ccall directly since it's used in the C source +for ET in [Nothing, Int, Union{Int, Nothing}, Any] + for n in [0, 1, 10] + arr = Vector{ET}(undef, n) + ccall(:jl_array_grow_end, Cvoid, (Any, UInt), arr, 1) + @test length(arr) == n+1 + end +end + # check if we can run multiple finalizers at the same time # Use a `@noinline` function to make sure the inefficient gc root generation # doesn't keep the object alive. From da9f934112f2bc7b47ce2b2cf8156fa9e2886cfe Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:16:38 +0900 Subject: [PATCH 060/198] fix `compute_trycatch` for `IRCode` /w `EnterNode` with `catch_dest==0` (#56846) --- Compiler/src/inferencestate.jl | 4 ++-- Compiler/test/irpasses.jl | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Compiler/src/inferencestate.jl b/Compiler/src/inferencestate.jl index 046f98df1f41d..0ea0fc684b689 100644 --- a/Compiler/src/inferencestate.jl +++ b/Compiler/src/inferencestate.jl @@ -475,7 +475,7 @@ function (::ComputeTryCatch{Handler})(code::Vector{Any}, bbs::Union{Vector{Basic (;handlers, handler_at) = handler_info = (handler_info === nothing ? HandlerInfo{Handler}(Handler[], fill((0, 0), n)) : handler_info) l = stmt.catch_dest - (bbs !== nothing) && (l = first(bbs[l].stmts)) + (bbs !== nothing) && (l != 0) && (l = first(bbs[l].stmts)) push!(handlers, Handler(stmt, pc)) handler_id = length(handlers) handler_at[pc + 1] = (handler_id, 0) @@ -519,7 +519,7 @@ function (::ComputeTryCatch{Handler})(code::Vector{Any}, bbs::Union{Vector{Basic break elseif isa(stmt, EnterNode) l = stmt.catch_dest - (bbs !== nothing) && (l = first(bbs[l].stmts)) + (bbs !== nothing) && (l != 0) && (l = first(bbs[l].stmts)) # We assigned a handler number above. Here we just merge that # with out current handler information. if l != 0 diff --git a/Compiler/test/irpasses.jl b/Compiler/test/irpasses.jl index 90d8c9dc6ab3d..27b6d75f86c93 100644 --- a/Compiler/test/irpasses.jl +++ b/Compiler/test/irpasses.jl @@ -1716,6 +1716,12 @@ end @test scope_folding_opt() == 1 @test_broken fully_eliminated(scope_folding) @test_broken fully_eliminated(scope_folding_opt) +let ir = first(only(Base.code_ircode(scope_folding, ()))) + @test Compiler.compute_trycatch(ir) isa Compiler.HandlerInfo +end +let ir = first(only(Base.code_ircode(scope_folding_opt, ()))) + @test Compiler.compute_trycatch(ir) isa Compiler.HandlerInfo +end # Function that happened to have lots of sroa that # happened to trigger a bad case in the renamer. We From e47670de3e2ed17e71535d9263c85939a8c6f87e Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 17 Dec 2024 23:16:13 +0900 Subject: [PATCH 061/198] EA: general cleanup (#56848) The handling of `Array` in EA was implemented before `Memory` was introduced and has now become stale. Analysis for `Array` should be reintroduced after the upcoming overhaul is completed. For now, I will remove the existing stale code. --- Compiler/src/ssair/EscapeAnalysis.jl | 292 +++---------- Compiler/src/ssair/disjoint_set.jl | 8 +- Compiler/test/EscapeAnalysis.jl | 617 +-------------------------- 3 files changed, 63 insertions(+), 854 deletions(-) diff --git a/Compiler/src/ssair/EscapeAnalysis.jl b/Compiler/src/ssair/EscapeAnalysis.jl index 4f32550d056b2..68a7aef1cbba4 100644 --- a/Compiler/src/ssair/EscapeAnalysis.jl +++ b/Compiler/src/ssair/EscapeAnalysis.jl @@ -13,22 +13,21 @@ export using Base: Base # imports -import Base: ==, getindex, setindex! +import Base: ==, copy, getindex, setindex! # usings -using Core: MethodMatch, SimpleVector, ifelse, sizeof +using Core: Builtin, IntrinsicFunction, SimpleVector, ifelse, sizeof using Core.IR using Base: # Base definitions @__MODULE__, @assert, @eval, @goto, @inbounds, @inline, @label, @noinline, - @nospecialize, @specialize, BitSet, Callable, Csize_t, IdDict, IdSet, UnitRange, Vector, - copy, delete!, empty!, enumerate, error, first, get, get!, haskey, in, isassigned, - isempty, ismutabletype, keys, last, length, max, min, missing, pop!, push!, pushfirst!, - unwrap_unionall, !, !=, !==, &, *, +, -, :, <, <<, =>, >, |, ∈, ∉, ∩, ∪, ≠, ≤, ≥, ⊆, - hasintersect + @nospecialize, @specialize, BitSet, IdDict, IdSet, UnitRange, Vector, + delete!, empty!, enumerate, first, get, get!, hasintersect, haskey, isassigned, + isempty, length, max, min, missing, println, push!, pushfirst!, + !, !==, &, *, +, -, :, <, <<, >, |, ∈, ∉, ∩, ∪, ≠, ≤, ≥, ⊆ using ..Compiler: # Compiler specific definitions - AbstractLattice, Bottom, IRCode, IR_FLAG_NOTHROW, InferenceResult, SimpleInferenceLattice, - argextype, fieldcount_noerror, hasintersect, has_flag, intrinsic_nothrow, - is_meta_expr_head, is_identity_free_argtype, isexpr, println, setfield!_nothrow, - singleton_type, try_compute_field, try_compute_fieldidx, widenconst, ⊑, Compiler + AbstractLattice, Compiler, IRCode, IR_FLAG_NOTHROW, + argextype, fieldcount_noerror, has_flag, intrinsic_nothrow, is_meta_expr_head, + is_identity_free_argtype, isexpr, setfield!_nothrow, singleton_type, try_compute_field, + try_compute_fieldidx, widenconst function include(x::String) if !isdefined(Base, :end_base_include) @@ -53,14 +52,13 @@ A lattice for escape information, which holds the following properties: * `pc ∈ x.ThrownEscape`: `x` may be thrown at the SSA statement at `pc` * `-1 ∈ x.ThrownEscape`: `x` may be thrown at arbitrary points of this call frame (the top) This information will be used by `escape_exception!` to propagate potential escapes via exception. -- `x.AliasInfo::Union{Bool,IndexableFields,IndexableElements,Unindexable}`: maintains all possible values +- `x.AliasInfo::Union{Bool,IndexableFields,Unindexable}`: maintains all possible values that can be aliased to fields or array elements of `x`: * `x.AliasInfo === false` indicates the fields/elements of `x` aren't analyzed yet * `x.AliasInfo === true` indicates the fields/elements of `x` can't be analyzed, e.g. the type of `x` is not known or is not concrete and thus its fields/elements can't be known precisely * `x.AliasInfo::IndexableFields` records all the possible values that can be aliased to fields of object `x` with precise index information - * `x.AliasInfo::IndexableElements` records all the possible values that can be aliased to elements of array `x` with precise index information * `x.AliasInfo::Unindexable` records all the possible values that can be aliased to fields/elements of `x` without precise index information - `x.Liveness::BitSet`: records SSA statement numbers where `x` should be live, e.g. to be used as a call argument, to be returned to a caller, or preserved for `:foreigncall`: @@ -87,14 +85,14 @@ struct EscapeInfo Analyzed::Bool ReturnEscape::Bool ThrownEscape::BitSet - AliasInfo #::Union{IndexableFields,IndexableElements,Unindexable,Bool} + AliasInfo #::Union{IndexableFields,Unindexable,Bool} Liveness::BitSet function EscapeInfo( Analyzed::Bool, ReturnEscape::Bool, ThrownEscape::BitSet, - AliasInfo#=::Union{IndexableFields,IndexableElements,Unindexable,Bool}=#, + AliasInfo#=::Union{IndexableFields,Unindexable,Bool}=#, Liveness::BitSet) @nospecialize AliasInfo return new( @@ -108,7 +106,7 @@ struct EscapeInfo x::EscapeInfo, # non-concrete fields should be passed as default arguments # in order to avoid allocating non-concrete `NamedTuple`s - AliasInfo#=::Union{IndexableFields,IndexableElements,Unindexable,Bool}=# = x.AliasInfo; + AliasInfo#=::Union{IndexableFields,Unindexable,Bool}=# = x.AliasInfo; Analyzed::Bool = x.Analyzed, ReturnEscape::Bool = x.ReturnEscape, ThrownEscape::BitSet = x.ThrownEscape, @@ -149,11 +147,11 @@ const ⊥, ⊤ = NotAnalyzed(), AllEscape() # Convenience names for some ⊑ₑ queries has_no_escape(x::EscapeInfo) = !x.ReturnEscape && isempty(x.ThrownEscape) && 0 ∉ x.Liveness -has_arg_escape(x::EscapeInfo) = 0 in x.Liveness +has_arg_escape(x::EscapeInfo) = 0 ∈ x.Liveness has_return_escape(x::EscapeInfo) = x.ReturnEscape -has_return_escape(x::EscapeInfo, pc::Int) = x.ReturnEscape && (-1 ∈ x.Liveness || pc in x.Liveness) +has_return_escape(x::EscapeInfo, pc::Int) = x.ReturnEscape && (-1 ∈ x.Liveness || pc ∈ x.Liveness) has_thrown_escape(x::EscapeInfo) = !isempty(x.ThrownEscape) -has_thrown_escape(x::EscapeInfo, pc::Int) = -1 ∈ x.ThrownEscape || pc in x.ThrownEscape +has_thrown_escape(x::EscapeInfo, pc::Int) = -1 ∈ x.ThrownEscape || pc ∈ x.ThrownEscape has_all_escape(x::EscapeInfo) = ⊤ ⊑ₑ x # utility lattice constructors @@ -166,14 +164,13 @@ ignore_liveness(x::EscapeInfo) = EscapeInfo(x; Liveness=BOT_LIVENESS) struct IndexableFields infos::Vector{AInfo} end -struct IndexableElements - infos::IdDict{Int,AInfo} -end struct Unindexable info::AInfo end IndexableFields(nflds::Int) = IndexableFields(AInfo[AInfo() for _ in 1:nflds]) Unindexable() = Unindexable(AInfo()) +copy(AliasInfo::IndexableFields) = IndexableFields(AInfo[copy(info) for info in AliasInfo.infos]) +copy(AliasInfo::Unindexable) = Unindexable(copy(AliasInfo.info)) merge_to_unindexable(AliasInfo::IndexableFields) = Unindexable(merge_to_unindexable(AliasInfo.infos)) merge_to_unindexable(AliasInfo::Unindexable, AliasInfos::IndexableFields) = Unindexable(merge_to_unindexable(AliasInfo.info, AliasInfos.infos)) @@ -184,15 +181,6 @@ function merge_to_unindexable(info::AInfo, infos::Vector{AInfo}) end return info end -merge_to_unindexable(AliasInfo::IndexableElements) = Unindexable(merge_to_unindexable(AliasInfo.infos)) -merge_to_unindexable(AliasInfo::Unindexable, AliasInfos::IndexableElements) = Unindexable(merge_to_unindexable(AliasInfo.info, AliasInfos.infos)) -merge_to_unindexable(infos::IdDict{Int,AInfo}) = merge_to_unindexable(AInfo(), infos) -function merge_to_unindexable(info::AInfo, infos::IdDict{Int,AInfo}) - for idx in keys(infos) - info = info ∪ infos[idx] - end - return info -end # we need to make sure this `==` operator corresponds to lattice equality rather than object equality, # otherwise `propagate_changes` can't detect the convergence @@ -215,9 +203,6 @@ x::EscapeInfo == y::EscapeInfo = begin elseif isa(xa, IndexableFields) isa(ya, IndexableFields) || return false xa.infos == ya.infos || return false - elseif isa(xa, IndexableElements) - isa(ya, IndexableElements) || return false - xa.infos == ya.infos || return false else xa = xa::Unindexable isa(ya, Unindexable) || return false @@ -269,8 +254,6 @@ x::EscapeInfo ⊑ₑ y::EscapeInfo = begin for i in 1:xn xinfos[i] ⊆ yinfos[i] || return false end - elseif isa(ya, IndexableElements) - return false elseif isa(ya, Unindexable) xinfos, yinfo = xa.infos, ya.info for i = length(xinfos) @@ -279,23 +262,6 @@ x::EscapeInfo ⊑ₑ y::EscapeInfo = begin else ya === true || return false end - elseif isa(xa, IndexableElements) - if isa(ya, IndexableElements) - xinfos, yinfos = xa.infos, ya.infos - keys(xinfos) ⊆ keys(yinfos) || return false - for idx in keys(xinfos) - xinfos[idx] ⊆ yinfos[idx] || return false - end - elseif isa(ya, IndexableFields) - return false - elseif isa(ya, Unindexable) - xinfos, yinfo = xa.infos, ya.info - for idx in keys(xinfos) - xinfos[idx] ⊆ yinfo || return false - end - else - ya === true || return false - end else xa = xa::Unindexable if isa(ya, Unindexable) @@ -401,33 +367,10 @@ function merge_alias_info(@nospecialize(xa), @nospecialize(ya)) else return true # handle conflicting case conservatively end - elseif isa(xa, IndexableElements) - if isa(ya, IndexableElements) - xinfos, yinfos = xa.infos, ya.infos - infos = IdDict{Int,AInfo}() - for idx in keys(xinfos) - if !haskey(yinfos, idx) - infos[idx] = xinfos[idx] - else - infos[idx] = xinfos[idx] ∪ yinfos[idx] - end - end - for idx in keys(yinfos) - haskey(xinfos, idx) && continue # unioned already - infos[idx] = yinfos[idx] - end - return IndexableElements(infos) - elseif isa(ya, Unindexable) - return merge_to_unindexable(ya, xa) - else - return true # handle conflicting case conservatively - end else xa = xa::Unindexable if isa(ya, IndexableFields) return merge_to_unindexable(xa, ya) - elseif isa(ya, IndexableElements) - return merge_to_unindexable(xa, ya) else ya = ya::Unindexable xinfo, yinfo = xa.info, ya.info @@ -439,8 +382,6 @@ end const AliasSet = IntDisjointSet{Int} -const ArrayInfo = IdDict{Int,Vector{Int}} - """ estate::EscapeState @@ -451,13 +392,12 @@ struct EscapeState escapes::Vector{EscapeInfo} aliasset::AliasSet nargs::Int - arrayinfo::Union{Nothing,ArrayInfo} end -function EscapeState(nargs::Int, nstmts::Int, arrayinfo::Union{Nothing,ArrayInfo}) +function EscapeState(nargs::Int, nstmts::Int) escapes = EscapeInfo[ 1 ≤ i ≤ nargs ? ArgEscape() : ⊥ for i in 1:(nargs+nstmts)] aliasset = AliasSet(nargs+nstmts) - return EscapeState(escapes, aliasset, nargs, arrayinfo) + return EscapeState(escapes, aliasset, nargs) end function getindex(estate::EscapeState, @nospecialize(x)) xidx = iridx(x, estate) @@ -503,8 +443,7 @@ that is analyzable in the context of `estate`. `iridx(irval(xidx, state), state) === xidx`. """ function irval(xidx::Int, estate::EscapeState) - x = xidx > estate.nargs ? SSAValue(xidx-estate.nargs) : Argument(xidx) - return x + return xidx > estate.nargs ? SSAValue(xidx-estate.nargs) : Argument(xidx) end function getaliases(x::Union{Argument,SSAValue}, estate::EscapeState) @@ -621,8 +560,8 @@ function analyze_escapes(ir::IRCode, nargs::Int, 𝕃ₒ::AbstractLattice, get_e stmts = ir.stmts nstmts = length(stmts) + length(ir.new_nodes.stmts) - tryregions, arrayinfo = compute_frameinfo(ir) - estate = EscapeState(nargs, nstmts, arrayinfo) + tryregions = compute_frameinfo(ir) + estate = EscapeState(nargs, nstmts) changes = Changes() # keeps changes that happen at current statement astate = AnalysisState(ir, estate, changes, 𝕃ₒ, get_escape_cache) @@ -712,21 +651,15 @@ function analyze_escapes(ir::IRCode, nargs::Int, 𝕃ₒ::AbstractLattice, get_e end """ - compute_frameinfo(ir::IRCode) -> (tryregions, arrayinfo) - -A preparatory linear scan before the escape analysis on `ir` to find: -- `tryregions::Union{Nothing,Vector{UnitRange{Int}}}`: regions in which potential `throw`s can be caught (used by `escape_exception!`) -- `arrayinfo::Union{Nothing,IdDict{Int,Vector{Int}}}`: array allocations whose dimensions are known precisely (with some very simple local analysis) + compute_frameinfo(ir::IRCode) -> tryregions -!!! note - This array dimension analysis to compute `arrayinfo` is very local and doesn't account - for flow-sensitivity nor complex aliasing. - Ideally this dimension analysis should be done as a part of type inference that - propagates array dimensions in a flow sensitive way. +A preparatory linear scan before the escape analysis on `ir` to find +`tryregions::Union{Nothing,Vector{UnitRange{Int}}}`, that represent regions in which +potential `throw`s can be caught (used by `escape_exception!`) """ function compute_frameinfo(ir::IRCode) nstmts, nnewnodes = length(ir.stmts), length(ir.new_nodes.stmts) - tryregions, arrayinfo = nothing, nothing + tryregions = nothing for idx in 1:nstmts+nnewnodes inst = ir[SSAValue(idx)] stmt = inst[:stmt] @@ -738,41 +671,9 @@ function compute_frameinfo(ir::IRCode) leave_pc = first(ir.cfg.blocks[leave_block].stmts) push!(tryregions, idx:leave_pc) end - elseif arrayinfo !== nothing - # TODO this super limited alias analysis is able to handle only very simple cases - # this should be replaced with a proper forward dimension analysis - if isa(stmt, PhiNode) - values = stmt.values - local dims = nothing - for i = 1:length(values) - if isassigned(values, i) - val = values[i] - if isa(val, SSAValue) && haskey(arrayinfo, val.id) - if dims === nothing - dims = arrayinfo[val.id] - continue - elseif dims == arrayinfo[val.id] - continue - end - end - end - @goto next_stmt - end - if dims !== nothing - arrayinfo[idx] = dims - end - elseif isa(stmt, PiNode) - if isdefined(stmt, :val) - val = stmt.val - if isa(val, SSAValue) && haskey(arrayinfo, val.id) - arrayinfo[idx] = arrayinfo[val.id] - end - end - end end - @label next_stmt end - return tryregions, arrayinfo + return tryregions end # propagate changes, and check convergence @@ -826,7 +727,7 @@ end info = estate.escapes[xidx] Liveness = info.Liveness Liveness === TOP_LIVENESS && return false - livepc in Liveness && return false + livepc ∈ Liveness && return false if Liveness === BOT_LIVENESS || Liveness === ARG_LIVENESS # if this Liveness is a constant, we shouldn't modify it and propagate this change as a new EscapeInfo Liveness = copy(Liveness) @@ -976,19 +877,6 @@ end is_nothrow(ir::IRCode, pc::Int) = has_flag(ir[SSAValue(pc)], IR_FLAG_NOTHROW) -# NOTE if we don't maintain the alias set that is separated from the lattice state, we can do -# something like below: it essentially incorporates forward escape propagation in our default -# backward propagation, and leads to inefficient convergence that requires more iterations -# # lhs = rhs: propagate escape information of `rhs` to `lhs` -# function escape_alias!(astate::AnalysisState, @nospecialize(lhs), @nospecialize(rhs)) -# if isa(rhs, SSAValue) || isa(rhs, Argument) -# vinfo = astate.estate[rhs] -# else -# return -# end -# add_escape_change!(astate, lhs, vinfo) -# end - """ escape_exception!(astate::AnalysisState, tryregions::Vector{UnitRange{Int}}) @@ -1044,7 +932,7 @@ function escape_exception!(astate::AnalysisState, tryregions::Vector{UnitRange{I xt === TOP_THROWN_ESCAPE && @goto propagate_exception_escape # fast pass for pc in xt for region in tryregions - pc in region && @goto propagate_exception_escape # early break because of AllEscape + pc ∈ region && @goto propagate_exception_escape # early break because of AllEscape end end continue @@ -1143,12 +1031,6 @@ function escape_foreigncall!(astate::AnalysisState, pc::Int, args::Vector{Any}) argtypes = args[3]::SimpleVector nargs = length(argtypes) name = args[1] - nn = normalize(name) - if isa(nn, Symbol) - # if nn === :jl_gc_add_finalizer_th - # # TODO add `FinalizerEscape` ? - # end - end # NOTE array allocations might have been proven as nothrow (https://github.com/JuliaLang/julia/pull/43565) nothrow = is_nothrow(astate.ir, pc) name_info = nothrow ? ⊥ : ThrownEscape(pc) @@ -1183,37 +1065,31 @@ function escape_gc_preserve!(astate::AnalysisState, pc::Int, args::Vector{Any}) add_liveness_changes!(astate, pc, beginargs) end -normalize(@nospecialize x) = isa(x, QuoteNode) ? x.value : x - function escape_call!(astate::AnalysisState, pc::Int, args::Vector{Any}) - ir = astate.ir - ft = argextype(first(args), ir, ir.sptypes, ir.argtypes) + ft = argextype(first(args), astate.ir) f = singleton_type(ft) - if isa(f, Core.IntrinsicFunction) - # XXX somehow `:call` expression can creep in here, ideally we should be able to do: - # argtypes = Any[argextype(args[i], astate.ir) for i = 2:length(args)] - argtypes = Any[] - for i = 2:length(args) - arg = args[i] - push!(argtypes, isexpr(arg, :call) ? Any : argextype(arg, ir)) + if f isa IntrinsicFunction + if is_nothrow(astate.ir, pc) + add_liveness_changes!(astate, pc, args, 2) + else + add_fallback_changes!(astate, pc, args, 2) end - if intrinsic_nothrow(f, argtypes) + # TODO needs to account for pointer operations? + elseif f isa Builtin + result = escape_builtin!(f, astate, pc, args) + if result === missing + # if this call hasn't been handled by any of pre-defined handlers, escape it conservatively + add_conservative_changes!(astate, pc, args) + elseif result === true + add_liveness_changes!(astate, pc, args, 2) + elseif is_nothrow(astate.ir, pc) add_liveness_changes!(astate, pc, args, 2) else add_fallback_changes!(astate, pc, args, 2) end - return # TODO accounts for pointer operations? - end - result = escape_builtin!(f, astate, pc, args) - if result === missing - # if this call hasn't been handled by any of pre-defined handlers, escape it conservatively - add_conservative_changes!(astate, pc, args) - elseif result === true - add_liveness_changes!(astate, pc, args, 2) - elseif is_nothrow(astate.ir, pc) - add_liveness_changes!(astate, pc, args, 2) else - add_fallback_changes!(astate, pc, args, 2) + # escape this generic function or unknown function call conservatively + add_conservative_changes!(astate, pc, args) end end @@ -1274,6 +1150,7 @@ function escape_new!(astate::AnalysisState, pc::Int, args::Vector{Any}) @goto escape_indexable_def end elseif isa(AliasInfo, IndexableFields) + AliasInfo = copy(AliasInfo) @label escape_indexable_def # fields are known precisely: propagate escape information imposed on recorded possibilities to the exact field values infos = AliasInfo.infos @@ -1290,6 +1167,7 @@ function escape_new!(astate::AnalysisState, pc::Int, args::Vector{Any}) end add_escape_change!(astate, obj, EscapeInfo(objinfo, AliasInfo)) # update with new AliasInfo elseif isa(AliasInfo, Unindexable) + AliasInfo = copy(AliasInfo) @label escape_unindexable_def # fields are known partially: propagate escape information imposed on recorded possibilities to all fields values info = AliasInfo.info @@ -1343,7 +1221,7 @@ function analyze_fields(ir::IRCode, @nospecialize(typ), @nospecialize(fld)) return IndexableFields(nflds), fidx end -function reanalyze_fields(ir::IRCode, AliasInfo::IndexableFields, @nospecialize(typ), @nospecialize(fld)) +function reanalyze_fields(AliasInfo::IndexableFields, ir::IRCode, @nospecialize(typ), @nospecialize(fld)) nflds = fieldcount_noerror(typ) if nflds === nothing return merge_to_unindexable(AliasInfo), 0 @@ -1357,6 +1235,7 @@ function reanalyze_fields(ir::IRCode, AliasInfo::IndexableFields, @nospecialize( if fidx === nothing return merge_to_unindexable(AliasInfo), 0 end + AliasInfo = copy(AliasInfo) infos = AliasInfo.infos ninfos = length(infos) if nflds > ninfos @@ -1393,12 +1272,13 @@ function escape_builtin!(::typeof(getfield), astate::AnalysisState, pc::Int, arg @goto record_unindexable_use end elseif isa(AliasInfo, IndexableFields) - AliasInfo, fidx = reanalyze_fields(ir, AliasInfo, typ, args[3]) + AliasInfo, fidx = reanalyze_fields(AliasInfo, ir, typ, args[3]) isa(AliasInfo, Unindexable) && @goto record_unindexable_use @label record_indexable_use push!(AliasInfo.infos[fidx], LocalUse(pc)) add_escape_change!(astate, obj, EscapeInfo(objinfo, AliasInfo)) # update with new AliasInfo elseif isa(AliasInfo, Unindexable) + AliasInfo = copy(AliasInfo) @label record_unindexable_use push!(AliasInfo.info, LocalUse(pc)) add_escape_change!(astate, obj, EscapeInfo(objinfo, AliasInfo)) # update with new AliasInfo @@ -1439,7 +1319,7 @@ function escape_builtin!(::typeof(setfield!), astate::AnalysisState, pc::Int, ar end elseif isa(AliasInfo, IndexableFields) typ = widenconst(argextype(obj, ir)) - AliasInfo, fidx = reanalyze_fields(ir, AliasInfo, typ, args[3]) + AliasInfo, fidx = reanalyze_fields(AliasInfo, ir, typ, args[3]) isa(AliasInfo, Unindexable) && @goto escape_unindexable_def @label escape_indexable_def add_alias_escapes!(astate, val, AliasInfo.infos[fidx]) @@ -1449,7 +1329,7 @@ function escape_builtin!(::typeof(setfield!), astate::AnalysisState, pc::Int, ar # propagate the escape information of this object ignoring field information add_escape_change!(astate, val, ignore_aliasinfo(objinfo)) elseif isa(AliasInfo, Unindexable) - info = AliasInfo.info + AliasInfo = copy(AliasInfo) @label escape_unindexable_def add_alias_escapes!(astate, val, AliasInfo.info) push!(AliasInfo.info, LocalDef(pc)) @@ -1483,64 +1363,6 @@ function escape_builtin!(::typeof(setfield!), astate::AnalysisState, pc::Int, ar end end -# NOTE this function models and thus should be synced with the implementation of: -# size_t array_nd_index(jl_array_t *a, jl_value_t **args, size_t nidxs, ...) -function array_nd_index(astate::AnalysisState, @nospecialize(ary), args::Vector{Any}, nidxs::Int = length(args)) - isa(ary, SSAValue) || return nothing - aryid = ary.id - arrayinfo = astate.estate.arrayinfo - isa(arrayinfo, ArrayInfo) || return nothing - haskey(arrayinfo, aryid) || return nothing - dims = arrayinfo[aryid] - local i = 0 - local k, stride = 0, 1 - local nd = length(dims) - while k < nidxs - arg = args[k+1] - argval = argextype(arg, astate.ir) - isa(argval, Const) || return nothing - argval = argval.val - isa(argval, Int) || return nothing - ii = argval - 1 - i += ii * stride - d = k ≥ nd ? 1 : dims[k+1] - k < nidxs - 1 && ii ≥ d && return nothing # BoundsError - stride *= d - k += 1 - end - while k < nd - stride *= dims[k+1] - k += 1 - end - i ≥ stride && return nothing # BoundsError - return i -end - -function mark_unindexable!(astate::AnalysisState, @nospecialize(ary)) - isa(ary, SSAValue) || return - aryinfo = astate.estate[ary] - AliasInfo = aryinfo.AliasInfo - isa(AliasInfo, IndexableElements) || return - AliasInfo = merge_to_unindexable(AliasInfo) - add_escape_change!(astate, ary, EscapeInfo(aryinfo, AliasInfo)) -end - -# FIXME this implementation is very conservative, improve the accuracy and solve broken test cases -function escape_array_copy!(astate::AnalysisState, pc::Int, args::Vector{Any}) - length(args) ≥ 6 || return add_fallback_changes!(astate, pc, args) - ary = args[6] - aryt = argextype(ary, astate.ir) - aryt ⊑ Array || return add_fallback_changes!(astate, pc, args) - if isa(ary, SSAValue) || isa(ary, Argument) - newary = SSAValue(pc) - aryinfo = astate.estate[ary] - newaryinfo = astate.estate[newary] - add_escape_change!(astate, newary, aryinfo) - add_escape_change!(astate, ary, newaryinfo) - end - add_liveness_changes!(astate, pc, args, 6) -end - function escape_builtin!(::typeof(Core.finalizer), astate::AnalysisState, pc::Int, args::Vector{Any}) if length(args) ≥ 3 obj = args[3] diff --git a/Compiler/src/ssair/disjoint_set.jl b/Compiler/src/ssair/disjoint_set.jl index 3f64fe643bd17..e000d7e8a582f 100644 --- a/Compiler/src/ssair/disjoint_set.jl +++ b/Compiler/src/ssair/disjoint_set.jl @@ -5,7 +5,7 @@ # imports import Base: length, eltype, union!, push! # usings -import Base: OneTo, collect, zero, zeros, one, typemax +using Base: OneTo, collect, zero, zeros, one, typemax # Disjoint-Set @@ -55,7 +55,7 @@ eltype(::Type{IntDisjointSet{T}}) where {T<:Integer} = T # path compression is implemented here function find_root_impl!(parents::Vector{T}, x::Integer) where {T<:Integer} p = parents[x] - @inbounds if parents[p] != p + @inbounds if parents[p] ≠ p parents[x] = p = _find_root_impl!(parents, p) end return p @@ -64,7 +64,7 @@ end # unsafe version of the above function _find_root_impl!(parents::Vector{T}, x::Integer) where {T<:Integer} @inbounds p = parents[x] - @inbounds if parents[p] != p + @inbounds if parents[p] ≠ p parents[x] = p = _find_root_impl!(parents, p) end return p @@ -95,7 +95,7 @@ function union!(s::IntDisjointSet{T}, x::T, y::T) where {T<:Integer} parents = s.parents xroot = find_root_impl!(parents, x) yroot = find_root_impl!(parents, y) - return xroot != yroot ? root_union!(s, xroot, yroot) : xroot + return xroot ≠ yroot ? root_union!(s, xroot, yroot) : xroot end """ diff --git a/Compiler/test/EscapeAnalysis.jl b/Compiler/test/EscapeAnalysis.jl index 1831bd355cd48..e1638e74e61fe 100644 --- a/Compiler/test/EscapeAnalysis.jl +++ b/Compiler/test/EscapeAnalysis.jl @@ -34,24 +34,9 @@ let utils_ex = quote Core.eval(@__MODULE__, utils_ex) end -using .EscapeAnalysis: - EscapeInfo, IndexableElements, IndexableFields, normalize +using .EscapeAnalysis: EscapeInfo, IndexableFields isϕ(@nospecialize x) = isa(x, Core.PhiNode) -function with_normalized_name(@nospecialize(f), @nospecialize(x)) - if Meta.isexpr(x, :foreigncall) - name = x.args[1] - nn = normalize(name) - return isa(nn, Symbol) && f(nn) - end - return false -end -isarrayalloc(@nospecialize x) = - with_normalized_name(nn::Symbol->false, x) -isarrayresize(@nospecialize x) = - with_normalized_name(nn::Symbol->false, x) -isarraycopy(@nospecialize x) = - with_normalized_name(nn::Symbol->false, x) """ is_load_forwardable(x::EscapeInfo) -> Bool @@ -61,7 +46,7 @@ function is_load_forwardable(x::EscapeInfo) AliasInfo = x.AliasInfo # NOTE technically we also need to check `!has_thrown_escape(x)` here as well, # but we can also do equivalent check during forwarding - return isa(AliasInfo, IndexableFields) || isa(AliasInfo, IndexableElements) + return isa(AliasInfo, IndexableFields) end @testset "EAUtils" begin @@ -1501,585 +1486,6 @@ let result = @code_escapes compute!(MPoint(1+.5im, 2+.5im), MPoint(2+.25im, 4+.7 end end -@testset "array primitives" begin - # arrayref - @test_skip let result = code_escapes((Vector{String},Int)) do xs, i - s = Base.arrayref(true, xs, i) - return s - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[Argument(2)], r) # xs - @test has_thrown_escape(result.state[Argument(2)]) # xs - @test !has_return_escape(result.state[Argument(3)], r) # i - end - @test_skip let result = code_escapes((Vector{String},Int)) do xs, i - s = Base.arrayref(false, xs, i) - return s - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[Argument(2)], r) # xs - @test !has_thrown_escape(result.state[Argument(2)]) # xs - @test !has_return_escape(result.state[Argument(3)], r) # i - end - @test_skip let result = code_escapes((Vector{String},Bool)) do xs, i - c = Base.arrayref(true, xs, i) # TypeError will happen here - return c - end - t = only(findall(iscall((result.ir, Base.arrayref)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - end - @test_skip let result = code_escapes((String,Int)) do xs, i - c = Base.arrayref(true, xs, i) # TypeError will happen here - return c - end - t = only(findall(iscall((result.ir, Base.arrayref)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - end - @test_skip let result = code_escapes((AbstractVector{String},Int)) do xs, i - c = Base.arrayref(true, xs, i) # TypeError may happen here - return c - end - t = only(findall(iscall((result.ir, Base.arrayref)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - end - @test_skip let result = code_escapes((Vector{String},Any)) do xs, i - c = Base.arrayref(true, xs, i) # TypeError may happen here - return c - end - t = only(findall(iscall((result.ir, Base.arrayref)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - end - - # arrayset - @test_skip let result = code_escapes((Vector{String},String,Int,)) do xs, x, i - Base.arrayset(true, xs, x, i) - return xs - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[Argument(2)], r) # xs - @test has_thrown_escape(result.state[Argument(2)]) # xs - @test has_return_escape(result.state[Argument(3)], r) # x - end - @test_skip let result = code_escapes((Vector{String},String,Int,)) do xs, x, i - Base.arrayset(false, xs, x, i) - return xs - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[Argument(2)], r) # xs - @test !has_thrown_escape(result.state[Argument(2)]) # xs - @test has_return_escape(result.state[Argument(3)], r) # x - end - @test_skip let result = code_escapes((String,String,String,)) do s, t, u - xs = Vector{String}(undef, 3) - Base.arrayset(true, xs, s, 1) - Base.arrayset(true, xs, t, 2) - Base.arrayset(true, xs, u, 3) - return xs - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) - for i in 2:result.state.nargs - @test has_return_escape(result.state[Argument(i)], r) - end - end - @test_skip let result = code_escapes((Vector{String},String,Bool,)) do xs, x, i - Base.arrayset(true, xs, x, i) # TypeError will happen here - return xs - end - t = only(findall(iscall((result.ir, Base.arrayset)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - @test has_thrown_escape(result.state[Argument(3)], t) # x - end - @test_skip let result = code_escapes((String,String,Int,)) do xs, x, i - Base.arrayset(true, xs, x, i) # TypeError will happen here - return xs - end - t = only(findall(iscall((result.ir, Base.arrayset)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs::String - @test has_thrown_escape(result.state[Argument(3)], t) # x::String - end - @test_skip let result = code_escapes((AbstractVector{String},String,Int,)) do xs, x, i - Base.arrayset(true, xs, x, i) # TypeError may happen here - return xs - end - t = only(findall(iscall((result.ir, Base.arrayset)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - @test has_thrown_escape(result.state[Argument(3)], t) # x - end - @test_skip let result = code_escapes((Vector{String},AbstractString,Int,)) do xs, x, i - Base.arrayset(true, xs, x, i) # TypeError may happen here - return xs - end - t = only(findall(iscall((result.ir, Base.arrayset)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - @test has_thrown_escape(result.state[Argument(3)], t) # x - end - - # arrayref and arrayset - @test_skip let result = code_escapes() do - a = Vector{Vector{Any}}(undef, 1) - b = Any[] - a[1] = b - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - ai = only(findall(result.ir.stmts.stmt) do @nospecialize x - isarrayalloc(x) && x.args[2] === Vector{Vector{Any}} - end) - bi = only(findall(result.ir.stmts.stmt) do @nospecialize x - isarrayalloc(x) && x.args[2] === Vector{Any} - end) - @test !has_return_escape(result.state[SSAValue(ai)], r) - @test has_return_escape(result.state[SSAValue(bi)], r) - end - @test_skip let result = code_escapes() do - a = Vector{Vector{Any}}(undef, 1) - b = Any[] - a[1] = b - return a - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - ai = only(findall(result.ir.stmts.stmt) do @nospecialize x - isarrayalloc(x) && x.args[2] === Vector{Vector{Any}} - end) - bi = only(findall(result.ir.stmts.stmt) do @nospecialize x - isarrayalloc(x) && x.args[2] === Vector{Any} - end) - @test has_return_escape(result.state[SSAValue(ai)], r) - @test has_return_escape(result.state[SSAValue(bi)], r) - end - @test_skip let result = code_escapes((Vector{Any},String,Int,Int)) do xs, s, i, j - x = SafeRef(s) - xs[i] = x - xs[j] # potential error - end - i = only(findall(isnew, result.ir.stmts.stmt)) - t = only(findall(iscall((result.ir, Base.arrayref)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(3)], t) # s - @test has_thrown_escape(result.state[SSAValue(i)], t) # x - end - - # arraysize - @test_skip let result = code_escapes((Vector{Any},)) do xs - Core.arraysize(xs, 1) - end - t = only(findall(iscall((result.ir, Core.arraysize)), result.ir.stmts.stmt)) - @test !has_thrown_escape(result.state[Argument(2)], t) - end - @test_skip let result = code_escapes((Vector{Any},Int,)) do xs, dim - Core.arraysize(xs, dim) - end - t = only(findall(iscall((result.ir, Core.arraysize)), result.ir.stmts.stmt)) - @test !has_thrown_escape(result.state[Argument(2)], t) - end - @test_skip let result = code_escapes((Any,)) do xs - Core.arraysize(xs, 1) - end - t = only(findall(iscall((result.ir, Core.arraysize)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) - end - - # arraylen - @test_skip let result = code_escapes((Vector{Any},)) do xs - Base.arraylen(xs) - end - t = only(findall(iscall((result.ir, Base.arraylen)), result.ir.stmts.stmt)) - @test !has_thrown_escape(result.state[Argument(2)], t) # xs - end - @test_skip let result = code_escapes((String,)) do xs - Base.arraylen(xs) - end - t = only(findall(iscall((result.ir, Base.arraylen)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - end - @test_skip let result = code_escapes((Vector{Any},)) do xs - Base.arraylen(xs, 1) - end - t = only(findall(iscall((result.ir, Base.arraylen)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - end - - # array resizing - # without BoundsErrors - @test_skip let result = code_escapes((Vector{Any},String)) do xs, x - @ccall jl_array_grow_beg(xs::Any, 2::UInt)::Cvoid - xs[1] = x - xs - end - t = only(findall(isarrayresize, result.ir.stmts.stmt)) - @test !has_thrown_escape(result.state[Argument(2)], t) # xs - @test !has_thrown_escape(result.state[Argument(3)], t) # x - end - @test_skip let result = code_escapes((Vector{Any},String)) do xs, x - @ccall jl_array_grow_end(xs::Any, 2::UInt)::Cvoid - xs[1] = x - xs - end - t = only(findall(isarrayresize, result.ir.stmts.stmt)) - @test !has_thrown_escape(result.state[Argument(2)], t) # xs - @test !has_thrown_escape(result.state[Argument(3)], t) # x - end - # with possible BoundsErrors - @test_skip let result = code_escapes((String,)) do x - xs = Any[1,2,3] - xs[3] = x - @ccall jl_array_del_beg(xs::Any, 2::UInt)::Cvoid # can potentially throw - xs - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - t = only(findall(isarrayresize, result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[SSAValue(i)], t) # xs - @test has_thrown_escape(result.state[Argument(2)], t) # x - end - @test_skip let result = code_escapes((String,)) do x - xs = Any[1,2,3] - xs[1] = x - @ccall jl_array_del_end(xs::Any, 2::UInt)::Cvoid # can potentially throw - xs - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - t = only(findall(isarrayresize, result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[SSAValue(i)], t) # xs - @test has_thrown_escape(result.state[Argument(2)], t) # x - end - @test_skip let result = code_escapes((String,)) do x - xs = Any[x] - @ccall jl_array_grow_at(xs::Any, 1::UInt, 2::UInt)::Cvoid # can potentially throw - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - t = only(findall(isarrayresize, result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[SSAValue(i)], t) # xs - @test has_thrown_escape(result.state[Argument(2)], t) # x - end - @test_skip let result = code_escapes((String,)) do x - xs = Any[x] - @ccall jl_array_del_at(xs::Any, 1::UInt, 2::UInt)::Cvoid # can potentially throw - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - t = only(findall(isarrayresize, result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[SSAValue(i)], t) # xs - @test has_thrown_escape(result.state[Argument(2)], t) # x - end - - # array copy - @test_skip let result = code_escapes((Vector{Any},)) do xs - return copy(xs) - end - i = only(findall(isarraycopy, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) - @test !has_return_escape(result.state[Argument(2)], r) - end - @test_skip let result = code_escapes((String,)) do s - xs = String[s] - xs′ = copy(xs) - return xs′[1] - end - i1 = only(findall(isarrayalloc, result.ir.stmts.stmt)) - i2 = only(findall(isarraycopy, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i1)]) - @test !has_return_escape(result.state[SSAValue(i2)]) - @test has_return_escape(result.state[Argument(2)], r) # s - end - @test_skip let result = code_escapes((Vector{Any},)) do xs - xs′ = copy(xs) - return xs′[1] # may potentially throw BoundsError, should escape `xs` conservatively (i.e. escape its elements) - end - i = only(findall(isarraycopy, result.ir.stmts.stmt)) - ref = only(findall(iscall((result.ir, Base.arrayref)), result.ir.stmts.stmt)) - ret = only(findall(isreturn, result.ir.stmts.stmt)) - @test_broken !has_thrown_escape(result.state[SSAValue(i)], ref) - @test_broken !has_return_escape(result.state[SSAValue(i)], ret) - @test has_thrown_escape(result.state[Argument(2)], ref) - @test has_return_escape(result.state[Argument(2)], ret) - end - @test_skip let result = code_escapes((String,)) do s - xs = Vector{String}(undef, 1) - xs[1] = s - xs′ = copy(xs) - length(xs′) > 2 && throw(xs′) - return xs′ - end - i1 = only(findall(isarrayalloc, result.ir.stmts.stmt)) - i2 = only(findall(isarraycopy, result.ir.stmts.stmt)) - t = only(findall(iscall((result.ir, throw)), result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test_broken !has_thrown_escape(result.state[SSAValue(i1)], t) - @test_broken !has_return_escape(result.state[SSAValue(i1)], r) - @test has_thrown_escape(result.state[SSAValue(i2)], t) - @test has_return_escape(result.state[SSAValue(i2)], r) - @test has_thrown_escape(result.state[Argument(2)], t) - @test has_return_escape(result.state[Argument(2)], r) - end - - # isassigned - let result = code_escapes((Vector{Any},Int)) do xs, i - return isassigned(xs, i) - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test_broken !has_return_escape(result.state[Argument(2)], r) - @test_broken !has_thrown_escape(result.state[Argument(2)]) - end - - # indexing analysis - # ----------------- - - # safe case - @test_skip let result = code_escapes((String,String)) do s, t - a = Vector{Any}(undef, 2) - a[1] = s - a[2] = t - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test is_load_forwardable(result.state[SSAValue(i)]) - @test has_return_escape(result.state[Argument(2)], r) # s - @test !has_return_escape(result.state[Argument(3)], r) # t - end - @test_skip let result = code_escapes((String,String)) do s, t - a = Matrix{Any}(undef, 1, 2) - a[1, 1] = s - a[1, 2] = t - return a[1, 1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test is_load_forwardable(result.state[SSAValue(i)]) - @test has_return_escape(result.state[Argument(2)], r) # s - @test !has_return_escape(result.state[Argument(3)], r) # t - end - @test_skip let result = code_escapes((Bool,String,String,String)) do c, s, t, u - a = Vector{Any}(undef, 2) - if c - a[1] = s - a[2] = u - else - a[1] = t - a[2] = u - end - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test is_load_forwardable(result.state[SSAValue(i)]) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test has_return_escape(result.state[Argument(3)], r) # s - @test has_return_escape(result.state[Argument(4)], r) # t - @test !has_return_escape(result.state[Argument(5)], r) # u - end - @test_skip let result = code_escapes((Bool,String,String,String)) do c, s, t, u - a = Any[nothing, nothing] # TODO how to deal with loop indexing? - if c - a[1] = s - a[2] = u - else - a[1] = t - a[2] = u - end - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test_broken is_load_forwardable(result.state[SSAValue(i)]) - @test has_return_escape(result.state[Argument(3)], r) # s - @test has_return_escape(result.state[Argument(4)], r) # t - @test_broken !has_return_escape(result.state[Argument(5)], r) # u - end - @test_skip let result = code_escapes((String,)) do s - a = Vector{Vector{Any}}(undef, 1) - b = Any[s] - a[1] = b - return a[1][1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - is = findall(isarrayalloc, result.ir.stmts.stmt) - @assert length(is) == 2 - ia, ib = is - @test !has_return_escape(result.state[SSAValue(ia)], r) - @test is_load_forwardable(result.state[SSAValue(ia)]) - @test !has_return_escape(result.state[SSAValue(ib)], r) - @test_broken is_load_forwardable(result.state[SSAValue(ib)]) - @test has_return_escape(result.state[Argument(2)], r) # s - end - @test_skip let result = code_escapes((Bool,String,String,Regex,Regex,)) do c, s1, s2, t1, t2 - if c - a = Vector{String}(undef, 2) - a[1] = s1 - a[2] = s2 - else - a = Vector{Regex}(undef, 2) - a[1] = t1 - a[2] = t2 - end - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - for i in findall(isarrayalloc, result.ir.stmts.stmt) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test is_load_forwardable(result.state[SSAValue(i)]) - end - @test has_return_escape(result.state[Argument(3)], r) # s1 - @test !has_return_escape(result.state[Argument(4)], r) # s2 - @test has_return_escape(result.state[Argument(5)], r) # t1 - @test !has_return_escape(result.state[Argument(6)], r) # t2 - end - @test_skip let result = code_escapes((String,String,Int)) do s, t, i - a = Any[s] - push!(a, t) - return a[2] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test_broken is_load_forwardable(result.state[SSAValue(i)]) - @test_broken !has_return_escape(result.state[Argument(2)], r) # s - @test has_return_escape(result.state[Argument(3)], r) # t - end - # unsafe cases - @test_skip let result = code_escapes((String,String,Int)) do s, t, i - a = Vector{Any}(undef, 2) - a[1] = s - a[2] = t - return a[i] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test !is_load_forwardable(result.state[SSAValue(i)]) - @test has_return_escape(result.state[Argument(2)], r) # s - @test has_return_escape(result.state[Argument(3)], r) # t - end - @test_skip let result = code_escapes((String,String,Int)) do s, t, i - a = Vector{Any}(undef, 2) - a[1] = s - a[i] = t - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test !is_load_forwardable(result.state[SSAValue(i)]) - @test has_return_escape(result.state[Argument(2)], r) # s - @test has_return_escape(result.state[Argument(3)], r) # t - end - @test_skip let result = code_escapes((String,String,Int,Int,Int)) do s, t, i, j, k - a = Vector{Any}(undef, 2) - a[3] = s # BoundsError - a[1] = t - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test !is_load_forwardable(result.state[SSAValue(i)]) - end - @test_skip let result = @eval Module() begin - @noinline some_resize!(a) = pushfirst!(a, nothing) - $code_escapes((String,String,Int)) do s, t, i - a = Vector{Any}(undef, 2) - a[1] = s - some_resize!(a) - return a[2] - end - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test_broken !has_return_escape(result.state[SSAValue(i)], r) - @test !is_load_forwardable(result.state[SSAValue(i)]) - end - - # circular reference - @test_skip let result = code_escapes() do - xs = Vector{Any}(undef, 1) - xs[1] = xs - return xs[1] - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) - end - @test_skip let result = @eval Module() begin - const Ax = Vector{Any}(undef, 1) - Ax[1] = Ax - $code_escapes() do - xs = Ax[1]::Vector{Any} - return xs[1] - end - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - for i in findall(iscall((result.ir, Core.arrayref)), result.ir.stmts.stmt) - @test has_return_escape(result.state[SSAValue(i)], r) - end - end - let result = @eval Module() begin - @noinline function genxs() - xs = Vector{Any}(undef, 1) - xs[1] = xs - return xs - end - $code_escapes() do - xs = genxs() - return xs[1] - end - end - i = only(findall(isinvoke(:genxs), result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) - end -end - -# demonstrate array primitive support with a realistic end to end example -@test_skip let result = code_escapes((Int,String,)) do n,s - xs = String[] - for i in 1:n - push!(xs, s) - end - xs - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) - @test !has_thrown_escape(result.state[SSAValue(i)]) - @test has_return_escape(result.state[Argument(3)], r) # s - @test !has_thrown_escape(result.state[Argument(3)]) # s -end -@test_skip let result = code_escapes((Int,String,)) do n,s - xs = String[] - for i in 1:n - pushfirst!(xs, s) - end - xs - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) # xs - @test !has_thrown_escape(result.state[SSAValue(i)]) # xs - @test has_return_escape(result.state[Argument(3)], r) # s - @test !has_thrown_escape(result.state[Argument(3)]) # s -end -@test_skip let result = code_escapes((String,String,String)) do s, t, u - xs = String[] - resize!(xs, 3) - xs[1] = s - xs[1] = t - xs[1] = u - xs - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) - @test has_thrown_escape(result.state[SSAValue(i)]) # xs - @test has_return_escape(result.state[Argument(2)], r) # s - @test has_return_escape(result.state[Argument(3)], r) # t - @test has_return_escape(result.state[Argument(4)], r) # u -end - # demonstrate a simple type level analysis can sometimes improve the analysis accuracy # by compensating the lack of yet unimplemented analyses @testset "special-casing bitstype" begin @@ -2111,25 +1517,6 @@ end end end -# # TODO implement a finalizer elision pass -# mutable struct WithFinalizer -# v -# function WithFinalizer(v) -# x = new(v) -# f(t) = @async println("Finalizing $t.") -# return finalizer(x, x) -# end -# end -# make_m(v = 10) = MyMutable(v) -# function simple(cond) -# m = make_m() -# if cond -# # println(m.v) -# return nothing # <= insert `finalize` call here -# end -# return m -# end - # interprocedural analysis # ======================== From 2ed1a411e0a080f3107e75bb65105a15a0533a90 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Tue, 17 Dec 2024 09:57:16 -0500 Subject: [PATCH 062/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?Distributed=20stdlib=20from=206c7cdb5=20to=20c613685=20(#56825)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: Distributed URL: https://github.com/JuliaLang/Distributed.jl Stdlib branch: master Julia branch: master Old commit: 6c7cdb5 New commit: c613685 Julia version: 1.12.0-DEV Distributed version: 1.11.0(Does not match) Bump invoked by: @DilumAluthge Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaLang/Distributed.jl/compare/6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781...c6136853451677f1957bec20ecce13419cde3a12 ``` $ git log --oneline 6c7cdb5..c613685 c613685 Merge pull request #116 from JuliaLang/ci-caching 20e2ce7 Use julia-actions/cache in CI 9c5d73a Merge pull request #112 from JuliaLang/dependabot/github_actions/codecov/codecov-action-5 ed12496 Merge pull request #107 from JamesWrigley/remotechannel-empty 010828a Update .github/workflows/ci.yml 11451a8 Bump codecov/codecov-action from 4 to 5 8b5983b Merge branch 'master' into remotechannel-empty 729ba6a Fix docstring of `@everywhere` (#110) af89e6c Adding better docs to exeflags kwarg (#108) 8537424 Implement Base.isempty(::RemoteChannel) 6a0383b Add a wait(::[Abstract]WorkerPool) (#106) 1cd2677 Bump codecov/codecov-action from 1 to 4 (#96) cde4078 Bump actions/cache from 1 to 4 (#98) 6c8245a Bump julia-actions/setup-julia from 1 to 2 (#97) 1ffaac8 Bump actions/checkout from 2 to 4 (#99) 8e3f849 Fix RemoteChannel iterator interface (#100) f4aaf1b Fix markdown errors in README.md (#95) 2017da9 Merge pull request #103 from JuliaLang/sf/sigquit_instead 07389dd Use `SIGQUIT` instead of `SIGTERM` ``` Co-authored-by: Dilum Aluthge --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/Distributed.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/md5 delete mode 100644 deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/sha512 create mode 100644 deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/md5 create mode 100644 deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/sha512 diff --git a/deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/md5 b/deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/md5 deleted file mode 100644 index 9904464c82b3b..0000000000000 --- a/deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -390521058a478a131ca49d349c9b9383 diff --git a/deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/sha512 b/deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/sha512 deleted file mode 100644 index a7fbe055c2251..0000000000000 --- a/deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -7f0f414d94739a25b7d713c46887e26cd349329828d42297f44928204b36d15ba9163ad6f670aba72ed9229557bb0f35ab4686429975d1f349fe12b1ba2b189f diff --git a/deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/md5 b/deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/md5 new file mode 100644 index 0000000000000..e1c0f9e87b7c7 --- /dev/null +++ b/deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/md5 @@ -0,0 +1 @@ +98b8b8bc0ea4bf24c4b2986a5b7ae3e9 diff --git a/deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/sha512 b/deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/sha512 new file mode 100644 index 0000000000000..ed816ebc21e97 --- /dev/null +++ b/deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/sha512 @@ -0,0 +1 @@ +4043933825bf716f2733f8e90632de34a95a437f3b31cda92edd510ffee208f8e374ec3c5922c8142342ae21b4ec4cbd1ecd4036b9057056a12c86169632ac7b diff --git a/stdlib/Distributed.version b/stdlib/Distributed.version index 02eac7eadf0ad..4a7ab49defed2 100644 --- a/stdlib/Distributed.version +++ b/stdlib/Distributed.version @@ -1,4 +1,4 @@ DISTRIBUTED_BRANCH = master -DISTRIBUTED_SHA1 = 6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781 +DISTRIBUTED_SHA1 = c6136853451677f1957bec20ecce13419cde3a12 DISTRIBUTED_GIT_URL := https://github.com/JuliaLang/Distributed.jl DISTRIBUTED_TAR_URL = https://api.github.com/repos/JuliaLang/Distributed.jl/tarball/$1 From 35729d9fc588d14db92596cbc78ae2818e441661 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Wed, 18 Dec 2024 00:49:21 +0900 Subject: [PATCH 063/198] inference: handle cases where `:the_exception` is used independently (#56836) `Expr(:the_exception)` is handled by the interpreter in all cases, however, inference assumes it is only used within frames containing `try/catch`. This commit corrects that assumption. --- Compiler/src/abstractinterpretation.jl | 12 ++++++++++-- Compiler/test/inference.jl | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 2efd8a2b7264f..0d0d4a2f80e9e 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -3240,8 +3240,16 @@ function abstract_eval_throw_undef_if_not(interp::AbstractInterpreter, e::Expr, end function abstract_eval_the_exception(::AbstractInterpreter, sv::InferenceState) - (;handlers, handler_at) = sv.handler_info::HandlerInfo - return the_exception_info(handlers[handler_at[sv.currpc][2]].exct) + (;handler_info) = sv + if handler_info === nothing + return the_exception_info(Any) + end + (;handlers, handler_at) = handler_info + handler_id = handler_at[sv.currpc][2] + if handler_id === 0 + return the_exception_info(Any) + end + return the_exception_info(handlers[handler_id].exct) end abstract_eval_the_exception(::AbstractInterpreter, ::IRInterpretationState) = the_exception_info(Any) the_exception_info(@nospecialize t) = RTEffects(t, Union{}, Effects(EFFECTS_TOTAL; consistent=ALWAYS_FALSE)) diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index e272ff6de8d99..132e1e2c14bad 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -6125,3 +6125,17 @@ function func_swapglobal!_must_throw(x) end @test Base.infer_return_type(func_swapglobal!_must_throw, (Int,); interp=SwapGlobalInterp()) === Union{} @test !Compiler.is_effect_free(Base.infer_effects(func_swapglobal!_must_throw, (Int,); interp=SwapGlobalInterp()) ) + +@eval get_exception() = $(Expr(:the_exception)) +@test Base.infer_return_type() do + get_exception() +end <: Any +@test @eval Base.infer_return_type((Float64,)) do x + out = $(Expr(:the_exception)) + try + out = sin(x) + catch + out = $(Expr(:the_exception)) + end + return out +end == Union{Float64,DomainError} From 37740148e1120ec833d6648dde245c0c5b79d76e Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Tue, 17 Dec 2024 20:00:26 +0000 Subject: [PATCH 064/198] precompileplkgs: release parallel limiter when waiting for another process (#56844) --- base/precompilation.jl | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/base/precompilation.jl b/base/precompilation.jl index 6eebded8b2f93..f61169c6ca16d 100644 --- a/base/precompilation.jl +++ b/base/precompilation.jl @@ -944,7 +944,7 @@ function _precompilepkgs(pkgs::Vector{String}, try # allows processes to wait if another process is precompiling a given package to # a functionally identical package cache (except for preferences, which may differ) - t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock(io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor) do + t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock(io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor, parallel_limiter) do Base.with_logger(Base.NullLogger()) do # The false here means we ignore loaded modules, so precompile for a fresh session keep_loaded_modules = false @@ -1130,7 +1130,7 @@ function _color_string(cstr::String, col::Union{Int64, Symbol}, hascolor) end # Can be merged with `maybe_cachefile_lock` in loading? -function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLock, fancyprint::Bool, pkg_config, pkgspidlocked, hascolor) +function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLock, fancyprint::Bool, pkg_config, pkgspidlocked, hascolor, parallel_limiter::Base.Semaphore) if !(isdefined(Base, :mkpidlock_hook) && isdefined(Base, :trymkpidlock_hook) && Base.isdefined(Base, :parse_pidfile_hook)) return f() end @@ -1153,17 +1153,22 @@ function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLo !fancyprint && lock(print_lock) do println(io, " ", pkg.name, _color_string(" Being precompiled by $(pkgspidlocked[pkg_config])", Base.info_color(), hascolor)) end - # wait until the lock is available - @invokelatest Base.mkpidlock_hook(() -> begin - # double-check in case the other process crashed or the lock expired - if Base.isprecompiled(pkg; ignore_loaded=true, flags=cacheflags) # don't use caches for this as the env state will have changed - return nothing # returning nothing indicates a process waited for another - else - delete!(pkgspidlocked, pkg_config) - return f() # precompile - end - end, - pidfile; stale_age) + Base.release(parallel_limiter) # release so other work can be done while waiting + try + # wait until the lock is available + @invokelatest Base.mkpidlock_hook(() -> begin + # double-check in case the other process crashed or the lock expired + if Base.isprecompiled(pkg; ignore_loaded=true, flags=cacheflags) # don't use caches for this as the env state will have changed + return nothing # returning nothing indicates a process waited for another + else + delete!(pkgspidlocked, pkg_config) + Base.acquire(f, parallel_limiter) # precompile + end + end, + pidfile; stale_age) + finally + Base.acquire(parallel_limiter) # re-acquire so the outer release is balanced + end end return cachefile end From bbaa6059fd4388f5d29bf19c5d7d76745cccc95f Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Wed, 18 Dec 2024 05:57:09 -0500 Subject: [PATCH 065/198] Tests for two AbstractString methods (#56247) Co-authored-by: Chengyu Han --- test/strings/basic.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/strings/basic.jl b/test/strings/basic.jl index bc4e5ae66419a..3fc611a660975 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -430,6 +430,8 @@ end @test Symbol(gstr) === Symbol("12") + @test eltype(gstr) == Char + @test firstindex(gstr) == 1 @test sizeof(gstr) == 2 @test ncodeunits(gstr) == 2 @test length(gstr) == 2 From e5b946c6b4b69040ae3adf638d9c3a057f8b98d8 Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Wed, 18 Dec 2024 05:58:10 -0500 Subject: [PATCH 066/198] Tests for annotated string/char c-tors (#56513) Co-authored-by: Chengyu Han --- test/strings/annotated.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/strings/annotated.jl b/test/strings/annotated.jl index a39d4b8d0eacb..dbb81cb48acbc 100644 --- a/test/strings/annotated.jl +++ b/test/strings/annotated.jl @@ -71,6 +71,9 @@ "AnnotatedString{String}(\"some string\", [(1:4, :thing, 0x01), (6:11, :other, 0x02), (1:11, :all, 0x03)])" @test eval(Meta.parse(repr(str))) == str @test sprint(show, MIME("text/plain"), str) == "\"some string\"" + + a = Base.AnnotatedString("hello", [(1:5, :label, 1)]) + @test first(a) == Base.AnnotatedChar('h', [(:label, 1)]) end @testset "AnnotatedChar" begin From b1007ce226501738f083486a03550d34a8cce140 Mon Sep 17 00:00:00 2001 From: Aaron Matthis Date: Wed, 18 Dec 2024 11:59:32 +0100 Subject: [PATCH 067/198] docs: fix example for `sort` and add new doctest (#56843) --- base/sort.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/base/sort.jl b/base/sort.jl index f9d74f626fe58..e1d46a8ba20ae 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -1700,13 +1700,16 @@ julia> v = [(1, "c"), (3, "a"), (2, "b")]; sort!(v, by = x -> x[2]); v (2, "b") (1, "c") -julia> sort(0:3, by=x->x-2, order=Base.Order.By(abs)) # same as sort(0:3, by=abs(x->x-2)) +julia> sort(0:3, by=x->x-2, order=Base.Order.By(abs)) 4-element Vector{Int64}: 2 1 3 0 +julia> sort(0:3, by=x->x-2, order=Base.Order.By(abs)) == sort(0:3, by=x->abs(x-2)) +true + julia> sort([2, NaN, 1, NaN, 3]) # correct sort with default lt=isless 5-element Vector{Float64}: 1.0 From 31ace712ed4b0eb54b22c1c7a3473890a4179aae Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 18 Dec 2024 06:36:51 -0500 Subject: [PATCH 068/198] jitlayers: re-delete deregisterEHFrames impl (#56854) Fixes https://github.com/maleadt/LLVM.jl/issues/496 --- src/jitlayers.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 25494ba57d257..a1b01af716bb4 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -1293,9 +1293,7 @@ class ForwardingMemoryManager : public RuntimeDyld::MemoryManager { size_t Size) override { return MemMgr->registerEHFrames(Addr, LoadAddr, Size); } - virtual void deregisterEHFrames() override { - return MemMgr->deregisterEHFrames(); - } + virtual void deregisterEHFrames() override { /* not actually supported or allowed with this */ } virtual bool finalizeMemory(std::string *ErrMsg = nullptr) override { bool b = false; if (MemMgr.use_count() == 2) From fc9e7c4a6a36d7d54ae7dd8b89ac14a8334a59c4 Mon Sep 17 00:00:00 2001 From: Priynsh <119518987+Priynsh@users.noreply.github.com> Date: Wed, 18 Dec 2024 20:04:45 +0530 Subject: [PATCH 069/198] docs: fix edge case in rational number conversion `float(a//b)` (#56772) Fixes #56726 added the changes that were suggested. fixing the mistake. --------- Co-authored-by: Max Horn Co-authored-by: Chengyu Han --- .../manual/complex-and-rational-numbers.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/doc/src/manual/complex-and-rational-numbers.md b/doc/src/manual/complex-and-rational-numbers.md index 9cab2ed1e4f24..d1d6ffeca245f 100644 --- a/doc/src/manual/complex-and-rational-numbers.md +++ b/doc/src/manual/complex-and-rational-numbers.md @@ -254,13 +254,30 @@ julia> float(3//4) ``` Conversion from rational to floating-point respects the following identity for any integral values -of `a` and `b`, with the exception of the two cases `b == 0` and `a == 0 && b < 0`: +of `a` and `b`, except when `a==0 && b <= 0`: ```jldoctest julia> a = 1; b = 2; julia> isequal(float(a//b), a/b) true + +julia> a, b = 0, 0 +(0, 0) + +julia> float(a//b) +ERROR: ArgumentError: invalid rational: zero(Int64)//zero(Int64) +Stacktrace: +[...] + +julia> a/b +NaN + +julia> a, b = 0, -1 +(0, -1) + +julia> float(a//b), a/b +(0.0, -0.0) ``` Constructing infinite rational values is acceptable: From 522624c35146f4a1ac05fb5d9234324dc0ff15a2 Mon Sep 17 00:00:00 2001 From: Arno Strouwen Date: Wed, 18 Dec 2024 15:39:08 +0100 Subject: [PATCH 070/198] docs: fix scope type of a `struct` to hard (#56755) Is struct not a hard scope? ```jl julia> b = 1 struct Tester tester Tester(tester) = new(tester) b = 2 Tester() = new(b) end b 1 ``` --- doc/src/manual/variables-and-scoping.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/manual/variables-and-scoping.md b/doc/src/manual/variables-and-scoping.md index 64a12ea88c7dd..99f7ba088311d 100644 --- a/doc/src/manual/variables-and-scoping.md +++ b/doc/src/manual/variables-and-scoping.md @@ -64,7 +64,7 @@ The constructs introducing scope blocks are: | Construct | Scope Type Introduced | Scope Types Able to Contain Construct | |:----------|:----------------------|:--------------------------------------| | [`module`](@ref), [`baremodule`](@ref) | global | global | -| [`struct`](@ref) | local (soft) | global | +| [`struct`](@ref) | local (hard) | global | | [`macro`](@ref) | local (hard) | global | | [`for`](@ref), [`while`](@ref), [`try`](@ref try) | local (soft) | global, local | | [`function`](@ref), [`do`](@ref), [`let`](@ref), [comprehensions](@ref man-comprehensions), [generators](@ref man-generators) | local (hard) | global, local | @@ -169,10 +169,10 @@ that location: 1. **Existing local:** If `x` is *already a local variable*, then the existing local `x` is assigned; 2. **Hard scope:** If `x` is *not already a local variable* and assignment occurs inside of any - hard scope construct (i.e. within a `let` block, function or macro body, comprehension, or + hard scope construct (i.e. within a `let` block, function, struct or macro body, comprehension, or generator), a new local named `x` is created in the scope of the assignment; 3. **Soft scope:** If `x` is *not already a local variable* and all of the scope constructs - containing the assignment are soft scopes (loops, `try`/`catch` blocks, or `struct` blocks), the + containing the assignment are soft scopes (loops, `try`/`catch` blocks), the behavior depends on whether the global variable `x` is defined: * if global `x` is *undefined*, a new local named `x` is created in the scope of the assignment; From 796d823b4fbb3ec94c09f7022f9b614fc846dced Mon Sep 17 00:00:00 2001 From: cossio Date: Wed, 18 Dec 2024 15:40:34 +0100 Subject: [PATCH 071/198] dict docs: document that ordering of keys/values/pairs match iterate (#56842) Fix #56841. Currently the documentation states that keys(dict) and values(dict) iterate in the same order. But it is not stated whether this is the same order as that used by pairs(dict), or when looping, for (k,v) in dict. This PR makes this guarantee explicit. --- base/abstractdict.jl | 12 ++++++++---- test/dict.jl | 7 +++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/base/abstractdict.jl b/base/abstractdict.jl index 85a726b4cdbf4..3be930151d4d4 100644 --- a/base/abstractdict.jl +++ b/base/abstractdict.jl @@ -88,8 +88,8 @@ Return an iterator over all keys in a dictionary. When the keys are stored internally in a hash table, as is the case for `Dict`, the order in which they are returned may vary. -But `keys(a)` and `values(a)` both iterate `a` and -return the elements in the same order. +But `keys(a)`, `values(a)` and `pairs(a)` all iterate `a` +and return the elements in the same order. # Examples ```jldoctest @@ -114,8 +114,8 @@ Return an iterator over all values in a collection. When the values are stored internally in a hash table, as is the case for `Dict`, the order in which they are returned may vary. -But `keys(a)` and `values(a)` both iterate `a` and -return the elements in the same order. +But `keys(a)`, `values(a)` and `pairs(a)` all iterate `a` +and return the elements in the same order. # Examples ```jldoctest @@ -138,6 +138,10 @@ values(a::AbstractDict) = ValueIterator(a) Return an iterator over `key => value` pairs for any collection that maps a set of keys to a set of values. This includes arrays, where the keys are the array indices. +When the entries are stored internally in a hash table, +as is the case for `Dict`, the order in which they are returned may vary. +But `keys(a)`, `values(a)` and `pairs(a)` all iterate `a` +and return the elements in the same order. # Examples ```jldoctest diff --git a/test/dict.jl b/test/dict.jl index 909afb3607907..83d35ae18bb85 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -787,6 +787,13 @@ end [v for (k, v) in d] == [d[x[1]] for (i, x) in enumerate(d)] end +@testset "consistency of dict iteration order (issue #56841)" begin + dict = Dict(randn() => randn() for _ = 1:100) + @test all(zip(dict, keys(dict), values(dict), pairs(dict))) do (d, k, v, p) + d == p && first(d) == first(p) == k && last(d) == last(p) == v + end +end + @testset "generators, similar" begin d = Dict(:a=>"a") # TODO: restore when 0.7 deprecation is removed From 65de0142f50c95ec75eb854ebfa5eaff2c8179d3 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 18 Dec 2024 13:09:33 -0500 Subject: [PATCH 072/198] fix abstract_eval_cfunction mistakes (#56856) Noticed in code reading, that 35e4a1f9689f4b98f301884e0683e4f07db7514b simplified this incorrectly resulting in all arguments being assigned to the function type, and then 7f8635f11cae5f3f592afcc7b55c8e0e23589c3d further broke the return type expected for the failure case. Co-authored-by: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> --- Compiler/src/abstractinterpretation.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 0d0d4a2f80e9e..4ab09ca3c88cf 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -2894,20 +2894,21 @@ end function abstract_eval_cfunction(interp::AbstractInterpreter, e::Expr, sstate::StatementState, sv::AbsIntState) f = abstract_eval_value(interp, e.args[2], sstate, sv) - # rt = sp_type_rewrap(e.args[3], sv.linfo, true) + # rt = sp_type_rewrap(e.args[3], sv.linfo, true) # verify that the result type make sense? + # rt === Bottom && return RTEffects(Union{}, Any, EFFECTS_UNKNOWN) atv = e.args[4]::SimpleVector at = Vector{Any}(undef, length(atv) + 1) at[1] = f for i = 1:length(atv) - at[i + 1] = sp_type_rewrap(at[i], frame_instance(sv), false) - at[i + 1] === Bottom && return + atᵢ = at[i + 1] = sp_type_rewrap(atv[i], frame_instance(sv), false) + atᵢ === Bottom && return RTEffects(Union{}, Any, EFFECTS_UNKNOWN) end # this may be the wrong world for the call, # but some of the result is likely to be valid anyways # and that may help generate better codegen abstract_call(interp, ArgInfo(nothing, at), StmtInfo(false, false), sv)::Future rt = e.args[1] - isa(rt, Type) || (rt = Any) + isconcretetype(rt) || (rt = Any) return RTEffects(rt, Any, EFFECTS_UNKNOWN) end From 03017db3abd8ebf7424802fd9a4ad776bd761b24 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Thu, 19 Dec 2024 05:14:14 +0900 Subject: [PATCH 073/198] inference: use `ssa_def_slot` for `typeassert` refinement (#56859) Allows type refinement in the following kind of case: ```julia julia> @test Base.infer_return_type((Vector{Any},)) do args codeinst = first(args) if codeinst isa Core.MethodInstance mi = codeinst else codeinst::Core.CodeInstance mi = codeinst.def end return mi end == Core.MethodInstance Test Passed ``` --- Compiler/src/abstractinterpretation.jl | 2 +- Compiler/test/inference.jl | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 4ab09ca3c88cf..59d382d8e4a34 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -2656,7 +2656,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), if sv isa InferenceState && f === typeassert # perform very limited back-propagation of invariants after this type assertion if rt !== Bottom && isa(fargs, Vector{Any}) - farg2 = fargs[2] + farg2 = ssa_def_slot(fargs[2], sv) if farg2 isa SlotNumber refinements = SlotRefinement(farg2, rt) end diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index 132e1e2c14bad..7cd6989bd2423 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -4103,6 +4103,17 @@ end == [Union{Some{Float64}, Some{Int}, Some{UInt8}}] end return a end == Union{Int32,Int64} + + @test Base.infer_return_type((Vector{Any},)) do args + codeinst = first(args) + if codeinst isa Core.MethodInstance + mi = codeinst + else + codeinst::Core.CodeInstance + mi = codeinst.def + end + return mi + end == Core.MethodInstance end callsig_backprop_basic(::Int) = nothing From 5d72906c5e5ab871c912d0423a71651ec6266f07 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:51:25 +0900 Subject: [PATCH 074/198] EA: use embedded `CodeInstance` directly for escape cache lookup (#56860) --- Compiler/src/optimize.jl | 8 ++- Compiler/src/ssair/EscapeAnalysis.jl | 10 +-- Compiler/test/EAUtils.jl | 97 +++++++++++++--------------- Compiler/test/EscapeAnalysis.jl | 12 +++- 4 files changed, 66 insertions(+), 61 deletions(-) diff --git a/Compiler/src/optimize.jl b/Compiler/src/optimize.jl index 1c02bd67b5bd4..bc3fc4f9705c4 100644 --- a/Compiler/src/optimize.jl +++ b/Compiler/src/optimize.jl @@ -647,9 +647,11 @@ struct GetNativeEscapeCache{CodeCache} GetNativeEscapeCache(code_cache::CodeCache) where CodeCache = new{CodeCache}(code_cache) end GetNativeEscapeCache(interp::AbstractInterpreter) = GetNativeEscapeCache(code_cache(interp)) -function ((; code_cache)::GetNativeEscapeCache)(mi::MethodInstance) - codeinst = get(code_cache, mi, nothing) - codeinst isa CodeInstance || return false +function ((; code_cache)::GetNativeEscapeCache)(codeinst::Union{CodeInstance,MethodInstance}) + if codeinst isa MethodInstance + codeinst = get(code_cache, codeinst, nothing) + codeinst isa CodeInstance || return false + end argescapes = traverse_analysis_results(codeinst) do @nospecialize result return result isa EscapeAnalysis.ArgEscapeCache ? result : nothing end diff --git a/Compiler/src/ssair/EscapeAnalysis.jl b/Compiler/src/ssair/EscapeAnalysis.jl index 68a7aef1cbba4..af8e9b1a4959e 100644 --- a/Compiler/src/ssair/EscapeAnalysis.jl +++ b/Compiler/src/ssair/EscapeAnalysis.jl @@ -944,14 +944,16 @@ end # escape statically-resolved call, i.e. `Expr(:invoke, ::MethodInstance, ...)` function escape_invoke!(astate::AnalysisState, pc::Int, args::Vector{Any}) - mi = first(args) - if !(mi isa MethodInstance) - mi = (mi::CodeInstance).def # COMBAK get escape info directly from CI instead? + codeinst = first(args) + if codeinst isa MethodInstance + mi = codeinst + else + mi = (codeinst::CodeInstance).def end first_idx, last_idx = 2, length(args) add_liveness_changes!(astate, pc, args, first_idx, last_idx) # TODO inspect `astate.ir.stmts[pc][:info]` and use const-prop'ed `InferenceResult` if available - cache = astate.get_escape_cache(mi) + cache = astate.get_escape_cache(codeinst) ret = SSAValue(pc) if cache isa Bool if cache diff --git a/Compiler/test/EAUtils.jl b/Compiler/test/EAUtils.jl index f124aea2544fd..64d2a62db8622 100644 --- a/Compiler/test/EAUtils.jl +++ b/Compiler/test/EAUtils.jl @@ -14,27 +14,11 @@ import .Compiler: AbstractInterpreter, NativeInterpreter, WorldView, WorldRange, InferenceParams, OptimizationParams, get_world_counter, get_inference_cache, ipo_dataflow_analysis! # usings -using Core: - CodeInstance, MethodInstance, CodeInfo -using .Compiler: - InferenceResult, InferenceState, OptimizationState, IRCode +using Core.IR +using .Compiler: InferenceResult, InferenceState, OptimizationState, IRCode using .EA: analyze_escapes, ArgEscapeCache, ArgEscapeInfo, EscapeInfo, EscapeState -struct EAToken end - -# when working outside of CC, -# cache entire escape state for later inspection and debugging -struct EscapeCacheInfo - argescapes::ArgEscapeCache - state::EscapeState # preserved just for debugging purpose - ir::IRCode # preserved just for debugging purpose -end - -struct EscapeCache - cache::IdDict{MethodInstance,EscapeCacheInfo} # TODO(aviatesk) Should this be CodeInstance to EscapeCacheInfo? -end -EscapeCache() = EscapeCache(IdDict{MethodInstance,EscapeCacheInfo}()) -const GLOBAL_ESCAPE_CACHE = EscapeCache() +mutable struct EscapeAnalyzerCacheToken end struct EscapeResultForEntry ir::IRCode @@ -47,15 +31,15 @@ mutable struct EscapeAnalyzer <: AbstractInterpreter const inf_params::InferenceParams const opt_params::OptimizationParams const inf_cache::Vector{InferenceResult} - const escape_cache::EscapeCache + const token::EscapeAnalyzerCacheToken const entry_mi::Union{Nothing,MethodInstance} result::EscapeResultForEntry - function EscapeAnalyzer(world::UInt, escape_cache::EscapeCache; + function EscapeAnalyzer(world::UInt, cache_token::EscapeAnalyzerCacheToken; entry_mi::Union{Nothing,MethodInstance}=nothing) inf_params = InferenceParams() opt_params = OptimizationParams() inf_cache = InferenceResult[] - return new(world, inf_params, opt_params, inf_cache, escape_cache, entry_mi) + return new(world, inf_params, opt_params, inf_cache, cache_token, entry_mi) end end @@ -63,20 +47,19 @@ Compiler.InferenceParams(interp::EscapeAnalyzer) = interp.inf_params Compiler.OptimizationParams(interp::EscapeAnalyzer) = interp.opt_params Compiler.get_inference_world(interp::EscapeAnalyzer) = interp.world Compiler.get_inference_cache(interp::EscapeAnalyzer) = interp.inf_cache -Compiler.cache_owner(::EscapeAnalyzer) = EAToken() -Compiler.get_escape_cache(interp::EscapeAnalyzer) = GetEscapeCache(interp) +Compiler.cache_owner(interp::EscapeAnalyzer) = interp.token +Compiler.get_escape_cache(::EscapeAnalyzer) = GetEscapeCache() function Compiler.ipo_dataflow_analysis!(interp::EscapeAnalyzer, opt::OptimizationState, - ir::IRCode, caller::InferenceResult) + ir::IRCode, caller::InferenceResult) # run EA on all frames that have been optimized nargs = Int(opt.src.nargs) 𝕃ₒ = Compiler.optimizer_lattice(interp) - get_escape_cache = GetEscapeCache(interp) estate = try - analyze_escapes(ir, nargs, 𝕃ₒ, get_escape_cache) + analyze_escapes(ir, nargs, 𝕃ₒ, GetEscapeCache()) catch err @error "error happened within EA, inspect `Main.failedanalysis`" - failedanalysis = FailedAnalysis(caller, ir, nargs, get_escape_cache) + failedanalysis = FailedAnalysis(caller, ir, nargs) Core.eval(Main, :(failedanalysis = $failedanalysis)) rethrow(err) end @@ -84,25 +67,31 @@ function Compiler.ipo_dataflow_analysis!(interp::EscapeAnalyzer, opt::Optimizati # return back the result interp.result = EscapeResultForEntry(Compiler.copy(ir), estate, caller.linfo) end - record_escapes!(interp, caller, estate, ir) + record_escapes!(caller, estate, ir) @invoke Compiler.ipo_dataflow_analysis!(interp::AbstractInterpreter, opt::OptimizationState, - ir::IRCode, caller::InferenceResult) + ir::IRCode, caller::InferenceResult) end -function record_escapes!(interp::EscapeAnalyzer, - caller::InferenceResult, estate::EscapeState, ir::IRCode) +# cache entire escape state for inspection and debugging +struct EscapeCacheInfo + argescapes::ArgEscapeCache + state::EscapeState # preserved just for debugging purpose + ir::IRCode # preserved just for debugging purpose +end + +function record_escapes!(caller::InferenceResult, estate::EscapeState, ir::IRCode) argescapes = ArgEscapeCache(estate) ecacheinfo = EscapeCacheInfo(argescapes, estate, ir) return Compiler.stack_analysis_result!(caller, ecacheinfo) end -struct GetEscapeCache - escape_cache::EscapeCache - GetEscapeCache(interp::EscapeAnalyzer) = new(interp.escape_cache) -end -function ((; escape_cache)::GetEscapeCache)(mi::MethodInstance) - ecacheinfo = get(escape_cache.cache, mi, nothing) +struct GetEscapeCache end +function (::GetEscapeCache)(codeinst::Union{CodeInstance,MethodInstance}) + codeinst isa CodeInstance || return false + ecacheinfo = Compiler.traverse_analysis_results(codeinst) do @nospecialize result + return result isa EscapeCacheInfo ? result : nothing + end return ecacheinfo === nothing ? false : ecacheinfo.argescapes end @@ -110,15 +99,6 @@ struct FailedAnalysis caller::InferenceResult ir::IRCode nargs::Int - get_escape_cache::GetEscapeCache -end - -function Compiler.finish!(interp::EscapeAnalyzer, state::InferenceState; can_discard_trees::Bool=Compiler.may_discard_trees(interp)) - ecacheinfo = Compiler.traverse_analysis_results(state.result) do @nospecialize result - return result isa EscapeCacheInfo ? result : nothing - end - ecacheinfo isa EscapeCacheInfo && (interp.escape_cache.cache[state.linfo] = ecacheinfo) - return @invoke Compiler.finish!(interp::AbstractInterpreter, state::InferenceState; can_discard_trees) end # printing @@ -313,23 +293,29 @@ while caching the analysis results. - `world::UInt = Base.get_world_counter()`: controls the world age to use when looking up methods, use current world age if not specified. -- `interp::EscapeAnalyzer = EscapeAnalyzer(world)`: - specifies the escape analyzer to use, by default a new analyzer with the global cache is created. +- `cache_token::EscapeAnalyzerCacheToken = EscapeAnalyzerCacheToken()`: + specifies the cache token to use, by default a new token is generated to ensure + that `code_escapes` uses a fresh cache and performs a new analysis on each invocation. + If you with to perform analysis with the global cache enabled, specify a particular token instance. +- `interp::EscapeAnalyzer = EscapeAnalyzer(world, cache_token)`: + specifies the escape analyzer to use. - `debuginfo::Symbol = :none`: controls the amount of code metadata present in the output, possible options are `:none` or `:source`. """ function code_escapes(@nospecialize(f), @nospecialize(types=Base.default_tt(f)); world::UInt = get_world_counter(), + cache_token::EscapeAnalyzerCacheToken = EscapeAnalyzerCacheToken(), debuginfo::Symbol = :none) tt = Base.signature_type(f, types) match = Base._which(tt; world, raise=true) mi = Compiler.specialize_method(match) - return code_escapes(mi; world, debuginfo) + return code_escapes(mi; world, cache_token, debuginfo) end function code_escapes(mi::MethodInstance; world::UInt = get_world_counter(), - interp::EscapeAnalyzer=EscapeAnalyzer(world, GLOBAL_ESCAPE_CACHE; entry_mi=mi), + cache_token::EscapeAnalyzerCacheToken = EscapeAnalyzerCacheToken(), + interp::EscapeAnalyzer=EscapeAnalyzer(world, cache_token; entry_mi=mi), debuginfo::Symbol = :none) frame = Compiler.typeinf_frame(interp, mi, #=run_optimizer=#true) isdefined(interp, :result) || error("optimization didn't happen: maybe everything has been constant folded?") @@ -351,12 +337,17 @@ Note that this version does not cache the analysis results. - `world::UInt = Base.get_world_counter()`: controls the world age to use when looking up methods, use current world age if not specified. -- `interp::AbstractInterpreter = EscapeAnalyzer(world, EscapeCache())`: +- `cache_token::EscapeAnalyzerCacheToken = EscapeAnalyzerCacheToken()`: + specifies the cache token to use, by default a new token is generated to ensure + that `code_escapes` uses a fresh cache and performs a new analysis on each invocation. + If you with to perform analysis with the global cache enabled, specify a particular token instance. +- `interp::AbstractInterpreter = EscapeAnalyzer(world, cache_token)`: specifies the abstract interpreter to use, by default a new `EscapeAnalyzer` with an empty cache is created. """ function code_escapes(ir::IRCode, nargs::Int; world::UInt = get_world_counter(), - interp::AbstractInterpreter=EscapeAnalyzer(world, EscapeCache())) + cache_token::EscapeAnalyzerCacheToken = EscapeAnalyzerCacheToken(), + interp::AbstractInterpreter=EscapeAnalyzer(world, cache_token)) estate = analyze_escapes(ir, nargs, Compiler.optimizer_lattice(interp), Compiler.get_escape_cache(interp)) return EscapeResult(ir, estate) # return back the result end diff --git a/Compiler/test/EscapeAnalysis.jl b/Compiler/test/EscapeAnalysis.jl index e1638e74e61fe..60364769c95a8 100644 --- a/Compiler/test/EscapeAnalysis.jl +++ b/Compiler/test/EscapeAnalysis.jl @@ -1527,7 +1527,17 @@ let result = code_escapes() do end i = last(findall(isnew, result.ir.stmts.stmt)) @test_broken !has_return_escape(result.state[SSAValue(i)]) # TODO interprocedural alias analysis - @test !has_thrown_escape(result.state[SSAValue(i)]) + @test_broken !has_thrown_escape(result.state[SSAValue(i)]) # IDEA embed const-prop'ed `CodeInstance` for `:invoke`? +end +let result = code_escapes((Base.RefValue{Base.RefValue{String}},)) do x + out1 = broadcast_noescape2(Ref(Ref("Hi"))) + out2 = broadcast_noescape2(x) + return out1, out2 + end + i = last(findall(isnew, result.ir.stmts.stmt)) + @test_broken !has_return_escape(result.state[SSAValue(i)]) # TODO interprocedural alias analysis + @test_broken !has_thrown_escape(result.state[SSAValue(i)]) # IDEA embed const-prop'ed `CodeInstance` for `:invoke`? + @test has_thrown_escape(result.state[Argument(2)]) end @noinline allescape_argument(a) = (global GV = a) # obvious escape let result = code_escapes() do From 82daca2c9f0c00274a05a4fc46ee36a62b73f8a2 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:23:20 +0900 Subject: [PATCH 075/198] Compiler.jl: use `Base.[all|any]` instead of `Compiler`'s own versions (#56851) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current `Compiler` defines its own versions of `all` and `any`, which are separate generic functions from `Base.[all|any]`: https://github.com/JuliaLang/julia/blob/2ed1a411e0a080f3107e75bb65105a15a0533a90/Compiler/src/utilities.jl#L15-L32 On the other hand, at the point where `Base.Compiler` is bootstrapped, only a subset of `Base.[all|any]` are defined, specifically those related to `Tuple`: https://github.com/JuliaLang/julia/blob/2ed1a411e0a080f3107e75bb65105a15a0533a90/base/tuple.jl#L657-L668. Consequently, in the type inference world, functions like `Base.all(::Generator)` are unavailable. If `Base.Compiler` attempts to perform operations such as `::BitSet ⊆ ::BitSet` (which internally uses `Base.[all|any]`), a world age error occurs (while `Compiler.[all|any]` can handle these operations, `::BitSet ⊆ ::BitSet` uses `Base.[all|any]`, leading to this issue) To resolve this problem, this commit removes the custom `Compiler` versions of `[all|any]` and switches to using the Base versions. One concern is that the previous `Compiler` versions of `[all|any]` utilized `@nospecialize`. That annotation was introduced a long time ago to prevent over-specialization, but it is questionable whether it is still effective with the current compiler implementation. The results of the nanosoldier benchmarks conducted below also seem to confirm that the `@nospecialize`s are no longer necessary for those functions. --- Compiler/src/Compiler.jl | 54 ++++----- Compiler/src/utilities.jl | 19 ---- base/Base_compiler.jl | 2 + base/anyall.jl | 231 ++++++++++++++++++++++++++++++++++++++ base/reduce.jl | 230 ------------------------------------- 5 files changed, 260 insertions(+), 276 deletions(-) create mode 100644 base/anyall.jl diff --git a/Compiler/src/Compiler.jl b/Compiler/src/Compiler.jl index 8dd15462ed998..06cdbe09e06fc 100644 --- a/Compiler/src/Compiler.jl +++ b/Compiler/src/Compiler.jl @@ -41,36 +41,36 @@ ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Compiler, using Core.Intrinsics, Core.IR -import Core: print, println, show, write, unsafe_write, - _apply_iterate, svec, apply_type, Builtin, IntrinsicFunction, - MethodInstance, CodeInstance, MethodTable, MethodMatch, PartialOpaque, - TypeofVararg, Core, SimpleVector, donotdelete, compilerbarrier, - memoryref_isassigned, memoryrefnew, memoryrefoffset, memoryrefget, - memoryrefset!, typename +using Core: Builtin, CodeInstance, IntrinsicFunction, MethodInstance, MethodMatch, + MethodTable, PartialOpaque, SimpleVector, TypeofVararg, + _apply_iterate, apply_type, compilerbarrier, donotdelete, memoryref_isassigned, + memoryrefget, memoryrefnew, memoryrefoffset, memoryrefset!, print, println, show, svec, + typename, unsafe_write, write using Base -using Base: Ordering, vect, EffectsOverride, BitVector, @_gc_preserve_begin, @_gc_preserve_end, RefValue, - @nospecializeinfer, @_foldable_meta, fieldindex, is_function_def, indexed_iterate, isexpr, methods, - get_world_counter, JLOptions, _methods_by_ftype, unwrap_unionall, cconvert, unsafe_convert, - issingletontype, isType, rewrap_unionall, has_free_typevars, isvarargtype, hasgenerator, - IteratorSize, SizeUnknown, _array_for, Bottom, generating_output, diff_names, - ismutationfree, NUM_EFFECTS_OVERRIDES, _NAMEDTUPLE_NAME, datatype_fieldtypes, - argument_datatype, isfieldatomic, unwrapva, iskindtype, _bits_findnext, copy_exprargs, - Generator, Filter, ismutabletypename, isvatuple, datatype_fieldcount, - isconcretedispatch, isdispatchelem, datatype_layoutsize, - datatype_arrayelem, unionlen, isidentityfree, _uniontypes, uniontypes, OneTo, Callable, - DataTypeFieldDesc, datatype_nfields, datatype_pointerfree, midpoint, is_valid_intrinsic_elptr, - allocatedinline, isbitsunion, widen_diagonal, unconstrain_vararg_length, - rename_unionall, may_invoke_generator, is_meta_expr_head, is_meta_expr, quoted, - specialize_method, hasintersect, is_nospecializeinfer, is_nospecialized, - get_nospecializeinfer_sig, tls_world_age, uniontype_layout, kwerr, - moduleroot, is_file_tracked, decode_effects_override, lookup_binding_partition, - is_some_imported, binding_kind, is_some_guard, is_some_const_binding, partition_restriction, - BINDING_KIND_GLOBAL, structdiff +using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospecializeinfer, + BINDING_KIND_GLOBAL, Base, BitVector, Bottom, Callable, DataTypeFieldDesc, + EffectsOverride, Filter, Generator, IteratorSize, JLOptions, NUM_EFFECTS_OVERRIDES, + OneTo, Ordering, RefValue, SizeUnknown, _NAMEDTUPLE_NAME, + _array_for, _bits_findnext, _methods_by_ftype, _uniontypes, all, allocatedinline, any, + argument_datatype, binding_kind, cconvert, copy_exprargs, datatype_arrayelem, + datatype_fieldcount, datatype_fieldtypes, datatype_layoutsize, datatype_nfields, + datatype_pointerfree, decode_effects_override, diff_names, fieldindex, + generating_output, get_nospecializeinfer_sig, get_world_counter, has_free_typevars, + hasgenerator, hasintersect, indexed_iterate, isType, is_file_tracked, is_function_def, + is_meta_expr, is_meta_expr_head, is_nospecialized, is_nospecializeinfer, + is_some_const_binding, is_some_guard, is_some_imported, is_valid_intrinsic_elptr, + isbitsunion, isconcretedispatch, isdispatchelem, isexpr, isfieldatomic, isidentityfree, + iskindtype, ismutabletypename, ismutationfree, issingletontype, isvarargtype, isvatuple, + kwerr, lookup_binding_partition, may_invoke_generator, methods, midpoint, moduleroot, + partition_restriction, quoted, rename_unionall, rewrap_unionall, specialize_method, + structdiff, tls_world_age, unconstrain_vararg_length, unionlen, uniontype_layout, + uniontypes, unsafe_convert, unwrap_unionall, unwrapva, vect, widen_diagonal using Base.Order -import Base: getindex, setindex!, length, iterate, push!, isempty, first, convert, ==, - copy, popfirst!, in, haskey, resize!, copy!, append!, last, get!, size, - get, iterate, findall, min_world, max_world, _topmod, isready + +import Base: ==, _topmod, append!, convert, copy, copy!, findall, first, get, get!, + getindex, haskey, in, isempty, isready, iterate, iterate, last, length, max_world, + min_world, popfirst!, push!, resize!, setindex!, size const getproperty = Core.getfield const setproperty! = Core.setfield! diff --git a/Compiler/src/utilities.jl b/Compiler/src/utilities.jl index da20f9aafbfb2..196722f8bca33 100644 --- a/Compiler/src/utilities.jl +++ b/Compiler/src/utilities.jl @@ -12,25 +12,6 @@ if !@isdefined(var"@timeit") end end -# avoid cycle due to over-specializing `any` when used by inference -function _any(@nospecialize(f), a) - for x in a - f(x) && return true - end - return false -end -any(@nospecialize(f), itr) = _any(f, itr) -any(itr) = _any(identity, itr) - -function _all(@nospecialize(f), a) - for x in a - f(x) || return false - end - return true -end -all(@nospecialize(f), itr) = _all(f, itr) -all(itr) = _all(identity, itr) - function contains_is(itr, @nospecialize(x)) for y in itr if y === x diff --git a/base/Base_compiler.jl b/base/Base_compiler.jl index 6014a6b7c9dd0..6582fe87e2045 100644 --- a/base/Base_compiler.jl +++ b/base/Base_compiler.jl @@ -249,6 +249,8 @@ using .Iterators: Flatten, Filter, product # for generators using .Iterators: Stateful # compat (was formerly used in reinterpretarray.jl) include("namedtuple.jl") +include("anyall.jl") + include("ordering.jl") using .Order diff --git a/base/anyall.jl b/base/anyall.jl new file mode 100644 index 0000000000000..e51515bb3187d --- /dev/null +++ b/base/anyall.jl @@ -0,0 +1,231 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +## all & any + +""" + any(itr) -> Bool + +Test whether any elements of a boolean collection are `true`, returning `true` as +soon as the first `true` value in `itr` is encountered (short-circuiting). To +short-circuit on `false`, use [`all`](@ref). + +If the input contains [`missing`](@ref) values, return `missing` if all non-missing +values are `false` (or equivalently, if the input contains no `true` value), following +[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). + +See also: [`all`](@ref), [`count`](@ref), [`sum`](@ref), [`|`](@ref), [`||`](@ref). + +# Examples +```jldoctest +julia> a = [true,false,false,true] +4-element Vector{Bool}: + 1 + 0 + 0 + 1 + +julia> any(a) +true + +julia> any((println(i); v) for (i, v) in enumerate(a)) +1 +true + +julia> any([missing, true]) +true + +julia> any([false, missing]) +missing +``` +""" +any(itr) = any(identity, itr) + +""" + all(itr) -> Bool + +Test whether all elements of a boolean collection are `true`, returning `false` as +soon as the first `false` value in `itr` is encountered (short-circuiting). To +short-circuit on `true`, use [`any`](@ref). + +If the input contains [`missing`](@ref) values, return `missing` if all non-missing +values are `true` (or equivalently, if the input contains no `false` value), following +[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). + +See also: [`all!`](@ref), [`any`](@ref), [`count`](@ref), [`&`](@ref), [`&&`](@ref), [`allunique`](@ref). + +# Examples +```jldoctest +julia> a = [true,false,false,true] +4-element Vector{Bool}: + 1 + 0 + 0 + 1 + +julia> all(a) +false + +julia> all((println(i); v) for (i, v) in enumerate(a)) +1 +2 +false + +julia> all([missing, false]) +false + +julia> all([true, missing]) +missing +``` +""" +all(itr) = all(identity, itr) + +""" + any(p, itr) -> Bool + +Determine whether predicate `p` returns `true` for any elements of `itr`, returning +`true` as soon as the first item in `itr` for which `p` returns `true` is encountered +(short-circuiting). To short-circuit on `false`, use [`all`](@ref). + +If the input contains [`missing`](@ref) values, return `missing` if all non-missing +values are `false` (or equivalently, if the input contains no `true` value), following +[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). + +# Examples +```jldoctest +julia> any(i->(4<=i<=6), [3,5,7]) +true + +julia> any(i -> (println(i); i > 3), 1:10) +1 +2 +3 +4 +true + +julia> any(i -> i > 0, [1, missing]) +true + +julia> any(i -> i > 0, [-1, missing]) +missing + +julia> any(i -> i > 0, [-1, 0]) +false +``` +""" +any(f, itr) = _any(f, itr, :) + +for ItrT = (Tuple,Any) + # define a generic method and a specialized version for `Tuple`, + # whose method bodies are identical, while giving better effects to the later + @eval function _any(f, itr::$ItrT, ::Colon) + $(ItrT === Tuple ? :(@_terminates_locally_meta) : :nothing) + anymissing = false + for x in itr + v = f(x) + if ismissing(v) + anymissing = true + else + v && return true + end + end + return anymissing ? missing : false + end +end + +# Specialized versions of any(f, ::Tuple) +# We fall back to the for loop implementation all elements have the same type or +# if the tuple is too large. +function any(f, itr::Tuple) + if itr isa NTuple || length(itr) > 32 + return _any(f, itr, :) + end + _any_tuple(f, false, itr...) +end + +@inline function _any_tuple(f, anymissing, x, rest...) + v = f(x) + if ismissing(v) + anymissing = true + elseif v + return true + end + return _any_tuple(f, anymissing, rest...) +end +@inline _any_tuple(f, anymissing) = anymissing ? missing : false + +""" + all(p, itr) -> Bool + +Determine whether predicate `p` returns `true` for all elements of `itr`, returning +`false` as soon as the first item in `itr` for which `p` returns `false` is encountered +(short-circuiting). To short-circuit on `true`, use [`any`](@ref). + +If the input contains [`missing`](@ref) values, return `missing` if all non-missing +values are `true` (or equivalently, if the input contains no `false` value), following +[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). + +# Examples +```jldoctest +julia> all(i->(4<=i<=6), [4,5,6]) +true + +julia> all(i -> (println(i); i < 3), 1:10) +1 +2 +3 +false + +julia> all(i -> i > 0, [1, missing]) +missing + +julia> all(i -> i > 0, [-1, missing]) +false + +julia> all(i -> i > 0, [1, 2]) +true +``` +""" +all(f, itr) = _all(f, itr, :) + +for ItrT = (Tuple,Any) + # define a generic method and a specialized version for `Tuple`, + # whose method bodies are identical, while giving better effects to the later + @eval function _all(f, itr::$ItrT, ::Colon) + $(ItrT === Tuple ? :(@_terminates_locally_meta) : :nothing) + anymissing = false + for x in itr + v = f(x) + if ismissing(v) + anymissing = true + else + v || return false + end + end + return anymissing ? missing : true + end +end + +# Specialized versions of all(f, ::Tuple), +# This is similar to any(f, ::Tuple) defined above. +function all(f, itr::Tuple) + if itr isa NTuple || length(itr) > 32 + return _all(f, itr, :) + end + _all_tuple(f, false, itr...) +end + +@inline function _all_tuple(f, anymissing, x, rest...) + v = f(x) + if ismissing(v) + anymissing = true + # this syntax allows throwing a TypeError for non-Bool, for consistency with any + elseif v + nothing + else + return false + end + return _all_tuple(f, anymissing, rest...) +end +@inline _all_tuple(f, anymissing) = anymissing ? missing : true + +all(::Tuple{Missing}) = missing diff --git a/base/reduce.jl b/base/reduce.jl index 6ceb76089d59c..25466eed4a105 100644 --- a/base/reduce.jl +++ b/base/reduce.jl @@ -1105,236 +1105,6 @@ julia> argmin([7, 1, 1, NaN]) """ argmin(itr) = findmin(itr)[2] -## all & any - -""" - any(itr) -> Bool - -Test whether any elements of a boolean collection are `true`, returning `true` as -soon as the first `true` value in `itr` is encountered (short-circuiting). To -short-circuit on `false`, use [`all`](@ref). - -If the input contains [`missing`](@ref) values, return `missing` if all non-missing -values are `false` (or equivalently, if the input contains no `true` value), following -[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). - -See also: [`all`](@ref), [`count`](@ref), [`sum`](@ref), [`|`](@ref), [`||`](@ref). - -# Examples -```jldoctest -julia> a = [true,false,false,true] -4-element Vector{Bool}: - 1 - 0 - 0 - 1 - -julia> any(a) -true - -julia> any((println(i); v) for (i, v) in enumerate(a)) -1 -true - -julia> any([missing, true]) -true - -julia> any([false, missing]) -missing -``` -""" -any(itr) = any(identity, itr) - -""" - all(itr) -> Bool - -Test whether all elements of a boolean collection are `true`, returning `false` as -soon as the first `false` value in `itr` is encountered (short-circuiting). To -short-circuit on `true`, use [`any`](@ref). - -If the input contains [`missing`](@ref) values, return `missing` if all non-missing -values are `true` (or equivalently, if the input contains no `false` value), following -[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). - -See also: [`all!`](@ref), [`any`](@ref), [`count`](@ref), [`&`](@ref), [`&&`](@ref), [`allunique`](@ref). - -# Examples -```jldoctest -julia> a = [true,false,false,true] -4-element Vector{Bool}: - 1 - 0 - 0 - 1 - -julia> all(a) -false - -julia> all((println(i); v) for (i, v) in enumerate(a)) -1 -2 -false - -julia> all([missing, false]) -false - -julia> all([true, missing]) -missing -``` -""" -all(itr) = all(identity, itr) - -""" - any(p, itr) -> Bool - -Determine whether predicate `p` returns `true` for any elements of `itr`, returning -`true` as soon as the first item in `itr` for which `p` returns `true` is encountered -(short-circuiting). To short-circuit on `false`, use [`all`](@ref). - -If the input contains [`missing`](@ref) values, return `missing` if all non-missing -values are `false` (or equivalently, if the input contains no `true` value), following -[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). - -# Examples -```jldoctest -julia> any(i->(4<=i<=6), [3,5,7]) -true - -julia> any(i -> (println(i); i > 3), 1:10) -1 -2 -3 -4 -true - -julia> any(i -> i > 0, [1, missing]) -true - -julia> any(i -> i > 0, [-1, missing]) -missing - -julia> any(i -> i > 0, [-1, 0]) -false -``` -""" -any(f, itr) = _any(f, itr, :) - -for ItrT = (Tuple,Any) - # define a generic method and a specialized version for `Tuple`, - # whose method bodies are identical, while giving better effects to the later - @eval function _any(f, itr::$ItrT, ::Colon) - $(ItrT === Tuple ? :(@_terminates_locally_meta) : :nothing) - anymissing = false - for x in itr - v = f(x) - if ismissing(v) - anymissing = true - else - v && return true - end - end - return anymissing ? missing : false - end -end - -# Specialized versions of any(f, ::Tuple) -# We fall back to the for loop implementation all elements have the same type or -# if the tuple is too large. -function any(f, itr::Tuple) - if itr isa NTuple || length(itr) > 32 - return _any(f, itr, :) - end - _any_tuple(f, false, itr...) -end - -@inline function _any_tuple(f, anymissing, x, rest...) - v = f(x) - if ismissing(v) - anymissing = true - elseif v - return true - end - return _any_tuple(f, anymissing, rest...) -end -@inline _any_tuple(f, anymissing) = anymissing ? missing : false - -""" - all(p, itr) -> Bool - -Determine whether predicate `p` returns `true` for all elements of `itr`, returning -`false` as soon as the first item in `itr` for which `p` returns `false` is encountered -(short-circuiting). To short-circuit on `true`, use [`any`](@ref). - -If the input contains [`missing`](@ref) values, return `missing` if all non-missing -values are `true` (or equivalently, if the input contains no `false` value), following -[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). - -# Examples -```jldoctest -julia> all(i->(4<=i<=6), [4,5,6]) -true - -julia> all(i -> (println(i); i < 3), 1:10) -1 -2 -3 -false - -julia> all(i -> i > 0, [1, missing]) -missing - -julia> all(i -> i > 0, [-1, missing]) -false - -julia> all(i -> i > 0, [1, 2]) -true -``` -""" -all(f, itr) = _all(f, itr, :) - -for ItrT = (Tuple,Any) - # define a generic method and a specialized version for `Tuple`, - # whose method bodies are identical, while giving better effects to the later - @eval function _all(f, itr::$ItrT, ::Colon) - $(ItrT === Tuple ? :(@_terminates_locally_meta) : :nothing) - anymissing = false - for x in itr - v = f(x) - if ismissing(v) - anymissing = true - else - v || return false - end - end - return anymissing ? missing : true - end -end - -# Specialized versions of all(f, ::Tuple), -# This is similar to any(f, ::Tuple) defined above. -function all(f, itr::Tuple) - if itr isa NTuple || length(itr) > 32 - return _all(f, itr, :) - end - _all_tuple(f, false, itr...) -end - -@inline function _all_tuple(f, anymissing, x, rest...) - v = f(x) - if ismissing(v) - anymissing = true - # this syntax allows throwing a TypeError for non-Bool, for consistency with any - elseif v - nothing - else - return false - end - return _all_tuple(f, anymissing, rest...) -end -@inline _all_tuple(f, anymissing) = anymissing ? missing : true - -all(::Tuple{Missing}) = missing - ## count _bool(f) = x->f(x)::Bool From d3c26b7ecce7e8319788bc0a035241d6dfd21ac0 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:38:45 +0100 Subject: [PATCH 076/198] Extend `Base.rationalize` instead of defining new function (#56793) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #55886 accidentally created a new function `Base.MathConstants.rationalize` instead of extending `Base.rationalize`, which is the reason why `Base.rationalize(Int, π)` isn’t constant-folded in Julia 1.10 and 1.11: ``` julia> @btime rationalize(Int,π); 1.837 ns (0 allocations: 0 bytes) # v1.9: constant-folded 88.416 μs (412 allocations: 15.00 KiB) # v1.10: not constant-folded ``` This PR fixes that. It should probably be backported to 1.10 and 1.11. --- base/mathconstants.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/mathconstants.jl b/base/mathconstants.jl index de6b98cea634d..d26f5115b5ccb 100644 --- a/base/mathconstants.jl +++ b/base/mathconstants.jl @@ -29,7 +29,7 @@ end Base.@assume_effects :foldable function (::Type{T})(x::_KnownIrrational, r::RoundingMode) where {T<:Union{Float32,Float64}} Base._irrational_to_float(T, x, r) end -Base.@assume_effects :foldable function rationalize(::Type{T}, x::_KnownIrrational; tol::Real=0) where {T<:Integer} +Base.@assume_effects :foldable function Base.rationalize(::Type{T}, x::_KnownIrrational; tol::Real=0) where {T<:Integer} Base._rationalize_irrational(T, x, tol) end Base.@assume_effects :foldable function Base.lessrational(rx::Rational, x::_KnownIrrational) From 6e04a0bbdd61685624594f1fd1ffcb3de25035bf Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Thu, 19 Dec 2024 13:22:16 -0500 Subject: [PATCH 077/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?LinearAlgebra=20stdlib=20from=2056d561c=20to=201137b4c=20(#5682?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: LinearAlgebra URL: https://github.com/JuliaLang/LinearAlgebra.jl.git Stdlib branch: master Julia branch: master Old commit: 56d561c New commit: 1137b4c Julia version: 1.12.0-DEV LinearAlgebra version: 1.11.0(Does not match) Bump invoked by: @DilumAluthge Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaLang/LinearAlgebra.jl/compare/56d561c22e1ab8e0421160edbdd42f3f194ecfa8...1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8 ``` $ git log --oneline 56d561c..1137b4c 1137b4c Port structured opnorm changes from main julia PR (#1138) ade3654 port bitarray tests to LinearAlgebra.jl (#1148) 130b94a Fix documentation bug in QR docstring (#1145) 128518e setup coverage (#1144) 15f7e32 ci: add linux-i686 (#1142) b6f87af Fallback `newindex` method with a `BandIndex` (#1143) d1e267f bring back [l/r]mul! shortcuts for (kn)own triangular types (#1137) 5cdeb46 don't refer to internal variable names in gemv exceptions (#1141) 4a3dbf8 un-revert "Simplify some views of Adjoint matrices" (#1122) 7b34d81 [CI] Install DependaBot (#1115) f567112 Port structured opnorm changes from main julia PR Originally written by mcognetta d406524 implements a `rank(::SVD)` method and adds unit tests. fixes #1126 (#1127) f13f940 faster implementation of rank(::QRPivoted) fixes #1128 (#1129) 8ab7e09 Merge pull request #1132 from JuliaLang/jishnub/qr_ldiv_R_cache 85919e6 Merge pull request #1108 from JuliaLang/jishnub/tri_muldiv_stride 195e678 Cache and reuse `R` in adjoint `QR` `ldiv!` cd0da66 Update comments LAPACK -> BLAS b3ec55f Fix argument name in stride d3a9a3e Non-contiguous matrices in triangular mul and div aecb714 Reduce number of test combinations in test/triangular.jl (#1123) 62e45d1 Update .github/dependabot.yml ff78c38 use an explicit file extension when creating sysimage (#1119) 43b541e try use updated windows compilers in PackageCompiler (#1120) c00cb77 [CI] Install DependaBot b285b1c Update LICENSE (#1113) 7efc3ba remove REPL from custom sysimage (#1112) b7f82ec add a README ``` Co-authored-by: Dilum Aluthge --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/LinearAlgebra.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/md5 create mode 100644 deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/sha512 delete mode 100644 deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/md5 delete mode 100644 deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/sha512 diff --git a/deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/md5 b/deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/md5 new file mode 100644 index 0000000000000..5bd44506fd874 --- /dev/null +++ b/deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/md5 @@ -0,0 +1 @@ +eb4df255412ad9a05b807010f626afc8 diff --git a/deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/sha512 b/deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/sha512 new file mode 100644 index 0000000000000..23617698dd26e --- /dev/null +++ b/deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/sha512 @@ -0,0 +1 @@ +3b4bf7b761d9585fb2d5c5b8418770be4d1d4399a5f25dd5b2e08785506f0732c8e140ada6f82f6d8a7a77a2c2f79e2feecd6eb0e19eda0c3ee519ba554c19ec diff --git a/deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/md5 b/deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/md5 deleted file mode 100644 index e240a1083833c..0000000000000 --- a/deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -00198e6d92d033fb33e75cf4eac34dca diff --git a/deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/sha512 b/deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/sha512 deleted file mode 100644 index 5eeceaf1dbed3..0000000000000 --- a/deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -ba4b390d99644c31d64594352da888e9ef18021cc9b7700c37a6cdb0c1ff2532eb208ecaccf93217e3183e1db8e6c089456fa5d93633b8ff037e8796199934e7 diff --git a/stdlib/LinearAlgebra.version b/stdlib/LinearAlgebra.version index d6a33ea421adf..3dac27119172a 100644 --- a/stdlib/LinearAlgebra.version +++ b/stdlib/LinearAlgebra.version @@ -1,4 +1,4 @@ LINEARALGEBRA_BRANCH = master -LINEARALGEBRA_SHA1 = 56d561c22e1ab8e0421160edbdd42f3f194ecfa8 +LINEARALGEBRA_SHA1 = 1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8 LINEARALGEBRA_GIT_URL := https://github.com/JuliaLang/LinearAlgebra.jl.git LINEARALGEBRA_TAR_URL = https://api.github.com/repos/JuliaLang/LinearAlgebra.jl/tarball/$1 From 9bc27ad0f7315b8f89635c666973e84568b2f6ab Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 20 Dec 2024 04:45:01 +0100 Subject: [PATCH 078/198] Add ABIOverride type for def field (#56555) Together with #54899, this PR is intending to replicate the functionality of #54373, which allowed particular specializations to have a different ABI signature than what would be suggested by the MethodInstance's `specTypes` field. This PR handles that by adding a special `ABIOverwrite` type, which, when placed in the `owner` field of a `CodeInstance` instructs the system to use the given signature instead. --- Compiler/src/Compiler.jl | 2 +- Compiler/src/abstractinterpretation.jl | 18 +++++- Compiler/src/ssair/show.jl | 8 ++- Compiler/src/stmtinfo.jl | 8 +-- Compiler/src/typeinfer.jl | 2 +- Compiler/test/inference.jl | 7 ++- base/arrayshow.jl | 2 +- base/boot.jl | 8 ++- base/show.jl | 8 ++- src/aotcompile.cpp | 16 +++--- src/builtins.c | 16 ++++-- src/clangsa/GCChecker.cpp | 1 + src/codegen.cpp | 77 +++++++++++++++----------- src/debuginfo.cpp | 4 +- src/engine.cpp | 2 +- src/gf.c | 17 +++--- src/interpreter.c | 4 +- src/ircode.c | 2 +- src/jitlayers.cpp | 14 ++--- src/jitlayers.h | 1 + src/jl_exported_data.inc | 1 + src/jltypes.c | 3 +- src/julia.h | 11 +++- src/julia_internal.h | 7 +++ src/precompile_utils.c | 2 +- src/staticdata.c | 16 +++--- src/staticdata_utils.c | 16 +++--- test/precompile.jl | 4 +- 28 files changed, 177 insertions(+), 100 deletions(-) diff --git a/Compiler/src/Compiler.jl b/Compiler/src/Compiler.jl index 06cdbe09e06fc..2f4efda51da9b 100644 --- a/Compiler/src/Compiler.jl +++ b/Compiler/src/Compiler.jl @@ -41,7 +41,7 @@ ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Compiler, using Core.Intrinsics, Core.IR -using Core: Builtin, CodeInstance, IntrinsicFunction, MethodInstance, MethodMatch, +using Core: ABIOverride, Builtin, CodeInstance, IntrinsicFunction, MethodInstance, MethodMatch, MethodTable, PartialOpaque, SimpleVector, TypeofVararg, _apply_iterate, apply_type, compilerbarrier, donotdelete, memoryref_isassigned, memoryrefget, memoryrefnew, memoryrefoffset, memoryrefset!, print, println, show, svec, diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 59d382d8e4a34..f2d4461a9874a 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -2212,6 +2212,18 @@ function abstract_call_unionall(interp::AbstractInterpreter, argtypes::Vector{An return CallMeta(ret, Any, Effects(EFFECTS_TOTAL; nothrow), call.info) end +function ci_abi(ci::CodeInstance) + def = ci.def + isa(def, ABIOverride) && return def.abi + (def::MethodInstance).specTypes +end + +function get_ci_mi(ci::CodeInstance) + def = ci.def + isa(def, ABIOverride) && return def.def + return def::MethodInstance +end + function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::StmtInfo, sv::AbsIntState) argtypes = arginfo.argtypes ft′ = argtype_by_index(argtypes, 2) @@ -2223,12 +2235,12 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt if isa(method_or_ci, CodeInstance) our_world = sv.world.this argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft)) - specsig = method_or_ci.def.specTypes - defdef = method_or_ci.def.def + specsig = ci_abi(method_or_ci) + defdef = get_ci_mi(method_or_ci).def exct = method_or_ci.exctype if !hasintersect(argtype, specsig) return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())) - elseif !(argtype <: specsig) || (isa(defdef, Method) && !(argtype <: defdef.sig)) + elseif !(argtype <: specsig) || ((!isa(method_or_ci.def, ABIOverride) && isa(defdef, Method)) && !(argtype <: defdef.sig)) exct = Union{exct, TypeError} end callee_valid_range = WorldRange(method_or_ci.min_world, method_or_ci.max_world) diff --git a/Compiler/src/ssair/show.jl b/Compiler/src/ssair/show.jl index 7d7b182655db7..e63d7b5cf640e 100644 --- a/Compiler/src/ssair/show.jl +++ b/Compiler/src/ssair/show.jl @@ -100,11 +100,17 @@ function print_stmt(io::IO, idx::Int, @nospecialize(stmt), code::Union{IRCode,Co if !(mi isa Core.MethodInstance) mi = (mi::Core.CodeInstance).def end + if isa(mi, Core.ABIOverride) + abi = mi.abi + mi = mi.def + else + abi = mi.specTypes + end show_unquoted(io, stmt.args[2], indent) print(io, "(") # XXX: this is wrong if `sig` is not a concretetype method # more correct would be to use `fieldtype(sig, i)`, but that would obscure / discard Varargs information in show - sig = mi.specTypes == Tuple ? Core.svec() : Base.unwrap_unionall(mi.specTypes).parameters::Core.SimpleVector + sig = abi == Tuple ? Core.svec() : Base.unwrap_unionall(abi).parameters::Core.SimpleVector print_arg(i) = sprint(; context=io) do io show_unquoted(io, stmt.args[i], indent) if (i - 1) <= length(sig) diff --git a/Compiler/src/stmtinfo.jl b/Compiler/src/stmtinfo.jl index 4f55f068e9456..a42a9e47b328e 100644 --- a/Compiler/src/stmtinfo.jl +++ b/Compiler/src/stmtinfo.jl @@ -71,7 +71,7 @@ function _add_edges_impl(edges::Vector{Any}, info::MethodMatchInfo, mi_edge::Boo mi = specialize_method(m) # don't allow `Method`-edge for this optimized format edge = mi else - mi = edge.def + mi = edge.def::MethodInstance end if mi.specTypes === m.spec_types add_one_edge!(edges, edge) @@ -103,7 +103,7 @@ function add_one_edge!(edges::Vector{Any}, edge::MethodInstance) while i <= length(edges) edgeᵢ = edges[i] edgeᵢ isa Int && (i += 2 + edgeᵢ; continue) - edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ.def) + edgeᵢ isa CodeInstance && (edgeᵢ = get_ci_mi(edgeᵢ)) edgeᵢ isa MethodInstance || (i += 1; continue) if edgeᵢ === edge && !(i > 1 && edges[i-1] isa Type) return # found existing covered edge @@ -118,7 +118,7 @@ function add_one_edge!(edges::Vector{Any}, edge::CodeInstance) while i <= length(edges) edgeᵢ_orig = edgeᵢ = edges[i] edgeᵢ isa Int && (i += 2 + edgeᵢ; continue) - edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ.def) + edgeᵢ isa CodeInstance && (edgeᵢ = get_ci_mi(edgeᵢ)) edgeᵢ isa MethodInstance || (i += 1; continue) if edgeᵢ === edge.def && !(i > 1 && edges[i-1] isa Type) if edgeᵢ_orig isa MethodInstance @@ -385,7 +385,7 @@ function add_inlining_edge!(edges::Vector{Any}, edge::CodeInstance) i += 1 end # add_invoke_edge alone - push!(edges, (edge.def.def::Method).sig) + push!(edges, (get_ci_mi(edge).def::Method).sig) push!(edges, edge) nothing end diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index 20c0a5000bd39..2e9fcf497faf6 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -528,7 +528,7 @@ function store_backedges(caller::CodeInstance, edges::SimpleVector) i += 2 continue elseif isa(callee, CodeInstance) - callee = callee.def + callee = get_ci_mi(callee) end ccall(:jl_method_instance_add_backedge, Cvoid, (Any, Any, Any), callee, item, caller) i += 2 diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index 7cd6989bd2423..9301a2809daf3 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -4110,7 +4110,12 @@ end == [Union{Some{Float64}, Some{Int}, Some{UInt8}}] mi = codeinst else codeinst::Core.CodeInstance - mi = codeinst.def + def = codeinst.def + if isa(def, Core.ABIOverride) + mi = def.def + else + mi = def::Core.MethodInstance + end end return mi end == Core.MethodInstance diff --git a/base/arrayshow.jl b/base/arrayshow.jl index 3bc69e563a967..623111ef0883d 100644 --- a/base/arrayshow.jl +++ b/base/arrayshow.jl @@ -41,7 +41,7 @@ Accept keyword args `c` for alternate single character marker. """ function replace_with_centered_mark(s::AbstractString;c::AbstractChar = '⋅') N = textwidth(ANSIIterator(s)) - return join(setindex!([" " for i=1:N],string(c),ceil(Int,N/2))) + return N == 0 ? string(c) : join(setindex!([" " for i=1:N],string(c),ceil(Int,N/2))) end const undef_ref_alignment = (3,3) diff --git a/base/boot.jl b/base/boot.jl index ed0a722c5e562..4652524530703 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -465,6 +465,12 @@ struct InitError <: WrappedException error end +struct ABIOverride + abi::Type + def::MethodInstance + ABIOverride(@nospecialize(abi::Type), def::MethodInstance) = new(abi, def) +end + struct PrecompilableError <: Exception end String(s::String) = s # no constructor yet @@ -552,7 +558,7 @@ end function CodeInstance( - mi::MethodInstance, owner, @nospecialize(rettype), @nospecialize(exctype), @nospecialize(inferred_const), + mi::Union{MethodInstance, ABIOverride}, owner, @nospecialize(rettype), @nospecialize(exctype), @nospecialize(inferred_const), @nospecialize(inferred), const_flags::Int32, min_world::UInt, max_world::UInt, effects::UInt32, @nospecialize(analysis_results), relocatability::UInt8, di::Union{DebugInfo,Nothing}, edges::SimpleVector) diff --git a/base/show.jl b/base/show.jl index cb36488b92bc1..d2f43e1ae92cc 100644 --- a/base/show.jl +++ b/base/show.jl @@ -1353,7 +1353,13 @@ end show(io::IO, mi::Core.MethodInstance) = show_mi(io, mi) function show(io::IO, codeinst::Core.CodeInstance) print(io, "CodeInstance for ") - show_mi(io, codeinst.def) + def = codeinst.def + if isa(def, Core.ABIOverride) + show_mi(io, def.def) + print(io, " (ABI Overridden)") + else + show_mi(io, def::MethodInstance) + end end function show_mi(io::IO, mi::Core.MethodInstance, from_stackframe::Bool=false) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index 198d7490cb092..b238c44c52676 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -105,7 +105,7 @@ jl_get_llvm_mis_impl(void *native_code, size_t *num_elements, jl_method_instance assert(*num_elements == map.size()); size_t i = 0; for (auto &ci : map) { - data[i++] = ci.first->def; + data[i++] = jl_get_ci_mi(ci.first); } } @@ -455,14 +455,14 @@ static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root if ((policy != CompilationPolicy::Default || params.params->trim) && jl_atomic_load_relaxed(&codeinst->inferred) == jl_nothing) { // XXX: SOURCE_MODE_FORCE_SOURCE is wrong here (neither sufficient nor necessary) - codeinst = jl_type_infer(codeinst->def, jl_atomic_load_relaxed(&codeinst->max_world), SOURCE_MODE_FORCE_SOURCE); + codeinst = jl_type_infer(jl_get_ci_mi(codeinst), jl_atomic_load_relaxed(&codeinst->max_world), SOURCE_MODE_FORCE_SOURCE); } if (codeinst) { orc::ThreadSafeModule result_m = - jl_create_ts_module(name_from_method_instance(codeinst->def), + jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)), params.tsctx, params.DL, params.TargetTriple); auto decls = jl_emit_codeinst(result_m, codeinst, NULL, params); - record_method_roots(method_roots, codeinst->def); + record_method_roots(method_roots, jl_get_ci_mi(codeinst)); if (result_m) it = compiled_functions.insert(std::make_pair(codeinst, std::make_pair(std::move(result_m), std::move(decls)))).first; } @@ -501,7 +501,7 @@ static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root proto.decl->setLinkage(GlobalVariable::InternalLinkage); //protodecl->setAlwaysInline(); jl_init_function(proto.decl, params.TargetTriple); - jl_method_instance_t *mi = codeinst->def; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); size_t nrealargs = jl_nparams(mi->specTypes); // number of actual arguments being passed bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure; // TODO: maybe this can be cached in codeinst->specfptr? @@ -641,12 +641,12 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm data->jl_fvar_map[codeinst] = std::make_tuple((uint32_t)-3, (uint32_t)-3); } else { - orc::ThreadSafeModule result_m = jl_create_ts_module(name_from_method_instance(codeinst->def), + orc::ThreadSafeModule result_m = jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)), params.tsctx, clone.getModuleUnlocked()->getDataLayout(), Triple(clone.getModuleUnlocked()->getTargetTriple())); jl_llvm_functions_t decls = jl_emit_codeinst(result_m, codeinst, NULL, params); JL_GC_PROMISE_ROOTED(codeinst->def); // analyzer seems confused - record_method_roots(method_roots, codeinst->def); + record_method_roots(method_roots, jl_get_ci_mi(codeinst)); if (result_m) compiled_functions[codeinst] = {std::move(result_m), std::move(decls)}; else if (jl_options.trim != JL_TRIM_NO) { @@ -2267,7 +2267,7 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, jl_ // To get correct names in the IR this needs to be at least 2 output.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0); JL_GC_PUSH1(&output.temporary_roots); - auto decls = jl_emit_code(m, mi, src, output); + auto decls = jl_emit_code(m, mi, src, NULL, output); output.temporary_roots = nullptr; JL_GC_POP(); // GC the global_targets array contents now since reflection doesn't need it diff --git a/src/builtins.c b/src/builtins.c index 06dbd84aff6c0..c326e53ea968d 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1589,11 +1589,19 @@ JL_CALLABLE(jl_f_invoke) return jl_gf_invoke_by_method(m, args[0], &args[2], nargs - 1); } else if (jl_is_code_instance(argtypes)) { jl_code_instance_t *codeinst = (jl_code_instance_t*)args[1]; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); jl_callptr_t invoke = jl_atomic_load_acquire(&codeinst->invoke); // N.B.: specTypes need not be a subtype of the method signature. We need to check both. - if (!jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)codeinst->def->specTypes) || - (jl_is_method(codeinst->def->def.value) && !jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)codeinst->def->def.method->sig))) { - jl_type_error("invoke: argument type error", codeinst->def->specTypes, arg_tuple(args[0], &args[2], nargs - 1)); + if (jl_is_abioverride(codeinst->def)) { + jl_datatype_t *abi = (jl_datatype_t*)((jl_abi_override_t*)(codeinst->def))->abi; + if (!jl_tuple1_isa(args[0], &args[2], nargs - 1, abi)) { + jl_type_error("invoke: argument type error (ABI overwrite)", (jl_value_t*)abi, arg_tuple(args[0], &args[2], nargs - 1)); + } + } else { + if (!jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)mi->specTypes) || + (jl_is_method(mi->def.value) && !jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)mi->def.method->sig))) { + jl_type_error("invoke: argument type error", mi->specTypes, arg_tuple(args[0], &args[2], nargs - 1)); + } } if (jl_atomic_load_relaxed(&codeinst->min_world) > jl_current_task->world_age || jl_current_task->world_age > jl_atomic_load_relaxed(&codeinst->max_world)) { @@ -1609,7 +1617,7 @@ JL_CALLABLE(jl_f_invoke) if (codeinst->owner != jl_nothing) { jl_error("Failed to invoke or compile external codeinst"); } - return jl_invoke(args[0], &args[2], nargs - 1, codeinst->def); + return jl_invoke(args[0], &args[2], nargs - 1, mi); } } if (!jl_is_tuple_type(jl_unwrap_unionall(argtypes))) diff --git a/src/clangsa/GCChecker.cpp b/src/clangsa/GCChecker.cpp index 40093ca15859b..fdbe5ec9d9e29 100644 --- a/src/clangsa/GCChecker.cpp +++ b/src/clangsa/GCChecker.cpp @@ -847,6 +847,7 @@ bool GCChecker::isGCTrackedType(QualType QT) { Name.ends_with_insensitive("jl_vararg_t") || Name.ends_with_insensitive("jl_opaque_closure_t") || Name.ends_with_insensitive("jl_globalref_t") || + Name.ends_with_insensitive("jl_abi_override_t") || // Probably not technically true for these, but let's allow it as a root Name.ends_with_insensitive("jl_ircode_state") || Name.ends_with_insensitive("typemap_intersection_env") || diff --git a/src/codegen.cpp b/src/codegen.cpp index 86c9afd134d9a..9ae905a8aba32 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3021,9 +3021,8 @@ static bool uses_specsig(jl_value_t *sig, bool needsparams, jl_value_t *rettype, return false; // jlcall sig won't require any box allocations } -static std::pair uses_specsig(jl_method_instance_t *lam, jl_value_t *rettype, bool prefer_specsig) +static std::pair uses_specsig(jl_value_t *abi, jl_method_instance_t *lam, jl_value_t *rettype, bool prefer_specsig) { - jl_value_t *sig = lam->specTypes; bool needsparams = false; if (jl_is_method(lam->def.method)) { if ((size_t)jl_subtype_env_size(lam->def.method->sig) != jl_svec_len(lam->sparam_vals)) @@ -3033,7 +3032,7 @@ static std::pair uses_specsig(jl_method_instance_t *lam, jl_value_t needsparams = true; } } - return std::make_pair(uses_specsig(sig, needsparams, rettype, prefer_specsig), needsparams); + return std::make_pair(uses_specsig(abi, needsparams, rettype, prefer_specsig), needsparams); } @@ -4341,6 +4340,7 @@ static jl_llvm_functions_t orc::ThreadSafeModule &TSM, jl_method_instance_t *lam, jl_code_info_t *src, + jl_value_t *abi, jl_value_t *rettype, jl_codegen_params_t ¶ms); @@ -5487,6 +5487,13 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt) return emit_invoke(ctx, lival, argv, nargs, rt, nullptr); } +static jl_value_t *get_ci_abi(jl_code_instance_t *ci) +{ + if (jl_typeof(ci->def) == (jl_value_t*)jl_abioverride_type) + return ((jl_abi_override_t*)ci->def)->abi; + return jl_get_ci_mi(ci)->specTypes; +} + static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayRef argv, size_t nargs, jl_value_t *rt, Value *age_ok) { ++EmittedInvokes; @@ -5501,7 +5508,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR else { ci = lival.constant; assert(jl_is_code_instance(ci)); - mi = ((jl_code_instance_t*)ci)->def; + mi = jl_get_ci_mi((jl_code_instance_t*)ci); } assert(jl_is_method_instance(mi)); if (mi == ctx.linfo) { @@ -5530,7 +5537,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR } else { bool specsig, needsparams; - std::tie(specsig, needsparams) = uses_specsig(mi, codeinst->rettype, ctx.params->prefer_specsig); + std::tie(specsig, needsparams) = uses_specsig(get_ci_abi(codeinst), mi, codeinst->rettype, ctx.params->prefer_specsig); if (needsparams) { if (trim_may_error(ctx.params->trim)) push_frames(ctx, ctx.linfo, mi); @@ -7256,7 +7263,7 @@ Function *emit_tojlinvoke(jl_code_instance_t *codeinst, StringRef theFptrName, M name, M); jl_init_function(f, params.TargetTriple); if (trim_may_error(params.params->trim)) { - push_frames(ctx, ctx.linfo, codeinst->def); + push_frames(ctx, ctx.linfo, jl_get_ci_mi(codeinst)); } jl_name_jlfunc_args(params, f); //f->setAlwaysInline(); @@ -7273,7 +7280,7 @@ Function *emit_tojlinvoke(jl_code_instance_t *codeinst, StringRef theFptrName, M } else { theFunc = prepare_call(jlinvoke_func); - theFarg = literal_pointer_val(ctx, (jl_value_t*)codeinst->def); + theFarg = literal_pointer_val(ctx, (jl_value_t*)jl_get_ci_mi(codeinst)); } theFarg = track_pjlvalue(ctx, theFarg); auto args = f->arg_begin(); @@ -8011,7 +8018,7 @@ const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value // generate a julia-callable function that calls f (AKA lam) // if is_opaque_closure, then generate the OC invoke, rather than a real invoke -static void gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *jlretty, jl_returninfo_t &f, unsigned nargs, int retarg, bool is_opaque_closure, StringRef funcName, +static void gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *abi, jl_value_t *jlretty, jl_returninfo_t &f, unsigned nargs, int retarg, bool is_opaque_closure, StringRef funcName, Module *M, jl_codegen_params_t ¶ms) { ++GeneratedInvokeWrappers; @@ -8047,7 +8054,7 @@ static void gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *jlretty, j argv[i] = mark_julia_slot(funcArg, oc_type, NULL, ctx.tbaa().tbaa_const); continue; } - jl_value_t *ty = jl_nth_slot_type(lam->specTypes, i); + jl_value_t *ty = jl_nth_slot_type(abi, i); Value *theArg; if (i == 0) { theArg = funcArg; @@ -8061,7 +8068,7 @@ static void gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *jlretty, j } argv[i] = mark_julia_type(ctx, theArg, true, ty); } - jl_cgval_t retval = emit_call_specfun_other(ctx, is_opaque_closure, lam->specTypes, jlretty, f, argv, nargs); + jl_cgval_t retval = emit_call_specfun_other(ctx, is_opaque_closure, abi, jlretty, f, argv, nargs); if (retarg != -1) { Value *theArg; if (retarg == 0) @@ -8293,13 +8300,13 @@ get_specsig_di(jl_codectx_t &ctx, jl_debugcache_t &debuginfo, jl_value_t *rt, jl } /* aka Core.Compiler.tuple_tfunc */ -static jl_datatype_t *compute_va_type(jl_method_instance_t *lam, size_t nreq) +static jl_datatype_t *compute_va_type(jl_value_t *sig, size_t nreq) { - size_t nvargs = jl_nparams(lam->specTypes)-nreq; + size_t nvargs = jl_nparams(sig)-nreq; jl_svec_t *tupargs = jl_alloc_svec(nvargs); JL_GC_PUSH1(&tupargs); - for (size_t i = nreq; i < jl_nparams(lam->specTypes); ++i) { - jl_value_t *argType = jl_nth_slot_type(lam->specTypes, i); + for (size_t i = nreq; i < jl_nparams(sig); ++i) { + jl_value_t *argType = jl_nth_slot_type(sig, i); // n.b. specTypes is required to be a datatype by construction for specsig if (is_uniquerep_Type(argType)) argType = jl_typeof(jl_tparam0(argType)); @@ -8339,6 +8346,7 @@ static jl_llvm_functions_t orc::ThreadSafeModule &TSM, jl_method_instance_t *lam, jl_code_info_t *src, + jl_value_t *abi, jl_value_t *jlrettype, jl_codegen_params_t ¶ms) { @@ -8417,7 +8425,7 @@ static jl_llvm_functions_t int n_ssavalues = jl_is_long(src->ssavaluetypes) ? jl_unbox_long(src->ssavaluetypes) : jl_array_nrows(src->ssavaluetypes); size_t vinfoslen = jl_array_dim0(src->slotflags); ctx.slots.resize(vinfoslen, jl_varinfo_t(ctx.builder.getContext())); - assert(lam->specTypes); // the specTypes field should always be assigned + assert(abi); // the specTypes field should always be assigned // create SAvalue locations for SSAValue objects @@ -8426,7 +8434,7 @@ static jl_llvm_functions_t ctx.ssavalue_usecount.assign(n_ssavalues, 0); bool specsig, needsparams; - std::tie(specsig, needsparams) = uses_specsig(lam, jlrettype, params.params->prefer_specsig); + std::tie(specsig, needsparams) = uses_specsig(abi, lam, jlrettype, params.params->prefer_specsig); // step 3. some variable analysis size_t i; @@ -8436,7 +8444,7 @@ static jl_llvm_functions_t jl_sym_t *argname = slot_symbol(ctx, i); if (argname == jl_unused_sym) continue; - jl_value_t *ty = jl_nth_slot_type(lam->specTypes, i); + jl_value_t *ty = jl_nth_slot_type(abi, i); // TODO: jl_nth_slot_type should call jl_rewrap_unionall // specTypes is required to be a datatype by construction for specsig, but maybe not otherwise // OpaqueClosure implicitly loads the env @@ -8454,7 +8462,7 @@ static jl_llvm_functions_t if (va && ctx.vaSlot != -1) { jl_varinfo_t &varinfo = ctx.slots[ctx.vaSlot]; varinfo.isArgument = true; - vatyp = specsig ? compute_va_type(lam, nreq) : (jl_tuple_type); + vatyp = specsig ? compute_va_type(abi, nreq) : (jl_tuple_type); varinfo.value = mark_julia_type(ctx, (Value*)NULL, false, vatyp); } @@ -8505,7 +8513,7 @@ static jl_llvm_functions_t ArgNames[i] = name; } } - returninfo = get_specsig_function(ctx, M, NULL, declarations.specFunctionObject, lam->specTypes, + returninfo = get_specsig_function(ctx, M, NULL, declarations.specFunctionObject, abi, jlrettype, ctx.is_opaque_closure, JL_FEAT_TEST(ctx,gcstack_arg), ArgNames, nreq); f = cast(returninfo.decl.getCallee()); @@ -8539,8 +8547,8 @@ static jl_llvm_functions_t std::string wrapName; raw_string_ostream(wrapName) << "jfptr_" << ctx.name << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1); declarations.functionObject = wrapName; - size_t nparams = jl_nparams(lam->specTypes); - gen_invoke_wrapper(lam, jlrettype, returninfo, nparams, retarg, ctx.is_opaque_closure, declarations.functionObject, M, ctx.emission_context); + size_t nparams = jl_nparams(abi); + gen_invoke_wrapper(lam, abi, jlrettype, returninfo, nparams, retarg, ctx.is_opaque_closure, declarations.functionObject, M, ctx.emission_context); // TODO: add attributes: maybe_mark_argument_dereferenceable(Arg, argType) // TODO: add attributes: dereferenceable // TODO: (if needsparams) add attributes: dereferenceable, readonly, nocapture @@ -8562,7 +8570,7 @@ static jl_llvm_functions_t if (!params.getContext().shouldDiscardValueNames() && ctx.emission_context.params->debug_info_level >= 2 && lam->def.method && jl_is_method(lam->def.method) && lam->specTypes != (jl_value_t*)jl_emptytuple_type) { ios_t sigbuf; ios_mem(&sigbuf, 0); - jl_static_show_func_sig((JL_STREAM*) &sigbuf, (jl_value_t*)lam->specTypes); + jl_static_show_func_sig((JL_STREAM*) &sigbuf, (jl_value_t*)abi); f->addFnAttr("julia.fsig", StringRef(sigbuf.buf, sigbuf.size)); ios_close(&sigbuf); } @@ -8619,7 +8627,7 @@ static jl_llvm_functions_t else if (!specsig) subrty = debugcache.jl_di_func_sig; else - subrty = get_specsig_di(ctx, debugcache, jlrettype, lam->specTypes, dbuilder); + subrty = get_specsig_di(ctx, debugcache, jlrettype, abi, dbuilder); SP = dbuilder.createFunction(nullptr ,dbgFuncName // Name ,f->getName() // LinkageName @@ -8951,7 +8959,7 @@ static jl_llvm_functions_t nullptr, nullptr, /*isboxed*/true, AtomicOrdering::NotAtomic, false, sizeof(void*)); } else { - jl_value_t *argType = jl_nth_slot_type(lam->specTypes, i); + jl_value_t *argType = jl_nth_slot_type(abi, i); // TODO: jl_nth_slot_type should call jl_rewrap_unionall? // specTypes is required to be a datatype by construction for specsig, but maybe not otherwise bool isboxed = deserves_argbox(argType); @@ -9025,10 +9033,10 @@ static jl_llvm_functions_t assert(vi.boxroot == NULL); } else if (specsig) { - ctx.nvargs = jl_nparams(lam->specTypes) - nreq; + ctx.nvargs = jl_nparams(abi) - nreq; SmallVector vargs(ctx.nvargs); - for (size_t i = nreq; i < jl_nparams(lam->specTypes); ++i) { - jl_value_t *argType = jl_nth_slot_type(lam->specTypes, i); + for (size_t i = nreq; i < jl_nparams(abi); ++i) { + jl_value_t *argType = jl_nth_slot_type(abi, i); // n.b. specTypes is required to be a datatype by construction for specsig bool isboxed = deserves_argbox(argType); Type *llvmArgType = isboxed ? ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, argType); @@ -9954,6 +9962,7 @@ jl_llvm_functions_t jl_emit_code( orc::ThreadSafeModule &m, jl_method_instance_t *li, jl_code_info_t *src, + jl_value_t *abi, jl_codegen_params_t ¶ms) { JL_TIMING(CODEGEN, CODEGEN_LLVM); @@ -9962,8 +9971,10 @@ jl_llvm_functions_t jl_emit_code( assert((params.params == &jl_default_cgparams /* fast path */ || !params.cache || compare_cgparams(params.params, &jl_default_cgparams)) && "functions compiled with custom codegen params must not be cached"); + if (!abi) + abi = li->specTypes; JL_TRY { - decls = emit_function(m, li, src, src->rettype, params); + decls = emit_function(m, li, src, abi, src->rettype, params); auto stream = *jl_ExecutionEngine->get_dump_emitted_mi_name_stream(); if (stream) { jl_printf(stream, "%s\t", decls.specFunctionObject.c_str()); @@ -10030,11 +10041,11 @@ jl_llvm_functions_t jl_emit_codeinst( jl_codegen_params_t ¶ms) { JL_TIMING(CODEGEN, CODEGEN_Codeinst); - jl_timing_show_method_instance(codeinst->def, JL_TIMING_DEFAULT_BLOCK); + jl_timing_show_method_instance(jl_get_ci_mi(codeinst), JL_TIMING_DEFAULT_BLOCK); JL_GC_PUSH1(&src); if (!src) { src = (jl_code_info_t*)jl_atomic_load_relaxed(&codeinst->inferred); - jl_method_instance_t *mi = codeinst->def; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); jl_method_t *def = mi->def.method; // Check if this is the generic method for opaque closure wrappers - // if so, this must compile specptr such that it holds the specptr -> invoke wrapper @@ -10052,7 +10063,7 @@ jl_llvm_functions_t jl_emit_codeinst( } } assert(jl_egal((jl_value_t*)jl_atomic_load_relaxed(&codeinst->debuginfo), (jl_value_t*)src->debuginfo) && "trying to generate code for a codeinst for an incompatible src"); - jl_llvm_functions_t decls = jl_emit_code(m, codeinst->def, src, params); + jl_llvm_functions_t decls = jl_emit_code(m, jl_get_ci_mi(codeinst), src, get_ci_abi(codeinst), params); const std::string &specf = decls.specFunctionObject; const std::string &f = decls.functionObject; @@ -10060,7 +10071,7 @@ jl_llvm_functions_t jl_emit_codeinst( // Prepare debug info to receive this function // record that this function name came from this linfo, // so we can build a reverse mapping for debug-info. - bool toplevel = !jl_is_method(codeinst->def->def.method); + bool toplevel = !jl_is_method(jl_get_ci_mi(codeinst)->def.method); if (!toplevel) { //Safe b/c params holds context lock const DataLayout &DL = m.getModuleUnlocked()->getDataLayout(); @@ -10076,7 +10087,7 @@ jl_llvm_functions_t jl_emit_codeinst( jl_value_t *inferred = jl_atomic_load_relaxed(&codeinst->inferred); // don't change inferred state if (inferred) { - jl_method_t *def = codeinst->def->def.method; + jl_method_t *def = jl_get_ci_mi(codeinst)->def.method; if (// keep code when keeping everything !(JL_DELETE_NON_INLINEABLE) || // aggressively keep code when debugging level >= 2 diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index 31f1ba8281a89..ce8406bf91490 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -167,7 +167,7 @@ void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const D // Non-opaque-closure MethodInstances are considered globally rooted // through their methods, but for OC, we need to create a global root // here. - jl_method_instance_t *mi = codeinst->def; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); if (jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure) jl_as_global_root((jl_value_t*)mi, 1); getJITDebugRegistry().add_code_in_flight(name, codeinst, DL); @@ -374,7 +374,7 @@ void JITDebugInfoRegistry::registerJITObject(const object::ObjectFile &Object, jl_method_instance_t *mi = NULL; if (codeinst) { JL_GC_PROMISE_ROOTED(codeinst); - mi = codeinst->def; + mi = jl_get_ci_mi(codeinst); } jl_profile_atomic([&]() JL_NOTSAFEPOINT { if (mi) diff --git a/src/engine.cpp b/src/engine.cpp index 2b68de731c4dd..858f37b55e85e 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -139,7 +139,7 @@ void jl_engine_fulfill(jl_code_instance_t *ci, jl_code_info_t *src) { jl_task_t *ct = jl_current_task; std::unique_lock lock(engine_lock); - auto record = Reservations.find(InferKey{ci->def, ci->owner}); + auto record = Reservations.find(InferKey{jl_get_ci_mi(ci), ci->owner}); if (record == Reservations.end() || record->second.ci != ci) return; assert(jl_atomic_load_relaxed(&ct->tid) == record->second.tid); diff --git a/src/gf.c b/src/gf.c index a5ba309784557..d220ad057176a 100644 --- a/src/gf.c +++ b/src/gf.c @@ -538,7 +538,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_task_t *ct = jl_current_task; jl_code_instance_t *codeinst = (jl_code_instance_t*)jl_gc_alloc(ct->ptls, sizeof(jl_code_instance_t), jl_code_instance_type); - codeinst->def = mi; + codeinst->def = (jl_value_t*)mi; codeinst->owner = owner; jl_atomic_store_relaxed(&codeinst->edges, edges); jl_atomic_store_relaxed(&codeinst->min_world, min_world); @@ -1772,17 +1772,18 @@ static void invalidate_code_instance(jl_code_instance_t *replaced, size_t max_wo JL_GC_POP(); } //jl_static_show(JL_STDERR, (jl_value_t*)replaced->def); - if (!jl_is_method(replaced->def->def.method)) + jl_method_instance_t *replaced_mi = jl_get_ci_mi(replaced); + if (!jl_is_method(replaced_mi->def.method)) return; // shouldn't happen, but better to be safe - JL_LOCK(&replaced->def->def.method->writelock); + JL_LOCK(&replaced_mi->def.method->writelock); if (jl_atomic_load_relaxed(&replaced->max_world) == ~(size_t)0) { assert(jl_atomic_load_relaxed(&replaced->min_world) - 1 <= max_world && "attempting to set illogical world constraints (probable race condition)"); jl_atomic_store_release(&replaced->max_world, max_world); } assert(jl_atomic_load_relaxed(&replaced->max_world) <= max_world); // recurse to all backedges to update their valid range also - _invalidate_backedges(replaced->def, max_world, depth + 1); - JL_UNLOCK(&replaced->def->def.method->writelock); + _invalidate_backedges(replaced_mi, max_world, depth + 1); + JL_UNLOCK(&replaced_mi->def.method->writelock); } static void _invalidate_backedges(jl_method_instance_t *replaced_mi, size_t max_world, int depth) { @@ -2329,7 +2330,7 @@ void jl_method_table_activate(jl_methtable_t *mt, jl_typemap_entry_t *newentry) int replaced_edge; if (invokeTypes) { // n.b. normally we must have mi.specTypes <: invokeTypes <: m.sig (though it might not strictly hold), so we only need to check the other subtypes - if (jl_egal(invokeTypes, caller->def->def.method->sig)) + if (jl_egal(invokeTypes, jl_get_ci_mi(caller)->def.method->sig)) replaced_edge = 0; // if invokeTypes == m.sig, then the only way to change this invoke is to replace the method itself else replaced_edge = jl_subtype(invokeTypes, type) && is_replacing(ambig, type, m, d, n, invokeTypes, NULL, morespec); @@ -2907,7 +2908,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t jl_callptr_t ucache_invoke = jl_atomic_load_acquire(&ucache->invoke); if (ucache_invoke == NULL) { if ((!jl_is_method(def) || def->source == jl_nothing) && - !jl_cached_uninferred(jl_atomic_load_relaxed(&ucache->def->cache), world)) { + !jl_cached_uninferred(jl_atomic_load_relaxed(&jl_get_ci_mi(ucache)->cache), world)) { jl_throw(jl_new_struct(jl_missingcodeerror_type, (jl_value_t*)mi)); } jl_generate_fptr_for_unspecialized(ucache); @@ -2953,7 +2954,7 @@ jl_value_t *jl_fptr_args(jl_value_t *f, jl_value_t **args, uint32_t nargs, jl_co jl_value_t *jl_fptr_sparam(jl_value_t *f, jl_value_t **args, uint32_t nargs, jl_code_instance_t *m) { - jl_svec_t *sparams = m->def->sparam_vals; + jl_svec_t *sparams = jl_get_ci_mi(m)->sparam_vals; assert(sparams != jl_emptysvec); jl_fptr_sparam_t invoke = jl_atomic_load_relaxed(&m->specptr.fptr3); assert(invoke && "Forgot to set specptr for jl_fptr_sparam!"); diff --git a/src/interpreter.c b/src/interpreter.c index a465fe27f5084..b9bd1997caa17 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -154,7 +154,7 @@ static jl_value_t *do_invoke(jl_value_t **args, size_t nargs, interpreter_state if (codeinst->owner != jl_nothing) { jl_error("Failed to invoke or compile external codeinst"); } - result = jl_invoke(argv[0], nargs == 2 ? NULL : &argv[1], nargs - 2, codeinst->def); + result = jl_invoke(argv[0], nargs == 2 ? NULL : &argv[1], nargs - 2, jl_get_ci_mi(codeinst)); } } else { result = jl_invoke(argv[0], nargs == 2 ? NULL : &argv[1], nargs - 2, (jl_method_instance_t*)c); @@ -767,7 +767,7 @@ jl_code_info_t *jl_code_for_interpreter(jl_method_instance_t *mi, size_t world) jl_value_t *NOINLINE jl_fptr_interpret_call(jl_value_t *f, jl_value_t **args, uint32_t nargs, jl_code_instance_t *codeinst) { interpreter_state *s; - jl_method_instance_t *mi = codeinst->def; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); jl_task_t *ct = jl_current_task; size_t world = ct->world_age; jl_code_info_t *src = NULL; diff --git a/src/ircode.c b/src/ircode.c index 9e64e3fe2b574..99c5833ac3be7 100644 --- a/src/ircode.c +++ b/src/ircode.c @@ -1194,7 +1194,7 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t ios_close(s.s); JL_UNLOCK(&m->writelock); // Might GC if (metadata) { - code->parent = metadata->def; + code->parent = jl_get_ci_mi(metadata); jl_gc_wb(code, code->parent); code->rettype = metadata->rettype; jl_gc_wb(code, code->rettype); diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index a1b01af716bb4..bdb8298df41a6 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -379,7 +379,7 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t jl_init_function(proto.decl, params.TargetTriple); // TODO: maybe this can be cached in codeinst->specfptr? int8_t gc_state = jl_gc_unsafe_enter(ct->ptls); // codegen may contain safepoints (such as jl_subtype calls) - jl_method_instance_t *mi = codeinst->def; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); size_t nrealargs = jl_nparams(mi->specTypes); // number of actual arguments being passed bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure; emit_specsig_to_fptr1(proto.decl, proto.cc, proto.return_roots, mi->specTypes, codeinst->rettype, is_opaque_closure, nrealargs, params, pinvoke); @@ -569,7 +569,7 @@ static void jl_compile_codeinst_now(jl_code_instance_t *codeinst) jl_ExecutionEngine->addModule(std::move(TSM)); // may safepoint // If logging of the compilation stream is enabled, // then dump the method-instance specialization type to the stream - jl_method_instance_t *mi = codeinst->def; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); if (jl_is_method(mi->def.method)) { auto stream = *jl_ExecutionEngine->get_dump_compiles_stream(); if (stream) { @@ -690,7 +690,7 @@ static void jl_emit_codeinst_to_jit( params.cache = true; params.imaging_mode = imaging_default(); orc::ThreadSafeModule result_m = - jl_create_ts_module(name_from_method_instance(codeinst->def), params.tsctx, params.DL, params.TargetTriple); + jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)), params.tsctx, params.DL, params.TargetTriple); params.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0); JL_GC_PUSH1(¶ms.temporary_roots); jl_llvm_functions_t decls = jl_emit_codeinst(result_m, codeinst, src, params); // contains safepoints @@ -698,7 +698,7 @@ static void jl_emit_codeinst_to_jit( JL_GC_POP(); return; } - jl_optimize_roots(params, codeinst->def, *result_m.getModuleUnlocked()); // contains safepoints + jl_optimize_roots(params, jl_get_ci_mi(codeinst), *result_m.getModuleUnlocked()); // contains safepoints params.temporary_roots = nullptr; JL_GC_POP(); { // drop lock before acquiring engine_lock @@ -922,14 +922,14 @@ void jl_generate_fptr_for_unspecialized_impl(jl_code_instance_t *unspec) compiler_start_time = jl_hrtime(); jl_code_info_t *src = NULL; JL_GC_PUSH1(&src); - jl_method_t *def = unspec->def->def.method; + jl_method_t *def = jl_get_ci_mi(unspec)->def.method; if (jl_is_method(def)) { src = (jl_code_info_t*)def->source; if (src && (jl_value_t*)src != jl_nothing) src = jl_uncompress_ir(def, NULL, (jl_value_t*)src); } else { - jl_method_instance_t *mi = unspec->def; + jl_method_instance_t *mi = jl_get_ci_mi(unspec); jl_code_instance_t *uninferred = jl_cached_uninferred( jl_atomic_load_relaxed(&mi->cache), 1); assert(uninferred); @@ -2234,7 +2234,7 @@ StringRef JuliaOJIT::getFunctionAtAddress(uint64_t Addr, jl_callptr_t invoke, jl else { stream_fname << "jlsys_"; } - const char* unadorned_name = jl_symbol_name(codeinst->def->def.method->name); + const char* unadorned_name = jl_symbol_name(jl_get_ci_mi(codeinst)->def.method->name); stream_fname << unadorned_name << "_" << RLST_inc++; *fname = std::move(stream_fname.str()); // store to ReverseLocalSymbolTable addGlobalMapping(*fname, Addr); diff --git a/src/jitlayers.h b/src/jitlayers.h index b6f1e9ec20c6b..342cb516debd7 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -279,6 +279,7 @@ jl_llvm_functions_t jl_emit_code( orc::ThreadSafeModule &M, jl_method_instance_t *mi, jl_code_info_t *src, + jl_value_t *abi, jl_codegen_params_t ¶ms); jl_llvm_functions_t jl_emit_codeinst( diff --git a/src/jl_exported_data.inc b/src/jl_exported_data.inc index 8711c14514145..62acce6ce1d65 100644 --- a/src/jl_exported_data.inc +++ b/src/jl_exported_data.inc @@ -116,6 +116,7 @@ XX(jl_simplevector_type) \ XX(jl_slotnumber_type) \ XX(jl_ssavalue_type) \ + XX(jl_abioverride_type) \ XX(jl_stackovf_exception) \ XX(jl_string_type) \ XX(jl_symbol_type) \ diff --git a/src/jltypes.c b/src/jltypes.c index 52b993cd5aa4d..fbdfe497ea312 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -3656,7 +3656,7 @@ void jl_init_types(void) JL_GC_DISABLED "specsigflags", "precompile", "relocatability", "invoke", "specptr"), // function object decls jl_svec(18, - jl_method_instance_type, + jl_any_type, jl_any_type, jl_any_type, jl_ulong_type, @@ -3952,6 +3952,7 @@ void post_boot_hooks(void) jl_weakref_type = (jl_datatype_t*)core("WeakRef"); jl_vecelement_typename = ((jl_datatype_t*)jl_unwrap_unionall(core("VecElement")))->name; jl_nulldebuginfo = (jl_debuginfo_t*)core("NullDebugInfo"); + jl_abioverride_type = (jl_datatype_t*)core("ABIOverride"); jl_init_box_caches(); diff --git a/src/julia.h b/src/julia.h index 049416a33336f..a71f9db030274 100644 --- a/src/julia.h +++ b/src/julia.h @@ -426,7 +426,7 @@ typedef struct _jl_opaque_closure_t { // This type represents an executable operation typedef struct _jl_code_instance_t { JL_DATA_TYPE - jl_method_instance_t *def; // method this is specialized from + jl_value_t *def; // MethodInstance or ABIOverride jl_value_t *owner; // Compiler token this belongs to, `jl_nothing` is reserved for native _Atomic(struct _jl_code_instance_t*) next; // pointer to the next cache entry @@ -479,6 +479,13 @@ typedef struct _jl_code_instance_t { } specptr; // private data for `jlcall entry point } jl_code_instance_t; +// May be used as the ->def field of a CodeInstance to override the ABI +typedef struct _jl_abi_override_t { + JL_DATA_TYPE + jl_value_t *abi; + jl_method_instance_t *def; +} jl_abi_override_t; + // all values are callable as Functions typedef jl_value_t jl_function_t; @@ -935,6 +942,7 @@ extern JL_DLLIMPORT jl_datatype_t *jl_fielderror_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_atomicerror_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_missingcodeerror_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_lineinfonode_type JL_GLOBALLY_ROOTED; +extern JL_DLLIMPORT jl_datatype_t *jl_abioverride_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_stackovf_exception JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_memory_exception JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_readonlymemory_exception JL_GLOBALLY_ROOTED; @@ -1570,6 +1578,7 @@ static inline int jl_field_isconst(jl_datatype_t *st, int i) JL_NOTSAFEPOINT #define jl_is_llvmpointer(v) (((jl_datatype_t*)jl_typeof(v))->name == jl_llvmpointer_typename) #define jl_is_intrinsic(v) jl_typetagis(v,jl_intrinsic_type) #define jl_is_addrspacecore(v) jl_typetagis(v,jl_addrspacecore_type) +#define jl_is_abioverride(v) jl_typetagis(v,jl_abioverride_type) #define jl_genericmemory_isbitsunion(a) (((jl_datatype_t*)jl_typetagof(a))->layout->flags.arrayelem_isunion) JL_DLLEXPORT int jl_subtype(jl_value_t *a, jl_value_t *b); diff --git a/src/julia_internal.h b/src/julia_internal.h index e0e8158f8e0d9..e452ff315d527 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -693,6 +693,13 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( uint32_t effects, jl_value_t *analysis_results, uint8_t relocatability, jl_debuginfo_t *di, jl_svec_t *edges /* , int absolute_max*/); +STATIC_INLINE jl_method_instance_t *jl_get_ci_mi(jl_code_instance_t *ci JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT +{ + if (jl_is_abioverride(ci->def)) + return ((jl_abi_override_t*)ci->def)->def; + return (jl_method_instance_t*)ci->def; +} + JL_DLLEXPORT const char *jl_debuginfo_file(jl_debuginfo_t *debuginfo) JL_NOTSAFEPOINT; JL_DLLEXPORT const char *jl_debuginfo_file1(jl_debuginfo_t *debuginfo) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_module_t *jl_debuginfo_module1(jl_value_t *debuginfo_def) JL_NOTSAFEPOINT; diff --git a/src/precompile_utils.c b/src/precompile_utils.c index 4717351d499b0..f2777455c4ed1 100644 --- a/src/precompile_utils.c +++ b/src/precompile_utils.c @@ -336,7 +336,7 @@ static void *jl_precompile_worklist(jl_array_t *worklist, jl_array_t *extext_met n = jl_array_nrows(new_ext_cis); for (i = 0; i < n; i++) { jl_code_instance_t *ci = (jl_code_instance_t*)jl_array_ptr_ref(new_ext_cis, i); - precompile_enq_specialization_(ci->def, m); + precompile_enq_specialization_(jl_get_ci_mi(ci), m); } } } diff --git a/src/staticdata.c b/src/staticdata.c index a0d56f3e38f54..ca335bd0fefee 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -101,7 +101,7 @@ extern "C" { // TODO: put WeakRefs on the weak_refs list during deserialization // TODO: handle finalizers -#define NUM_TAGS 194 +#define NUM_TAGS 195 // An array of references that need to be restored from the sysimg // This is a manually constructed dual of the gvars array, which would be produced by codegen for Julia code, for C. @@ -216,6 +216,7 @@ jl_value_t **const*const get_tags(void) { INSERT_TAG(jl_addrspace_typename); INSERT_TAG(jl_addrspacecore_type); INSERT_TAG(jl_debuginfo_type); + INSERT_TAG(jl_abioverride_type); // special typenames INSERT_TAG(jl_tuple_typename); @@ -909,13 +910,14 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_ } if (s->incremental && jl_is_code_instance(v)) { jl_code_instance_t *ci = (jl_code_instance_t*)v; + jl_method_instance_t *mi = jl_get_ci_mi(ci); // make sure we don't serialize other reachable cache entries of foreign methods // Should this now be: // if (ci !in ci->defs->cache) // record_field_change((jl_value_t**)&ci->next, NULL); // Why are we checking that the method/module this originates from is in_image? // and then disconnect this CI? - if (jl_object_in_image((jl_value_t*)ci->def->def.value)) { + if (jl_object_in_image((jl_value_t*)mi->def.value)) { // TODO: if (ci in ci->defs->cache) record_field_change((jl_value_t**)&ci->next, NULL); } @@ -923,8 +925,8 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_ if (inferred && inferred != jl_nothing) { // disregard if there is nothing here to delete (e.g. builtins, unspecialized) if (!is_relocatable_ci(&relocatable_ext_cis, ci)) record_field_change((jl_value_t**)&ci->inferred, jl_nothing); - else if (jl_is_method(ci->def->def.method) && // don't delete toplevel code - ci->def->def.method->source) { // don't delete code from optimized opaque closures that can't be reconstructed (and builtins) + else if (jl_is_method(mi->def.method) && // don't delete toplevel code + mi->def.method->source) { // don't delete code from optimized opaque closures that can't be reconstructed (and builtins) if (jl_atomic_load_relaxed(&ci->max_world) != ~(size_t)0 || // delete all code that cannot run jl_atomic_load_relaxed(&ci->invoke) == jl_fptr_const_return) { // delete all code that just returns a constant record_field_change((jl_value_t**)&ci->inferred, jl_nothing); @@ -1809,7 +1811,7 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED fptr_id = JL_API_CONST; } else { - if (jl_is_method(ci->def->def.method)) { + if (jl_is_method(jl_get_ci_mi(ci)->def.method)) { builtin_id = jl_fptr_id(jl_atomic_load_relaxed(&ci->specptr.fptr)); if (builtin_id) { // found in the table of builtins assert(builtin_id >= 2); @@ -2352,9 +2354,9 @@ static void jl_update_all_fptrs(jl_serializer_state *s, jl_image_t *image) offset = ~offset; } jl_code_instance_t *codeinst = (jl_code_instance_t*)(base + offset); - assert(jl_is_method(codeinst->def->def.method) && jl_atomic_load_relaxed(&codeinst->invoke) != jl_fptr_const_return); + assert(jl_is_method(jl_get_ci_mi(codeinst)->def.method) && jl_atomic_load_relaxed(&codeinst->invoke) != jl_fptr_const_return); assert(specfunc ? jl_atomic_load_relaxed(&codeinst->invoke) != NULL : jl_atomic_load_relaxed(&codeinst->invoke) == NULL); - linfos[i] = codeinst->def; // now it's a MethodInstance + linfos[i] = jl_get_ci_mi(codeinst); // now it's a MethodInstance void *fptr = fvars.ptrs[i]; for (; clone_idx < fvars.nclones; clone_idx++) { uint32_t idx = fvars.clone_idxs[clone_idx] & jl_sysimg_val_mask; diff --git a/src/staticdata_utils.c b/src/staticdata_utils.c index ea0b7216155bd..5ff7a7b1b1fc0 100644 --- a/src/staticdata_utils.c +++ b/src/staticdata_utils.c @@ -188,7 +188,7 @@ static int has_backedge_to_worklist(jl_method_instance_t *mi, htable_t *visited, jl_code_instance_t *be; i = get_next_edge(mi->backedges, i, NULL, &be); JL_GC_PROMISE_ROOTED(be); // get_next_edge propagates the edge for us here - int child_found = has_backedge_to_worklist(be->def, visited, stack); + int child_found = has_backedge_to_worklist(jl_get_ci_mi(be), visited, stack); if (child_found == 1 || child_found == 2) { // found what we were looking for, so terminate early found = 1; @@ -219,7 +219,7 @@ static int is_relocatable_ci(htable_t *relocatable_ext_cis, jl_code_instance_t * { if (!ci->relocatability) return 0; - jl_method_instance_t *mi = ci->def; + jl_method_instance_t *mi = jl_get_ci_mi(ci); jl_method_t *m = mi->def.method; if (!ptrhash_has(relocatable_ext_cis, ci) && jl_object_in_image((jl_value_t*)m) && (!jl_is_method(m) || jl_object_in_image((jl_value_t*)m->module))) return 0; @@ -249,7 +249,7 @@ static jl_array_t *queue_external_cis(jl_array_t *list) assert(jl_is_code_instance(ci)); if (!ci->relocatability) continue; - jl_method_instance_t *mi = ci->def; + jl_method_instance_t *mi = jl_get_ci_mi(ci); jl_method_t *m = mi->def.method; if (ci->owner == jl_nothing && jl_atomic_load_relaxed(&ci->inferred) && jl_is_method(m) && jl_object_in_image((jl_value_t*)m->module)) { int found = has_backedge_to_worklist(mi, &visited, &stack); @@ -283,7 +283,7 @@ static void jl_collect_new_roots(htable_t *relocatable_ext_cis, jl_array_t *root for (size_t i = 0; i < l; i++) { jl_code_instance_t *ci = (jl_code_instance_t*)jl_array_ptr_ref(new_ext_cis, i); assert(jl_is_code_instance(ci)); - jl_method_t *m = ci->def->def.method; + jl_method_t *m = jl_get_ci_mi(ci)->def.method; assert(jl_is_method(m)); ptrhash_put(&mset, (void*)m, (void*)m); ptrhash_put(relocatable_ext_cis, (void*)ci, (void*)ci); @@ -864,7 +864,7 @@ static int jl_verify_method(jl_code_instance_t *codeinst, size_t *minworld, size *minworld = 1; size_t current_world = jl_atomic_load_relaxed(&jl_world_counter); *maxworld = current_world; - assert(jl_is_method_instance(codeinst->def) && jl_is_method(codeinst->def->def.method)); + assert(jl_is_method_instance(jl_get_ci_mi(codeinst)) && jl_is_method(jl_get_ci_mi(codeinst)->def.method)); void **bp = ptrhash_bp(visiting, codeinst); if (*bp != HT_NOTFOUND) return (char*)*bp - (char*)HT_NOTFOUND; // cycle idx @@ -893,7 +893,7 @@ static int jl_verify_method(jl_code_instance_t *codeinst, size_t *minworld, size size_t max_valid2; assert(!jl_is_method(edge)); // `Method`-edge isn't allowed for the optimized one-edge format if (jl_is_code_instance(edge)) - edge = (jl_value_t*)((jl_code_instance_t*)edge)->def; + edge = (jl_value_t*)jl_get_ci_mi((jl_code_instance_t*)edge); if (jl_is_method_instance(edge)) { jl_method_instance_t *mi = (jl_method_instance_t*)edge; sig = jl_type_intersection(mi->def.method->sig, (jl_value_t*)mi->specTypes); // TODO: ?? @@ -917,7 +917,7 @@ static int jl_verify_method(jl_code_instance_t *codeinst, size_t *minworld, size continue; } if (jl_is_code_instance(callee)) - callee = ((jl_code_instance_t*)callee)->def; + callee = jl_get_ci_mi((jl_code_instance_t*)callee); if (jl_is_method_instance(callee)) { meth = callee->def.method; } @@ -1048,7 +1048,7 @@ static void jl_insert_backedges(jl_array_t *edges, jl_array_t *ext_ci_list) for (size_t i = 0; i < nedges; i++) { jl_code_instance_t *codeinst = (jl_code_instance_t*)jl_array_ptr_ref(edges, i); jl_svec_t *callees = jl_atomic_load_relaxed(&codeinst->edges); - jl_method_instance_t *caller = codeinst->def; + jl_method_instance_t *caller = jl_get_ci_mi(codeinst); jl_verify_method_graph(codeinst, &stack, &visiting); size_t minvalid = jl_atomic_load_relaxed(&codeinst->min_world); size_t maxvalid = jl_atomic_load_relaxed(&codeinst->max_world); diff --git a/test/precompile.jl b/test/precompile.jl index 1607d4c6b502b..d9bbf524609c9 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -915,7 +915,7 @@ precompile_test_harness("code caching") do dir # external callers mods = Module[] for be in mi.backedges - push!(mods, (be.def.def::Method).module) # XXX + push!(mods, ((be.def::Core.MethodInstance).def::Method).module) # XXX end @test MA ∈ mods @test MB ∈ mods @@ -1837,7 +1837,7 @@ precompile_test_harness("PkgCacheInspector") do load_path m = only(external_methods).func::Method @test m.name == :repl_cmd && m.nargs < 2 @test new_ext_cis === nothing || any(new_ext_cis) do ci - mi = ci.def + mi = ci.def::Core.MethodInstance mi.specTypes == Tuple{typeof(Base.repl_cmd), Int, String} end end From ff97facbc94089f6964782f0d2b961a5c8f7b813 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:30:47 +0900 Subject: [PATCH 079/198] EAUtils: perform `code_escapes` with a global cache by default (#56868) In JuliaLang/julia#56860, `EAUtils.EscapeAnalyzer` was updated to create a new cache for each invocation of `code_escapes`, similar to how Cthulhu.jl behaves. However, `code_escapes` is often used for performance analysis like `@benchmark code_escapes(...)`, and in such cases, a large number of `CodeInstance`s can be generated for each invocation. This could potentially impact native code execution. So this commit changes the default behavior so that `code_escapes` uses the same pre-existing cache by default. We can still opt-in to perform a fresh analysis by specifying `cache_token=EAUtils.EscapeAnalyzerCacheToken()`. --- Compiler/test/EAUtils.jl | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Compiler/test/EAUtils.jl b/Compiler/test/EAUtils.jl index 64d2a62db8622..990a7de3b8141 100644 --- a/Compiler/test/EAUtils.jl +++ b/Compiler/test/EAUtils.jl @@ -19,6 +19,7 @@ using .Compiler: InferenceResult, InferenceState, OptimizationState, IRCode using .EA: analyze_escapes, ArgEscapeCache, ArgEscapeInfo, EscapeInfo, EscapeState mutable struct EscapeAnalyzerCacheToken end +global GLOBAL_EA_CACHE_TOKEN::EscapeAnalyzerCacheToken = EscapeAnalyzerCacheToken() struct EscapeResultForEntry ir::IRCode @@ -293,10 +294,10 @@ while caching the analysis results. - `world::UInt = Base.get_world_counter()`: controls the world age to use when looking up methods, use current world age if not specified. -- `cache_token::EscapeAnalyzerCacheToken = EscapeAnalyzerCacheToken()`: - specifies the cache token to use, by default a new token is generated to ensure - that `code_escapes` uses a fresh cache and performs a new analysis on each invocation. - If you with to perform analysis with the global cache enabled, specify a particular token instance. +- `cache_token::EscapeAnalyzerCacheToken = GLOBAL_EA_CACHE_TOKEN`: + specifies the cache token to use, by default a global token is used so that the analysis + can use the caches from previous invocations. If you with to use a fresh cache and perform + a new analysis, specify a new `EscapeAnalyzerCacheToken` instance. - `interp::EscapeAnalyzer = EscapeAnalyzer(world, cache_token)`: specifies the escape analyzer to use. - `debuginfo::Symbol = :none`: @@ -304,7 +305,7 @@ while caching the analysis results. """ function code_escapes(@nospecialize(f), @nospecialize(types=Base.default_tt(f)); world::UInt = get_world_counter(), - cache_token::EscapeAnalyzerCacheToken = EscapeAnalyzerCacheToken(), + cache_token::EscapeAnalyzerCacheToken = GLOBAL_EA_CACHE_TOKEN, debuginfo::Symbol = :none) tt = Base.signature_type(f, types) match = Base._which(tt; world, raise=true) @@ -314,7 +315,7 @@ end function code_escapes(mi::MethodInstance; world::UInt = get_world_counter(), - cache_token::EscapeAnalyzerCacheToken = EscapeAnalyzerCacheToken(), + cache_token::EscapeAnalyzerCacheToken = GLOBAL_EA_CACHE_TOKEN, interp::EscapeAnalyzer=EscapeAnalyzer(world, cache_token; entry_mi=mi), debuginfo::Symbol = :none) frame = Compiler.typeinf_frame(interp, mi, #=run_optimizer=#true) @@ -337,16 +338,16 @@ Note that this version does not cache the analysis results. - `world::UInt = Base.get_world_counter()`: controls the world age to use when looking up methods, use current world age if not specified. -- `cache_token::EscapeAnalyzerCacheToken = EscapeAnalyzerCacheToken()`: - specifies the cache token to use, by default a new token is generated to ensure - that `code_escapes` uses a fresh cache and performs a new analysis on each invocation. - If you with to perform analysis with the global cache enabled, specify a particular token instance. +- `cache_token::EscapeAnalyzerCacheToken = GLOBAL_EA_CACHE_TOKEN`: + specifies the cache token to use, by default a global token is used so that the analysis + can use the caches from previous invocations. If you with to use a fresh cache and perform + a new analysis, specify a new `EscapeAnalyzerCacheToken` instance. - `interp::AbstractInterpreter = EscapeAnalyzer(world, cache_token)`: specifies the abstract interpreter to use, by default a new `EscapeAnalyzer` with an empty cache is created. """ function code_escapes(ir::IRCode, nargs::Int; world::UInt = get_world_counter(), - cache_token::EscapeAnalyzerCacheToken = EscapeAnalyzerCacheToken(), + cache_token::EscapeAnalyzerCacheToken = GLOBAL_EA_CACHE_TOKEN, interp::AbstractInterpreter=EscapeAnalyzer(world, cache_token)) estate = analyze_escapes(ir, nargs, Compiler.optimizer_lattice(interp), Compiler.get_escape_cache(interp)) return EscapeResult(ir, estate) # return back the result From 083b24eaa4d5f5a0711791f16109e93d52cd6834 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 20 Dec 2024 20:38:01 +0100 Subject: [PATCH 080/198] Small ABIOverride follow up and add basic test (#56877) Just a basic `invoke` test for now. There's various other code paths that should also be tested with ABI overwrites, but this gives us the basic framework and more tests can be added as needed. --- Compiler/src/Compiler.jl | 3 ++- Compiler/src/typeinfer.jl | 3 --- Compiler/test/abioverride.jl | 52 ++++++++++++++++++++++++++++++++++++ Compiler/test/testgroups | 1 + base/reflection.jl | 13 ++++----- base/runtime_internals.jl | 11 ++++++++ src/codegen.cpp | 25 +++++++++++------ 7 files changed, 90 insertions(+), 18 deletions(-) create mode 100644 Compiler/test/abioverride.jl diff --git a/Compiler/src/Compiler.jl b/Compiler/src/Compiler.jl index 2f4efda51da9b..a9ab27a682ad7 100644 --- a/Compiler/src/Compiler.jl +++ b/Compiler/src/Compiler.jl @@ -65,7 +65,8 @@ using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospeciali kwerr, lookup_binding_partition, may_invoke_generator, methods, midpoint, moduleroot, partition_restriction, quoted, rename_unionall, rewrap_unionall, specialize_method, structdiff, tls_world_age, unconstrain_vararg_length, unionlen, uniontype_layout, - uniontypes, unsafe_convert, unwrap_unionall, unwrapva, vect, widen_diagonal + uniontypes, unsafe_convert, unwrap_unionall, unwrapva, vect, widen_diagonal, + _uncompressed_ir using Base.Order import Base: ==, _topmod, append!, convert, copy, copy!, findall, first, get, get!, diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index 2e9fcf497faf6..f7cd574abbcef 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -1092,9 +1092,6 @@ function ci_meets_requirement(code::CodeInstance, source_mode::UInt8) return false end -_uncompressed_ir(codeinst::CodeInstance, s::String) = - ccall(:jl_uncompress_ir, Ref{CodeInfo}, (Any, Any, Any), codeinst.def.def::Method, codeinst, s) - # compute (and cache) an inferred AST and return type function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance, source_mode::UInt8) start_time = ccall(:jl_typeinf_timing_begin, UInt64, ()) diff --git a/Compiler/test/abioverride.jl b/Compiler/test/abioverride.jl new file mode 100644 index 0000000000000..d35fa8876cf1c --- /dev/null +++ b/Compiler/test/abioverride.jl @@ -0,0 +1,52 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +using Base.Meta +include("irutils.jl") + +# In this test, we will manually construct a CodeInstance that specializes the `myplus` +# method on a constant for the second argument and test various, interfaces surrounding +# CodeInstances with ABI overrides. +myplus(x::Int, y::Int) = x + y + +struct SecondArgConstOverride + arg2::Int +end + +world = Base.tls_world_age() +mi = Base.specialize_method(only(Base._methods_by_ftype(Tuple{typeof(myplus), Int, Int}, -1, world))) +interp = Compiler.NativeInterpreter(world) +ci = Compiler.typeinf_ext(interp, mi, Compiler.SOURCE_MODE_FORCE_SOURCE) + +function is_known_call(@nospecialize(x), @nospecialize(func), src::Core.CodeInfo) + isexpr(x, :call) || return false + ft = Compiler.argextype(x.args[1], src, Compiler.VarState[]) + return Compiler.singleton_type(ft) === func +end + +# Construct a CodeInstance with an ABI override +new_ci = let new_source = copy(Base.uncompressed_ir(ci)) + ## Sanity check + @assert length(new_source.code) == 2 + add = new_source.code[1] + @assert is_known_call(add, Core.Intrinsics.add_int, new_source) && add.args[3] == Core.Argument(3) + + ## Replace x + y by x + 1 + add.args[3] = 1 + + ## Remove the argument + resize!(new_source.slotnames, 2) + resize!(new_source.slotflags, 2) + + # Construct the CodeInstance + new_ci = Core.CodeInstance(Core.ABIOverride(Tuple{typeof(myplus), Int}, mi), + SecondArgConstOverride(1), ci.rettype, ci.exctype, nothing, new_source, + Int32(0), ci.min_world, ci.max_world, ci.ipo_purity_bits, nothing, ci.relocatability, ci.debuginfo, ci.edges) + + # Poke the CI into the global cache + ccall(:jl_mi_cache_insert, Cvoid, (Any, Any), mi, new_ci) + + new_ci +end + +@test contains(repr(new_ci), "ABI Overridden") +@test invoke(myplus, new_ci, 10) == 11 diff --git a/Compiler/test/testgroups b/Compiler/test/testgroups index 5075caa8b34cf..d17735a52a025 100644 --- a/Compiler/test/testgroups +++ b/Compiler/test/testgroups @@ -15,3 +15,4 @@ ssair tarjan validation special_loading +abioverride diff --git a/base/reflection.jl b/base/reflection.jl index 9246b4cb0ac71..be344648f8f52 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -131,12 +131,13 @@ isempty(mt::Core.MethodTable) = (mt.defs === nothing) uncompressed_ir(m::Method) = isdefined(m, :source) ? _uncompressed_ir(m) : isdefined(m, :generator) ? error("Method is @generated; try `code_lowered` instead.") : error("Code for this Method is not available.") -function _uncompressed_ir(m::Method) - s = m.source - if s isa String - s = ccall(:jl_uncompress_ir, Ref{CodeInfo}, (Any, Ptr{Cvoid}, Any), m, C_NULL, s) - end - return s::CodeInfo + +function uncompressed_ir(ci::CodeInstance) + inferred = ci.inferred + isa(inferred, CodeInfo) && return inferred + isa(inferred, String) && return _uncompressed_ir(ci, inferred) + inferred === nothing && error("Inferred code was deleted.") + error(string("Unknown inferred code type ", typeof(inferred))) end # for backwards compat diff --git a/base/runtime_internals.jl b/base/runtime_internals.jl index cbbde7d9535a2..13c467667c51e 100644 --- a/base/runtime_internals.jl +++ b/base/runtime_internals.jl @@ -1391,6 +1391,17 @@ end hasgenerator(m::Method) = isdefined(m, :generator) hasgenerator(m::Core.MethodInstance) = hasgenerator(m.def::Method) +function _uncompressed_ir(m::Method) + s = m.source + if s isa String + s = ccall(:jl_uncompress_ir, Ref{CodeInfo}, (Any, Ptr{Cvoid}, Any), m, C_NULL, s) + end + return s::CodeInfo +end + +_uncompressed_ir(codeinst::CodeInstance, s::String) = + ccall(:jl_uncompress_ir, Ref{CodeInfo}, (Any, Any, Any), codeinst.def.def::Method, codeinst, s) + """ Base.generating_output([incremental::Bool])::Bool diff --git a/src/codegen.cpp b/src/codegen.cpp index 9ae905a8aba32..5bf7c74deedcb 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5440,6 +5440,22 @@ static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, jl_method_instance_ specFunctionObject, fromexternal, argv, nargs, cc, return_roots, inferred_retty, age_ok); } +static jl_value_t *get_ci_abi(jl_code_instance_t *ci) +{ + if (jl_typeof(ci->def) == (jl_value_t*)jl_abioverride_type) + return ((jl_abi_override_t*)ci->def)->abi; + return jl_get_ci_mi(ci)->specTypes; +} + +static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, jl_code_instance_t *ci, jl_value_t *jlretty, StringRef specFunctionObject, jl_code_instance_t *fromexternal, + ArrayRef argv, size_t nargs, jl_returninfo_t::CallingConv *cc, unsigned *return_roots, jl_value_t *inferred_retty, Value *age_ok) +{ + jl_method_instance_t *mi = jl_get_ci_mi(ci); + bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure; + return emit_call_specfun_other(ctx, is_opaque_closure, get_ci_abi(ci), jlretty, NULL, + specFunctionObject, fromexternal, argv, nargs, cc, return_roots, inferred_retty, age_ok); +} + static jl_cgval_t emit_call_specfun_boxed(jl_codectx_t &ctx, jl_value_t *jlretty, StringRef specFunctionObject, jl_code_instance_t *fromexternal, ArrayRef argv, size_t nargs, jl_value_t *inferred_retty, Value *age_ok) { @@ -5487,13 +5503,6 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt) return emit_invoke(ctx, lival, argv, nargs, rt, nullptr); } -static jl_value_t *get_ci_abi(jl_code_instance_t *ci) -{ - if (jl_typeof(ci->def) == (jl_value_t*)jl_abioverride_type) - return ((jl_abi_override_t*)ci->def)->abi; - return jl_get_ci_mi(ci)->specTypes; -} - static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayRef argv, size_t nargs, jl_value_t *rt, Value *age_ok) { ++EmittedInvokes; @@ -5589,7 +5598,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; unsigned return_roots = 0; if (specsig) - result = emit_call_specfun_other(ctx, mi, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt, age_ok); + result = emit_call_specfun_other(ctx, codeinst, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt, age_ok); else result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, rt, age_ok); handled = true; From bb1892ebac9f4406a1360afa0d2882751792335b Mon Sep 17 00:00:00 2001 From: Fons van der Plas Date: Sat, 21 Dec 2024 17:12:27 +0100 Subject: [PATCH 081/198] Package docstring: more peaceful README introduction (#56798) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hello! 👋 #39093 is great! This PR styles the banner ("Displaying contents of readme found at ...") differently: Before: ``` help?> DifferentialEquations search: DifferentialEquations No docstring found for module DifferentialEquations. Exported names ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡ @derivatives, @ode_def, @ode_def_all, @ode_def_bare, ... (manually truncated) Displaying contents of readme found at /Users/ian/.julia/packages/DifferentialEquations/HSWeG/README.md ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡ DifferentialEquations.jl ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡ (Image: Join the chat at https://gitter.im/JuliaDiffEq/Lobby) (https://gitter.im/JuliaDiffEq/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) (Image: Build Status) (https://github.com/SciML/DifferentialEquations.jl/actions?query=workflow%3ACI) (Image: Stable) (http://diffeq.sciml.ai/stable/) (Image: Dev) (http://diffeq.sciml.ai/dev/) (Image: DOI) (https://zenodo.org/badge/latestdoi/58516043) This is a suite for numerically solving differential equations written in Julia and available for use in Julia, Python, and R. The purpose of this package is to supply efficient Julia implementations of solvers for various differential equations. Equations within the realm of this package include: • Discrete equations (function maps, discrete stochastic (Gillespie/Markov) simulations) • Ordinary differential equations (ODEs) ``` After: ``` help?> DifferentialEquations search: DifferentialEquations No docstring found for module DifferentialEquations. Exported names ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡ @derivatives, @ode_def, @ode_def_all, @ode_def_bare, ... (manually truncated) ──────────────────────────────────────────────────────────────────────────── Package description from README.md: DifferentialEquations.jl ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡ (Image: Join the chat at https://gitter.im/JuliaDiffEq/Lobby) (https://gitter.im/JuliaDiffEq/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) (Image: Build Status) (https://github.com/SciML/DifferentialEquations.jl/actions?query=workflow%3ACI) (Image: Stable) (http://diffeq.sciml.ai/stable/) (Image: Dev) (http://diffeq.sciml.ai/dev/) (Image: DOI) (https://zenodo.org/badge/latestdoi/58516043) This is a suite for numerically solving differential equations written in Julia and available for use in Julia, Python, and R. The purpose of this package is to supply efficient Julia implementations of solvers for various differential equations. Equations within the realm of this package include: • Discrete equations (function maps, discrete stochastic (Gillespie/Markov) simulations) • Ordinary differential equations (ODEs) ``` I think this makes it a bit less technical (the word "Displaying" and the long filename), and it improves the reading flow. --- stdlib/REPL/src/docview.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index 566046f325499..0868d3e80c824 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -416,7 +416,9 @@ function summarize(io::IO, m::Module, binding::Binding; nlines::Int = 200) if !isnothing(readme_path) readme_lines = readlines(readme_path) isempty(readme_lines) && return # don't say we are going to print empty file - println(io, "# Displaying contents of readme found at `$(readme_path)`") + println(io) + println(io, "---") + println(io, "_Package description from `$(basename(readme_path))`:_") for line in first(readme_lines, nlines) println(io, line) end From b772be322f737b7af15874ee49c0cb23218f211a Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 22 Dec 2024 03:21:01 +0530 Subject: [PATCH 082/198] Support indexing `Broadcasted` objects using `Integer`s (#56470) This adds support for `IndexLinear` `eachindex`, as well as bounds-checking and `getindex` for a `Broadcasted` with an `Integer` index. Instead of using the number of dimensions in `eachindex` to determine whether to use `CartesianIndices`, we may use the `IndexStyle`. This should not change anything currently, but this adds the possibility of `nD` broadcasting using linear indexing if the `IndexStyle` of the `Broadcasted` object is `IndexLinear`. After this, ```julia julia> bc = Broadcast.broadcasted(+, reshape(1:4, 2, 2), 1:2) Base.Broadcast.Broadcasted(+, ([1 3; 2 4], 1:2)) julia> eachindex(bc) CartesianIndices((2, 2)) julia> eachindex(IndexLinear(), bc) Base.OneTo(4) julia> [bc[I] for I in eachindex(IndexLinear(), bc)] 4-element Vector{Int64}: 2 4 4 6 julia> vec(collect(bc)) 4-element Vector{Int64}: 2 4 4 6 ``` This PR doesn't add true linear indexing support for `IndexCartesian` `Broadcasted` objects. In such cases, an `Integer` index is converted to a `CartesianIndex` before it is used in indexing. --- base/broadcast.jl | 26 +++++++++++++++++++++----- test/broadcast.jl | 25 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/base/broadcast.jl b/base/broadcast.jl index 927c946e53e02..7f278fc1ca66f 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -250,9 +250,11 @@ BroadcastStyle(::Type{<:Broadcasted{S}}) where {S<:Union{Nothing,Unknown}} = argtype(::Type{BC}) where {BC<:Broadcasted} = fieldtype(BC, :args) argtype(bc::Broadcasted) = argtype(typeof(bc)) -@inline Base.eachindex(bc::Broadcasted) = _eachindex(axes(bc)) -_eachindex(t::Tuple{Any}) = t[1] -_eachindex(t::Tuple) = CartesianIndices(t) +@inline Base.eachindex(bc::Broadcasted) = eachindex(IndexStyle(bc), bc) +@inline Base.eachindex(s::IndexStyle, bc::Broadcasted) = _eachindex(s, axes(bc)) +_eachindex(::IndexCartesian, t::Tuple) = CartesianIndices(t) +_eachindex(s::IndexLinear, t::Tuple) = eachindex(s, LinearIndices(t)) +_eachindex(::IndexLinear, t::Tuple{Any}) = t[1] Base.IndexStyle(bc::Broadcasted) = IndexStyle(typeof(bc)) Base.IndexStyle(::Type{<:Broadcasted{<:Any,<:Tuple{Any}}}) = IndexLinear() @@ -604,18 +606,32 @@ Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple{}) = () (Base.length(ind1)::Integer != 1, keep...), (first(ind1), Idefault...) end -@inline function Base.getindex(bc::Broadcasted, Is::Vararg{Union{Integer,CartesianIndex},N}) where {N} +Base.@propagate_inbounds function Base.getindex(bc::Broadcasted, Is::Vararg{Union{Integer,CartesianIndex},N}) where {N} I = to_index(Base.IteratorsMD.flatten(Is)) + _getindex(IndexStyle(bc), bc, I) +end +@inline function _getindex(::IndexStyle, bc, I) @boundscheck checkbounds(bc, I) @inbounds _broadcast_getindex(bc, I) end +Base.@propagate_inbounds function _getindex(s::IndexCartesian, bc, I::Integer) + C = CartesianIndices(axes(bc)) + _getindex(s, bc, C[I]) +end +Base.@propagate_inbounds function _getindex(s::IndexLinear, bc, I::CartesianIndex) + L = LinearIndices(axes(bc)) + _getindex(s, bc, L[I]) +end to_index(::Tuple{}) = CartesianIndex() to_index(Is::Tuple{Any}) = Is[1] to_index(Is::Tuple) = CartesianIndex(Is) -@inline Base.checkbounds(bc::Broadcasted, I::Union{Integer,CartesianIndex}) = +@inline Base.checkbounds(bc::Broadcasted, I::CartesianIndex) = Base.checkbounds_indices(Bool, axes(bc), (I,)) || Base.throw_boundserror(bc, (I,)) +@inline Base.checkbounds(bc::Broadcasted, I::Integer) = + Base.checkindex(Bool, eachindex(IndexLinear(), bc), I) || Base.throw_boundserror(bc, (I,)) + """ _broadcast_getindex(A, I) diff --git a/test/broadcast.jl b/test/broadcast.jl index b2232258744ac..57441de67c0ce 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -876,6 +876,31 @@ let @test copy(bc) == [v for v in bc] == collect(bc) @test eltype(copy(bc)) == eltype([v for v in bc]) == eltype(collect(bc)) @test ndims(copy(bc)) == ndims([v for v in bc]) == ndims(collect(bc)) == ndims(bc) + + struct MyFill{T,N} <: AbstractArray{T,N} + val :: T + sz :: NTuple{N,Int} + end + Base.size(M::MyFill) = M.sz + function Base.getindex(M::MyFill{<:Any,N}, i::Vararg{Int, N}) where {N} + checkbounds(M, i...) + M.val + end + Base.IndexStyle(::Type{<:Base.Broadcast.Broadcasted{<:Any,<:Any,<:Any,<:Tuple{MyFill}}}) = IndexLinear() + bc = Broadcast.instantiate(Broadcast.broadcasted(+, MyFill(2, (3,3)))) + @test IndexStyle(bc) == IndexLinear() + @test eachindex(bc) === Base.OneTo(9) + @test bc[2] == bc[CartesianIndex(2,1)] + + for bc in Any[ + Broadcast.broadcasted(+, collect(reshape(1:9, 3, 3)), 1:3), # IndexCartesian + Broadcast.broadcasted(+, [1,2], 2), # IndexLinear + ] + bci = Broadcast.instantiate(bc) + for (Ilin, Icart) in zip(eachindex(IndexLinear(), bc), eachindex(IndexCartesian(), bc)) + @test bc[Ilin] == bc[Icart] + end + end end # issue 43847: collect preserves shape of broadcasted From 9d80765516d15b662ecccce40d95943fde205205 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 22 Dec 2024 03:49:49 +0530 Subject: [PATCH 083/198] Limit the scope of `@inbounds` in `searchsorted*` (#56882) This removes bounds-checking only in the indexing operation, instead of for the entire block. --- base/sort.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/base/sort.jl b/base/sort.jl index e1d46a8ba20ae..e1680d545bdc6 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -186,10 +186,10 @@ partialsort(v::AbstractVector, k::Union{Integer,OrdinalRange}; kws...) = function searchsortedfirst(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::keytype(v) where T<:Integer hi = hi + T(1) len = hi - lo - @inbounds while len != 0 + while len != 0 half_len = len >>> 0x01 m = lo + half_len - if lt(o, v[m], x) + if lt(o, @inbounds(v[m]), x) lo = m + 1 len -= half_len + 1 else @@ -206,9 +206,9 @@ function searchsortedlast(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::keyt u = T(1) lo = lo - u hi = hi + u - @inbounds while lo != hi - u + while lo != hi - u m = midpoint(lo, hi) - if lt(o, x, v[m]) + if lt(o, x, @inbounds(v[m])) hi = m else lo = m @@ -224,11 +224,11 @@ function searchsorted(v::AbstractVector, x, ilo::T, ihi::T, o::Ordering)::UnitRa u = T(1) lo = ilo - u hi = ihi + u - @inbounds while lo != hi - u + while lo != hi - u m = midpoint(lo, hi) - if lt(o, v[m], x) + if lt(o, @inbounds(v[m]), x) lo = m - elseif lt(o, x, v[m]) + elseif lt(o, x, @inbounds(v[m])) hi = m else a = searchsortedfirst(v, x, lo+u, m, o) From 5ee67b85513fc3e1a7bc4608bc850c6c046ccc07 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 22 Dec 2024 18:25:27 +0530 Subject: [PATCH 084/198] Remove trailing comma in 0-dim `reshape` summary (#56853) Currently, there is an extra comma in displaying the summary for a 0-dim `ReshapedArray`: ```julia julia> reshape(1:1) 0-dimensional reshape(::UnitRange{Int64}, ) with eltype Int64: 1 ``` This PR only prints the comma if `dims` isn't empty, so that we now obtain ```julia julia> reshape(1:1) 0-dimensional reshape(::UnitRange{Int64}) with eltype Int64: 1 ``` --- base/show.jl | 4 +++- test/show.jl | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/base/show.jl b/base/show.jl index d2f43e1ae92cc..5b121fdac5e80 100644 --- a/base/show.jl +++ b/base/show.jl @@ -3265,7 +3265,9 @@ showindices(io) = nothing function showarg(io::IO, r::ReshapedArray, toplevel) print(io, "reshape(") showarg(io, parent(r), false) - print(io, ", ", join(r.dims, ", ")) + if !isempty(r.dims) + print(io, ", ", join(r.dims, ", ")) + end print(io, ')') toplevel && print(io, " with eltype ", eltype(r)) return nothing diff --git a/test/show.jl b/test/show.jl index 07916c249d533..75f04c1e02096 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1861,6 +1861,9 @@ end B = @view ones(2)[r] Base.showarg(io, B, false) @test String(take!(io)) == "view(::Vector{Float64}, $(repr(r)))" + + Base.showarg(io, reshape(UnitRange{Int64}(1,1)), false) + @test String(take!(io)) == "reshape(::UnitRange{Int64})" end @testset "Methods" begin From cc4122caea994427177d3b8ad2b18585cb2d96e9 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 22 Dec 2024 21:02:59 +0100 Subject: [PATCH 085/198] Switch debug registry mapping to `CodeInstance` (#56878) Currently our debugging code maps from pointers to `MethodInstance`. However, I think it makes more sense to map to `CodeInstance` instead, since that's what we're actually compiling and as we're starting to make more use of external owners and custom specializations, we'll want to be able to annotate that in backtraces. This only adjusts the internal data structures - any actual printing changes for those sorts of use cases will have to come separately. --- base/errorshow.jl | 12 +++---- base/stacktraces.jl | 71 +++++++++++++++++++++++++++++++----------- src/debug-registry.h | 8 ++--- src/debuginfo.cpp | 33 +++++++++----------- src/julia_internal.h | 2 +- src/stackwalk.c | 2 +- test/opaque_closure.jl | 9 ++++-- test/stacktraces.jl | 7 +++-- 8 files changed, 88 insertions(+), 56 deletions(-) diff --git a/base/errorshow.jl b/base/errorshow.jl index 70ac8105feb21..d4b9b3666fbb7 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -915,9 +915,9 @@ function _collapse_repeated_frames(trace) [3] g(x::Int64) <-- useless @ Main ./REPL[1]:1 =# - if frame.linfo isa MethodInstance && last_frame.linfo isa MethodInstance && - frame.linfo.def isa Method && last_frame.linfo.def isa Method - m, last_m = frame.linfo.def::Method, last_frame.linfo.def::Method + m, last_m = StackTraces.frame_method_or_module(frame), + StackTraces.frame_method_or_module(last_frame) + if m isa Method && last_m isa Method params, last_params = Base.unwrap_unionall(m.sig).parameters, Base.unwrap_unionall(last_m.sig).parameters if last_m.nkw != 0 pos_sig_params = last_params[(last_m.nkw+2):end] @@ -944,7 +944,6 @@ function _collapse_repeated_frames(trace) return trace[kept_frames] end - function process_backtrace(t::Vector, limit::Int=typemax(Int); skipC = true) n = 0 last_frame = StackTraces.UNKNOWN @@ -965,9 +964,8 @@ function process_backtrace(t::Vector, limit::Int=typemax(Int); skipC = true) if (lkup.from_c && skipC) continue end - code = lkup.linfo - if code isa MethodInstance - def = code.def + if lkup.linfo isa Union{MethodInstance, CodeInstance} + def = StackTraces.frame_method_or_module(lkup) if def isa Method && def.name !== :kwcall && def.sig <: Tuple{typeof(Core.kwcall),NamedTuple,Any,Vararg} # hide kwcall() methods, which are probably internal keyword sorter methods # (we print the internal method instead, after demangling diff --git a/base/stacktraces.jl b/base/stacktraces.jl index e16757541cfc9..01e8a3cf62e72 100644 --- a/base/stacktraces.jl +++ b/base/stacktraces.jl @@ -7,7 +7,7 @@ module StackTraces import Base: hash, ==, show -import Core: CodeInfo, MethodInstance +import Core: CodeInfo, MethodInstance, CodeInstance using Base.IRShow: normalize_method_name, append_scopes!, LineInfoNode export StackTrace, StackFrame, stacktrace @@ -21,9 +21,9 @@ Stack information representing execution context, with the following fields: The name of the function containing the execution context. -- `linfo::Union{Method, Core.MethodInstance, Core.CodeInfo, Nothing}` +- `linfo::Union{Method, Core.MethodInstance, Core.CodeInstance, Core.CodeInfo, Nothing}` - The Method, MethodInstance, or CodeInfo containing the execution context (if it could be found), \ + The Method, MethodInstance, CodeInstance, or CodeInfo containing the execution context (if it could be found), \ or nothing (for example, if the inlining was a result of macro expansion). - `file::Symbol` @@ -54,9 +54,9 @@ struct StackFrame # this type should be kept platform-agnostic so that profiles file::Symbol "the line number in the file containing the execution context" line::Int - "the MethodInstance or CodeInfo containing the execution context (if it could be found), \ + "the CodeInstance or CodeInfo containing the execution context (if it could be found), \ or nothing (for example, if the inlining was a result of macro expansion)." - linfo::Union{MethodInstance, Method, CodeInfo, Nothing} + linfo::Union{Core.MethodInstance, Core.CodeInstance, Method, CodeInfo, Nothing} "true if the code is from C" from_c::Bool "true if the code is from an inlined frame" @@ -137,16 +137,26 @@ function lookup(ip::Base.InterpreterIP) line = meth.line codeinfo = meth.source else + func = top_level_scope_sym + file = empty_sym + line = Int32(0) if code isa Core.CodeInstance codeinfo = code.inferred::CodeInfo + def = code.def + if isa(def, Core.ABIOverride) + def = def.def + end + if isa(def, MethodInstance) && isa(def.def, Method) + meth = def.def + func = meth.name + file = meth.file + line = meth.line + end else codeinfo = code::CodeInfo end - func = top_level_scope_sym - file = empty_sym - line = Int32(0) end - def = (code isa MethodInstance ? code : StackTraces) # Module just used as a token for top-level code + def = (code isa CodeInfo ? StackTraces : code) # Module just used as a token for top-level code pc::Int = max(ip.stmt + 1, 0) # n.b. ip.stmt is 0-indexed scopes = LineInfoNode[] append_scopes!(scopes, pc, codeinfo.debuginfo, def) @@ -157,7 +167,7 @@ function lookup(ip::Base.InterpreterIP) scopes = map(scopes) do lno if inlined def = lno.method - def isa Union{Method,MethodInstance} || (def = nothing) + def isa Union{Method,Core.CodeInstance,MethodInstance} || (def = nothing) else def = codeinfo end @@ -227,6 +237,23 @@ end is_top_level_frame(f::StackFrame) = f.linfo isa CodeInfo || (f.linfo === nothing && f.func === top_level_scope_sym) +function frame_method_or_module(lkup::StackFrame) + code = lkup.linfo + code isa Method && return code + code isa Module && return code + mi = frame_mi(lkup) + mi isa MethodInstance || return nothing + return mi.def +end + +function frame_mi(lkup::StackFrame) + code = lkup.linfo + code isa Core.CodeInstance && (code = code.def) + code isa Core.ABIOverride && (code = code.def) + code isa MethodInstance || return nothing + return code +end + function show_spec_linfo(io::IO, frame::StackFrame) linfo = frame.linfo if linfo === nothing @@ -241,16 +268,18 @@ function show_spec_linfo(io::IO, frame::StackFrame) print(io, "top-level scope") elseif linfo isa Module Base.print_within_stacktrace(io, Base.demangle_function_name(string(frame.func)), bold=true) - elseif linfo isa MethodInstance - def = linfo.def - if def isa Module - Base.show_mi(io, linfo, #=from_stackframe=#true) + else + if linfo isa Union{MethodInstance, CodeInstance} + def = frame_method_or_module(frame) + if def isa Module + Base.show_mi(io, linfo, #=from_stackframe=#true) + else + show_spec_sig(io, def, frame_mi(frame).specTypes) + end else - show_spec_sig(io, def, linfo.specTypes) + m = linfo::Method + show_spec_sig(io, m, m.sig) end - else - m = linfo::Method - show_spec_sig(io, m, m.sig) end end @@ -302,6 +331,12 @@ end function Base.parentmodule(frame::StackFrame) linfo = frame.linfo + if linfo isa CodeInstance + linfo = linfo.def + if isa(linfo, Core.ABIOverride) + linfo = linfo.def + end + end if linfo isa MethodInstance def = linfo.def if def isa Module diff --git a/src/debug-registry.h b/src/debug-registry.h index 4d0b7a44f19e5..72189c60d3d40 100644 --- a/src/debug-registry.h +++ b/src/debug-registry.h @@ -14,7 +14,7 @@ typedef struct { int64_t slide; } objfileentry_t; -// Central registry for resolving function addresses to `jl_method_instance_t`s and +// Central registry for resolving function addresses to `jl_code_instance_t`s and // originating `ObjectFile`s (for the DWARF debug info). // // A global singleton instance is notified by the JIT whenever a new object is emitted, @@ -82,7 +82,7 @@ class JITDebugInfoRegistry struct image_info_t { uint64_t base; jl_image_fptrs_t fptrs; - jl_method_instance_t **fvars_linfo; + jl_code_instance_t **fvars_cinst; size_t fvars_n; }; @@ -124,7 +124,7 @@ class JITDebugInfoRegistry typedef rev_map objfilemap_t; objectmap_t objectmap{}; - rev_map> linfomap{}; + rev_map> cimap{}; // Maintain a mapping of unrealized function names -> linfo objects // so that when we see it get emitted, we can add a link back to the linfo @@ -145,7 +145,7 @@ class JITDebugInfoRegistry libc_frames_t libc_frames{}; void add_code_in_flight(llvm::StringRef name, jl_code_instance_t *codeinst, const llvm::DataLayout &DL) JL_NOTSAFEPOINT; - jl_method_instance_t *lookupLinfo(size_t pointer) JL_NOTSAFEPOINT; + jl_code_instance_t *lookupCodeInstance(size_t pointer) JL_NOTSAFEPOINT; void registerJITObject(const llvm::object::ObjectFile &Object, std::function getLoadAddress) JL_NOTSAFEPOINT; objectmap_t& getObjectMap() JL_NOTSAFEPOINT; diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index ce8406bf91490..c16fb559a6516 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -94,12 +94,12 @@ void JITDebugInfoRegistry::add_code_in_flight(StringRef name, jl_code_instance_t (**codeinst_in_flight)[mangle(name, DL)] = codeinst; } -jl_method_instance_t *JITDebugInfoRegistry::lookupLinfo(size_t pointer) +jl_code_instance_t *JITDebugInfoRegistry::lookupCodeInstance(size_t pointer) { jl_lock_profile(); - auto region = linfomap.lower_bound(pointer); - jl_method_instance_t *linfo = NULL; - if (region != linfomap.end() && pointer < region->first + region->second.first) + auto region = cimap.lower_bound(pointer); + jl_code_instance_t *linfo = NULL; + if (region != cimap.end() && pointer < region->first + region->second.first) linfo = region->second.second; jl_unlock_profile(); return linfo; @@ -371,14 +371,9 @@ void JITDebugInfoRegistry::registerJITObject(const object::ObjectFile &Object, codeinst_in_flight.erase(codeinst_it); } } - jl_method_instance_t *mi = NULL; - if (codeinst) { - JL_GC_PROMISE_ROOTED(codeinst); - mi = jl_get_ci_mi(codeinst); - } jl_profile_atomic([&]() JL_NOTSAFEPOINT { - if (mi) - linfomap[Addr] = std::make_pair(Size, mi); + if (codeinst) + cimap[Addr] = std::make_pair(Size, codeinst); hassection = true; objectmap.insert(std::pair{SectionLoadAddr, SectionInfo{ ObjectCopy, @@ -506,7 +501,7 @@ static int lookup_pointer( std::size_t semi_pos = func_name.find(';'); if (semi_pos != std::string::npos) { func_name = func_name.substr(0, semi_pos); - frame->linfo = NULL; // Looked up on Julia side + frame->ci = NULL; // Looked up on Julia side } } } @@ -692,9 +687,9 @@ openDebugInfo(StringRef debuginfopath, const debug_link_info &info) JL_NOTSAFEPO } extern "C" JL_DLLEXPORT_CODEGEN void jl_register_fptrs_impl(uint64_t image_base, const jl_image_fptrs_t *fptrs, - jl_method_instance_t **linfos, size_t n) + jl_code_instance_t **cinfos, size_t n) { - getJITDebugRegistry().add_image_info({(uintptr_t) image_base, *fptrs, linfos, n}); + getJITDebugRegistry().add_image_info({(uintptr_t) image_base, *fptrs, cinfos, n}); } template @@ -1177,13 +1172,13 @@ static int jl_getDylibFunctionInfo(jl_frame_t **frames, size_t pointer, int skip if (saddr == image.fptrs.clone_ptrs[i]) { uint32_t idx = image.fptrs.clone_idxs[i] & jl_sysimg_val_mask; if (idx < image.fvars_n) // items after this were cloned but not referenced directly by a method (such as our ccall PLT thunks) - frame0->linfo = image.fvars_linfo[idx]; + frame0->ci = image.fvars_cinst[idx]; break; } } for (size_t i = 0; i < image.fvars_n; i++) { if (saddr == image.fptrs.ptrs[i]) { - frame0->linfo = image.fvars_linfo[i]; + frame0->ci = image.fvars_cinst[i]; break; } } @@ -1255,16 +1250,16 @@ extern "C" JL_DLLEXPORT_CODEGEN int jl_getFunctionInfo_impl(jl_frame_t **frames_ int64_t slide; uint64_t symsize; if (jl_DI_for_fptr(pointer, &symsize, &slide, &Section, &context)) { - frames[0].linfo = getJITDebugRegistry().lookupLinfo(pointer); + frames[0].ci = getJITDebugRegistry().lookupCodeInstance(pointer); int nf = lookup_pointer(Section, context, frames_out, pointer, slide, true, noInline); return nf; } return jl_getDylibFunctionInfo(frames_out, pointer, skipC, noInline); } -extern "C" jl_method_instance_t *jl_gdblookuplinfo(void *p) JL_NOTSAFEPOINT +extern "C" jl_code_instance_t *jl_gdblookupci(void *p) JL_NOTSAFEPOINT { - return getJITDebugRegistry().lookupLinfo((size_t)p); + return getJITDebugRegistry().lookupCodeInstance((size_t)p); } #if defined(_OS_DARWIN_) && defined(LLVM_SHLIB) diff --git a/src/julia_internal.h b/src/julia_internal.h index e452ff315d527..f0debd31e2fec 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -1349,7 +1349,7 @@ typedef struct { char *func_name; char *file_name; int line; - jl_method_instance_t *linfo; + jl_code_instance_t *ci; int fromC; int inlined; } jl_frame_t; diff --git a/src/stackwalk.c b/src/stackwalk.c index d6fca2c909f23..28adef030395e 100644 --- a/src/stackwalk.c +++ b/src/stackwalk.c @@ -624,7 +624,7 @@ JL_DLLEXPORT jl_value_t *jl_lookup_code_address(void *ip, int skipC) jl_svecset(r, 1, jl_empty_sym); free(frame.file_name); jl_svecset(r, 2, jl_box_long(frame.line)); - jl_svecset(r, 3, frame.linfo != NULL ? (jl_value_t*)frame.linfo : jl_nothing); + jl_svecset(r, 3, frame.ci != NULL ? (jl_value_t*)frame.ci : jl_nothing); jl_svecset(r, 4, jl_box_bool(frame.fromC)); jl_svecset(r, 5, jl_box_bool(frame.inlined)); } diff --git a/test/opaque_closure.jl b/test/opaque_closure.jl index 79c456de127bd..6c988b068a668 100644 --- a/test/opaque_closure.jl +++ b/test/opaque_closure.jl @@ -347,9 +347,12 @@ let (bt, did_gc) = make_oc_and_collect_bt() GC.gc(true); GC.gc(true); GC.gc(true); @test did_gc[] @test any(stacktrace(bt)) do frame - isa(frame.linfo, Core.MethodInstance) || return false - isa(frame.linfo.def, Method) || return false - return frame.linfo.def.is_for_opaque_closure + li = frame.linfo + isa(li, Core.CodeInstance) && (li = li.def) + isa(li, Core.ABIOverride) && (li = li.def) + isa(li, Core.MethodInstance) || return false + isa(li.def, Method) || return false + return li.def.is_for_opaque_closure end end diff --git a/test/stacktraces.jl b/test/stacktraces.jl index 12da6d571013e..ca553c2a2e801 100644 --- a/test/stacktraces.jl +++ b/test/stacktraces.jl @@ -92,9 +92,10 @@ can_inline = Bool(Base.JLOptions().can_inline) for (frame, func, inlined) in zip(trace, [g,h,f], (can_inline, can_inline, false)) @test frame.func === typeof(func).name.mt.name # broken until #50082 can be addressed - @test frame.linfo.def.module === which(func, (Any,)).module broken=inlined - @test frame.linfo.def === which(func, (Any,)) broken=inlined - @test frame.linfo.specTypes === Tuple{typeof(func), Int} broken=inlined + mi = isa(frame.linfo, Core.CodeInstance) ? frame.linfo.def : frame.linfo + @test mi.def.module === which(func, (Any,)).module broken=inlined + @test mi.def === which(func, (Any,)) broken=inlined + @test mi.specTypes === Tuple{typeof(func), Int} broken=inlined # line @test frame.file === Symbol(@__FILE__) @test !frame.from_c From 34c30dcf46afc0564b58f9a116b2017c026af61d Mon Sep 17 00:00:00 2001 From: Erik Schnetter Date: Sun, 22 Dec 2024 17:17:01 -0500 Subject: [PATCH 086/198] binaryplatforms.jl: Remove duplicated riscv64 entry (#56888) --- base/binaryplatforms.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/base/binaryplatforms.jl b/base/binaryplatforms.jl index a372137edeb98..598b618f0d1ed 100644 --- a/base/binaryplatforms.jl +++ b/base/binaryplatforms.jl @@ -631,9 +631,6 @@ const arch_march_isa_mapping = let "a64fx" => get_set("aarch64", "a64fx"), "apple_m1" => get_set("aarch64", "apple_m1"), ], - "riscv64" => [ - "riscv64" => get_set("riscv64", "riscv64") - ], "powerpc64le" => [ "power8" => get_set("powerpc64le", "power8"), ], From ccfeb938caa7c244cb63e1d6f24400180fb9ea78 Mon Sep 17 00:00:00 2001 From: abhro <5664668+abhro@users.noreply.github.com> Date: Sun, 22 Dec 2024 19:32:40 -0500 Subject: [PATCH 087/198] Minor documentation updates (#56883) - Array/Vector/Matrix output showing - Syntax highlighting for fenced code block examples --------- Co-authored-by: Chengyu Han Co-authored-by: Lilith Orion Hafner --- base/asyncmap.jl | 12 +++---- base/docs/basedocs.jl | 32 +++++++++---------- base/essentials.jl | 4 +-- base/file.jl | 18 +++++------ base/genericmemory.jl | 2 +- base/multidimensional.jl | 6 ++-- base/show.jl | 2 +- base/stream.jl | 4 +-- doc/src/base/sort.md | 12 +++---- doc/src/manual/arrays.md | 16 +++++----- doc/src/manual/calling-c-and-fortran-code.md | 8 ++--- doc/src/manual/distributed-computing.md | 32 +++++++++---------- doc/src/manual/documentation.md | 2 +- doc/src/manual/functions.md | 4 +-- doc/src/manual/networking-and-streams.md | 10 +++--- stdlib/REPL/docs/src/index.md | 8 ++--- .../REPL/src/TerminalMenus/MultiSelectMenu.jl | 4 +-- stdlib/REPL/src/TerminalMenus/RadioMenu.jl | 8 ++--- stdlib/Random/src/Random.jl | 4 +-- stdlib/Sockets/src/addrinfo.jl | 6 ++-- 20 files changed, 97 insertions(+), 97 deletions(-) diff --git a/base/asyncmap.jl b/base/asyncmap.jl index 02e515d2e0c6c..1914ddc645f31 100644 --- a/base/asyncmap.jl +++ b/base/asyncmap.jl @@ -28,11 +28,11 @@ The following examples highlight execution in different tasks by returning the `objectid` of the tasks in which the mapping function is executed. First, with `ntasks` undefined, each element is processed in a different task. -``` +```julia-repl julia> tskoid() = objectid(current_task()); julia> asyncmap(x->tskoid(), 1:5) -5-element Array{UInt64,1}: +5-element Vector{UInt64}: 0x6e15e66c75c75853 0x440f8819a1baa682 0x9fb3eeadd0c83985 @@ -44,9 +44,9 @@ julia> length(unique(asyncmap(x->tskoid(), 1:5))) ``` With `ntasks=2` all elements are processed in 2 tasks. -``` +```julia-repl julia> asyncmap(x->tskoid(), 1:5; ntasks=2) -5-element Array{UInt64,1}: +5-element Vector{UInt64}: 0x027ab1680df7ae94 0xa23d2f80cd7cf157 0x027ab1680df7ae94 @@ -60,12 +60,12 @@ julia> length(unique(asyncmap(x->tskoid(), 1:5; ntasks=2))) With `batch_size` defined, the mapping function needs to be changed to accept an array of argument tuples and return an array of results. `map` is used in the modified mapping function to achieve this. -``` +```julia-repl julia> batch_func(input) = map(x->string("args_tuple: ", x, ", element_val: ", x[1], ", task: ", tskoid()), input) batch_func (generic function with 1 method) julia> asyncmap(batch_func, 1:5; ntasks=2, batch_size=2) -5-element Array{String,1}: +5-element Vector{String}: "args_tuple: (1,), element_val: 1, task: 9118321258196414413" "args_tuple: (2,), element_val: 2, task: 4904288162898683522" "args_tuple: (3,), element_val: 3, task: 9118321258196414413" diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index cef5e12a9e0d8..16175010a20fa 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -406,11 +406,11 @@ Assigning `a` to `b` does not create a copy of `b`; instead use [`copy`](@ref) o ```jldoctest julia> b = [1]; a = b; b[1] = 2; a -1-element Array{Int64, 1}: +1-element Vector{Int64}: 2 julia> b = [1]; a = copy(b); b[1] = 2; a -1-element Array{Int64, 1}: +1-element Vector{Int64}: 1 ``` @@ -420,7 +420,7 @@ julia> function f!(x); x[:] .+= 1; end f! (generic function with 1 method) julia> a = [1]; f!(a); a -1-element Array{Int64, 1}: +1-element Vector{Int64}: 2 ``` @@ -439,7 +439,7 @@ julia> a, b Assignment can operate on multiple variables in series, and will return the value of the right-hand-most expression: ```jldoctest julia> a = [1]; b = [2]; c = [3]; a = b = c -1-element Array{Int64, 1}: +1-element Vector{Int64}: 3 julia> b[1] = 2; a, b, c @@ -449,11 +449,11 @@ julia> b[1] = 2; a, b, c Assignment at out-of-bounds indices does not grow a collection. If the collection is a [`Vector`](@ref) it can instead be grown with [`push!`](@ref) or [`append!`](@ref). ```jldoctest julia> a = [1, 1]; a[3] = 2 -ERROR: BoundsError: attempt to access 2-element Array{Int64, 1} at index [3] +ERROR: BoundsError: attempt to access 2-element Vector{Int64} at index [3] [...] julia> push!(a, 2, 3) -4-element Array{Int64, 1}: +4-element Vector{Int64}: 1 1 2 @@ -467,7 +467,7 @@ ERROR: DimensionMismatch: tried to assign 0 elements to 1 destinations [...] julia> filter!(x -> x > 1, a) # in-place & thus more efficient than a = a[a .> 1] -2-element Array{Int64, 1}: +2-element Vector{Int64}: 2 3 @@ -490,14 +490,14 @@ assignment expression is converted into a single loop. julia> A = zeros(4, 4); B = [1, 2, 3, 4]; julia> A .= B -4×4 Array{Float64, 2}: +4×4 Matrix{Float64}: 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0 3.0 3.0 3.0 3.0 4.0 4.0 4.0 4.0 julia> A -4×4 Array{Float64, 2}: +4×4 Matrix{Float64}: 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0 3.0 3.0 3.0 3.0 @@ -1018,12 +1018,12 @@ collection or the last index of a dimension of an array. # Examples ```jldoctest julia> A = [1 2; 3 4] -2×2 Array{Int64, 2}: +2×2 Matrix{Int64}: 1 2 3 4 julia> A[end, :] -2-element Array{Int64, 1}: +2-element Vector{Int64}: 3 4 ``` @@ -1429,12 +1429,12 @@ collection or the first index of a dimension of an array. For example, # Examples ```jldoctest julia> A = [1 2; 3 4] -2×2 Array{Int64,2}: +2×2 Matrix{Int64}: 1 2 3 4 julia> A[begin, :] -2-element Array{Int64,1}: +2-element Matrix{Int64}: 1 2 ``` @@ -2826,7 +2826,7 @@ Construct an uninitialized [`Vector{T}`](@ref) of length `n`. # Examples ```julia-repl julia> Vector{Float64}(undef, 3) -3-element Array{Float64, 1}: +3-element Vector{Float64}: 6.90966e-310 6.90966e-310 6.90966e-310 @@ -2876,7 +2876,7 @@ Construct an uninitialized [`Matrix{T}`](@ref) of size `m`×`n`. # Examples ```julia-repl julia> Matrix{Float64}(undef, 2, 3) -2×3 Array{Float64, 2}: +2×3 Matrix{Float64}: 2.36365e-314 2.28473e-314 5.0e-324 2.26704e-314 2.26711e-314 NaN @@ -3014,7 +3014,7 @@ an alias for `UndefInitializer()`. # Examples ```julia-repl julia> Array{Float64, 1}(UndefInitializer(), 3) -3-element Array{Float64, 1}: +3-element Vector{Float64}: 2.2752528595e-314 2.202942107e-314 2.275252907e-314 diff --git a/base/essentials.jl b/base/essentials.jl index 3574116261968..fa5cf79192f56 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -93,7 +93,7 @@ f(y) = [x for x in y] # Examples -```julia +```julia-repl julia> f(A::AbstractArray) = g(A) f (generic function with 1 method) @@ -1270,7 +1270,7 @@ The `@world` macro is primarily used in the printing of bindings that are no lon available in the current world. ## Example -``` +```julia-repl julia> struct Foo; a::Int; end Foo diff --git a/base/file.jl b/base/file.jl index c69a598f42623..66e8114aba4ba 100644 --- a/base/file.jl +++ b/base/file.jl @@ -128,7 +128,7 @@ julia> pwd() "/home/JuliaUser" julia> cd(readdir, "/home/JuliaUser/Projects/julia") -34-element Array{String,1}: +34-element Vector{String}: ".circleci" ".freebsdci.sh" ".git" @@ -211,17 +211,17 @@ julia> mkpath("my/test/dir") # creates three directories "my/test/dir" julia> readdir() -1-element Array{String,1}: +1-element Vector{String}: "my" julia> cd("my") julia> readdir() -1-element Array{String,1}: +1-element Vector{String}: "test" julia> readdir("test") -1-element Array{String,1}: +1-element Vector{String}: "dir" julia> mkpath("intermediate_dir/actually_a_directory.txt") # creates two directories @@ -943,7 +943,7 @@ See also: [`walkdir`](@ref). julia> cd("/home/JuliaUser/dev/julia") julia> readdir() -30-element Array{String,1}: +30-element Vector{String}: ".appveyor.yml" ".git" ".gitattributes" @@ -953,7 +953,7 @@ julia> readdir() "usr-staging" julia> readdir(join=true) -30-element Array{String,1}: +30-element Vector{String}: "/home/JuliaUser/dev/julia/.appveyor.yml" "/home/JuliaUser/dev/julia/.git" "/home/JuliaUser/dev/julia/.gitattributes" @@ -963,7 +963,7 @@ julia> readdir(join=true) "/home/JuliaUser/dev/julia/usr-staging" julia> readdir("base") -145-element Array{String,1}: +145-element Vector{String}: ".gitignore" "Base.jl" "Enums.jl" @@ -973,7 +973,7 @@ julia> readdir("base") "weakkeydict.jl" julia> readdir("base", join=true) -145-element Array{String,1}: +145-element Vector{String}: "base/.gitignore" "base/Base.jl" "base/Enums.jl" @@ -983,7 +983,7 @@ julia> readdir("base", join=true) "base/weakkeydict.jl" julia> readdir(abspath("base"), join=true) -145-element Array{String,1}: +145-element Vector{String}: "/home/JuliaUser/dev/julia/base/.gitignore" "/home/JuliaUser/dev/julia/base/Base.jl" "/home/JuliaUser/dev/julia/base/Enums.jl" diff --git a/base/genericmemory.jl b/base/genericmemory.jl index fbf60255935a3..9d4614135050b 100644 --- a/base/genericmemory.jl +++ b/base/genericmemory.jl @@ -10,7 +10,7 @@ Fixed-size [`DenseVector{T}`](@ref DenseVector). `kind` can currently be either `:not_atomic` or `:atomic`. For details on what `:atomic` implies, see [`AtomicMemory`](@ref) `addrspace` can currently only be set to `Core.CPU`. It is designed to permit extension by other systems such as GPUs, which might define values such as: -``` +```julia module CUDA const Generic = bitcast(Core.AddrSpace{CUDA}, 0) const Global = bitcast(Core.AddrSpace{CUDA}, 1) diff --git a/base/multidimensional.jl b/base/multidimensional.jl index c82f1c1ba75d7..ba08f0679590b 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -1313,16 +1313,16 @@ See also: [`circshift`](@ref). # Examples ```julia-repl julia> src = reshape(Vector(1:16), (4,4)) -4×4 Array{Int64,2}: +4×4 Matrix{Int64}: 1 5 9 13 2 6 10 14 3 7 11 15 4 8 12 16 -julia> dest = OffsetArray{Int}(undef, (0:3,2:5)) +julia> dest = OffsetArray{Int}(undef, (0:3,2:5)); julia> circcopy!(dest, src) -OffsetArrays.OffsetArray{Int64,2,Array{Int64,2}} with indices 0:3×2:5: +4×4 OffsetArray(::Matrix{Int64}, 0:3, 2:5) with eltype Int64 with indices 0:3×2:5: 8 12 16 4 5 9 13 1 6 10 14 2 diff --git a/base/show.jl b/base/show.jl index 5b121fdac5e80..381c0e7d1480a 100644 --- a/base/show.jl +++ b/base/show.jl @@ -3150,7 +3150,7 @@ Print to a stream `io`, or return a string `str`, giving a brief description of a value. By default returns `string(typeof(x))`, e.g. [`Int64`](@ref). For arrays, returns a string of size and type info, -e.g. `10-element Array{Int64,1}`. +e.g. `10-element Vector{Int64}` or `9×4×5 Array{Float64, 3}`. # Examples ```jldoctest diff --git a/base/stream.jl b/base/stream.jl index 488acd41d2a9e..e81f65685df72 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -76,7 +76,7 @@ function getproperty(stream::LibuvStream, name::Symbol) end # IO -# +- GenericIOBuffer{T<:AbstractArray{UInt8,1}} (not exported) +# +- GenericIOBuffer{T<:AbstractVector{UInt8}} (not exported) # +- AbstractPipe (not exported) # . +- Pipe # . +- Process (not exported) @@ -89,7 +89,7 @@ end # . +- TTY (not exported) # . +- UDPSocket # . +- BufferStream (FIXME: 2.0) -# +- IOBuffer = Base.GenericIOBuffer{Array{UInt8,1}} +# +- IOBuffer = Base.GenericIOBuffer{Vector{UInt8}} # +- IOStream # IOServer diff --git a/doc/src/base/sort.md b/doc/src/base/sort.md index b9d333ef2a939..cef080c5f8995 100644 --- a/doc/src/base/sort.md +++ b/doc/src/base/sort.md @@ -41,7 +41,7 @@ indices that puts the array into sorted order: ```julia-repl julia> v = randn(5) -5-element Array{Float64,1}: +5-element Vector{Float64}: 0.297288 0.382396 -0.597634 @@ -49,7 +49,7 @@ julia> v = randn(5) -0.839027 julia> p = sortperm(v) -5-element Array{Int64,1}: +5-element Vector{Int64}: 5 3 4 @@ -57,7 +57,7 @@ julia> p = sortperm(v) 2 julia> v[p] -5-element Array{Float64,1}: +5-element Vector{Float64}: -0.839027 -0.597634 -0.0104452 @@ -69,7 +69,7 @@ Arrays can be sorted according to an arbitrary transformation of their values: ```julia-repl julia> sort(v, by=abs) -5-element Array{Float64,1}: +5-element Vector{Float64}: -0.0104452 0.297288 0.382396 @@ -81,7 +81,7 @@ Or in reverse order by a transformation: ```julia-repl julia> sort(v, by=abs, rev=true) -5-element Array{Float64,1}: +5-element Vector{Float64}: -0.839027 -0.597634 0.382396 @@ -93,7 +93,7 @@ If needed, the sorting algorithm can be chosen: ```julia-repl julia> sort(v, alg=InsertionSort) -5-element Array{Float64,1}: +5-element Vector{Float64}: -0.839027 -0.597634 -0.0104452 diff --git a/doc/src/manual/arrays.md b/doc/src/manual/arrays.md index 8a33d31a23cf8..02d71fcd9939e 100644 --- a/doc/src/manual/arrays.md +++ b/doc/src/manual/arrays.md @@ -355,7 +355,7 @@ julia> Int8[[1 2] [3 4]] Comprehensions provide a general and powerful way to construct arrays. Comprehension syntax is similar to set construction notation in mathematics: -``` +```julia A = [ F(x, y, ...) for x=rx, y=ry, ... ] ``` @@ -366,11 +366,11 @@ The result is an N-d dense array with dimensions that are the concatenation of t of the variable ranges `rx`, `ry`, etc. and each `F(x,y,...)` evaluation returns a scalar. The following example computes a weighted average of the current element and its left and right -neighbor along a 1-d grid. : +neighbor along a 1-d grid: ```julia-repl julia> x = rand(8) -8-element Array{Float64,1}: +8-element Vector{Float64}: 0.843025 0.869052 0.365105 @@ -381,7 +381,7 @@ julia> x = rand(8) 0.809411 julia> [ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ] -6-element Array{Float64,1}: +6-element Vector{Float64}: 0.736559 0.57468 0.685417 @@ -1040,7 +1040,7 @@ be to replicate the vector to the size of the matrix: julia> a = rand(2, 1); A = rand(2, 3); julia> repeat(a, 1, 3) + A -2×3 Array{Float64,2}: +2×3 Matrix{Float64}: 1.20813 1.82068 1.25387 1.56851 1.86401 1.67846 ``` @@ -1051,16 +1051,16 @@ without using extra memory, and applies the given function elementwise: ```julia-repl julia> broadcast(+, a, A) -2×3 Array{Float64,2}: +2×3 Matrix{Float64}: 1.20813 1.82068 1.25387 1.56851 1.86401 1.67846 julia> b = rand(1,2) -1×2 Array{Float64,2}: +1×2 Matrix{Float64}: 0.867535 0.00457906 julia> broadcast(+, a, b) -2×2 Array{Float64,2}: +2×2 Matrix{Float64}: 1.71056 0.847604 1.73659 0.873631 ``` diff --git a/doc/src/manual/calling-c-and-fortran-code.md b/doc/src/manual/calling-c-and-fortran-code.md index f675ab5eb16e8..d198c796a2e0b 100644 --- a/doc/src/manual/calling-c-and-fortran-code.md +++ b/doc/src/manual/calling-c-and-fortran-code.md @@ -27,9 +27,9 @@ commonly passed in registers when using C or Julia calling conventions. The syntax for [`@ccall`](@ref) to generate a call to the library function is: ```julia - @ccall library.function_name(argvalue1::argtype1, ...)::returntype - @ccall function_name(argvalue1::argtype1, ...)::returntype - @ccall $function_pointer(argvalue1::argtype1, ...)::returntype +@ccall library.function_name(argvalue1::argtype1, ...)::returntype +@ccall function_name(argvalue1::argtype1, ...)::returntype +@ccall $function_pointer(argvalue1::argtype1, ...)::returntype ``` where `library` is a string constant or literal (but see [Non-constant Function @@ -825,7 +825,7 @@ Instead define a [`Base.cconvert`](@ref) method and pass the variables directly automatically arranges that all of its arguments will be preserved from garbage collection until the call returns. If a C API will store a reference to memory allocated by Julia, after the `@ccall` returns, you must ensure that the object remains visible to the garbage collector. The suggested -way to do this is to make a global variable of type `Array{Ref,1}` to hold these values until +way to do this is to make a global variable of type `Vector{Ref}` to hold these values until the C library notifies you that it is finished with them. Whenever you have created a pointer to Julia data, you must ensure the original data exists until diff --git a/doc/src/manual/distributed-computing.md b/doc/src/manual/distributed-computing.md index f60dfb7004ada..873a94ffb2181 100644 --- a/doc/src/manual/distributed-computing.md +++ b/doc/src/manual/distributed-computing.md @@ -48,7 +48,7 @@ Generally it makes sense for `n` to equal the number of CPU threads (logical cor argument implicitly loads module [`Distributed`](@ref man-distributed). -```julia +```julia-repl $ julia -p 2 julia> r = remotecall(rand, 2, 2, 2) @@ -58,7 +58,7 @@ julia> s = @spawnat 2 1 .+ fetch(r) Future(2, 1, 5, nothing) julia> fetch(s) -2×2 Array{Float64,2}: +2×2 Matrix{Float64}: 1.18526 1.50912 1.16296 1.60607 ``` @@ -106,7 +106,7 @@ julia> s = @spawnat :any 1 .+ fetch(r) Future(3, 1, 5, nothing) julia> fetch(s) -2×2 Array{Float64,2}: +2×2 Matrix{Float64}: 1.38854 1.9098 1.20939 1.57158 ``` @@ -153,7 +153,7 @@ julia> function rand2(dims...) end julia> rand2(2,2) -2×2 Array{Float64,2}: +2×2 Matrix{Float64}: 0.153756 0.368514 1.15119 0.918912 @@ -262,7 +262,7 @@ as a programmatic means of adding, removing and querying the processes in a clus julia> using Distributed julia> addprocs(2) -2-element Array{Int64,1}: +2-element Vector{Int64}: 2 3 ``` @@ -734,7 +734,7 @@ serialization/deserialization of data. Consequently, the call refers to the same as passed - no copies are created. This behavior is highlighted below: ```julia-repl -julia> using Distributed; +julia> using Distributed julia> rc = RemoteChannel(()->Channel(3)); # RemoteChannel created on local node @@ -748,7 +748,7 @@ julia> for i in 1:3 julia> result = [take!(rc) for _ in 1:3]; julia> println(result); -Array{Int64,1}[[3], [3], [3]] +[[3], [3], [3]] julia> println("Num Unique objects : ", length(unique(map(objectid, result)))); Num Unique objects : 1 @@ -767,7 +767,7 @@ julia> for i in 1:3 julia> result = [take!(rc) for _ in 1:3]; julia> println(result); -Array{Int64,1}[[1], [2], [3]] +[[1], [2], [3]] julia> println("Num Unique objects : ", length(unique(map(objectid, result)))); Num Unique objects : 3 @@ -855,7 +855,7 @@ Here's a brief example: julia> using Distributed julia> addprocs(3) -3-element Array{Int64,1}: +3-element Vector{Int64}: 2 3 4 @@ -863,7 +863,7 @@ julia> addprocs(3) julia> @everywhere using SharedArrays julia> S = SharedArray{Int,2}((3,4), init = S -> S[localindices(S)] = repeat([myid()], length(localindices(S)))) -3×4 SharedArray{Int64,2}: +3×4 SharedMatrix{Int64}: 2 2 3 4 2 3 3 4 2 3 4 4 @@ -872,7 +872,7 @@ julia> S[3,2] = 7 7 julia> S -3×4 SharedArray{Int64,2}: +3×4 SharedMatrix{Int64}: 2 2 3 4 2 3 3 4 2 7 4 4 @@ -884,7 +884,7 @@ you wish: ```julia-repl julia> S = SharedArray{Int,2}((3,4), init = S -> S[indexpids(S):length(procs(S)):length(S)] = repeat([myid()], length( indexpids(S):length(procs(S)):length(S)))) -3×4 SharedArray{Int64,2}: +3×4 SharedMatrix{Int64}: 2 2 2 2 3 3 3 3 4 4 4 4 @@ -1371,7 +1371,7 @@ julia> all(C .≈ 4*π) true julia> typeof(C) -Array{Float64,1} +Vector{Float64} (alias for Array{Float64, 1}) julia> dB = distribute(B); @@ -1383,7 +1383,7 @@ julia> all(dC .≈ 4*π) true julia> typeof(dC) -DistributedArrays.DArray{Float64,1,Array{Float64,1}} +DistributedArrays.DArray{Float64,1,Vector{Float64}} julia> cuB = CuArray(B); @@ -1419,7 +1419,7 @@ function declaration, let's see if it works with the aforementioned datatypes: julia> M = [2. 1; 1 1]; julia> v = rand(2) -2-element Array{Float64,1}: +2-element Vector{Float64}: 0.40395 0.445877 @@ -1442,7 +1442,7 @@ julia> dv = distribute(v); julia> dC = power_method(dM, dv); julia> typeof(dC) -Tuple{DistributedArrays.DArray{Float64,1,Array{Float64,1}},Float64} +Tuple{DistributedArrays.DArray{Float64,1,Vector{Float64}},Float64} ``` To end this short exposure to external packages, we can consider `MPI.jl`, a Julia wrapper diff --git a/doc/src/manual/documentation.md b/doc/src/manual/documentation.md index d41249abe6af8..a11d41d441b73 100644 --- a/doc/src/manual/documentation.md +++ b/doc/src/manual/documentation.md @@ -142,7 +142,7 @@ As in the example above, we recommend following some simple conventions when wri # Examples ```jldoctest julia> a = [1 2; 3 4] - 2×2 Array{Int64,2}: + 2×2 Matrix{Int64}: 1 2 3 4 ``` diff --git a/doc/src/manual/functions.md b/doc/src/manual/functions.md index be81fe529ef7d..0fcfdeb80d7b9 100644 --- a/doc/src/manual/functions.md +++ b/doc/src/manual/functions.md @@ -616,9 +616,9 @@ julia> foo(A(3, 4)) For anonymous functions, destructuring a single argument requires an extra comma: -``` +```julia-repl julia> map(((x, y),) -> x + y, [(1, 2), (3, 4)]) -2-element Array{Int64,1}: +2-element Vector{Int64}: 3 7 ``` diff --git a/doc/src/manual/networking-and-streams.md b/doc/src/manual/networking-and-streams.md index 35ba7fdf16601..3ef41754c1e07 100644 --- a/doc/src/manual/networking-and-streams.md +++ b/doc/src/manual/networking-and-streams.md @@ -31,7 +31,7 @@ For example, to read a simple byte array, we could do: ```julia-repl julia> x = zeros(UInt8, 4) -4-element Array{UInt8,1}: +4-element Vector{UInt8}: 0x00 0x00 0x00 @@ -39,7 +39,7 @@ julia> x = zeros(UInt8, 4) julia> read!(stdin, x) abcd -4-element Array{UInt8,1}: +4-element Vector{UInt8}: 0x61 0x62 0x63 @@ -52,7 +52,7 @@ example, we could have written the above as: ```julia-repl julia> read(stdin, 4) abcd -4-element Array{UInt8,1}: +4-element Vector{UInt8}: 0x61 0x62 0x63 @@ -151,7 +151,7 @@ julia> f = open("hello.txt") IOStream() julia> readlines(f) -1-element Array{String,1}: +1-element Vector{String}: "Hello, World!" ``` @@ -367,7 +367,7 @@ julia> task = Threads.@spawn open("foo.txt", "w") do io julia> wait(task) julia> readlines("foo.txt") -1-element Array{String,1}: +1-element Vector{String}: "Hello, World!" ``` diff --git a/stdlib/REPL/docs/src/index.md b/stdlib/REPL/docs/src/index.md index 6250fc84dc6b2..eabd7e729280e 100644 --- a/stdlib/REPL/docs/src/index.md +++ b/stdlib/REPL/docs/src/index.md @@ -68,7 +68,7 @@ It's possible, as an experimental feature, to specify the attributes used by the ```julia-repl julia> rand(2, 2) -2×2 Array{Float64,2}: +2×2 Matrix{Float64}: 0.8833 0.329197 0.719708 0.59114 @@ -78,7 +78,7 @@ julia> show(IOContext(stdout, :compact => false), "text/plain", rand(2, 2)) julia> Base.active_repl.options.iocontext[:compact] = false; julia> rand(2, 2) -2×2 Array{Float64,2}: +2×2 Matrix{Float64}: 0.2083967319174056 0.13330606013126012 0.6244375177790158 0.9777957560761545 ``` @@ -368,13 +368,13 @@ julia> π julia> e\_1[TAB] = [1,0] julia> e₁ = [1,0] -2-element Array{Int64,1}: +2-element Vector{Int64}: 1 0 julia> e\^1[TAB] = [1 0] julia> e¹ = [1 0] -1×2 Array{Int64,2}: +1×2 Matrix{Int64}: 1 0 julia> \sqrt[TAB]2 # √ is equivalent to the sqrt function diff --git a/stdlib/REPL/src/TerminalMenus/MultiSelectMenu.jl b/stdlib/REPL/src/TerminalMenus/MultiSelectMenu.jl index 5c3ecf3808c49..fd660fc0f7824 100644 --- a/stdlib/REPL/src/TerminalMenus/MultiSelectMenu.jl +++ b/stdlib/REPL/src/TerminalMenus/MultiSelectMenu.jl @@ -38,7 +38,7 @@ end """ - MultiSelectMenu(options::Array{String,1}; pagesize::Int=10, selected=[], kwargs...) + MultiSelectMenu(options::Vector{String}; pagesize::Int=10, selected=[], kwargs...) Create a MultiSelectMenu object. Use `request(menu::MultiSelectMenu)` to get user input. It returns a `Set` containing the indices of options that @@ -46,7 +46,7 @@ were selected by the user. # Arguments - - `options::Array{String, 1}`: Options to be displayed + - `options::Vector{String}`: Options to be displayed - `pagesize::Int=10`: The number of options to be displayed at one time, the menu will scroll if length(options) > pagesize - `selected=[]`: pre-selected items. `i ∈ selected` means that `options[i]` is preselected. diff --git a/stdlib/REPL/src/TerminalMenus/RadioMenu.jl b/stdlib/REPL/src/TerminalMenus/RadioMenu.jl index 32a6373b719d7..8e35e37f7f973 100644 --- a/stdlib/REPL/src/TerminalMenus/RadioMenu.jl +++ b/stdlib/REPL/src/TerminalMenus/RadioMenu.jl @@ -31,9 +31,9 @@ end """ - RadioMenu(options::Array{String,1}; pagesize::Int=10, - keybindings::Vector{Char}=Char[], - kwargs...) + RadioMenu(options::Vector{String}; pagesize::Int=10, + keybindings::Vector{Char}=Char[], + kwargs...) Create a RadioMenu object. Use `request(menu::RadioMenu)` to get user input. `request()` returns an `Int` which is the index of the option selected by the @@ -41,7 +41,7 @@ user. # Arguments - - `options::Array{String, 1}`: Options to be displayed + - `options::Vector{String}`: Options to be displayed - `pagesize::Int=10`: The number of options to be displayed at one time, the menu will scroll if length(options) > pagesize - `keybindings::Vector{Char}=Char[]`: Shortcuts to pick corresponding entry from `options` diff --git a/stdlib/Random/src/Random.jl b/stdlib/Random/src/Random.jl index 26116d3bf4c81..2d75f49480a7b 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -355,7 +355,7 @@ See also [`randn`](@ref) for normally distributed numbers, and [`rand!`](@ref) a # Examples ```julia-repl julia> rand(Int, 2) -2-element Array{Int64,1}: +2-element Vector{Int64}: 1339893410598768192 1575814717733606317 @@ -368,7 +368,7 @@ julia> rand((2, 3)) 3 julia> rand(Float64, (2, 3)) -2×3 Array{Float64,2}: +2×3 Matrix{Float64}: 0.999717 0.0143835 0.540787 0.696556 0.783855 0.938235 ``` diff --git a/stdlib/Sockets/src/addrinfo.jl b/stdlib/Sockets/src/addrinfo.jl index 93194b85d4e8c..f5599b8623a0b 100644 --- a/stdlib/Sockets/src/addrinfo.jl +++ b/stdlib/Sockets/src/addrinfo.jl @@ -58,7 +58,7 @@ Uses the operating system's underlying `getaddrinfo` implementation, which may d # Examples ```julia-repl julia> getalladdrinfo("google.com") -2-element Array{IPAddr,1}: +2-element Vector{IPAddr}: ip"172.217.6.174" ip"2607:f8b0:4000:804::200e" ``` @@ -307,7 +307,7 @@ The `loopback` keyword argument dictates whether loopback addresses (e.g. `ip"12 # Examples ```julia-repl julia> getipaddrs() -5-element Array{IPAddr,1}: +5-element Vector{IPAddr}: ip"198.51.100.17" ip"203.0.113.2" ip"2001:db8:8:4:445e:5fff:fe5d:5500" @@ -315,7 +315,7 @@ julia> getipaddrs() ip"fe80::445e:5fff:fe5d:5500" julia> getipaddrs(IPv6) -3-element Array{IPv6,1}: +3-element Vector{IPv6}: ip"2001:db8:8:4:445e:5fff:fe5d:5500" ip"2001:db8:8:4:c164:402e:7e3c:3668" ip"fe80::445e:5fff:fe5d:5500" From dde5028a11662fca831dd676505264566aec84ab Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Mon, 23 Dec 2024 12:52:54 +0530 Subject: [PATCH 088/198] Remove `similar` specialization with `Integer`s (#56881) This method seems unnecessary, as the method on line 830 does the same thing. Having this method in `Base` requires packages to disambiguate against this by adding redundant methods. --- base/abstractarray.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 6102a0a8a00fa..6d222e7e26281 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -828,7 +828,6 @@ similar(a::AbstractArray, ::Type{T}, dims::DimOrInd...) where {T} = similar(a, # define this method to convert supported axes to Ints, with the expectation that an offset array # package will define a method with dims::Tuple{Union{Integer, UnitRange}, Vararg{Union{Integer, UnitRange}}} similar(a::AbstractArray, ::Type{T}, dims::Tuple{Union{Integer, OneTo}, Vararg{Union{Integer, OneTo}}}) where {T} = similar(a, T, to_shape(dims)) -similar(a::AbstractArray, ::Type{T}, dims::Tuple{Integer, Vararg{Integer}}) where {T} = similar(a, T, to_shape(dims)) # similar creates an Array by default similar(a::AbstractArray, ::Type{T}, dims::Dims{N}) where {T,N} = Array{T,N}(undef, dims) From 8fac39b71ca1c2a423ae1c7fc768722aff9005ee Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Mon, 23 Dec 2024 17:11:01 -0500 Subject: [PATCH 089/198] simplify and slightly improve memorynew inference (#56857) while investigating some missed optimizations in https://github.com/JuliaLang/julia/pull/56847, @gbaraldi and I realized that `copy(::Array)` was using `jl_genericmemory_copy_slice` rather than the `memmove`/`jl_genericmemory_copyto` that `copyto!` lowers to. This version lets us use the faster LLVM based Memory initialization, and the memove can theoretically be further optimized by LLVM (e.g. not copying elements that get over-written without ever being read). ``` julia> @btime copy($[1,2,3]) 15.521 ns (2 allocations: 80 bytes) # before 12.116 ns (2 allocations: 80 bytes) #after julia> m = Memory{Int}(undef, 3); julia> m.=[1,2,3]; julia> @btime copy($m) 11.013 ns (1 allocation: 48 bytes) #before 9.042 ns (1 allocation: 48 bytes) #after ``` We also optimize the `memorynew` type inference to make it so that getting the length of a memory with known length will propagate that length information (which is important for cases like `similar`/`copy` etc). --- Compiler/src/tfuncs.jl | 20 +++++++------------- base/array.jl | 9 +++++---- base/genericmemory.jl | 9 ++++++++- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Compiler/src/tfuncs.jl b/Compiler/src/tfuncs.jl index 906bc9521adf9..e51d43e5b2fe1 100644 --- a/Compiler/src/tfuncs.jl +++ b/Compiler/src/tfuncs.jl @@ -2017,9 +2017,12 @@ function tuple_tfunc(𝕃::AbstractLattice, argtypes::Vector{Any}) return anyinfo ? PartialStruct(𝕃, typ, argtypes) : typ end -@nospecs function memorynew_tfunc(𝕃::AbstractLattice, memtype, m) - hasintersect(widenconst(m), Int) || return Bottom - return tmeet(𝕃, instanceof_tfunc(memtype, true)[1], GenericMemory) +@nospecs function memorynew_tfunc(𝕃::AbstractLattice, memtype, memlen) + hasintersect(widenconst(memlen), Int) || return Bottom + memt = tmeet(𝕃, instanceof_tfunc(memtype, true)[1], GenericMemory) + memt == Union{} && return memt + # PartialStruct so that loads of Const `length` get inferred + return PartialStruct(𝕃, memt, Any[memlen, Ptr{Nothing}]) end add_tfunc(Core.memorynew, 2, 2, memorynew_tfunc, 10) @@ -3125,16 +3128,7 @@ add_tfunc(Core.get_binding_type, 2, 2, @nospecs((𝕃::AbstractLattice, args...) const FOREIGNCALL_ARG_START = 6 -function foreigncall_effects(@specialize(abstract_eval), e::Expr) - args = e.args - name = args[1] - isa(name, QuoteNode) && (name = name.value) - if name === :jl_alloc_genericmemory - nothrow = new_genericmemory_nothrow(abstract_eval, args) - return Effects(EFFECTS_TOTAL; consistent=CONSISTENT_IF_NOTRETURNED, nothrow) - elseif name === :jl_genericmemory_copy_slice - return Effects(EFFECTS_TOTAL; consistent=CONSISTENT_IF_NOTRETURNED, nothrow=false) - end +function foreigncall_effects(@nospecialize(abstract_eval), e::Expr) # `:foreigncall` can potentially perform all sorts of operations, including calling # overlay methods, but the `:foreigncall` itself is not dispatched, and there is no # concern that the method calls that potentially occur within the `:foreigncall` will diff --git a/base/array.jl b/base/array.jl index 4c3dde73d52ba..aafcfc182124b 100644 --- a/base/array.jl +++ b/base/array.jl @@ -346,12 +346,13 @@ See also [`copy!`](@ref Base.copy!), [`copyto!`](@ref), [`deepcopy`](@ref). """ copy -@eval function copy(a::Array{T}) where {T} - # `jl_genericmemory_copy_slice` only throws when the size exceeds the max allocation - # size, but since we're copying an existing array, we're guaranteed that this will not happen. +@eval function copy(a::Array) + # `copy` only throws when the size exceeds the max allocation size, + # but since we're copying an existing array, we're guaranteed that this will not happen. @_nothrow_meta ref = a.ref - newmem = ccall(:jl_genericmemory_copy_slice, Ref{Memory{T}}, (Any, Ptr{Cvoid}, Int), ref.mem, ref.ptr_or_offset, length(a)) + newmem = typeof(ref.mem)(undef, length(a)) + @inbounds unsafe_copyto!(memoryref(newmem), ref, length(a)) return $(Expr(:new, :(typeof(a)), :(memoryref(newmem)), :(a.size))) end diff --git a/base/genericmemory.jl b/base/genericmemory.jl index 9d4614135050b..2a33336c0aad6 100644 --- a/base/genericmemory.jl +++ b/base/genericmemory.jl @@ -144,6 +144,7 @@ function unsafe_copyto!(dest::Memory{T}, doffs, src::Memory{T}, soffs, n) where{ return dest end +#fallback method when types don't match function unsafe_copyto!(dest::Memory, doffs, src::Memory, soffs, n) @_terminates_locally_meta n == 0 && return dest @@ -171,7 +172,13 @@ function unsafe_copyto!(dest::Memory, doffs, src::Memory, soffs, n) return dest end -copy(a::T) where {T<:Memory} = ccall(:jl_genericmemory_copy, Ref{T}, (Any,), a) +function copy(a::T) where {T<:Memory} + # `copy` only throws when the size exceeds the max allocation size, + # but since we're copying an existing array, we're guaranteed that this will not happen. + @_nothrow_meta + newmem = T(undef, length(a)) + @inbounds unsafe_copyto!(newmem, 1, a, 1, length(a)) +end copyto!(dest::Memory, src::Memory) = copyto!(dest, 1, src, 1, length(src)) function copyto!(dest::Memory, doffs::Integer, src::Memory, soffs::Integer, n::Integer) From 64d37f533b80851f2f5a3aee43374638420a98ec Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Tue, 24 Dec 2024 08:49:50 +0530 Subject: [PATCH 090/198] Update the OffsetArrays test helper (#56892) This updates the test helper to match v1.15.0 of `OffsetArrays.jl`. The current version was copied over from v1.11.2, which was released on May 20, 2022, so this bump fetches the intermediate updates to the package. The main changes are updates to `unsafe_wrap` and `reshape`. In the latter, several redundant methods are now removed, whereas, in the former, methods are added to wrap a `Ptr` in an `OffsetArray` (https://github.com/JuliaArrays/OffsetArrays.jl/issues/275#issue-1222585268). A third major change is that an `OffsetArray` now shares its parent's `eltype` and `ndims` in the struct definition, whereas previously this was ensured through the constructor. Other miscellaneous changes are included, such as performance-related ones. --- test/testhelpers/OffsetArrays.jl | 115 +++++++++++++++++++------------ 1 file changed, 72 insertions(+), 43 deletions(-) diff --git a/test/testhelpers/OffsetArrays.jl b/test/testhelpers/OffsetArrays.jl index e895372a34974..5acaa88064245 100644 --- a/test/testhelpers/OffsetArrays.jl +++ b/test/testhelpers/OffsetArrays.jl @@ -5,7 +5,7 @@ # This test file is designed to exercise support for generic indexing, # even though offset arrays aren't implemented in Base. -# OffsetArrays v1.11.2 +# OffsetArrays v1.15.0 # No compat patch and docstrings module OffsetArrays @@ -73,10 +73,15 @@ end IdOffsetRange(r::IdOffsetRange) = r # Constructor to make `show` round-trippable +# try to preserve typeof(values) if the indices are known to be 1-based +_subtractindexoffset(values, indices::Union{Base.OneTo, IdentityUnitRange{<:Base.OneTo}}, offset) = values +_subtractindexoffset(values, indices, offset) = _subtractoffset(values, offset) function IdOffsetRange(; values::AbstractUnitRange{<:Integer}, indices::AbstractUnitRange{<:Integer}) length(values) == length(indices) || throw(ArgumentError("values and indices must have the same length")) + values_nooffset = no_offset_view(values) offset = first(indices) - 1 - return IdOffsetRange(values .- offset, offset) + values_minus_offset = _subtractindexoffset(values_nooffset, indices, offset) + return IdOffsetRange(values_minus_offset, offset) end # Conversions to an AbstractUnitRange{Int} (and to an OrdinalRange{Int,Int} on Julia v"1.6") are necessary @@ -110,12 +115,19 @@ offset_coerce(::Type{I}, r::AbstractUnitRange) where I<:AbstractUnitRange = @inline Base.unsafe_indices(r::IdOffsetRange) = (Base.axes1(r),) @inline Base.length(r::IdOffsetRange) = length(r.parent) @inline Base.isempty(r::IdOffsetRange) = isempty(r.parent) +#= We specialize on reduced_indices to work around cases where the parent axis type doesn't +support reduced_index, but the axes do support reduced_indices +The difference is that reduced_index expects the axis type to remain unchanged, +which may not always be possible, eg. for statically sized axes +See https://github.com/JuliaArrays/OffsetArrays.jl/issues/204 +=# +function Base.reduced_indices(inds::Tuple{IdOffsetRange, Vararg{IdOffsetRange}}, d::Int) + parents_reduced = Base.reduced_indices(map(parent, inds), d) + ntuple(i -> IdOffsetRange(parents_reduced[i], inds[i].offset), Val(length(inds))) +end Base.reduced_index(i::IdOffsetRange) = typeof(i)(first(i):first(i)) # Workaround for #92 on Julia < 1.4 Base.reduced_index(i::IdentityUnitRange{<:IdOffsetRange}) = typeof(i)(first(i):first(i)) -for f in [:firstindex, :lastindex] - @eval @inline Base.$f(r::IdOffsetRange) = $f(r.parent) + r.offset -end for f in [:first, :last] # coerce the type to deal with values that get promoted on addition (eg. Bool) @eval @inline Base.$f(r::IdOffsetRange) = eltype(r)($f(r.parent) + r.offset) @@ -142,7 +154,7 @@ end @inline function Base.getindex(r::IdOffsetRange, i::Integer) i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) @boundscheck checkbounds(r, i) - @inbounds eltype(r)(r.parent[oftype(r.offset, i) - r.offset] + r.offset) + @inbounds eltype(r)(r.parent[i - r.offset] + r.offset) end # Logical indexing following https://github.com/JuliaLang/julia/pull/31829 @@ -186,18 +198,20 @@ for R in [:IIUR, :IdOffsetRange] end # offset-preserve broadcasting -Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(-), r::IdOffsetRange{T}, x::Integer) where T = - IdOffsetRange{T}(r.parent .- x, r.offset) -Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(+), r::IdOffsetRange{T}, x::Integer) where T = - IdOffsetRange{T}(r.parent .+ x, r.offset) -Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(+), x::Integer, r::IdOffsetRange{T}) where T = - IdOffsetRange{T}(x .+ r.parent, r.offset) +Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(-), r::IdOffsetRange, x::Integer) = + IdOffsetRange(r.parent .- x, r.offset) +Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(+), r::IdOffsetRange, x::Integer) = + IdOffsetRange(r.parent .+ x, r.offset) +Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(+), x::Integer, r::IdOffsetRange) = + IdOffsetRange(x .+ r.parent, r.offset) +Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(big), r::IdOffsetRange) = + IdOffsetRange(big.(r.parent), r.offset) Base.show(io::IO, r::IdOffsetRange) = print(io, IdOffsetRange, "(values=",first(r), ':', last(r),", indices=",first(eachindex(r)),':',last(eachindex(r)), ")") # Optimizations @inline Base.checkindex(::Type{Bool}, inds::IdOffsetRange, i::Real) = Base.checkindex(Bool, inds.parent, i - inds.offset) -Base._firstslice(r::IdOffsetRange) = IdOffsetRange(Base._firstslice(r.parent), r.offset) +Base._firstslice(i::IdOffsetRange) = IdOffsetRange(Base._firstslice(i.parent), i.offset) ######################################################################################################## # origin.jl @@ -309,12 +323,12 @@ _popreshape(A::AbstractArray, ax, inds) = A # Technically we know the length of CartesianIndices but we need to convert it first, so here we # don't put it in OffsetAxisKnownLength. -const OffsetAxisKnownLength = Union{Integer,AbstractUnitRange} -const OffsetAxis = Union{OffsetAxisKnownLength,Colon} -const ArrayInitializer = Union{UndefInitializer,Missing,Nothing} +const OffsetAxisKnownLength = Union{Integer, AbstractUnitRange} +const OffsetAxis = Union{OffsetAxisKnownLength, Colon} +const ArrayInitializer = Union{UndefInitializer, Missing, Nothing} ## OffsetArray -struct OffsetArray{T,N,AA<:AbstractArray} <: AbstractArray{T,N} +struct OffsetArray{T,N,AA<:AbstractArray{T,N}} <: AbstractArray{T,N} parent::AA offsets::NTuple{N,Int} @inline function OffsetArray{T, N, AA}(parent::AA, offsets::NTuple{N, Int}; checkoverflow = true) where {T, N, AA<:AbstractArray{T,N}} @@ -482,6 +496,10 @@ Base.parent(A::OffsetArray) = A.parent # Base.Broadcast.BroadcastStyle(::Type{<:OffsetArray{<:Any, <:Any, AA}}) where AA = Base.Broadcast.BroadcastStyle(AA) @inline Base.size(A::OffsetArray) = size(parent(A)) +# specializing length isn't necessary, as length(A) = prod(size(A)), +# but specializing length enables constant-propagation for statically sized arrays +# see https://github.com/JuliaArrays/OffsetArrays.jl/pull/304 +@inline Base.length(A::OffsetArray) = length(parent(A)) @inline Base.axes(A::OffsetArray) = map(IdOffsetRange, axes(parent(A)), A.offsets) @inline Base.axes(A::OffsetArray, d) = d <= ndims(A) ? IdOffsetRange(axes(parent(A), d), A.offsets[d]) : IdOffsetRange(axes(parent(A), d)) @@ -528,7 +546,9 @@ _similar_axes_or_length(A, T, ax::I, ::I) where {I} = similar(A, T, map(_indexle _similar_axes_or_length(AT, ax::I, ::I) where {I} = similar(AT, map(_indexlength, ax)) # reshape accepts a single colon -Base.reshape(A::AbstractArray, inds::OffsetAxis...) = reshape(A, inds) +# this method is limited to AbstractUnitRange{<:Integer} to avoid method overwritten errors if Base defines the same, +# see https://github.com/JuliaLang/julia/pull/56850 +Base.reshape(A::AbstractArray, inds::Union{Integer, Colon, AbstractUnitRange{<:Integer}}...) = reshape(A, inds) function Base.reshape(A::AbstractArray, inds::Tuple{Vararg{OffsetAxis}}) AR = reshape(no_offset_view(A), map(_indexlength, inds)) O = OffsetArray(AR, map(_offset, axes(AR), inds)) @@ -553,21 +573,9 @@ _reshape2(A, inds) = reshape(A, inds) _reshape2(A::OffsetArray, inds) = reshape(parent(A), inds) _reshape_nov(A, inds) = _reshape(no_offset_view(A), inds) -Base.reshape(A::OffsetArray, inds::Tuple{OffsetAxis,Vararg{OffsetAxis}}) = - OffsetArray(_reshape(parent(A), inds), map(_toaxis, inds)) # And for non-offset axes, we can just return a reshape of the parent directly -Base.reshape(A::OffsetArray, inds::Tuple{Union{Integer,Base.OneTo},Vararg{Union{Integer,Base.OneTo}}}) = _reshape_nov(A, inds) Base.reshape(A::OffsetArray, inds::Tuple{Integer,Vararg{Integer}}) = _reshape_nov(A, inds) -Base.reshape(A::OffsetArray, inds::Tuple{Union{Colon, Integer}, Vararg{Union{Colon, Integer}}}) = _reshape_nov(A, inds) Base.reshape(A::OffsetArray, inds::Dims) = _reshape_nov(A, inds) -Base.reshape(A::OffsetVector, ::Colon) = A -Base.reshape(A::OffsetVector, ::Tuple{Colon}) = A -Base.reshape(A::OffsetArray, inds::Union{Int,Colon}...) = reshape(A, inds) -Base.reshape(A::OffsetArray, inds::Tuple{Vararg{Union{Int,Colon}}}) = _reshape_nov(A, inds) -# The following two additional methods for Colon are added to resolve method ambiguities to -# Base: https://github.com/JuliaLang/julia/pull/45387#issuecomment-1132859663 -Base.reshape(A::OffsetArray, inds::Colon) = _reshape_nov(A, inds) -Base.reshape(A::OffsetArray, inds::Tuple{Colon}) = _reshape_nov(A, inds) # permutedims in Base does not preserve axes, and can not be fixed in a non-breaking way # This is a stopgap solution @@ -583,7 +591,7 @@ Base.fill!(A::OffsetArray, x) = parent_call(Ap -> fill!(Ap, x), A) # Δi = i - first(r) # i′ = first(r.parent) + Δi # and one obtains the result below. -parentindex(r::IdOffsetRange, i) = oftype(r.offset, i) - r.offset +parentindex(r::IdOffsetRange, i) = i - r.offset @propagate_inbounds Base.getindex(A::OffsetArray{<:Any,0}) = A.parent[] @@ -632,7 +640,7 @@ Base.copy(A::OffsetArray) = parent_call(copy, A) Base.strides(A::OffsetArray) = strides(parent(A)) Base.elsize(::Type{OffsetArray{T,N,A}}) where {T,N,A} = Base.elsize(A) -Base.cconvert(::Type{Ptr{T}}, A::OffsetArray{T}) where {T} = Base.cconvert(Ptr{T}, parent(A)) +Base.cconvert(P::Type{Ptr{T}}, A::OffsetArray{T}) where {T} = Base.cconvert(P, parent(A)) # For fast broadcasting: ref https://discourse.julialang.org/t/why-is-there-a-performance-hit-on-broadcasting-with-offsetarrays/32194 Base.dataids(A::OffsetArray) = Base.dataids(parent(A)) @@ -732,15 +740,6 @@ if eltype(IIUR) === Int Base.map(::Type{T}, r::IdentityUnitRange) where {T<:Real} = _indexedby(map(T, UnitRange(r)), axes(r)) end -# mapreduce is faster with an IdOffsetRange than with an OffsetUnitRange -# We therefore convert OffsetUnitRanges to IdOffsetRanges with the same values and axes -function Base.mapreduce(f, op, A1::OffsetUnitRange{<:Integer}, As::OffsetUnitRange{<:Integer}...; kw...) - As = (A1, As...) - ofs = map(A -> first(axes(A,1)) - 1, As) - AIds = map((A, of) -> IdOffsetRange(_subtractoffset(parent(A), of), of), As, ofs) - mapreduce(f, op, AIds...; kw...) -end - # Optimize certain reductions that treat an OffsetVector as a list for f in [:minimum, :maximum, :extrema, :sum] @eval Base.$f(r::OffsetRange) = $f(parent(r)) @@ -762,7 +761,8 @@ Base.append!(A::OffsetVector, items) = (append!(A.parent, items); A) Base.empty!(A::OffsetVector) = (empty!(A.parent); A) # These functions keep the summary compact -function Base.inds2string(inds::Tuple{Vararg{Union{IdOffsetRange, IdentityUnitRange{<:IdOffsetRange}}}}) +const OffsetIndices = Union{IdOffsetRange, IdentityUnitRange{<:IdOffsetRange}} +function Base.inds2string(inds::Tuple{OffsetIndices, Vararg{OffsetIndices}}) Base.inds2string(map(UnitRange, inds)) end Base.showindices(io::IO, ind1::IdOffsetRange, inds::IdOffsetRange...) = Base.showindices(io, map(UnitRange, (ind1, inds...))...) @@ -786,7 +786,33 @@ function Base.replace_in_print_matrix(A::OffsetArray{<:Any,1}, i::Integer, j::In Base.replace_in_print_matrix(parent(A), ip, j, s) end +# Actual unsafe_wrap implementation +@inline function _unsafe_wrap(pointer::Ptr{T}, inds::NTuple{N, OffsetAxisKnownLength}; own = false, kw...) where {T,N} + _checkindices(N, inds, "indices") + AA = Base.unsafe_wrap(Array, pointer, map(_indexlength, inds); own=own) + OffsetArray{T, N, typeof(AA)}(AA, map(_indexoffset, inds); kw...) +end +const OffsetArrayUnion{T,N} = Union{Type{OffsetArray}, Type{OffsetArray{T}}, Type{OffsetArray{T,N}}, Type{OffsetArray{T1, N} where T1}} where {T,N} + +@inline function Base.unsafe_wrap(::OffsetArrayUnion{T,N}, pointer::Ptr{T}, inds::NTuple{N, OffsetAxisKnownLength}; kw...) where {T,N} + _unsafe_wrap(pointer, inds; kw...) +end +# Avoid ambiguity +@inline function Base.unsafe_wrap(::OffsetArrayUnion{T,N}, pointer::Ptr{T}, inds::NTuple{N, <:Integer}; kw...) where {T,N} + _unsafe_wrap(pointer, inds; kw...) +end +@inline function Base.unsafe_wrap(::OffsetArrayUnion{T,N}, pointer::Ptr{T}, inds::Vararg{OffsetAxisKnownLength,N}; kw...) where {T,N} + _unsafe_wrap(pointer, inds; kw...) +end +# Avoid ambiguity +@inline function Base.unsafe_wrap(::OffsetArrayUnion{T,N}, pointer::Ptr{T}, inds::Vararg{Integer,N}; kw...) where {T,N} + _unsafe_wrap(pointer, inds; kw...) +end + no_offset_view(A::OffsetArray) = no_offset_view(parent(A)) +no_offset_view(a::Base.Slice{<:Base.OneTo}) = a +no_offset_view(a::Base.Slice) = Base.Slice(UnitRange(a)) +no_offset_view(S::SubArray) = view(parent(S), map(no_offset_view, parentindices(S))...) no_offset_view(a::Array) = a no_offset_view(i::Number) = i no_offset_view(A::AbstractArray) = _no_offset_view(axes(A), A) @@ -802,9 +828,12 @@ _no_offset_view(::Any, A::AbstractUnitRange) = UnitRange(A) # These two helpers are deliberately not exported; their meaning can be very different in # other scenarios and will be very likely to cause name conflicts if exported. ##### + +_halfroundInt(v, r::RoundingMode) = div(v, 2, r) + function center(A::AbstractArray, r::RoundingMode=RoundDown) map(axes(A)) do inds - round(Int, (length(inds)-1)/2, r) + first(inds) + _halfroundInt(length(inds)-1, r) + first(inds) end end From cab11bbd2d5452f523ef277bfee2affec4e3c9f5 Mon Sep 17 00:00:00 2001 From: NegaScout <42321060+NegaScout@users.noreply.github.com> Date: Tue, 24 Dec 2024 14:50:19 +0100 Subject: [PATCH 091/198] fix: Base.GMP.MPZ.invert yielding return code instead of return value (#56894) There is a bug in `Base.GMP.MPZ.invert` it returned GMP return code, instead of the actual value. This commit fixes it. Before: ``` julia> Base.GMP.MPZ.invert(big"3", big"7") 1 ``` After: ``` julia> Base.GMP.MPZ.invert(big"3", big"7") 5 ``` --- base/gmp.jl | 2 +- test/gmp.jl | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/base/gmp.jl b/base/gmp.jl index df0d9fee49348..d5db71b0630d6 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -174,8 +174,8 @@ end invert!(x::BigInt, a::BigInt, b::BigInt) = ccall((:__gmpz_invert, libgmp), Cint, (mpz_t, mpz_t, mpz_t), x, a, b) -invert(a::BigInt, b::BigInt) = invert!(BigInt(), a, b) invert!(x::BigInt, b::BigInt) = invert!(x, x, b) +invert(a::BigInt, b::BigInt) = (ret=BigInt(); invert!(ret, a, b); ret) for op in (:add_ui, :sub_ui, :mul_ui, :mul_2exp, :fdiv_q_2exp, :pow_ui, :bin_ui) op! = Symbol(op, :!) diff --git a/test/gmp.jl b/test/gmp.jl index 13413abe55f9d..9ca327e63493b 100644 --- a/test/gmp.jl +++ b/test/gmp.jl @@ -468,6 +468,34 @@ end end end +@testset "modular invert" begin + # test invert is correct and does not mutate + a = BigInt(3) + b = BigInt(7) + i = BigInt(5) + @test Base.GMP.MPZ.invert(a, b) == i + @test a == BigInt(3) + @test b == BigInt(7) + + # test in place invert does mutate first argument + a = BigInt(3) + b = BigInt(7) + i = BigInt(5) + i_inplace = BigInt(3) + Base.GMP.MPZ.invert!(i_inplace, b) + @test i_inplace == i + + # test in place invert does mutate only first argument + a = BigInt(3) + b = BigInt(7) + i = BigInt(5) + i_inplace = BigInt(0) + Base.GMP.MPZ.invert!(i_inplace, a, b) + @test i_inplace == i + @test a == BigInt(3) + @test b == BigInt(7) +end + @testset "math ops returning BigFloat" begin # operations that when applied to Int64 give Float64, should give BigFloat @test typeof(exp(a)) == BigFloat From e3f90c4062af3a40ee548203242744424f2029fa Mon Sep 17 00:00:00 2001 From: Simeon David Schaub Date: Wed, 25 Dec 2024 23:26:15 +0100 Subject: [PATCH 092/198] fix precompilation error printing if `CI` is set (#56905) Co-authored-by: Ian Butterworth --- base/precompilation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/precompilation.jl b/base/precompilation.jl index f61169c6ca16d..c493690bab64e 100644 --- a/base/precompilation.jl +++ b/base/precompilation.jl @@ -1098,7 +1098,7 @@ function _precompilepkgs(pkgs::Vector{String}, direct = strict ? "" : "direct " err_msg = "The following $n_direct_errs $(direct)dependenc$(pluralde) failed to precompile:\n$(String(take!(err_str)))" if internal_call # aka. auto-precompilation - if isinteractive() && !get(ENV, "CI", false) + if isinteractive() plural1 = length(failed_deps) == 1 ? "y" : "ies" println(io, " ", color_string("$(length(failed_deps))", Base.error_color()), " dependenc$(plural1) errored.") println(io, " For a report of the errors see `julia> err`. To retry use `pkg> precompile`") From 8788497dc215088227af37b9a7065e00ca959859 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Fri, 27 Dec 2024 15:38:22 -0600 Subject: [PATCH 093/198] Add #53664, public&export error to news (#56911) Suggested by @simeonschaub [here](https://github.com/JuliaLang/julia/pull/53664#issuecomment-2562408676) --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index 3c893566c7219..15d5e90c9c949 100644 --- a/NEWS.md +++ b/NEWS.md @@ -46,6 +46,9 @@ Language changes behavior. Infinite loops that actually do things (e.g. have side effects or sleep) were never and are still not undefined behavior. ([#52999]) + - It is now an error to mark a symbol as both `public` and `export`ed. + ([#53664]) + Compiler/Runtime improvements ----------------------------- From b4e4ba7bc4f4c3569c10d7c94da6d12dfcd5630e Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Sat, 28 Dec 2024 13:16:14 +0900 Subject: [PATCH 094/198] restrict `optimize_until` argument type correctly (#56912) The object types that `optimize_until` can accept are restricted by `matchpass`, so this restriction should also be reflected in functions like `typeinf_ircode` too. --- Compiler/src/optimize.jl | 2 +- Compiler/src/typeinfer.jl | 12 ++++++------ base/reflection.jl | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Compiler/src/optimize.jl b/Compiler/src/optimize.jl index bc3fc4f9705c4..12b2f3c9a269f 100644 --- a/Compiler/src/optimize.jl +++ b/Compiler/src/optimize.jl @@ -1025,7 +1025,7 @@ function run_passes_ipo_safe( optimize_until = nothing, # run all passes by default ) __stage__ = 0 # used by @pass - # NOTE: The pass name MUST be unique for `optimize_until::AbstractString` to work + # NOTE: The pass name MUST be unique for `optimize_until::String` to work @pass "convert" ir = convert_to_ircode(ci, sv) @pass "slot2reg" ir = slot2reg(ir, ci, sv) # TODO: Domsorting can produce an updated domtree - no need to recompute here diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index f7cd574abbcef..eba520a03ada1 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -977,23 +977,23 @@ end """ typeinf_ircode(interp::AbstractInterpreter, match::MethodMatch, - optimize_until::Union{Integer,AbstractString,Nothing}) -> (ir::Union{IRCode,Nothing}, returntype::Type) + optimize_until::Union{Int,String,Nothing}) -> (ir::Union{IRCode,Nothing}, returntype::Type) typeinf_ircode(interp::AbstractInterpreter, method::Method, atype, sparams::SimpleVector, - optimize_until::Union{Integer,AbstractString,Nothing}) -> (ir::Union{IRCode,Nothing}, returntype::Type) + optimize_until::Union{Int,String,Nothing}) -> (ir::Union{IRCode,Nothing}, returntype::Type) typeinf_ircode(interp::AbstractInterpreter, mi::MethodInstance, - optimize_until::Union{Integer,AbstractString,Nothing}) -> (ir::Union{IRCode,Nothing}, returntype::Type) + optimize_until::Union{Int,String,Nothing}) -> (ir::Union{IRCode,Nothing}, returntype::Type) Infer a `method` and return an `IRCode` with inferred `returntype` on success. """ typeinf_ircode(interp::AbstractInterpreter, match::MethodMatch, - optimize_until::Union{Integer,AbstractString,Nothing}) = + optimize_until::Union{Int,String,Nothing}) = typeinf_ircode(interp, specialize_method(match), optimize_until) typeinf_ircode(interp::AbstractInterpreter, method::Method, @nospecialize(atype), sparams::SimpleVector, - optimize_until::Union{Integer,AbstractString,Nothing}) = + optimize_until::Union{Int,String,Nothing}) = typeinf_ircode(interp, specialize_method(method, atype, sparams), optimize_until) function typeinf_ircode(interp::AbstractInterpreter, mi::MethodInstance, - optimize_until::Union{Integer,AbstractString,Nothing}) + optimize_until::Union{Int,String,Nothing}) frame = typeinf_frame(interp, mi, false) if frame === nothing return nothing, Any diff --git a/base/reflection.jl b/base/reflection.jl index be344648f8f52..f7952ac7a78d7 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -463,7 +463,7 @@ internals. when looking up methods, use current world age if not specified. - `interp::Core.Compiler.AbstractInterpreter = Core.Compiler.NativeInterpreter(world)`: optional, controls the abstract interpreter to use, use the native interpreter if not specified. -- `optimize_until::Union{Integer,AbstractString,Nothing} = nothing`: optional, +- `optimize_until::Union{Int,String,Nothing} = nothing`: optional, controls the optimization passes to run. If it is a string, it specifies the name of the pass up to which the optimizer is run. If it is an integer, it specifies the number of passes to run. @@ -507,7 +507,7 @@ function code_ircode_by_type( @nospecialize(tt::Type); world::UInt=get_world_counter(), interp=nothing, - optimize_until::Union{Integer,AbstractString,Nothing}=nothing, + optimize_until::Union{Int,String,Nothing}=nothing, ) passed_interp = interp interp = passed_interp === nothing ? invoke_default_compiler(:_default_interp, world) : interp From 5198c062a2f9d6f308465bb464d3974965f95a97 Mon Sep 17 00:00:00 2001 From: Neven Sajko <4944410+nsajko@users.noreply.github.com> Date: Sun, 29 Dec 2024 07:57:48 +0100 Subject: [PATCH 095/198] doc: manual: give the Performance Tips a table of contents (#56917) The page is quite long, and now it also has a more intricate structure than before, IMO it deserves a TOC. --- doc/src/manual/performance-tips.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/src/manual/performance-tips.md b/doc/src/manual/performance-tips.md index 1166164241c60..d506ac9946ba6 100644 --- a/doc/src/manual/performance-tips.md +++ b/doc/src/manual/performance-tips.md @@ -3,6 +3,13 @@ In the following sections, we briefly go through a few techniques that can help make your Julia code run as fast as possible. +## [Table of contents](@id man-performance-tips-toc) + +```@contents +Pages = ["performance-tips.md"] +Depth = 3 +``` + ## General advice ### Performance critical code should be inside a function From 4b2f4d9d2eb85c2e585f2fdc4fdadc313b00bebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Guedes?= Date: Sun, 29 Dec 2024 21:03:01 -0300 Subject: [PATCH 096/198] ReentrantLock: wakeup a single task on unlock and add a short spin (#56814) I propose a change in the implementation of the `ReentrantLock` to improve its overall throughput for short critical sections and fix the quadratic wake-up behavior where each unlock schedules **all** waiting tasks on the lock's wait queue. This implementation follows the same principles of the `Mutex` in the [parking_lot](https://github.com/Amanieu/parking_lot/tree/master) Rust crate which is based on the Webkit [WTF::ParkingLot](https://webkit.org/blog/6161/locking-in-webkit/) class. Only the basic working principle is implemented here, further improvements such as eventual fairness will be proposed separately. The gist of the change is that we add one extra state to the lock, essentially going from: ``` 0x0 => The lock is not locked 0x1 => The lock is locked by exactly one task. No other task is waiting for it. 0x2 => The lock is locked and some other task tried to lock but failed (conflict) ``` To: ``` # PARKED_BIT | LOCKED_BIT | Description # 0 | 0 | The lock is not locked, nor is anyone waiting for it. # -----------+------------+------------------------------------------------------------------ # 0 | 1 | The lock is locked by exactly one task. No other task is # | | waiting for it. # -----------+------------+------------------------------------------------------------------ # 1 | 0 | The lock is not locked. One or more tasks are parked. # -----------+------------+------------------------------------------------------------------ # 1 | 1 | The lock is locked by exactly one task. One or more tasks are # | | parked waiting for the lock to become available. # | | In this state, PARKED_BIT is only ever cleared when the cond_wait lock # | | is held (i.e. on unlock). This ensures that # | | we never end up in a situation where there are parked tasks but # | | PARKED_BIT is not set (which would result in those tasks # | | potentially never getting woken up). ``` In the current implementation we must schedule all tasks to cause a conflict (state 0x2) because on unlock we only notify any task if the lock is in the conflict state. This behavior means that with high contention and a short critical section the tasks will be effectively spinning in the scheduler queue. With the extra state the proposed implementation has enough information to know if there are other tasks to be notified or not, which means we can always notify one task at a time while preserving the optimized path of not notifying if there are no tasks waiting. To improve throughput for short critical sections we also introduce a bounded amount of spinning before attempting to park. ### Results Not spinning on the scheduler queue greatly reduces the CPU utilization of the following example: ```julia function example() lock = ReentrantLock() @sync begin for i in 1:10000 Threads.@spawn begin @lock lock begin sleep(0.001) end end end end end @time example() ``` Current: ``` 28.890623 seconds (101.65 k allocations: 7.646 MiB, 0.25% compilation time) ``` ![image](https://github.com/user-attachments/assets/dbd6ce57-c760-4f5a-b68a-27df6a97a46e) Proposed: ``` 22.806669 seconds (101.65 k allocations: 7.814 MiB, 0.35% compilation time) ``` ![image](https://github.com/user-attachments/assets/b0254180-658d-4493-86d3-dea4c500b5ac) In a micro-benchmark where 8 threads contend for a single lock with a very short critical section we see a ~2x improvement. Current: ``` 8-element Vector{Int64}: 6258688 5373952 6651904 6389760 6586368 3899392 5177344 5505024 Total iterations: 45842432 ``` Proposed: ``` 8-element Vector{Int64}: 12320768 12976128 10354688 12845056 7503872 13598720 13860864 11993088 Total iterations: 95453184 ``` ~~In the uncontended scenario the extra bookkeeping causes a 10% throughput reduction:~~ EDIT: I reverted _trylock to the simple case to recover the uncontended throughput and now both implementations are on the same ballpark (without hurting the above numbers). In the uncontended scenario: Current: ``` Total iterations: 236748800 ``` Proposed: ``` Total iterations: 237699072 ``` Closes #56182 --- base/lock.jl | 126 +++++++++++++++++++++++++++++++++++++++--------- test/threads.jl | 3 +- 2 files changed, 106 insertions(+), 23 deletions(-) diff --git a/base/lock.jl b/base/lock.jl index a44cd4c0d63cf..59e554c01c24a 100644 --- a/base/lock.jl +++ b/base/lock.jl @@ -9,6 +9,14 @@ Get the currently running [`Task`](@ref). """ current_task() = ccall(:jl_get_current_task, Ref{Task}, ()) +# This bit is set in the `havelock` of a `ReentrantLock` when that lock is locked by some task. +const LOCKED_BIT = 0b01 +# This bit is set in the `havelock` of a `ReentrantLock` just before parking a task. A task is being +# parked if it wants to lock the lock, but it is currently being held by some other task. +const PARKED_BIT = 0b10 + +const MAX_SPIN_ITERS = 40 + # Advisory reentrant lock """ ReentrantLock() @@ -43,7 +51,28 @@ mutable struct ReentrantLock <: AbstractLock # offset32 = 20, offset64 = 24 reentrancy_cnt::UInt32 # offset32 = 24, offset64 = 28 - @atomic havelock::UInt8 # 0x0 = none, 0x1 = lock, 0x2 = conflict + # + # This atomic integer holds the current state of the lock instance. Only the two lowest bits + # are used. See `LOCKED_BIT` and `PARKED_BIT` for the bitmask for these bits. + # + # # State table: + # + # PARKED_BIT | LOCKED_BIT | Description + # 0 | 0 | The lock is not locked, nor is anyone waiting for it. + # -----------+------------+------------------------------------------------------------------ + # 0 | 1 | The lock is locked by exactly one task. No other task is + # | | waiting for it. + # -----------+------------+------------------------------------------------------------------ + # 1 | 0 | The lock is not locked. One or more tasks are parked. + # -----------+------------+------------------------------------------------------------------ + # 1 | 1 | The lock is locked by exactly one task. One or more tasks are + # | | parked waiting for the lock to become available. + # | | In this state, PARKED_BIT is only ever cleared when the cond_wait lock + # | | is held (i.e. on unlock). This ensures that + # | | we never end up in a situation where there are parked tasks but + # | | PARKED_BIT is not set (which would result in those tasks + # | | potentially never getting woken up). + @atomic havelock::UInt8 # offset32 = 28, offset64 = 32 cond_wait::ThreadSynchronizer # 2 words # offset32 = 36, offset64 = 48 @@ -112,7 +141,7 @@ function islocked end # `ReentrantLock`. function islocked(rl::ReentrantLock) - return (@atomic :monotonic rl.havelock) != 0 + return (@atomic :monotonic rl.havelock) & LOCKED_BIT != 0 end """ @@ -136,7 +165,6 @@ function trylock end @inline function trylock(rl::ReentrantLock) ct = current_task() if rl.locked_by === ct - #@assert rl.havelock !== 0x00 rl.reentrancy_cnt += 0x0000_0001 return true end @@ -144,9 +172,8 @@ function trylock end end @noinline function _trylock(rl::ReentrantLock, ct::Task) GC.disable_finalizers() - if (@atomicreplace :acquire rl.havelock 0x00 => 0x01).success - #@assert rl.locked_by === nothing - #@assert rl.reentrancy_cnt === 0 + state = (@atomic :monotonic rl.havelock) & PARKED_BIT + if (@atomicreplace :acquire rl.havelock state => (state | LOCKED_BIT)).success rl.reentrancy_cnt = 0x0000_0001 @atomic :release rl.locked_by = ct return true @@ -168,23 +195,69 @@ Each `lock` must be matched by an [`unlock`](@ref). trylock(rl) || (@noinline function slowlock(rl::ReentrantLock) Threads.lock_profiling() && Threads.inc_lock_conflict_count() c = rl.cond_wait - lock(c.lock) - try - while true - if (@atomicreplace rl.havelock 0x01 => 0x02).old == 0x00 # :sequentially_consistent ? # now either 0x00 or 0x02 - # it was unlocked, so try to lock it ourself - _trylock(rl, current_task()) && break - else # it was locked, so now wait for the release to notify us - wait(c) + ct = current_task() + iteration = 1 + while true + state = @atomic :monotonic rl.havelock + # Grab the lock if it isn't locked, even if there is a queue on it + if state & LOCKED_BIT == 0 + GC.disable_finalizers() + result = (@atomicreplace :acquire :monotonic rl.havelock state => (state | LOCKED_BIT)) + if result.success + rl.reentrancy_cnt = 0x0000_0001 + @atomic :release rl.locked_by = ct + return end + GC.enable_finalizers() + continue end - finally - unlock(c.lock) + + if state & PARKED_BIT == 0 + # If there is no queue, try spinning a few times + if iteration <= MAX_SPIN_ITERS + Base.yield() + iteration += 1 + continue + end + + # If still not locked, try setting the parked bit + @atomicreplace :monotonic :monotonic rl.havelock state => (state | PARKED_BIT) + end + + # lock the `cond_wait` + lock(c.lock) + + # Last check before we wait to make sure `unlock` did not win the race + # to the `cond_wait` lock and cleared the parked bit + state = @atomic :acquire rl.havelock + if state != LOCKED_BIT | PARKED_BIT + unlock(c.lock) + continue + end + + # It was locked, so now wait for the unlock to notify us + wait_no_relock(c) + + # Loop back and try locking again + iteration = 1 end end)(rl) return end +function wait_no_relock(c::GenericCondition) + ct = current_task() + _wait2(c, ct) + token = unlockall(c.lock) + try + return wait() + catch + ct.queue === nothing || list_deletefirst!(ct.queue, ct) + rethrow() + end +end + + """ unlock(lock) @@ -201,18 +274,27 @@ internal counter and return immediately. rl.reentrancy_cnt = n if n == 0x0000_00000 @atomic :monotonic rl.locked_by = nothing - if (@atomicswap :release rl.havelock = 0x00) == 0x02 + result = (@atomicreplace :release :monotonic rl.havelock LOCKED_BIT => 0x00) + if result.success + return true + else (@noinline function notifywaiters(rl) cond_wait = rl.cond_wait lock(cond_wait) - try - notify(cond_wait) - finally - unlock(cond_wait) + + notify(cond_wait, all=false) + if !isempty(cond_wait.waitq) + @atomic :release rl.havelock = PARKED_BIT + else + # We may have won the race to the `cond_wait` lock as a task was about to park + # but we unlock anyway as any parking task will retry + @atomic :release rl.havelock = 0x00 end + + unlock(cond_wait) end)(rl) + return true end - return true end return false end)(rl) && GC.enable_finalizers() diff --git a/test/threads.jl b/test/threads.jl index 4d928ca05da16..179279dbab4e6 100644 --- a/test/threads.jl +++ b/test/threads.jl @@ -16,7 +16,8 @@ let lk = ReentrantLock() t2 = @async (notify(c2); trylock(lk)) wait(c1) wait(c2) - @test t1.queue === lk.cond_wait.waitq + # wait for the task to park in the queue (it may be spinning) + @test timedwait(() -> t1.queue === lk.cond_wait.waitq, 1.0) == :ok @test t2.queue !== lk.cond_wait.waitq @test istaskdone(t2) @test !fetch(t2) From d12bcfca4fae7785ca0fe3a8cfffdde0c6eeab87 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Mon, 30 Dec 2024 11:24:48 -0500 Subject: [PATCH 097/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?Pkg=20stdlib=20from=20e7c37f342=20to=20c7e611bc8=20(#56918)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/md5 | 1 + .../Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/sha512 | 1 + .../Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/md5 | 1 - .../Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/sha512 | 1 - stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/md5 create mode 100644 deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/sha512 delete mode 100644 deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/sha512 diff --git a/deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/md5 b/deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/md5 new file mode 100644 index 0000000000000..ac906597fde45 --- /dev/null +++ b/deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/md5 @@ -0,0 +1 @@ +7e3e14d5f6f5851f91a487cbef962ddc diff --git a/deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/sha512 b/deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/sha512 new file mode 100644 index 0000000000000..b5e016fae36a7 --- /dev/null +++ b/deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/sha512 @@ -0,0 +1 @@ +2c492da39ecb43ff1c2ebac877a2de8b152564b4cac7ac1e3bdea006a80305168f7cd2d2d289073fc4db67b0686d6cc707b1f7ba04dacaef353bef9a4cbea61a diff --git a/deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/md5 b/deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/md5 deleted file mode 100644 index 6627dc3683c65..0000000000000 --- a/deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -7024326f0c033e3da419ed217754fbed diff --git a/deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/sha512 b/deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/sha512 deleted file mode 100644 index cfc9d5f30f0e8..0000000000000 --- a/deps/checksums/Pkg-e7c37f34293ab12051258828884755ea116b77df.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -bef19838be850f027fb3dedadce0efa762cd64797809030210ec95830f538ced1b2aede3bd2ca5f32d489e2dc517b7c8e38307adcba194db417ce792437cfb56 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 50105c42c642c..5102be7bdce46 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = master -PKG_SHA1 = e7c37f34293ab12051258828884755ea116b77df +PKG_SHA1 = c7e611bc89826bc462c4b2a308f1a71dbb617145 PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From a6520678f2036ddb4a6f668af83a3a378e8d0121 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Mon, 30 Dec 2024 15:51:41 -0500 Subject: [PATCH 098/198] Don't report only-inferred methods as recompiles (#56914) --- src/gf.c | 12 +++++++++++- test/cmdlineargs.jl | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/gf.c b/src/gf.c index d220ad057176a..52741094c0533 100644 --- a/src/gf.c +++ b/src/gf.c @@ -2863,7 +2863,17 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t // Everything from here on is considered (user facing) compile time uint64_t start = jl_typeinf_timing_begin(); - int is_recompile = jl_atomic_load_relaxed(&mi->cache) != NULL; + + // Is a recompile if there is cached code, and it was compiled (not only inferred) before + int is_recompile = 0; + jl_code_instance_t *codeinst_old = jl_atomic_load_relaxed(&mi->cache); + while (codeinst_old != NULL) { + if (jl_atomic_load_relaxed(&codeinst_old->invoke) != NULL) { + is_recompile = 1; + break; + } + codeinst_old = jl_atomic_load_relaxed(&codeinst_old->next); + } // This codeinst hasn't been previously inferred do that now // jl_type_infer will internally do a cache lookup and jl_engine_reserve call diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index 5df174694049d..74f953250cd37 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -818,6 +818,26 @@ let exename = `$(Base.julia_cmd()) --startup-file=no --color=no` @test occursin(" ms =# precompile(Tuple{typeof(Main.foo), Int", _stderr) end + # Base.@trace_compile (local version of the 2 above args) + let + io = IOBuffer() + v = writereadpipeline( + """ + f(x::Int) = 1 + applyf(container) = f(container[1]) + Base.@trace_compile @eval applyf([100]) + Base.@trace_compile @eval applyf(Any[100]) + f(::Bool) = 2 + Base.@trace_compile @eval applyf([true]) + Base.@trace_compile @eval applyf(Any[true]) + """, + `$exename -i`, + stderr=io) + _stderr = String(take!(io)) + @test length(findall(r"precompile\(", _stderr)) == 5 + @test length(findall(r" # recompile", _stderr)) == 1 + end + # --trace-dispatch let io = IOBuffer() From 27ebbf01ccc44d78694516ff6daf55af65b7439b Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Mon, 30 Dec 2024 15:52:23 -0500 Subject: [PATCH 099/198] precompilepkgs: respect loaded dependencies when precompiling for load (#56901) --- base/loading.jl | 4 ++-- base/precompilation.jl | 24 ++++++++++++++---------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/base/loading.jl b/base/loading.jl index 8ed43e4539c20..024c4ceb356fd 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -1828,7 +1828,7 @@ function compilecache_path(pkg::PkgId; path = nothing isnothing(sourcepath) && error("Cannot locate source for $(repr("text/plain", pkg))") for path_to_try in cachepaths - staledeps = stale_cachefile(sourcepath, path_to_try, ignore_loaded = true, requested_flags=flags) + staledeps = stale_cachefile(sourcepath, path_to_try; ignore_loaded, requested_flags=flags) if staledeps === true continue end @@ -2649,7 +2649,7 @@ function __require_prelocked(pkg::PkgId, env) parallel_precompile_attempted = true unlock(require_lock) try - Precompilation.precompilepkgs([pkg.name]; _from_loading=true) + Precompilation.precompilepkgs([pkg.name]; _from_loading=true, ignore_loaded=false) finally lock(require_lock) end diff --git a/base/precompilation.jl b/base/precompilation.jl index c493690bab64e..c7dcd0af64caa 100644 --- a/base/precompilation.jl +++ b/base/precompilation.jl @@ -418,11 +418,12 @@ function precompilepkgs(pkgs::Vector{String}=String[]; io::IO=stderr, # asking for timing disables fancy mode, as timing is shown in non-fancy mode fancyprint::Bool = can_fancyprint(io) && !timing, - manifest::Bool=false,) + manifest::Bool=false, + ignore_loaded::Bool=true) # monomorphize this to avoid latency problems _precompilepkgs(pkgs, internal_call, strict, warn_loaded, timing, _from_loading, configs isa Vector{Config} ? configs : [configs], - IOContext{IO}(io), fancyprint, manifest) + IOContext{IO}(io), fancyprint, manifest, ignore_loaded) end function _precompilepkgs(pkgs::Vector{String}, @@ -434,7 +435,8 @@ function _precompilepkgs(pkgs::Vector{String}, configs::Vector{Config}, io::IOContext{IO}, fancyprint::Bool, - manifest::Bool) + manifest::Bool, + ignore_loaded::Bool) requested_pkgs = copy(pkgs) # for understanding user intent time_start = time_ns() @@ -918,7 +920,7 @@ function _precompilepkgs(pkgs::Vector{String}, wait(was_processed[(dep,config)]) end circular = pkg in circular_deps - is_stale = !Base.isprecompiled(pkg; ignore_loaded=true, stale_cache, cachepath_cache, cachepaths, sourcepath, flags=cacheflags) + is_stale = !Base.isprecompiled(pkg; ignore_loaded, stale_cache, cachepath_cache, cachepaths, sourcepath, flags=cacheflags) if !circular && is_stale Base.acquire(parallel_limiter) is_project_dep = pkg in project_deps @@ -944,10 +946,10 @@ function _precompilepkgs(pkgs::Vector{String}, try # allows processes to wait if another process is precompiling a given package to # a functionally identical package cache (except for preferences, which may differ) - t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock(io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor, parallel_limiter) do + t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock(io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor, parallel_limiter, ignore_loaded) do Base.with_logger(Base.NullLogger()) do - # The false here means we ignore loaded modules, so precompile for a fresh session - keep_loaded_modules = false + # whether to respect already loaded dependency versions + keep_loaded_modules = !ignore_loaded # for extensions, any extension in our direct dependencies is one we have a right to load # for packages, we may load any extension (all possible triggers are accounted for above) loadable_exts = haskey(ext_to_parent, pkg) ? filter((dep)->haskey(ext_to_parent, dep), direct_deps[pkg]) : nothing @@ -1037,9 +1039,11 @@ function _precompilepkgs(pkgs::Vector{String}, plural1 = length(configs) > 1 ? "dependency configurations" : n_loaded == 1 ? "dependency" : "dependencies" plural2 = n_loaded == 1 ? "a different version is" : "different versions are" plural3 = n_loaded == 1 ? "" : "s" + plural4 = n_loaded == 1 ? "this package" : "these packages" print(iostr, "\n ", color_string(string(n_loaded), Base.warn_color()), - " $(plural1) precompiled but $(plural2) currently loaded. Restart julia to access the new version$(plural3)" + " $(plural1) precompiled but $(plural2) currently loaded. Restart julia to access the new version$(plural3). \ + Otherwise, loading dependents of $(plural4) may trigger further precompilation to work with the unexpected version$(plural3)." ) end if !isempty(precomperr_deps) @@ -1130,7 +1134,7 @@ function _color_string(cstr::String, col::Union{Int64, Symbol}, hascolor) end # Can be merged with `maybe_cachefile_lock` in loading? -function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLock, fancyprint::Bool, pkg_config, pkgspidlocked, hascolor, parallel_limiter::Base.Semaphore) +function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLock, fancyprint::Bool, pkg_config, pkgspidlocked, hascolor, parallel_limiter::Base.Semaphore, ignore_loaded::Bool) if !(isdefined(Base, :mkpidlock_hook) && isdefined(Base, :trymkpidlock_hook) && Base.isdefined(Base, :parse_pidfile_hook)) return f() end @@ -1158,7 +1162,7 @@ function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLo # wait until the lock is available @invokelatest Base.mkpidlock_hook(() -> begin # double-check in case the other process crashed or the lock expired - if Base.isprecompiled(pkg; ignore_loaded=true, flags=cacheflags) # don't use caches for this as the env state will have changed + if Base.isprecompiled(pkg; ignore_loaded, flags=cacheflags) # don't use caches for this as the env state will have changed return nothing # returning nothing indicates a process waited for another else delete!(pkgspidlocked, pkg_config) From 90dee4d1090abbd28608a33a1a638639e6b31720 Mon Sep 17 00:00:00 2001 From: Arno Strouwen Date: Mon, 30 Dec 2024 22:57:23 +0100 Subject: [PATCH 100/198] Add julia-repl in destructuring docs (#56866) From 16230c01bf9fb40634225fd432aa5cadb55a58a2 Mon Sep 17 00:00:00 2001 From: Neven Sajko <4944410+nsajko@users.noreply.github.com> Date: Tue, 31 Dec 2024 05:48:23 +0100 Subject: [PATCH 101/198] doc: manual: Command-line Interface: tiny Markdown code formatting fix (#56919) --- doc/src/manual/command-line-interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/manual/command-line-interface.md b/doc/src/manual/command-line-interface.md index 3477f61164c50..14dd60d89b384 100644 --- a/doc/src/manual/command-line-interface.md +++ b/doc/src/manual/command-line-interface.md @@ -216,7 +216,7 @@ The following is a complete list of command-line switches available when launchi |`--output-asm ` |Generate an assembly file (.s)| |`--output-incremental={yes\|no*}` |Generate an incremental output file (rather than complete)| |`--trace-compile={stderr\|name}` |Print precompile statements for methods compiled during execution or save to stderr or a path. Methods that were recompiled are printed in yellow or with a trailing comment if color is not supported| -|`--trace-compile-timing` |If --trace-compile is enabled show how long each took to compile in ms| +|`--trace-compile-timing` |If `--trace-compile` is enabled show how long each took to compile in ms| |`--trace-dispatch={stderr\|name}` |Print precompile statements for methods dispatched during execution or save to stderr or a path.| |`--image-codegen` |Force generate code in imaging mode| |`--permalloc-pkgimg={yes\|no*}` |Copy the data section of package images into memory| From d604057050dd9642fcf7fa0dd03f96f22923c4f9 Mon Sep 17 00:00:00 2001 From: James Wrigley Date: Tue, 31 Dec 2024 15:30:47 +0100 Subject: [PATCH 102/198] Make threadpoolsize(), threadpooltids(), and ngcthreads() public (#55701) --- base/threadingconstructs.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/threadingconstructs.jl b/base/threadingconstructs.jl index 07ff814af1570..3d86e203ef72e 100644 --- a/base/threadingconstructs.jl +++ b/base/threadingconstructs.jl @@ -3,7 +3,7 @@ export threadid, nthreads, @threads, @spawn, threadpool, nthreadpools -public Condition +public Condition, threadpoolsize, ngcthreads """ Threads.threadid([t::Task]) -> Int From 6136893eeed0c3559263a5aa465b630d2c7dc821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:34:05 +0100 Subject: [PATCH 103/198] [Test] Print RNG of a failed testset and add option to set it (#56260) Also, add a keyword option to `@testset` to let users override the seed used there, to make testsets more replicable. To give you a taster of what this PR enables: ``` julia> using Random, Test julia> @testset begin @test rand() == 0 end; test set: Test Failed at REPL[2]:2 Expression: rand() == 0 Evaluated: 0.559472630416976 == 0 Stacktrace: [1] top-level scope @ REPL[2]:2 [2] macro expansion @ ~/repo/julia/usr/share/julia/stdlib/v1.12/Test/src/Test.jl:1713 [inlined] [3] macro expansion @ REPL[2]:2 [inlined] [4] macro expansion @ ~/repo/julia/usr/share/julia/stdlib/v1.12/Test/src/Test.jl:679 [inlined] Test Summary: | Fail Total Time test set | 1 1 0.9s ERROR: Some tests did not pass: 0 passed, 1 failed, 0 errored, 0 broken. Random seed for this testset: Xoshiro(0x2e026445595ed28e, 0x07bb81ac4c54926d, 0x83d7d70843e8bad6, 0xdbef927d150af80b, 0xdbf91ddf2534f850) julia> @testset rng=Xoshiro(0x2e026445595ed28e, 0x07bb81ac4c54926d, 0x83d7d70843e8bad6, 0xdbef927d150af80b, 0xdbf91ddf2534f850) begin @test rand() == 0.559472630416976 end; Test Summary: | Pass Total Time test set | 1 1 0.0s ``` This also works with nested testsets, and testsets on for loops: ``` julia> @testset rng=Xoshiro(0xc380f460355639ee, 0xb39bc754b7d63bbf, 0x1551dbcfb5ed5668, 0x71ab5a18fec21a25, 0x649d0c1be1ca5436) "Outer" begin @test rand() == 0.0004120194925605336 @testset rng=Xoshiro(0xee97f5b53f7cdc49, 0x480ac387b0527d3d, 0x614b416502a9e0f5, 0x5250cb36e4a4ceb1, 0xed6615c59e475fa0) "Inner: $(i)" for i in 1:10 @test rand() == 0.39321938407066637 end end; Test Summary: | Pass Total Time Outer | 11 11 0.0s ``` Being able to see what was the seed inside a testset and being able to set it afterwards should make replicating test failures which only depend on the state of the RNG much easier to debug. --- NEWS.md | 9 +++++ stdlib/Test/src/Test.jl | 64 +++++++++++++++++++++++++++++------- stdlib/Test/test/runtests.jl | 31 +++++++++++++---- 3 files changed, 86 insertions(+), 18 deletions(-) diff --git a/NEWS.md b/NEWS.md index 15d5e90c9c949..e6d12f1822da4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -183,6 +183,15 @@ Standard library changes #### Test +* A failing `DefaultTestSet` now prints to screen the random number generator (RNG) of the failed test, to help reproducing a stochastic failure which only depends on the state of the RNG. + It is also possible seed a test set by passing the `rng` keyword argument to `@testset`: + ```julia + using Test, Random + @testset rng=Xoshiro(0x2e026445595ed28e, 0x07bb81ac4c54926d, 0x83d7d70843e8bad6, 0xdbef927d150af80b, 0xdbf91ddf2534f850) begin + @test rand() == 0.559472630416976 + end + ``` + #### Dates #### Statistics diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index 3a60527a26e11..79fdb89399d42 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -1071,8 +1071,9 @@ mutable struct DefaultTestSet <: AbstractTestSet time_end::Union{Float64,Nothing} failfast::Bool file::Union{String,Nothing} + rng::Union{Nothing,AbstractRNG} end -function DefaultTestSet(desc::AbstractString; verbose::Bool = false, showtiming::Bool = true, failfast::Union{Nothing,Bool} = nothing, source = nothing) +function DefaultTestSet(desc::AbstractString; verbose::Bool = false, showtiming::Bool = true, failfast::Union{Nothing,Bool} = nothing, source = nothing, rng = nothing) if isnothing(failfast) # pass failfast state into child testsets parent_ts = get_testset() @@ -1082,7 +1083,7 @@ function DefaultTestSet(desc::AbstractString; verbose::Bool = false, showtiming: failfast = false end end - return DefaultTestSet(String(desc)::String, [], 0, false, verbose, showtiming, time(), nothing, failfast, extract_file(source)) + return DefaultTestSet(String(desc)::String, [], 0, false, verbose, showtiming, time(), nothing, failfast, extract_file(source), rng) end extract_file(source::LineNumberNode) = extract_file(source.file) extract_file(file::Symbol) = string(file) @@ -1219,6 +1220,13 @@ function print_test_results(ts::AbstractTestSet, depth_pad=0) println() # Recursively print a summary at every level print_counts(ts, depth_pad, align, pass_width, fail_width, error_width, broken_width, total_width, duration_width, timing) + # Print the RNG of the outer testset if there are failures + if total != total_pass + total_broken + rng = get_rng(ts) + if !isnothing(rng) + println("RNG of the outermost testset: ", rng) + end + end end @@ -1290,6 +1298,24 @@ function filter_errors(ts::DefaultTestSet) efs end +""" + Test.get_rng(ts::AbstractTestSet) -> Union{Nothing,AbstractRNG} + +Return the global random number generator (RNG) associated to the input testset `ts`. +If no RNG is associated to it, return `nothing`. +""" +get_rng(::AbstractTestSet) = nothing +get_rng(ts::DefaultTestSet) = ts.rng +""" + Test.set_rng!(ts::AbstractTestSet, rng::AbstractRNG) -> AbstractRNG + +Set the global random number generator (RNG) associated to the input testset `ts` to `rng`. +If no RNG is associated to it, do nothing. +In any case, always return the input `rng`. +""" +set_rng!(::AbstractTestSet, rng::AbstractRNG) = rng +set_rng!(ts::DefaultTestSet, rng::AbstractRNG) = ts.rng = rng + """ TestCounts @@ -1494,14 +1520,17 @@ along with a summary of the test results. Any custom testset type (subtype of `AbstractTestSet`) can be given and it will also be used for any nested `@testset` invocations. The given options are only applied to the test set where they are given. The default test set type -accepts three boolean options: -- `verbose`: if `true`, the result summary of the nested testsets is shown even +accepts the following options: +- `verbose::Bool`: if `true`, the result summary of the nested testsets is shown even when they all pass (the default is `false`). -- `showtiming`: if `true`, the duration of each displayed testset is shown +- `showtiming::Bool`: if `true`, the duration of each displayed testset is shown (the default is `true`). -- `failfast`: if `true`, any test failure or error will cause the testset and any +- `failfast::Bool`: if `true`, any test failure or error will cause the testset and any child testsets to return immediately (the default is `false`). This can also be set globally via the env var `JULIA_TEST_FAILFAST`. +- `rng::Random.AbstractRNG`: use the given random number generator (RNG) as the global one + for the testset. `rng` must be `copy!`-able. This option can be useful to locally + reproduce stochastic test failures which only depend on the state of the global RNG. !!! compat "Julia 1.8" `@testset test_func()` requires at least Julia 1.8. @@ -1509,6 +1538,9 @@ accepts three boolean options: !!! compat "Julia 1.9" `failfast` requires at least Julia 1.9. +!!! compat "Julia 1.12" + The `rng` option requires at least Julia 1.12. + The description string accepts interpolation from the loop indices. If no description is provided, one is constructed based on the variables. If a function call is provided, its name will be used. @@ -1521,13 +1553,19 @@ method, which by default will return a list of the testset objects used in each iteration. Before the execution of the body of a `@testset`, there is an implicit -call to `Random.seed!(seed)` where `seed` is the current seed of the global RNG. +call to `copy!(Random.default_rng(), rng)` where `rng` is the RNG of the current task, or +the value of the RNG passed via the `rng` option. Moreover, after the execution of the body, the state of the global RNG is restored to what it was before the `@testset`. This is meant to ease reproducibility in case of failure, and to allow seamless re-arrangements of `@testset`s regardless of their side-effect on the global RNG state. +!!! note "RNG of nested testsets" + Unless changed with the `rng` option, the same RNG is set at the beginning of all + nested testsets. The RNG printed to screen when a testset has failures is the global RNG of + the outermost testset even if inner testsets have different RNGs manually set by the user. + ## Examples ```jldoctest; filter = r"trigonometric identities | 4 4 [0-9\\.]+s" julia> @testset "trigonometric identities" begin @@ -1717,9 +1755,11 @@ function testset_beginend_call(args, tests, source) # by wrapping the body in a function local default_rng_orig = copy(default_rng()) local tls_seed_orig = copy(Random.get_tls_seed()) + local tls_seed = isnothing(get_rng(ts)) ? set_rng!(ts, tls_seed_orig) : get_rng(ts) try # default RNG is reset to its state from last `seed!()` to ease reproduce a failed test - copy!(Random.default_rng(), tls_seed_orig) + copy!(Random.default_rng(), tls_seed) + copy!(Random.get_tls_seed(), Random.default_rng()) let $(esc(tests)) end @@ -1800,10 +1840,10 @@ function testset_forloop(args, testloop, source) finish_errored = true push!(arr, finish(ts)) finish_errored = false - copy!(default_rng(), tls_seed_orig) + copy!(default_rng(), tls_seed) end ts = if ($testsettype === $DefaultTestSet) && $(isa(source, LineNumberNode)) - $(testsettype)($desc; source=$(QuoteNode(source.file)), $options...) + $(testsettype)($desc; source=$(QuoteNode(source.file)), $options..., rng=tls_seed) else $(testsettype)($desc; $options...) end @@ -1825,10 +1865,12 @@ function testset_forloop(args, testloop, source) local arr = Vector{Any}() local first_iteration = true local ts + local rng_option = get($(options), :rng, nothing) local finish_errored = false local default_rng_orig = copy(default_rng()) local tls_seed_orig = copy(Random.get_tls_seed()) - copy!(Random.default_rng(), tls_seed_orig) + local tls_seed = isnothing(rng_option) ? copy(Random.get_tls_seed()) : rng_option + copy!(Random.default_rng(), tls_seed) try let $(Expr(:for, Expr(:block, [esc(v) for v in loopvars]...), blk)) diff --git a/stdlib/Test/test/runtests.jl b/stdlib/Test/test/runtests.jl index 0c08f78ef356f..995d2c983437c 100644 --- a/stdlib/Test/test/runtests.jl +++ b/stdlib/Test/test/runtests.jl @@ -1712,13 +1712,13 @@ end # this tests both the `TestCounts` parts as well as the fallback `x`s expected = r""" - Test Summary: | Pass Fail Error Broken Total Time - outer | 3 1 1 1 6 \s*\d*.\ds - a | 1 1 \s*\d*.\ds - custom | 1 1 1 1 4 \s*?s - no-record | x x x x ? \s*?s - b | 1 1 \s*\d*.\ds - ERROR: Some tests did not pass: 3 passed, 1 failed, 1 errored, 1 broken. + Test Summary: \| Pass Fail Error Broken Total Time + outer \| 3 1 1 1 6 \s*\d*.\ds + a \| 1 1 \s*\d*.\ds + custom \| 1 1 1 1 4 \s*\?s + no-record \| x x x x \? \s*\?s + b \| 1 1 \s*\d*.\ds + RNG of the outermost testset: .* """ cmd = `$(Base.julia_cmd()) --startup-file=no --color=no $f` @@ -1753,3 +1753,20 @@ module M54082 end @test only(result) isa Test.Fail end end + +@testset "Set RNG of testset" begin + rng1 = Xoshiro(0x2e026445595ed28e, 0x07bb81ac4c54926d, 0x83d7d70843e8bad6, 0xdbef927d150af80b, 0xdbf91ddf2534f850) + rng2 = Xoshiro(0xc380f460355639ee, 0xb39bc754b7d63bbf, 0x1551dbcfb5ed5668, 0x71ab5a18fec21a25, 0x649d0c1be1ca5436) + rng3 = Xoshiro(0xee97f5b53f7cdc49, 0x480ac387b0527d3d, 0x614b416502a9e0f5, 0x5250cb36e4a4ceb1, 0xed6615c59e475fa0) + + @testset rng=rng1 begin + @test rand() == rand(rng1) + end + + @testset rng=rng2 "Outer" begin + @test rand() == rand(rng2) + @testset rng=rng3 "Inner: $(i)" for i in 1:10 + @test rand() == rand(rng3) + end + end +end From 8e9c59f062173bbbb51341fcb6e84a41956cc4cc Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Tue, 31 Dec 2024 23:17:26 -0500 Subject: [PATCH 104/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?Pkg=20stdlib=20from=20c7e611bc8=20to=20739a64a0b=20(#56927)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/md5 | 1 + .../Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/sha512 | 1 + .../Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/md5 | 1 - .../Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/sha512 | 1 - stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/md5 create mode 100644 deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/sha512 delete mode 100644 deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/sha512 diff --git a/deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/md5 b/deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/md5 new file mode 100644 index 0000000000000..ca4ab8cc00ab2 --- /dev/null +++ b/deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/md5 @@ -0,0 +1 @@ +e647741a0c769fc636712d78f262536d diff --git a/deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/sha512 b/deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/sha512 new file mode 100644 index 0000000000000..dbfe7f0f4b9a6 --- /dev/null +++ b/deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/sha512 @@ -0,0 +1 @@ +5e98a337fed1558e2704c478e6f62c6f775e5d4c665c3c2ae5089bd334df52ba8badc982fcea35904927b8bcbad427de868f709da95babca78aee6091ea53d32 diff --git a/deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/md5 b/deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/md5 deleted file mode 100644 index ac906597fde45..0000000000000 --- a/deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -7e3e14d5f6f5851f91a487cbef962ddc diff --git a/deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/sha512 b/deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/sha512 deleted file mode 100644 index b5e016fae36a7..0000000000000 --- a/deps/checksums/Pkg-c7e611bc89826bc462c4b2a308f1a71dbb617145.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -2c492da39ecb43ff1c2ebac877a2de8b152564b4cac7ac1e3bdea006a80305168f7cd2d2d289073fc4db67b0686d6cc707b1f7ba04dacaef353bef9a4cbea61a diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 5102be7bdce46..982ac2e313b43 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = master -PKG_SHA1 = c7e611bc89826bc462c4b2a308f1a71dbb617145 +PKG_SHA1 = 739a64a0b1d4a8d79c703e99c73bd0433b32ebfa PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From 9a231690964dc30101ce6024a85d52cbebed17db Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Wed, 1 Jan 2025 19:49:35 -0500 Subject: [PATCH 105/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?Pkg=20stdlib=20from=20739a64a0b=20to=208d3cf02e5=20(#56930)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/md5 | 1 - .../Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/sha512 | 1 - .../Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 | 1 + .../Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 | 1 + stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/sha512 create mode 100644 deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 create mode 100644 deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 diff --git a/deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/md5 b/deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/md5 deleted file mode 100644 index ca4ab8cc00ab2..0000000000000 --- a/deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -e647741a0c769fc636712d78f262536d diff --git a/deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/sha512 b/deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/sha512 deleted file mode 100644 index dbfe7f0f4b9a6..0000000000000 --- a/deps/checksums/Pkg-739a64a0b1d4a8d79c703e99c73bd0433b32ebfa.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -5e98a337fed1558e2704c478e6f62c6f775e5d4c665c3c2ae5089bd334df52ba8badc982fcea35904927b8bcbad427de868f709da95babca78aee6091ea53d32 diff --git a/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 b/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 new file mode 100644 index 0000000000000..0ec07e44a059d --- /dev/null +++ b/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 @@ -0,0 +1 @@ +30eed5409ab2f5e7791cac9f6583ccad diff --git a/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 b/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 new file mode 100644 index 0000000000000..37415fcac993c --- /dev/null +++ b/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 @@ -0,0 +1 @@ +bb995ff7bc047121e79162da8775cbf21a2874427af53ea46ccf9db2a01d5d3e864262d232e2988f41248e6b45a266a64467ada7e6a88f2306135ac4f1bb794f diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 982ac2e313b43..568a15dae1cc0 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = master -PKG_SHA1 = 739a64a0b1d4a8d79c703e99c73bd0433b32ebfa +PKG_SHA1 = 8d3cf02e5e35913c89440c3b5c6678c1a806e975 PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From 51c27665e1f14b638ae948c02bd20c3828da46d5 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Thu, 2 Jan 2025 02:07:10 -0500 Subject: [PATCH 106/198] doc: summary of output functions: cross-ref println and printstyled (#55860) Slight tweak to #54547 to add cross-referenes to `println` and `printstyled`. Co-authored-by: Dilum Aluthge --- doc/src/manual/types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/manual/types.md b/doc/src/manual/types.md index 0b1d380c2c601..f13e2e6865d0f 100644 --- a/doc/src/manual/types.md +++ b/doc/src/manual/types.md @@ -1595,7 +1595,7 @@ Most new types should only need to define `show` methods, if anything. * [`display(x)`](@ref) tells the current environment to display `x` in whatever way it thinks best. (This might even be a graphical display in something like a Jupyter or Pluto notebook.) By default (e.g. in scripts or in the text REPL), it calls `show(io, "text/plain", x)`, or equivalently `show(io, MIME"text/plain"(), x)`, for an appropriate `io` stream. (In the REPL, `io` is an [`IOContext`](@ref) wrapper around [`stdout`](@ref).) The REPL uses `display` to output the result of an evaluated expression. * The 3-argument [`show(io, ::MIME"text/plain", x)`](@ref) method performs verbose pretty-printing of `x`. By default (if no 3-argument method is defined for `typeof(x)`), it calls the 2-argument `show(io, x)`. It is called by the 2-argument `repr("text/plain", x)`. Other 3-argument `show` methods can be defined for additional MIME types as discussed above, to enable richer display of `x` in some interactive environments. * The 2-argument [`show(io, x)`](@ref) is the default simple text representation of `x`. It is called by the 1-argument [`repr(x)`](@ref), and is typically the format you might employ to input `x` into Julia. The 1-argument `show(x)` calls `show(stdout, x)`. -* [`print(io, x)`](@ref) by default calls `show(io, x)`, but a few types have a distinct `print` format — most notably, when `x` is a string, `print` outputs the raw text whereas `show` outputs an escaped string enclosed in quotation marks. The 1-argument `print(x)` calls `print(stdout, x)`. `print` is also called by [`string(x)`](@ref). +* [`print(io, x)`](@ref) by default calls `show(io, x)`, but a few types have a distinct `print` format — most notably, when `x` is a string, `print` outputs the raw text whereas `show` outputs an escaped string enclosed in quotation marks. The 1-argument `print(x)` calls `print(stdout, x)`. `print` is also called by [`string(x)`](@ref). See also [`println`](@ref) (to append a newline) and [`printstyled`](@ref) (to add colors etc.), both of which call `print`. * [`write(io, x)`](@ref), if it is defined (it generally has *no* default definition for new types), writes a "raw" binary representation of `x` to `io`, e.g. an `x::Int32` will be written as 4 bytes. It is also helpful to be familiar with the metadata that can be attached to an `io` stream by an [`IOContext`](@ref) wrapper. For example, the REPL sets the `:limit => true` flag from `display` for an evaluated expression, in order to limit the output to fit in the terminal; you can query this flag with `get(io, :limit, false)`. And when displaying an object contained within, for example, a multi-column matrix, the `:compact => true` flag could be set, which you can query with `get(io, :compact, false)`. From 4f1842f10d09711f888f2a3ba93bc09c685fe8dc Mon Sep 17 00:00:00 2001 From: matthias314 <56549971+matthias314@users.noreply.github.com> Date: Thu, 2 Jan 2025 04:53:57 -0500 Subject: [PATCH 107/198] Make `Markdown.parse` public and add a docstring (#56818) --- stdlib/Markdown/docs/src/index.md | 1 + stdlib/Markdown/src/Common/block.jl | 2 +- stdlib/Markdown/src/GitHub/GitHub.jl | 2 +- stdlib/Markdown/src/Markdown.jl | 13 +++++++++++++ stdlib/Markdown/src/parse/parse.jl | 15 +++++++++------ 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/stdlib/Markdown/docs/src/index.md b/stdlib/Markdown/docs/src/index.md index ad620c22eae5d..926e3921d339d 100644 --- a/stdlib/Markdown/docs/src/index.md +++ b/stdlib/Markdown/docs/src/index.md @@ -420,6 +420,7 @@ custom flavour of Markdown can be used, but this should generally be unnecessary Markdown.MD Markdown.@md_str Markdown.@doc_str +Markdown.parse Markdown.html Markdown.latex ``` diff --git a/stdlib/Markdown/src/Common/block.jl b/stdlib/Markdown/src/Common/block.jl index 1b5cc1a752bcb..247c894769f15 100644 --- a/stdlib/Markdown/src/Common/block.jl +++ b/stdlib/Markdown/src/Common/block.jl @@ -21,7 +21,7 @@ function paragraph(stream::IO, md::MD) char == '\r' && !eof(stream) && peek(stream, Char) == '\n' && read(stream, Char) if prev_char == '\\' write(buffer, '\n') - elseif blankline(stream) || parse(stream, md, breaking = true) + elseif blankline(stream) || _parse(stream, md, breaking = true) break else write(buffer, ' ') diff --git a/stdlib/Markdown/src/GitHub/GitHub.jl b/stdlib/Markdown/src/GitHub/GitHub.jl index 61807d267511d..676ae4a137779 100644 --- a/stdlib/Markdown/src/GitHub/GitHub.jl +++ b/stdlib/Markdown/src/GitHub/GitHub.jl @@ -44,7 +44,7 @@ function github_paragraph(stream::IO, md::MD) for char in readeach(stream, Char) if char == '\n' eof(stream) && break - if blankline(stream) || parse(stream, md, breaking = true) + if blankline(stream) || _parse(stream, md, breaking = true) break else write(buffer, '\n') diff --git a/stdlib/Markdown/src/Markdown.jl b/stdlib/Markdown/src/Markdown.jl index 0d45d9e534df2..8d79cc93d6171 100644 --- a/stdlib/Markdown/src/Markdown.jl +++ b/stdlib/Markdown/src/Markdown.jl @@ -35,6 +35,8 @@ include("render/terminal/render.jl") export @md_str, @doc_str +public MD, parse + const MARKDOWN_FACES = [ :markdown_header => Face(weight=:bold), :markdown_h1 => Face(height=1.25, inherit=:markdown_header), @@ -57,7 +59,16 @@ const MARKDOWN_FACES = [ __init__() = foreach(addface!, MARKDOWN_FACES) parse(markdown::String; flavor = julia) = parse(IOBuffer(markdown), flavor = flavor) + +""" + Markdown.parse(markdown::AbstractString) -> MD + +Parse `markdown` as Julia-flavored Markdown text and return the corresponding `MD` object. + +See also [`@md_str`](@ref). +""" parse(markdown::AbstractString; flavor = julia) = parse(String(markdown), flavor = flavor) + parse_file(file::AbstractString; flavor = julia) = parse(read(file, String), flavor = flavor) function mdexpr(s, flavor = :julia) @@ -74,6 +85,8 @@ end Parse the given string as Markdown text and return a corresponding [`MD`](@ref) object. +See also [`Markdown.parse`](@ref Markdown.parse(::AbstractString)). + # Examples ```jldoctest julia> s = md"# Hello, world!" diff --git a/stdlib/Markdown/src/parse/parse.jl b/stdlib/Markdown/src/parse/parse.jl index 389099b2984f6..dee1e781bfbef 100644 --- a/stdlib/Markdown/src/parse/parse.jl +++ b/stdlib/Markdown/src/parse/parse.jl @@ -15,8 +15,6 @@ mutable struct MD new(content, meta) end -public MD - MD(xs...) = MD(vcat(xs...)) function MD(cfg::Config, xs...) @@ -85,7 +83,7 @@ parseinline(s, md::MD) = parseinline(s, md, config(md)) # Block parsing -function parse(stream::IO, block::MD, config::Config; breaking = false) +function _parse(stream::IO, block::MD, config::Config; breaking = false) skipblank(stream) eof(stream) && return false for parser in (breaking ? config.breaking : [config.breaking; config.regular]) @@ -94,12 +92,17 @@ function parse(stream::IO, block::MD, config::Config; breaking = false) return false end -parse(stream::IO, block::MD; breaking = false) = - parse(stream, block, config(block), breaking = breaking) +_parse(stream::IO, block::MD; breaking = false) = + _parse(stream, block, config(block), breaking = breaking) + +""" + parse(stream::IO) -> MD +Parse the content of `stream` as Julia-flavored Markdown text and return the corresponding `MD` object. +""" function parse(stream::IO; flavor = julia) isa(flavor, Symbol) && (flavor = flavors[flavor]) markdown = MD(flavor) - while parse(stream, markdown, flavor) end + while _parse(stream, markdown, flavor) end return markdown end From 27b44cf9304b86fbb01b3697d5cfab11e0eee0c2 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 2 Jan 2025 07:30:08 -0500 Subject: [PATCH 108/198] precompilepkgs: color the "is currently loaded" text to make meaning clearer (#56926) --- base/precompilation.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/base/precompilation.jl b/base/precompilation.jl index c7dcd0af64caa..820cf260df71f 100644 --- a/base/precompilation.jl +++ b/base/precompilation.jl @@ -1042,7 +1042,9 @@ function _precompilepkgs(pkgs::Vector{String}, plural4 = n_loaded == 1 ? "this package" : "these packages" print(iostr, "\n ", color_string(string(n_loaded), Base.warn_color()), - " $(plural1) precompiled but $(plural2) currently loaded. Restart julia to access the new version$(plural3). \ + " $(plural1) precompiled but ", + color_string("$(plural2) currently loaded", Base.warn_color()), + ". Restart julia to access the new version$(plural3). \ Otherwise, loading dependents of $(plural4) may trigger further precompilation to work with the unexpected version$(plural3)." ) end From a393c6f18324f5d4cfab14108c991b31976358c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20=C3=96qvist?= Date: Thu, 2 Jan 2025 15:12:40 +0100 Subject: [PATCH 109/198] Remove unused variable from `endswith` (#56934) This is a trivial code cleanup suggestion. The `cub` variable was unused in `endswith(::Union{String, SubString{String}}, ::Union{String, SubString{String}})`. I ran the tests with `make test`, there were some failures but they did not appear to be related to the change. --- base/strings/util.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/base/strings/util.jl b/base/strings/util.jl index 1b73fbbbab5cf..87c2abab5344c 100644 --- a/base/strings/util.jl +++ b/base/strings/util.jl @@ -100,7 +100,6 @@ Base.startswith(io::IO, prefix::AbstractString) = startswith(io, String(prefix)) function endswith(a::Union{String, SubString{String}}, b::Union{String, SubString{String}}) - cub = ncodeunits(b) astart = ncodeunits(a) - ncodeunits(b) + 1 if astart < 1 false From 0741f9b99587e90333b736999110fba3d1bc6cac Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Thu, 2 Jan 2025 09:30:50 -0500 Subject: [PATCH 110/198] deps: support Unicode 16 via utf8proc 2.10.0 (#56925) Similar to #51799, support [Unicode 16](https://www.unicode.org/versions/Unicode16.0.0/) by bumping utf8proc to 2.10.0 (thanks to https://github.com/JuliaStrings/utf8proc/pull/277 by @eschnett). This allows us to use [7 exciting new emoji characters](https://www.unicode.org/emoji/charts-16.0/emoji-released.html) as identifiers, including "face with bags under eyes" ![image](https://github.com/user-attachments/assets/4959b7ca-100e-4efc-af58-b03184ae2dca) `"\U1fae9"` (but still no superscript "q"). Closes #56035. --- NEWS.md | 1 + deps/checksums/utf8proc | 4 ++-- deps/utf8proc.version | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index e6d12f1822da4..8f02045a213d6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -22,6 +22,7 @@ New language features The available metrics are: - actual running time for the task (`Base.Experimental.task_running_time_ns`), and - wall-time for the task (`Base.Experimental.task_wall_time_ns`). +- Support for Unicode 16 ([#56925]). Language changes ---------------- diff --git a/deps/checksums/utf8proc b/deps/checksums/utf8proc index 543c1805afbd8..2055d3323b7e1 100644 --- a/deps/checksums/utf8proc +++ b/deps/checksums/utf8proc @@ -1,2 +1,2 @@ -utf8proc-34db3f7954e9298e89f42641ac78e0450f80a70d.tar.gz/md5/e70e4fd2c914b4d4c0e3f0e2ca6c96d4 -utf8proc-34db3f7954e9298e89f42641ac78e0450f80a70d.tar.gz/sha512/0037f144e1150abd1b330d8a0c3a46c8352903acc9f4c8aad6bddd1370b19cc34551f8def58752cdff4eaace3efe54180bc11439a0e35c5ccad2fec4678c017e +utf8proc-a1b99daa2a3393884220264c927a48ba1251a9c6.tar.gz/md5/2c404870fdc19982ec5313ee78e478d7 +utf8proc-a1b99daa2a3393884220264c927a48ba1251a9c6.tar.gz/sha512/a6652f5840439fe051d973d9467ca9805dcea8d0ac75a2d35e3f8041c513d6ccd5d205a3873f28d7cb5e33ce6471165850164997f188ca359111963b3aac9a16 diff --git a/deps/utf8proc.version b/deps/utf8proc.version index a026ca858cfd3..c880d6561ce09 100644 --- a/deps/utf8proc.version +++ b/deps/utf8proc.version @@ -1,2 +1,2 @@ -UTF8PROC_BRANCH=v2.9.0 -UTF8PROC_SHA1=34db3f7954e9298e89f42641ac78e0450f80a70d +UTF8PROC_BRANCH=v2.10.0 +UTF8PROC_SHA1=a1b99daa2a3393884220264c927a48ba1251a9c6 From 5c88b72ebc9979a1b856eefda25b9bc11fefaae1 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 20 Dec 2024 20:24:09 +0000 Subject: [PATCH 111/198] teach jitlayers to use equivalent edges Sometimes an edge (especially from precompile file, but sometimes from inference) will specify a CodeInstance that does not need to be compiled for its ABI and simply needs to be cloned to point to the existing copy of it. --- src/gf.c | 6 +--- src/jitlayers.cpp | 79 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 71 insertions(+), 14 deletions(-) diff --git a/src/gf.c b/src/gf.c index 52741094c0533..dcf1823f57746 100644 --- a/src/gf.c +++ b/src/gf.c @@ -344,7 +344,7 @@ jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_a jl_code_instance_t *jl_type_infer(jl_method_instance_t *mi, size_t world, uint8_t source_mode) { if (jl_typeinf_func == NULL) - return NULL; + return jl_method_inferred_with_abi(mi, world); jl_task_t *ct = jl_current_task; if (ct->reentrant_timing & 0b1000) { // We must avoid attempting to re-enter inference here @@ -2857,9 +2857,6 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t } // Ok, compilation is enabled. We'll need to try to compile something (probably). - // Try to find a codeinst we have already inferred (e.g. while we were compiling - // something else). - codeinst = jl_method_inferred_with_abi(mi, world); // Everything from here on is considered (user facing) compile time uint64_t start = jl_typeinf_timing_begin(); @@ -2875,7 +2872,6 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t codeinst_old = jl_atomic_load_relaxed(&codeinst_old->next); } - // This codeinst hasn't been previously inferred do that now // jl_type_infer will internally do a cache lookup and jl_engine_reserve call // to synchronize this across threads if (!codeinst) { diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index bdb8298df41a6..139a5631d63c0 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -301,6 +301,29 @@ static void finish_params(Module *M, jl_codegen_params_t ¶ms) JL_NOTSAFEPOIN } } +// look for something with an egal ABI that is already in the JIT +static jl_code_instance_t *jl_method_compiled_egal(jl_code_instance_t *ci JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT +{ + jl_method_instance_t *mi = ci->def; + jl_value_t *owner = ci->owner; + jl_value_t *rettype = ci->rettype; + size_t min_world = jl_atomic_load_relaxed(&ci->min_world); + size_t max_world = jl_atomic_load_relaxed(&ci->max_world); + jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache); + while (codeinst) { + if (codeinst != ci && + jl_atomic_load_relaxed(&codeinst->inferred) != NULL && + jl_atomic_load_relaxed(&codeinst->invoke) != NULL && + jl_atomic_load_relaxed(&codeinst->min_world) <= min_world && + jl_atomic_load_relaxed(&codeinst->max_world) >= max_world && + jl_egal(codeinst->owner, owner) && + jl_egal(codeinst->rettype, rettype)) { + return codeinst; + } + codeinst = jl_atomic_load_relaxed(&codeinst->next); + } + return codeinst; +} static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t ¶ms, bool forceall=false) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER { @@ -309,6 +332,7 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t std::swap(params.workqueue, edges); for (auto &it : edges) { jl_code_instance_t *codeinst = it.first; + JL_GC_PROMISE_ROOTED(codeinst); auto &proto = it.second; // try to emit code for this item from the workqueue StringRef invokeName = ""; @@ -321,7 +345,7 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t // But it must be consistent with the following invokenames lookup, which is protected by the engine_lock uint8_t specsigflags; void *fptr; - void jl_read_codeinst_invoke(jl_code_instance_t *ci, uint8_t *specsigflags, jl_callptr_t *invoke, void **specptr, int waitcompile) JL_NOTSAFEPOINT; // not a safepoint (or deadlock) in this file due to 0 parameter + void jl_read_codeinst_invoke(jl_code_instance_t *ci, uint8_t *specsigflags, jl_callptr_t *invoke, void **specptr, int waitcompile) JL_NOTSAFEPOINT; // declare it is not a safepoint (or deadlock) in this file due to 0 parameter jl_read_codeinst_invoke(codeinst, &specsigflags, &invoke, &fptr, 0); //if (specsig ? specsigflags & 0b1 : invoke == jl_fptr_args_addr) if (invoke == jl_fptr_args_addr) { @@ -349,6 +373,40 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t force = true; } } + if (preal_decl.empty()) { + // there may be an equivalent method already compiled (or at least registered with the JIT to compile), in which case we should be using that instead + jl_code_instance_t *compiled_ci = jl_method_compiled_egal(codeinst); + if (compiled_ci) { + codeinst = compiled_ci; + uint8_t specsigflags; + void *fptr; + jl_read_codeinst_invoke(codeinst, &specsigflags, &invoke, &fptr, 0); + //if (specsig ? specsigflags & 0b1 : invoke == jl_fptr_args_addr) + if (invoke == jl_fptr_args_addr) { + preal_decl = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, invoke, codeinst); + } + else if (specsigflags & 0b1) { + preal_decl = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, invoke, codeinst); + preal_specsig = true; + } + if (preal_decl.empty()) { + auto it = invokenames.find(codeinst); + if (it != invokenames.end()) { + auto &decls = it->second; + invokeName = decls.functionObject; + if (decls.functionObject == "jl_fptr_args") { + preal_decl = decls.specFunctionObject; + isedge = true; + } + else if (decls.functionObject != "jl_fptr_sparam" && decls.functionObject != "jl_f_opaque_closure_call") { + preal_decl = decls.specFunctionObject; + preal_specsig = true; + isedge = true; + } + } + } + } + } if (!preal_decl.empty() || force) { // if we have a prototype emitted, compare it to what we emitted earlier Module *mod = proto.decl->getParent(); @@ -733,14 +791,17 @@ static void recursive_compile_graph( while (!workqueue.empty()) { auto this_code = workqueue.pop_back_val(); if (Seen.insert(this_code).second) { - if (this_code != codeinst) { - JL_GC_PROMISE_ROOTED(this_code); // rooted transitively from following edges from original argument - jl_emit_codeinst_to_jit(this_code, nullptr); // contains safepoints - } - jl_unique_gcsafe_lock lock(engine_lock); - auto edges = complete_graph.find(this_code); - if (edges != complete_graph.end()) { - workqueue.append(edges->second); + jl_code_instance_t *compiled_ci = jl_method_compiled_egal(codeinst); + if (!compiled_ci) { + if (this_code != codeinst) { + JL_GC_PROMISE_ROOTED(this_code); // rooted transitively from following edges from original argument + jl_emit_codeinst_to_jit(this_code, nullptr); // contains safepoints + } + jl_unique_gcsafe_lock lock(engine_lock); + auto edges = complete_graph.find(this_code); + if (edges != complete_graph.end()) { + workqueue.append(edges->second); + } } } } From b6fbd8123af1f68fb8aa5f06551bd28b0fd1ee3a Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 18 Dec 2024 18:52:48 +0000 Subject: [PATCH 112/198] opaque_closure: fix data-race mistakes with reading fields by using standard helper function --- src/gf.c | 1 + src/opaque_closure.c | 28 +++++++++++++++------------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/gf.c b/src/gf.c index dcf1823f57746..8086d75329bef 100644 --- a/src/gf.c +++ b/src/gf.c @@ -2722,6 +2722,7 @@ void jl_read_codeinst_invoke(jl_code_instance_t *ci, uint8_t *specsigflags, jl_c initial_invoke = jl_atomic_load_acquire(&ci->invoke); // happens-before for subsequent read of fptr } void *fptr = jl_atomic_load_relaxed(&ci->specptr.fptr); + // TODO: if fptr is NULL, it may mean we read this too fast, and should have spun and waited for jl_compile_codeinst to finish if (initial_invoke == NULL || fptr == NULL) { *invoke = initial_invoke; *specptr = NULL; diff --git a/src/opaque_closure.c b/src/opaque_closure.c index e3334c037f5a9..8a9dcac30a4f8 100644 --- a/src/opaque_closure.c +++ b/src/opaque_closure.c @@ -67,12 +67,14 @@ static jl_opaque_closure_t *new_opaque_closure(jl_tupletype_t *argt, jl_value_t ci = jl_compile_method_internal(mi, world); } - jl_fptr_args_t invoke = (jl_fptr_args_t)jl_interpret_opaque_closure; + jl_fptr_args_t callptr = (jl_fptr_args_t)jl_interpret_opaque_closure; void *specptr = NULL; if (ci) { - invoke = (jl_fptr_args_t)jl_atomic_load_relaxed(&ci->invoke); - specptr = jl_atomic_load_relaxed(&ci->specptr.fptr); + uint8_t specsigflags; + jl_callptr_t invoke; + jl_read_codeinst_invoke(ci, &specsigflags, &invoke, &specptr, 1); + callptr = (jl_fptr_args_t)invoke; // codegen puts the object (or a jl_fptr_interpret_call token )here for us, even though it was the wrong type to put here selected_rt = ci->rettype; // If we're not allowed to generate a specsig with this, rt, fall @@ -82,7 +84,7 @@ static jl_opaque_closure_t *new_opaque_closure(jl_tupletype_t *argt, jl_value_t // TODO: It would be better to try to get a specialization with the // correct rt check here (or we could codegen a wrapper). specptr = NULL; // this will force codegen of the unspecialized version - invoke = (jl_fptr_args_t)jl_interpret_opaque_closure; + callptr = (jl_fptr_args_t)jl_interpret_opaque_closure; jl_value_t *ts[2] = {rt_lb, (jl_value_t*)ci->rettype}; selected_rt = jl_type_union(ts, 2); } @@ -90,18 +92,18 @@ static jl_opaque_closure_t *new_opaque_closure(jl_tupletype_t *argt, jl_value_t // TODO: It would be better to try to get a specialization with the // correct rt check here (or we could codegen a wrapper). specptr = NULL; // this will force codegen of the unspecialized version - invoke = (jl_fptr_args_t)jl_interpret_opaque_closure; + callptr = (jl_fptr_args_t)jl_interpret_opaque_closure; selected_rt = jl_type_intersection(rt_ub, selected_rt); } - if (invoke == (jl_fptr_args_t) jl_fptr_interpret_call) { - invoke = (jl_fptr_args_t)jl_interpret_opaque_closure; + if (callptr == (jl_fptr_args_t)jl_fptr_interpret_call) { + callptr = (jl_fptr_args_t)jl_interpret_opaque_closure; } - else if (invoke == (jl_fptr_args_t)jl_fptr_args && specptr) { - invoke = (jl_fptr_args_t)specptr; + else if (callptr == (jl_fptr_args_t)jl_fptr_args && specptr != NULL) { + callptr = (jl_fptr_args_t)specptr; } - else if (invoke == (jl_fptr_args_t)jl_fptr_const_return) { - invoke = jl_isa(ci->rettype_const, selected_rt) ? + else if (callptr == (jl_fptr_args_t)jl_fptr_const_return) { + callptr = jl_isa(ci->rettype_const, selected_rt) ? (jl_fptr_args_t)jl_fptr_const_opaque_closure : (jl_fptr_args_t)jl_fptr_const_opaque_closure_typeerror; captures = ci->rettype_const; @@ -117,14 +119,14 @@ static jl_opaque_closure_t *new_opaque_closure(jl_tupletype_t *argt, jl_value_t // OC wrapper methods are not world dependent and have no edges or other info ci = jl_get_method_inferred(mi_generic, selected_rt, 1, ~(size_t)0, NULL, NULL); if (!jl_atomic_load_acquire(&ci->invoke)) - jl_compile_codeinst(ci); // confusing this actually calls jl_emit_oc_wrapper and never actually compiles ci (which would be impossible) + jl_compile_codeinst(ci); // confusing this actually calls jl_emit_oc_wrapper and never actually compiles ci (which would be impossible since it cannot have source) specptr = jl_atomic_load_relaxed(&ci->specptr.fptr); } jl_opaque_closure_t *oc = (jl_opaque_closure_t*)jl_gc_alloc(ct->ptls, sizeof(jl_opaque_closure_t), oc_type); oc->source = source; oc->captures = captures; oc->world = world; - oc->invoke = invoke; + oc->invoke = callptr; oc->specptr = specptr; JL_GC_POP(); From 835c8ac9aacdbb806695230aed875b4508bbf319 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 18 Dec 2024 20:39:34 +0000 Subject: [PATCH 113/198] opaque_closure: fix world-age mistake in fallback path This was failing the h_world_age test sometimes. --- src/codegen.cpp | 13 ++++++++++++- src/gf.c | 12 ++++++++++++ src/julia.h | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 5bf7c74deedcb..ceaba9507e4c7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -996,6 +996,15 @@ static const auto jlinvoke_func = new JuliaFunction<>{ {AttributeSet(), Attributes(C, {Attribute::ReadOnly, Attribute::NoCapture})}); }, }; +static const auto jlinvokeoc_func = new JuliaFunction<>{ + XSTR(jl_invoke_oc), + get_func2_sig, + [](LLVMContext &C) { return AttributeList::get(C, + AttributeSet(), + Attributes(C, {Attribute::NonNull}), + {AttributeSet(), + Attributes(C, {Attribute::ReadOnly, Attribute::NoCapture})}); }, +}; static const auto jlopaque_closure_call_func = new JuliaFunction<>{ XSTR(jl_f_opaque_closure_call), get_func_sig, @@ -7288,7 +7297,9 @@ Function *emit_tojlinvoke(jl_code_instance_t *codeinst, StringRef theFptrName, M theFarg = literal_pointer_val(ctx, (jl_value_t*)codeinst); } else { - theFunc = prepare_call(jlinvoke_func); + jl_method_instance_t *mi = codeinst->def; + bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure; + theFunc = prepare_call(is_opaque_closure ? jlinvokeoc_func : jlinvoke_func); theFarg = literal_pointer_val(ctx, (jl_value_t*)jl_get_ci_mi(codeinst)); } theFarg = track_pjlvalue(ctx, theFarg); diff --git a/src/gf.c b/src/gf.c index 8086d75329bef..3a308ca6154fc 100644 --- a/src/gf.c +++ b/src/gf.c @@ -3373,6 +3373,18 @@ JL_DLLEXPORT jl_value_t *jl_invoke(jl_value_t *F, jl_value_t **args, uint32_t na return _jl_invoke(F, args, nargs, mfunc, world); } +JL_DLLEXPORT jl_value_t *jl_invoke_oc(jl_value_t *F, jl_value_t **args, uint32_t nargs, jl_method_instance_t *mfunc) +{ + jl_opaque_closure_t *oc = (jl_opaque_closure_t*)F; + jl_task_t *ct = jl_current_task; + size_t last_age = ct->world_age; + size_t world = oc->world; + ct->world_age = world; + jl_value_t *ret = _jl_invoke(F, args, nargs, mfunc, world); + ct->world_age = last_age; + return ret; +} + STATIC_INLINE int sig_match_fast(jl_value_t *arg1t, jl_value_t **args, jl_value_t **sig, size_t n) { // NOTE: This function is a huge performance hot spot!! diff --git a/src/julia.h b/src/julia.h index a71f9db030274..9b8d090fe37cb 100644 --- a/src/julia.h +++ b/src/julia.h @@ -2237,6 +2237,7 @@ STATIC_INLINE int jl_vinfo_usedundef(uint8_t vi) JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t *F, jl_value_t **args, uint32_t nargs); JL_DLLEXPORT jl_value_t *jl_invoke(jl_value_t *F, jl_value_t **args, uint32_t nargs, jl_method_instance_t *meth); +JL_DLLEXPORT jl_value_t *jl_invoke_oc(jl_value_t *F, jl_value_t **args, uint32_t nargs, jl_method_instance_t *meth); JL_DLLEXPORT int32_t jl_invoke_api(jl_code_instance_t *linfo); STATIC_INLINE jl_value_t *jl_apply(jl_value_t **args, uint32_t nargs) From 59d74d46f8aeb4c826f2b2c65f36978589cdfafb Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 11 Dec 2024 16:33:46 +0000 Subject: [PATCH 114/198] inference,codegen: connect source directly to jit This avoids unnecessary compression when running (not generating code). While generating code, we continue the legacy behavior of storing compressed code, since restarting from a ji without that is quite slow. Eventually, we should also remove that code also once we have generated the object file from it. This replaces the defective SOURCE_MODE_FORCE_SOURCE option with a new `typeinf_ext_toplevel` batch-mode interface for compilation which returns all required source code. Only two options remain now: SOURCE_MODE_NOT_REQUIRED : Require only that the IPO information (e.g. rettype and friends) is present. SOURCE_MODE_FORCE_ABI : Require that the IPO information is present (for ABI computation) and that the returned CodeInstance can be invoked on the host target (preferably after inference, called directly, but perfectly acceptable for Base.Compiler to instead force the runtime to use a stub there or call into it with the interpreter instead by having failed to provide any code). This replaces the awkward `jl_create_native` interface (which is now just a shim for calling the new batch-mode `typeinf_ext_toplevel`) with a simpler `jl_emit_native` API, which does not do any inference or other callbacks, but simply is a batch-mode call to `jl_emit_codeinfo` and the work to build the external wrapper around them for linkage. --- Compiler/src/bootstrap.jl | 19 +- Compiler/src/tfuncs.jl | 18 +- Compiler/src/typeinfer.jl | 245 ++++++++++++++++---------- Compiler/src/types.jl | 13 +- Compiler/src/utilities.jl | 3 + Compiler/test/abioverride.jl | 30 ++-- base/reflection.jl | 8 - src/aotcompile.cpp | 332 +++++++++++++++-------------------- src/ccall.cpp | 8 +- src/codegen-stubs.c | 20 ++- src/codegen.cpp | 81 +-------- src/gf.c | 60 ++++++- src/jitlayers.cpp | 46 +++-- src/jitlayers.h | 8 +- src/jl_exported_funcs.inc | 3 +- src/julia.h | 1 + src/julia_internal.h | 17 +- src/precompile_utils.c | 16 +- src/toplevel.c | 16 +- test/precompile.jl | 59 +++---- 20 files changed, 501 insertions(+), 502 deletions(-) diff --git a/Compiler/src/bootstrap.jl b/Compiler/src/bootstrap.jl index 475c53e317152..ea7510df313c7 100644 --- a/Compiler/src/bootstrap.jl +++ b/Compiler/src/bootstrap.jl @@ -16,9 +16,9 @@ function activate_codegen!() end function bootstrap!() + global bootstrapping_compiler = true let time() = ccall(:jl_clock_now, Float64, ()) println("Compiling the compiler. This may take several minutes ...") - interp = NativeInterpreter() ssa_inlining_pass!_tt = Tuple{typeof(ssa_inlining_pass!), IRCode, InliningState{NativeInterpreter}, Bool} optimize_tt = Tuple{typeof(optimize), NativeInterpreter, OptimizationState{NativeInterpreter}, InferenceResult} @@ -45,13 +45,15 @@ function bootstrap!() end end starttime = time() + methods = Any[] + world = get_world_counter() for f in fs if isa(f, DataType) && f.name === typename(Tuple) tt = f else tt = Tuple{typeof(f), Vararg{Any}} end - matches = _methods_by_ftype(tt, 10, get_world_counter())::Vector + matches = _methods_by_ftype(tt, 10, world)::Vector if isempty(matches) println(stderr, "WARNING: no matching method found for `", tt, "`") else @@ -62,14 +64,25 @@ function bootstrap!() for i = 1:length(params) params[i] = unwraptv(params[i]) end - typeinf_type(interp, m.method, Tuple{params...}, m.sparams) + mi = specialize_method(m.method, Tuple{params...}, m.sparams) + #isa_compileable_sig(mi) || println(stderr, "WARNING: inferring `", mi, "` which isn't expected to be called.") + push!(methods, mi) end end end + codeinfos = typeinf_ext_toplevel(methods, [world], false) + for i = 1:2:length(codeinfos) + ci = codeinfos[i]::CodeInstance + src = codeinfos[i + 1]::CodeInfo + isa_compileable_sig(ci.def) || continue # println(stderr, "WARNING: compiling `", ci.def, "` which isn't expected to be called.") + ccall(:jl_add_codeinst_to_jit, Cvoid, (Any, Any), ci, src) + end endtime = time() println("Base.Compiler ──── ", sub_float(endtime,starttime), " seconds") end activate_codegen!() + global bootstrapping_compiler = false + nothing end function activate!(; reflection=true, codegen=false) diff --git a/Compiler/src/tfuncs.jl b/Compiler/src/tfuncs.jl index e51d43e5b2fe1..f0c793a4ae3b7 100644 --- a/Compiler/src/tfuncs.jl +++ b/Compiler/src/tfuncs.jl @@ -42,11 +42,10 @@ macro nospecs(ex) push!(names, arg) end @assert isexpr(body, :block) - if !isempty(names) - lin = first(body.args)::LineNumberNode - nospec = Expr(:macrocall, Symbol("@nospecialize"), lin, names...) - insert!(body.args, 2, nospec) - end + isempty(names) && throw(ArgumentError("no arguments for @nospec")) + lin = first(body.args)::LineNumberNode + nospec = Expr(:macrocall, GlobalRef(@__MODULE__, :var"@nospecialize"), lin, names...) + insert!(body.args, 2, nospec) return esc(ex) end @@ -2115,7 +2114,7 @@ add_tfunc(memoryrefoffset, 1, 1, memoryrefoffset_tfunc, 5) return true end -@nospecs function memoryref_elemtype(@nospecialize mem) +@nospecs function memoryref_elemtype(mem) m = widenconst(mem) if !has_free_typevars(m) && m <: GenericMemoryRef m0 = m @@ -2131,7 +2130,7 @@ end return Any end -@nospecs function _memoryref_elemtype(@nospecialize mem) +@nospecs function _memoryref_elemtype(mem) m = widenconst(mem) if !has_free_typevars(m) && m <: GenericMemoryRef m0 = m @@ -2166,7 +2165,7 @@ end end # whether getindex for the elements can potentially throw UndefRef -function array_type_undefable(@nospecialize(arytype)) +@nospecs function array_type_undefable(arytype) arytype = unwrap_unionall(arytype) if isa(arytype, Union) return array_type_undefable(arytype.a) || array_type_undefable(arytype.b) @@ -2247,7 +2246,7 @@ end return boundscheck ⊑ Bool && memtype ⊑ GenericMemoryRef && order ⊑ Symbol end -@nospecs function memorynew_nothrow(argtypes::Vector{Any}) +function memorynew_nothrow(argtypes::Vector{Any}) if !(argtypes[1] isa Const && argtypes[2] isa Const) return false end @@ -2263,6 +2262,7 @@ end overflows = checked_smul_int(len, elsz)[2] return !overflows end + # Query whether the given builtin is guaranteed not to throw given the `argtypes`. # `argtypes` can be assumed not to contain varargs. function _builtin_nothrow(𝕃::AbstractLattice, @nospecialize(f::Builtin), argtypes::Vector{Any}, diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index eba520a03ada1..45df4707e4caa 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -92,8 +92,7 @@ If set to `true`, record per-method-instance timings within type inference in th __set_measure_typeinf(onoff::Bool) = __measure_typeinf__[] = onoff const __measure_typeinf__ = RefValue{Bool}(false) -function finish!(interp::AbstractInterpreter, caller::InferenceState; - can_discard_trees::Bool=may_discard_trees(interp)) +function finish!(interp::AbstractInterpreter, caller::InferenceState) result = caller.result opt = result.src if opt isa OptimizationState @@ -120,20 +119,28 @@ function finish!(interp::AbstractInterpreter, caller::InferenceState; store_backedges(ci, edges) end inferred_result = nothing + uncompressed = inferred_result relocatability = 0x1 const_flag = is_result_constabi_eligible(result) - if !can_discard_trees || (is_cached(caller) && !const_flag) + discard_src = caller.cache_mode === CACHE_MODE_NULL || const_flag + if !discard_src inferred_result = transform_result_for_cache(interp, result) # TODO: do we want to augment edges here with any :invoke targets that we got from inlining (such that we didn't have a direct edge to it already)? - relocatability = 0x0 if inferred_result isa CodeInfo + if may_compress(interp) + nslots = length(inferred_result.slotflags) + resize!(inferred_result.slottypes::Vector{Any}, nslots) + resize!(inferred_result.slotnames, nslots) + end di = inferred_result.debuginfo uncompressed = inferred_result - inferred_result = maybe_compress_codeinfo(interp, result.linfo, inferred_result, can_discard_trees) - result.is_src_volatile |= uncompressed !== inferred_result + inferred_result = maybe_compress_codeinfo(interp, result.linfo, inferred_result) + result.is_src_volatile = false elseif ci.owner === nothing # The global cache can only handle objects that codegen understands inferred_result = nothing + else + relocatability = 0x0 end if isa(inferred_result, String) t = @_gc_preserve_begin inferred_result @@ -141,7 +148,7 @@ function finish!(interp::AbstractInterpreter, caller::InferenceState; @_gc_preserve_end t end end - # n.b. relocatability = isa(inferred_result, String) && inferred_result[end] + # n.b. relocatability = !isa(inferred_result, String) || inferred_result[end] if !@isdefined di di = DebugInfo(result.linfo) end @@ -149,6 +156,19 @@ function finish!(interp::AbstractInterpreter, caller::InferenceState; ci, inferred_result, const_flag, first(result.valid_worlds), last(result.valid_worlds), encode_effects(result.ipo_effects), result.analysis_results, relocatability, di, edges) engine_reject(interp, ci) + if !discard_src && isdefined(interp, :codegen) && uncompressed isa CodeInfo + # record that the caller could use this result to generate code when required, if desired, to avoid repeating n^2 work + interp.codegen[ci] = uncompressed + if bootstrapping_compiler && inferred_result == nothing + # This is necessary to get decent bootstrapping performance + # when compiling the compiler to inject everything eagerly + # where codegen can start finding and using it right away + mi = result.linfo + if mi.def isa Method && isa_compileable_sig(mi) + ccall(:jl_add_codeinst_to_jit, Cvoid, (Any, Any), ci, uncompressed) + end + end + end end return nothing end @@ -223,19 +243,13 @@ end transform_result_for_cache(::AbstractInterpreter, result::InferenceResult) = result.src -function maybe_compress_codeinfo(interp::AbstractInterpreter, mi::MethodInstance, ci::CodeInfo, - can_discard_trees::Bool=may_discard_trees(interp)) +function maybe_compress_codeinfo(interp::AbstractInterpreter, mi::MethodInstance, ci::CodeInfo) def = mi.def isa(def, Method) || return ci # don't compress toplevel code - cache_the_tree = true - if can_discard_trees - cache_the_tree = is_inlineable(ci) || isa_compileable_sig(mi.specTypes, mi.sparam_vals, def) - end + can_discard_trees = may_discard_trees(interp) + cache_the_tree = !can_discard_trees || is_inlineable(ci) if cache_the_tree if may_compress(interp) - nslots = length(ci.slotflags) - resize!(ci.slottypes::Vector{Any}, nslots) - resize!(ci.slotnames, nslots) return ccall(:jl_compress_ir, String, (Any, Any), def, ci) else return ci @@ -476,7 +490,7 @@ function finishinfer!(me::InferenceState, interp::AbstractInterpreter) rettype_const = nothing const_flags = 0x0 end - relocatability = 0x0 + relocatability = 0x1 di = nothing edges = empty_edges # `edges` will be updated within `finish!` ci = result.ci @@ -484,10 +498,10 @@ function finishinfer!(me::InferenceState, interp::AbstractInterpreter) ci, widenconst(result_type), widenconst(result.exc_result), rettype_const, const_flags, first(result.valid_worlds), last(result.valid_worlds), encode_effects(result.ipo_effects), result.analysis_results, di, edges) - if is_cached(me) + if is_cached(me) # CACHE_MODE_GLOBAL cached_result = cache_result!(me.interp, result, ci) if !cached_result - me.cache_mode = CACHE_MODE_NULL + me.cache_mode = CACHE_MODE_VOLATILE end end end @@ -705,7 +719,7 @@ function resolve_call_cycle!(interp::AbstractInterpreter, mi::MethodInstance, pa for frameid = reverse(1:length(frames)) frame = frames[frameid] isa(frame, InferenceState) || break - uncached |= !is_cached(frame) # ensure we never add an uncached frame to a cycle + uncached |= !is_cached(frame) # ensure we never add a (globally) uncached frame to a cycle if is_same_frame(interp, mi, frame) if uncached # our attempt to speculate into a constant call lead to an undesired self-cycle @@ -796,6 +810,7 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize cache_mode = CACHE_MODE_GLOBAL # cache edge targets globally by default force_inline = is_stmt_inline(get_curr_ssaflag(caller)) edge_ci = nothing + # check cache with SOURCE_MODE_NOT_REQUIRED source_mode let codeinst = get(code_cache(interp), mi, nothing) if codeinst isa CodeInstance # return existing rettype if the code is already inferred inferred = @atomic :monotonic codeinst.inferred @@ -945,21 +960,6 @@ function codeinfo_for_const(interp::AbstractInterpreter, mi::MethodInstance, @no return tree end -""" - codeinstance_for_const_with_code(interp::AbstractInterpreter, code::CodeInstance) - -Given a constabi `CodeInstance`, create another (uncached) CodeInstance that contains the dummy code created -by [`codeinfo_for_const`](@ref) for use in reflection functions that require this. See [`codeinfo_for_const`](@ref) for -more details. -""" -function codeinstance_for_const_with_code(interp::AbstractInterpreter, code::CodeInstance) - src = codeinfo_for_const(interp, code.def, code.rettype_const) - return CodeInstance(code.def, cache_owner(interp), code.rettype, code.exctype, code.rettype_const, src, - Int32(0x3), code.min_world, code.max_world, - code.ipo_purity_bits, code.analysis_results, - code.relocatability, src.debuginfo, src.edges) -end - result_is_constabi(interp::AbstractInterpreter, result::InferenceResult) = may_discard_trees(interp) && is_result_constabi_eligible(result) @@ -1051,44 +1051,35 @@ it has constabi) or one that can be made so by compiling its `->inferred` field. N.B.: The `->inferred` field is volatile and the compiler may delete it. -In such a case, it will first set the `invoke` field to a method that -will block the thread until compilation is completed. """ const SOURCE_MODE_ABI = 0x1 -""" - SOURCE_MODE_FORCE_SOURCE - -Indicates that inference must always produce source in the `->inferred` field. -This may mean that inference will need to re-do inference (if the `->inferred` -field was previously deleted by the JIT) or may need to synthesize source for -other kinds of CodeInstances. - -N.B.: The same caching considerations as SOURCE_MODE_ABI apply. -""" -const SOURCE_MODE_FORCE_SOURCE = 0x2 - -function ci_has_source(code::CodeInstance) - inf = @atomic :monotonic code.inferred - return code.owner === nothing ? (isa(inf, CodeInfo) || isa(inf, String)) : inf !== nothing -end - """ ci_has_abi(code::CodeInstance) Determine whether this CodeInstance is something that could be invoked if we gave it -to the runtime system (either because it already has an ->invoke ptr, or because it -has source that could be compiled). +to the runtime system (either because it already has an ->invoke ptr, or +because it has source that could be compiled). Note that this information may +be stale by the time the user see it, so the user will need to perform their +own checks if they actually need the abi from it. """ function ci_has_abi(code::CodeInstance) - ci_has_source(code) && return true - return code.invoke !== C_NULL + (@atomic :acquire code.invoke) !== C_NULL && return true + inf = @atomic :monotonic code.inferred + if code.owner === nothing ? (isa(inf, CodeInfo) || isa(inf, String)) : inf !== nothing + # interp.codegen[code] = maybe_uncompress(code, inf) # TODO: the correct way to ensure this information doesn't become stale would be to push it into the stable codegen cache + return true + end + return false +end + +function ci_has_invoke(code::CodeInstance) + return (@atomic :monotonic code.invoke) !== C_NULL end function ci_meets_requirement(code::CodeInstance, source_mode::UInt8) source_mode == SOURCE_MODE_NOT_REQUIRED && return true source_mode == SOURCE_MODE_ABI && return ci_has_abi(code) - source_mode == SOURCE_MODE_FORCE_SOURCE && return ci_has_source(code) return false end @@ -1098,11 +1089,6 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance, source_mod let code = get(code_cache(interp), mi, nothing) if code isa CodeInstance # see if this code already exists in the cache - if source_mode == SOURCE_MODE_FORCE_SOURCE && use_const_api(code) - code = codeinstance_for_const_with_code(interp, code) - ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) - return code - end if ci_meets_requirement(code, source_mode) ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) return code @@ -1124,12 +1110,6 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance, source_mod let code = get(code_cache(interp), mi, nothing) if code isa CodeInstance # see if this code already exists in the cache - if source_mode == SOURCE_MODE_FORCE_SOURCE && use_const_api(code) - engine_reject(interp, ci) - code = codeinstance_for_const_with_code(interp, code) - ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) - return code - end if ci_meets_requirement(code, source_mode) engine_reject(interp, ci) ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) @@ -1148,26 +1128,15 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance, source_mod ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) ci = result.ci # reload from result in case it changed - if source_mode == SOURCE_MODE_ABI && frame.cache_mode != CACHE_MODE_GLOBAL - # XXX: jl_type_infer somewhat ambiguously assumes this must be cached, while jl_ci_cache_lookup sort of ambiguously re-caches it + @assert frame.cache_mode != CACHE_MODE_NULL + @assert is_result_constabi_eligible(result) || (!isdefined(interp, :codegen) || haskey(interp.codegen, ci)) + @assert is_result_constabi_eligible(result) == use_const_api(ci) + @assert isdefined(ci, :inferred) "interpreter did not fulfill our expectations" + if !is_cached(frame) && source_mode == SOURCE_MODE_ABI + # XXX: jl_type_infer somewhat ambiguously assumes this must be cached # XXX: this should be using the CI from the cache, if possible instead: haskey(cache, mi) && (ci = cache[mi]) - @assert isdefined(ci, :inferred) "interpreter did not fulfill its requirements" code_cache(interp)[mi] = ci end - if source_mode == SOURCE_MODE_FORCE_SOURCE && use_const_api(ci) - # If the caller cares about the code and this is constabi, still use our synthesis function - # anyway, because we will have not finished inferring the code inside the CodeInstance once - # we realized it was constabi, but we want reflection to pretend that we did. - # XXX: the one user of this does not actually want this behavior, but it is required by the flag definition currently - ci = codeinstance_for_const_with_code(interp, ci) - @assert ci_meets_requirement(ci, source_mode) - return ci - end - if !ci_meets_requirement(ci, source_mode) - can_discard_trees = false - finish!(interp, frame; can_discard_trees) # redo finish! with the correct can_discard_trees parameter value - @assert ci_meets_requirement(ci, source_mode) - end return ci end @@ -1212,10 +1181,104 @@ function typeinf_type(interp::AbstractInterpreter, mi::MethodInstance) return widenconst(ignorelimited(result.result)) end -# This is a bridge for the C code calling `jl_typeinf_func()` -typeinf_ext_toplevel(mi::MethodInstance, world::UInt, source_mode::UInt8) = typeinf_ext_toplevel(NativeInterpreter(world), mi, source_mode) -function typeinf_ext_toplevel(interp::AbstractInterpreter, mi::MethodInstance, source_mode::UInt8) - return typeinf_ext(interp, mi, source_mode) +# collect a list of all code that is needed along with CodeInstance to codegen it fully +function collectinvokes!(wq::Vector{CodeInstance}, ci::CodeInfo) + src = ci.code + for i = 1:length(src) + stmt = src[i] + isexpr(stmt, :(=)) && (stmt = stmt.args[2]) + if isexpr(stmt, :invoke) || isexpr(stmt, :invoke_modify) + edge = stmt.args[1] + edge isa CodeInstance && isdefined(edge, :inferred) && push!(wq, edge) + end + # TODO: handle other StmtInfo like @cfunction and OpaqueClosure? + end +end + +# This is a bridge for the C code calling `jl_typeinf_func()` on a single Method match +function typeinf_ext_toplevel(mi::MethodInstance, world::UInt, source_mode::UInt8) + interp = NativeInterpreter(world) + ci = typeinf_ext(interp, mi, source_mode) + if source_mode == SOURCE_MODE_ABI && ci isa CodeInstance && !ci_has_invoke(ci) + inspected = IdSet{CodeInstance}() + tocompile = Vector{CodeInstance}() + push!(tocompile, ci) + while !isempty(tocompile) + # ci_has_real_invoke(ci) && return ci # optimization: cease looping if ci happens to get compiled (not just jl_fptr_wait_for_compiled, but fully jl_is_compiled_codeinst) + callee = pop!(tocompile) + ci_has_invoke(callee) && continue + callee in inspected && continue + src = get(interp.codegen, callee, nothing) + if !isa(src, CodeInfo) + src = @atomic :monotonic callee.inferred + if isa(src, String) + src = _uncompressed_ir(callee, src) + end + if !isa(src, CodeInfo) + newcallee = typeinf_ext(interp, callee.def, source_mode) + if newcallee isa CodeInstance + callee === ci && (ci = newcallee) # ci stopped meeting the requirements after typeinf_ext last checked, try again with newcallee + push!(tocompile, newcallee) + #else + # println("warning: could not get source code for ", callee.def) + end + continue + end + end + push!(inspected, callee) + collectinvokes!(tocompile, src) + ccall(:jl_add_codeinst_to_jit, Cvoid, (Any, Any), callee, src) + end + end + return ci +end + +# This is a bridge for the C code calling `jl_typeinf_func()` on set of Method matches +function typeinf_ext_toplevel(methods::Vector{Any}, worlds::Vector{UInt}, trim::Bool) + inspected = IdSet{CodeInstance}() + tocompile = Vector{CodeInstance}() + codeinfos = [] + # first compute the ABIs of everything + for this_world in reverse(sort!(worlds)) + interp = NativeInterpreter(this_world) + for i = 1:length(methods) + # each item in this list is either a MethodInstance indicating something + # to compile, or an svec(rettype, sig) describing a C-callable alias to create. + item = methods[i] + if item isa MethodInstance + # if this method is generally visible to the current compilation world, + # and this is either the primary world, or not applicable in the primary world + # then we want to compile and emit this + if item.def.primary_world <= this_world <= item.def.deleted_world + ci = typeinf_ext(interp, item, SOURCE_MODE_NOT_REQUIRED) + ci isa CodeInstance && !use_const_api(ci) && push!(tocompile, ci) + end + elseif item isa SimpleVector + push!(codeinfos, item[1]::Type) + push!(codeinfos, item[2]::Type) + end + end + while !isempty(tocompile) + callee = pop!(tocompile) + callee in inspected && continue + push!(inspected, callee) + # now make sure everything has source code, if desired + # TODO: typeinf_code could return something with different edges/ages (needing an update to callee), which we don't handle here + if use_const_api(callee) + src = codeinfo_for_const(interp, callee.def, code.rettype_const) + elseif haskey(interp.codegen, callee) + src = interp.codegen[callee] + else + src = typeinf_code(interp, callee.def, true) + end + if src isa CodeInfo + collectinvokes!(tocompile, src) + push!(codeinfos, callee) + push!(codeinfos, src) + end + end + end + return codeinfos end function return_type(@nospecialize(f), t::DataType) # this method has a special tfunc diff --git a/Compiler/src/types.jl b/Compiler/src/types.jl index 5669ec3175c9e..6ffb5402682f3 100644 --- a/Compiler/src/types.jl +++ b/Compiler/src/types.jl @@ -366,6 +366,7 @@ struct NativeInterpreter <: AbstractInterpreter # Cache of inference results for this particular interpreter inf_cache::Vector{InferenceResult} + codegen::IdDict{CodeInstance,CodeInfo} # Parameters for inference and optimization inf_params::InferenceParams @@ -386,16 +387,8 @@ function NativeInterpreter(world::UInt = get_world_counter(); @assert world <= curr_max_world method_table = CachedMethodTable(InternalMethodTable(world)) inf_cache = Vector{InferenceResult}() # Initially empty cache - return NativeInterpreter(world, method_table, inf_cache, inf_params, opt_params) -end - -function NativeInterpreter(interp::NativeInterpreter; - world::UInt = interp.world, - method_table::CachedMethodTable{InternalMethodTable} = interp.method_table, - inf_cache::Vector{InferenceResult} = interp.inf_cache, - inf_params::InferenceParams = interp.inf_params, - opt_params::OptimizationParams = interp.opt_params) - return NativeInterpreter(world, method_table, inf_cache, inf_params, opt_params) + codegen = IdDict{CodeInstance,CodeInfo}() + return NativeInterpreter(world, method_table, inf_cache, codegen, inf_params, opt_params) end # Quickly and easily satisfy the AbstractInterpreter API contract diff --git a/Compiler/src/utilities.jl b/Compiler/src/utilities.jl index 196722f8bca33..c322d1062cea1 100644 --- a/Compiler/src/utilities.jl +++ b/Compiler/src/utilities.jl @@ -149,6 +149,9 @@ end isa_compileable_sig(@nospecialize(atype), sparams::SimpleVector, method::Method) = !iszero(ccall(:jl_isa_compileable_sig, Int32, (Any, Any, Any), atype, sparams, method)) +isa_compileable_sig(m::MethodInstance) = (def = m.def; !isa(def, Method) || isa_compileable_sig(m.specTypes, m.sparam_vals, def)) +isa_compileable_sig(m::ABIOverride) = false + has_typevar(@nospecialize(t), v::TypeVar) = ccall(:jl_has_typevar, Cint, (Any, Any), t, v) != 0 """ diff --git a/Compiler/test/abioverride.jl b/Compiler/test/abioverride.jl index d35fa8876cf1c..e257074852099 100644 --- a/Compiler/test/abioverride.jl +++ b/Compiler/test/abioverride.jl @@ -12,19 +12,23 @@ struct SecondArgConstOverride arg2::Int end -world = Base.tls_world_age() -mi = Base.specialize_method(only(Base._methods_by_ftype(Tuple{typeof(myplus), Int, Int}, -1, world))) -interp = Compiler.NativeInterpreter(world) -ci = Compiler.typeinf_ext(interp, mi, Compiler.SOURCE_MODE_FORCE_SOURCE) - function is_known_call(@nospecialize(x), @nospecialize(func), src::Core.CodeInfo) isexpr(x, :call) || return false ft = Compiler.argextype(x.args[1], src, Compiler.VarState[]) return Compiler.singleton_type(ft) === func end + # Construct a CodeInstance with an ABI override -new_ci = let new_source = copy(Base.uncompressed_ir(ci)) +let world = Base.tls_world_age() + # Get some inferred source code to give to the compiler + # Do not look at a CodeInstance here, since those fields are only valid to + # use while attached to a cache, and are thus invalid to make copies of + # (since you'd have to have made the copy to insert into the cache before + # making the original CodeInstance to copy from, which is obviously + # rather temporally-challenged) + new_source = only(code_typed(myplus, (Int, Int)))[1] + mi = new_source.parent ## Sanity check @assert length(new_source.code) == 2 add = new_source.code[1] @@ -37,15 +41,19 @@ new_ci = let new_source = copy(Base.uncompressed_ir(ci)) resize!(new_source.slotnames, 2) resize!(new_source.slotflags, 2) - # Construct the CodeInstance - new_ci = Core.CodeInstance(Core.ABIOverride(Tuple{typeof(myplus), Int}, mi), - SecondArgConstOverride(1), ci.rettype, ci.exctype, nothing, new_source, - Int32(0), ci.min_world, ci.max_world, ci.ipo_purity_bits, nothing, ci.relocatability, ci.debuginfo, ci.edges) + # Construct the CodeInstance from the modified CodeInfo data + global new_ci = Core.CodeInstance(Core.ABIOverride(Tuple{typeof(myplus), Int}, mi), + #=owner=#SecondArgConstOverride(1), new_source.rettype, Any#=new_source.exctype is missing=#, + #=inferred_const=#nothing, #=code=#nothing, #=const_flags=#Int32(0), + new_source.min_world, new_source.max_world, #=new_source.ipo_purity_bits is missing=#UInt32(0), + #=analysis_results=#nothing, #=not relocatable?=#UInt8(0), new_source.debuginfo, new_source.edges) # Poke the CI into the global cache + # This isn't necessary, but does conveniently give it the mandatory permanent GC-root before calling `invoke` ccall(:jl_mi_cache_insert, Cvoid, (Any, Any), mi, new_ci) - new_ci + # Poke the source code into the JIT for it + ccall(:jl_add_codeinst_to_jit, Cvoid, (Any, Any), new_ci, new_source) end @test contains(repr(new_ci), "ABI Overridden") diff --git a/base/reflection.jl b/base/reflection.jl index f7952ac7a78d7..f9c5dd9765533 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -132,14 +132,6 @@ uncompressed_ir(m::Method) = isdefined(m, :source) ? _uncompressed_ir(m) : isdefined(m, :generator) ? error("Method is @generated; try `code_lowered` instead.") : error("Code for this Method is not available.") -function uncompressed_ir(ci::CodeInstance) - inferred = ci.inferred - isa(inferred, CodeInfo) && return inferred - isa(inferred, String) && return _uncompressed_ir(ci, inferred) - inferred === nothing && error("Inferred code was deleted.") - error(string("Unknown inferred code type ", typeof(inferred))) -end - # for backwards compat const uncompressed_ast = uncompressed_ir const _uncompressed_ast = _uncompressed_ir diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index b238c44c52676..0600106c41aa6 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -52,7 +52,6 @@ using namespace llvm; #define DEBUG_TYPE "julia_aotcompile" -STATISTIC(CICacheLookups, "Number of codeinst cache lookups"); STATISTIC(CreateNativeCalls, "Number of jl_create_native calls made"); STATISTIC(CreateNativeMethods, "Number of methods compiled for jl_create_native"); STATISTIC(CreateNativeMax, "Max number of methods compiled at once for jl_create_native"); @@ -307,37 +306,6 @@ static void makeSafeName(GlobalObject &G) G.setName(StringRef(SafeName.data(), SafeName.size())); } -static jl_code_instance_t *jl_ci_cache_lookup(jl_method_instance_t *mi, size_t world, jl_codeinstance_lookup_t lookup) -{ - ++CICacheLookups; - jl_value_t *ci = lookup(mi, world, world); - JL_GC_PROMISE_ROOTED(ci); - jl_code_instance_t *codeinst = NULL; - if (ci != jl_nothing && jl_atomic_load_relaxed(&((jl_code_instance_t *)ci)->inferred) != jl_nothing) { - codeinst = (jl_code_instance_t*)ci; - } - else { - if (lookup != jl_rettype_inferred_addr) { - // XXX: This will corrupt and leak a lot of memory which may be very bad - jl_error("Refusing to automatically run type inference with custom cache lookup."); - } - else { - // XXX: SOURCE_MODE_ABI is wrong here (not sufficient) - codeinst = jl_type_infer(mi, world, SOURCE_MODE_ABI); - /* Even if this codeinst is ordinarily not cacheable, we need to force - * it into the cache here, since it was explicitly requested and is - * otherwise not reachable from anywhere in the system image. - */ - if (codeinst && !jl_mi_cache_has_ci(mi, codeinst)) { - JL_GC_PUSH1(&codeinst); - jl_mi_cache_insert(mi, codeinst); - JL_GC_POP(); - } - } - } - return codeinst; -} - namespace { // file-local namespace class egal_set { public: @@ -432,7 +400,7 @@ static void aot_optimize_roots(jl_codegen_params_t ¶ms, egal_set &method_roo } } -static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_roots, CompilationPolicy policy, jl_compiled_functions_t &compiled_functions) +static void resolve_workqueue(jl_codegen_params_t ¶ms, egal_set &method_roots, jl_compiled_functions_t &compiled_functions) { decltype(params.workqueue) workqueue; std::swap(params.workqueue, workqueue); @@ -449,24 +417,6 @@ static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root bool preal_specsig = false; { auto it = compiled_functions.find(codeinst); - if (it == compiled_functions.end()) { - // Reinfer the function. The JIT came along and removed the inferred - // method body. See #34993 - if ((policy != CompilationPolicy::Default || params.params->trim) && - jl_atomic_load_relaxed(&codeinst->inferred) == jl_nothing) { - // XXX: SOURCE_MODE_FORCE_SOURCE is wrong here (neither sufficient nor necessary) - codeinst = jl_type_infer(jl_get_ci_mi(codeinst), jl_atomic_load_relaxed(&codeinst->max_world), SOURCE_MODE_FORCE_SOURCE); - } - if (codeinst) { - orc::ThreadSafeModule result_m = - jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)), - params.tsctx, params.DL, params.TargetTriple); - auto decls = jl_emit_codeinst(result_m, codeinst, NULL, params); - record_method_roots(method_roots, jl_get_ci_mi(codeinst)); - if (result_m) - it = compiled_functions.insert(std::make_pair(codeinst, std::make_pair(std::move(result_m), std::move(decls)))).first; - } - } if (it != compiled_functions.end()) { auto &decls = it->second.second; invokeName = decls.functionObject; @@ -478,6 +428,12 @@ static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root preal_specsig = true; } } + else if (params.params->trim) { + jl_safe_printf("warning: no code provided for function"); + jl_(codeinst->def); + if (params.params->trim) + abort(); + } } // patch up the prototype we emitted earlier Module *mod = proto.decl->getParent(); @@ -485,7 +441,7 @@ static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root Function *pinvoke = nullptr; if (preal_decl.empty()) { if (invokeName.empty() && params.params->trim) { - errs() << "Bailed out to invoke when compiling:"; + jl_safe_printf("warning: bailed out to invoke when compiling:"); jl_(codeinst->def); abort(); } @@ -543,31 +499,109 @@ static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root JL_GC_POP(); } + // takes the running content that has collected in the shadow module and dump it to disk -// this builds the object file portion of the sysimage files for fast startup, and can +// this builds the object file portion of the sysimage files for fast startup +// `_external_linkage` create linkages between pkgimages. +extern "C" JL_DLLEXPORT_CODEGEN +void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, int _trim, int _external_linkage, size_t world) +{ + JL_TIMING(INFERENCE, INFERENCE); + auto ct = jl_current_task; + bool timed = (ct->reentrant_timing & 1) == 0; + if (timed) + ct->reentrant_timing |= 1; + uint64_t compiler_start_time = 0; + uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); + if (measure_compile_time_enabled) + compiler_start_time = jl_hrtime(); + + jl_cgparams_t cgparams = jl_default_cgparams; + cgparams.trim = _trim ? 1 : 0; + size_t compile_for[] = { jl_typeinf_world, world }; + int compiler_world = 1; + if (_trim || compile_for[0] == 0) + compiler_world = 0; + jl_value_t **fargs; + JL_GC_PUSHARGS(fargs, 4); + jl_array_t *codeinfos = NULL; + if (jl_typeinf_func) { + fargs[0] = (jl_value_t*)jl_typeinf_func; + fargs[1] = (jl_value_t*)methods; +#ifdef _P64 + jl_value_t *jl_array_ulong_type = jl_array_uint64_type; +#else + jl_value_t *jl_array_ulong_type = jl_array_uint32_type; +#endif + jl_array_t *worlds = jl_alloc_array_1d(jl_array_ulong_type, 1 + compiler_world); + fargs[2] = (jl_value_t*)worlds; + jl_array_data(worlds, size_t)[0] = jl_typeinf_world; + jl_array_data(worlds, size_t)[compiler_world] = world; // might overwrite previous + fargs[3] = _trim ? jl_true : jl_false; + size_t last_age = ct->world_age; + ct->world_age = jl_typeinf_world; + codeinfos = (jl_array_t*)jl_apply(fargs, 4); + ct->world_age = last_age; + JL_TYPECHK(create_native, array_any, (jl_value_t*)codeinfos); + } + else { + // we could put a very simple generator here, but there is no reason to do that right now + jl_error("inference not available for generating compiled output"); + } + fargs[0] = (jl_value_t*)codeinfos; + void *data = jl_emit_native(codeinfos, llvmmod, &cgparams, _external_linkage); + + // move everything inside, now that we've merged everything + // (before adding the exported headers) + ((jl_native_code_desc_t*)data)->M.withModuleDo([&](Module &M) { + auto TT = Triple(M.getTargetTriple()); + Function *juliapersonality_func = nullptr; + if (TT.isOSWindows() && TT.getArch() == Triple::x86_64) { + // setting the function personality enables stack unwinding and catching exceptions + // so make sure everything has something set + Type *T_int32 = Type::getInt32Ty(M.getContext()); + juliapersonality_func = Function::Create(FunctionType::get(T_int32, true), + Function::ExternalLinkage, "__julia_personality", M); + juliapersonality_func->setDLLStorageClass(GlobalValue::DLLImportStorageClass); + } + for (GlobalObject &G : M.global_objects()) { + if (!G.isDeclaration()) { + G.setLinkage(GlobalValue::InternalLinkage); + G.setDSOLocal(true); + makeSafeName(G); + if (Function *F = dyn_cast(&G)) { + if (juliapersonality_func) { + // Add unwind exception personalities to functions to handle async exceptions + F->setPersonalityFn(juliapersonality_func); + } + } + } + } + }); + + JL_GC_POP(); + if (timed) { + if (measure_compile_time_enabled) { + auto end = jl_hrtime(); + jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, end - compiler_start_time); + } + ct->reentrant_timing &= ~1ull; + } + return data; +} + // also be used be extern consumers like GPUCompiler.jl to obtain a module containing // all reachable & inferrrable functions. -// The `policy` flag switches between the default mode `0` and the extern mode `1` used by GPUCompiler. -// `_imaging_mode` controls if raw pointers can be embedded (e.g. the code will be loaded into the same session). -// `_external_linkage` create linkages between pkgimages. extern "C" JL_DLLEXPORT_CODEGEN -void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int _policy, int _imaging_mode, int _external_linkage, size_t _world, jl_codeinstance_lookup_t lookup) +void *jl_emit_native_impl(jl_array_t *codeinfos, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int _external_linkage) { JL_TIMING(NATIVE_AOT, NATIVE_Create); ++CreateNativeCalls; - CreateNativeMax.updateMax(jl_array_nrows(methods)); + CreateNativeMax.updateMax(jl_array_nrows(codeinfos)); if (cgparams == NULL) cgparams = &jl_default_cgparams; - if (lookup == NULL) - lookup = &jl_rettype_inferred_native; jl_native_code_desc_t *data = new jl_native_code_desc_t; - CompilationPolicy policy = (CompilationPolicy) _policy; - bool imaging = imaging_default() || _imaging_mode == 1; jl_method_instance_t *mi = NULL; - auto ct = jl_current_task; - bool timed = (ct->reentrant_timing & 1) == 0; - if (timed) - ct->reentrant_timing |= 1; orc::ThreadSafeContext ctx; orc::ThreadSafeModule backing; if (!llvmmod) { @@ -577,13 +611,7 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm orc::ThreadSafeModule &clone = llvmmod ? *unwrap(llvmmod) : backing; auto ctxt = clone.getContext(); - uint64_t compiler_start_time = 0; - uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); - if (measure_compile_time_enabled) - compiler_start_time = jl_hrtime(); - // compile all methods for the current world and type-inference world - auto target_info = clone.withModuleDo([&](Module &M) { return std::make_pair(M.getDataLayout(), Triple(M.getTargetTriple())); }); @@ -592,84 +620,57 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm if (!llvmmod) params.getContext().setDiscardValueNames(true); params.params = cgparams; - params.imaging_mode = imaging; + assert(params.imaging_mode); // `_imaging_mode` controls if broken features like code-coverage are disabled params.external_linkage = _external_linkage; params.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0); JL_GC_PUSH3(¶ms.temporary_roots, &method_roots.list, &method_roots.keyset); - size_t compile_for[] = { jl_typeinf_world, _world }; - int worlds = 0; - if (jl_options.trim != JL_TRIM_NO) - worlds = 1; jl_compiled_functions_t compiled_functions; - for (; worlds < 2; worlds++) { - JL_TIMING(NATIVE_AOT, NATIVE_Codegen); - size_t this_world = compile_for[worlds]; - if (!this_world) - continue; - // Don't emit methods for the typeinf_world with extern policy - if (policy != CompilationPolicy::Default && this_world == jl_typeinf_world) - continue; - size_t i, l; - for (i = 0, l = jl_array_nrows(methods); i < l; i++) { - // each item in this list is either a MethodInstance indicating something - // to compile, or an svec(rettype, sig) describing a C-callable alias to create. - jl_value_t *item = jl_array_ptr_ref(methods, i); - if (jl_is_simplevector(item)) { - if (worlds == 1) - jl_compile_extern_c(wrap(&clone), ¶ms, NULL, jl_svecref(item, 0), jl_svecref(item, 1)); - continue; - } - mi = (jl_method_instance_t*)item; - // if this method is generally visible to the current compilation world, - // and this is either the primary world, or not applicable in the primary world - // then we want to compile and emit this - if (jl_atomic_load_relaxed(&mi->def.method->primary_world) <= this_world && this_world <= jl_atomic_load_relaxed(&mi->def.method->deleted_world)) { - // find and prepare the source code to compile - jl_code_instance_t *codeinst = jl_ci_cache_lookup(mi, this_world, lookup); - JL_GC_PROMISE_ROOTED(codeinst); - if (jl_options.trim != JL_TRIM_NO && !codeinst) { - // If we're building a small image, we need to compile everything - // to ensure that we have all the information we need. - jl_safe_printf("Codegen decided not to compile code root"); - jl_(mi); - abort(); - } - if (codeinst && !compiled_functions.count(codeinst) && !data->jl_fvar_map.count(codeinst)) { - // now add it to our compilation results - // Const returns do not do codegen, but juliac inspects codegen results so make a dummy fvar entry to represent it - if (jl_options.trim != JL_TRIM_NO && jl_atomic_load_relaxed(&codeinst->invoke) == jl_fptr_const_return_addr) { - data->jl_fvar_map[codeinst] = std::make_tuple((uint32_t)-3, (uint32_t)-3); - } - else { - orc::ThreadSafeModule result_m = jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)), - params.tsctx, clone.getModuleUnlocked()->getDataLayout(), - Triple(clone.getModuleUnlocked()->getTargetTriple())); - jl_llvm_functions_t decls = jl_emit_codeinst(result_m, codeinst, NULL, params); - JL_GC_PROMISE_ROOTED(codeinst->def); // analyzer seems confused - record_method_roots(method_roots, jl_get_ci_mi(codeinst)); - if (result_m) - compiled_functions[codeinst] = {std::move(result_m), std::move(decls)}; - else if (jl_options.trim != JL_TRIM_NO) { - // if we're building a small image, we need to compile everything - // to ensure that we have all the information we need. - jl_safe_printf("codegen failed to compile code root"); - jl_(mi); - abort(); - } - } + size_t i, l; + for (i = 0, l = jl_array_nrows(codeinfos); i < l; i++) { + // each item in this list is either a CodeInstance followed by a CodeInfo indicating something + // to compile, or a rettype followed by a sig describing a C-callable alias to create. + jl_value_t *item = jl_array_ptr_ref(codeinfos, i); + if (jl_is_code_instance(item)) { + // now add it to our compilation results + jl_code_instance_t *codeinst = (jl_code_instance_t*)item; + jl_code_info_t *src = (jl_code_info_t*)jl_array_ptr_ref(codeinfos, ++i); + assert(jl_is_code_info(src)); + if (compiled_functions.count(codeinst)) + continue; // skip any duplicates that accidentally made there way in here (or make this an error?) + if (_external_linkage) { + uint8_t specsigflags; + jl_callptr_t invoke; + void *fptr; + jl_read_codeinst_invoke(codeinst, &specsigflags, &invoke, &fptr, 0); + if (invoke != NULL && (specsigflags & 0b100)) { + // this codeinst is already available externally + // TODO: for performance, avoid generating the src code when we know it would reach here anyways + continue; } } - else if (this_world != jl_typeinf_world) { - /* - jl_safe_printf("Codegen could not find requested codeinstance to be compiled\n"); + orc::ThreadSafeModule result_m = jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)), + params.tsctx, clone.getModuleUnlocked()->getDataLayout(), + Triple(clone.getModuleUnlocked()->getTargetTriple())); + jl_llvm_functions_t decls = jl_emit_codeinst(result_m, codeinst, src, params); + record_method_roots(method_roots, jl_get_ci_mi(codeinst)); + if (result_m) + compiled_functions[codeinst] = {std::move(result_m), std::move(decls)}; + else if (params.params->trim) { + // if we're building a small image, we need to compile everything + // to ensure that we have all the information we need. + jl_safe_printf("codegen failed to compile code root"); jl_(mi); abort(); - */ } } + else { + jl_value_t *sig = jl_array_ptr_ref(codeinfos, ++i); + assert(jl_is_type(item) && jl_is_type(sig)); + jl_compile_extern_c(wrap(&clone), ¶ms, NULL, item, sig); + } } - // finally, make sure all referenced methods also get compiled or fixed up - compile_workqueue(params, method_roots, policy, compiled_functions); + // finally, make sure all referenced methods get fixed up, particularly if the user declined to compile them + resolve_workqueue(params, method_roots, compiled_functions); aot_optimize_roots(params, method_roots, compiled_functions); params.temporary_roots = nullptr; JL_GC_POP(); @@ -712,7 +713,6 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm // clones the contents of the module `m` to the shadow_output collector // while examining and recording what kind of function pointer we have { - JL_TIMING(NATIVE_AOT, NATIVE_Merge); Linker L(*clone.getModuleUnlocked()); for (auto &def : compiled_functions) { jl_merge_module(clone, std::move(std::get<0>(def.second))); @@ -762,45 +762,7 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm } CreateNativeGlobals += gvars.size(); - //Safe b/c context is locked by params - auto TT = Triple(clone.getModuleUnlocked()->getTargetTriple()); - Function *juliapersonality_func = nullptr; - if (TT.isOSWindows() && TT.getArch() == Triple::x86_64) { - // setting the function personality enables stack unwinding and catching exceptions - // so make sure everything has something set - Type *T_int32 = Type::getInt32Ty(clone.getModuleUnlocked()->getContext()); - juliapersonality_func = Function::Create(FunctionType::get(T_int32, true), - Function::ExternalLinkage, "__julia_personality", clone.getModuleUnlocked()); - juliapersonality_func->setDLLStorageClass(GlobalValue::DLLImportStorageClass); - } - - // move everything inside, now that we've merged everything - // (before adding the exported headers) - if (policy == CompilationPolicy::Default) { - //Safe b/c context is locked by params - for (GlobalObject &G : clone.getModuleUnlocked()->global_objects()) { - if (!G.isDeclaration()) { - G.setLinkage(GlobalValue::InternalLinkage); - G.setDSOLocal(true); - makeSafeName(G); - if (Function *F = dyn_cast(&G)) { - if (TT.isOSWindows() && TT.getArch() == Triple::x86_64) { - // Add unwind exception personalities to functions to handle async exceptions - F->setPersonalityFn(juliapersonality_func); - } - } - } - } - } - data->M = std::move(clone); - if (timed) { - if (measure_compile_time_enabled) { - auto end = jl_hrtime(); - jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, end - compiler_start_time); - } - ct->reentrant_timing &= ~1ull; - } return (void*)data; } @@ -1954,8 +1916,7 @@ void jl_dump_native_impl(void *native_code, sysimg_outputs = compile(sysimgM, "sysimg", 1, [](Module &) {}); } - bool imaging_mode = imaging_default() || jl_options.outputo; - + const bool imaging_mode = true; unsigned threads = 1; unsigned nfvars = 0; unsigned ngvars = 0; @@ -2062,8 +2023,7 @@ void jl_dump_native_impl(void *native_code, data_outputs = compile(*dataM, "text", threads, [data](Module &) { delete data; }); } - if (params->emit_metadata) - { + if (params->emit_metadata) { JL_TIMING(NATIVE_AOT, NATIVE_Metadata); LLVMContext Context; Context.setDiscardValueNames(true); @@ -2258,13 +2218,7 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, jl_ }); jl_codegen_params_t output(ctx, std::move(target_info.first), std::move(target_info.second)); output.params = ¶ms; - output.imaging_mode = imaging_default(); - // This would be nice, but currently it causes some assembly regressions that make printed output - // differ very significantly from the actual non-imaging mode code. - // // Force imaging mode for names of pointers - // output.imaging = true; - // This would also be nice, but it seems to cause OOMs on the windows32 builder - // To get correct names in the IR this needs to be at least 2 + output.imaging_mode = jl_options.image_codegen; output.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0); JL_GC_PUSH1(&output.temporary_roots); auto decls = jl_emit_code(m, mi, src, NULL, output); diff --git a/src/ccall.cpp b/src/ccall.cpp index 3937570896f82..1b635ca40840f 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -697,14 +697,12 @@ static jl_cgval_t emit_cglobal(jl_codectx_t &ctx, jl_value_t **args, size_t narg } else if (sym.fptr != NULL) { res = ConstantInt::get(lrt, (uint64_t)sym.fptr); - if (ctx.emission_context.imaging_mode) - jl_printf(JL_STDERR,"WARNING: literal address used in cglobal for %s; code cannot be statically compiled\n", sym.f_name); } else if (sym.f_name != NULL) { if (sym.lib_expr) { res = runtime_sym_lookup(ctx, getPointerTy(ctx.builder.getContext()), NULL, sym.lib_expr, sym.f_name, ctx.f); } - else /*if (ctx.emission_context.imaging) */{ + else { res = runtime_sym_lookup(ctx, getPointerTy(ctx.builder.getContext()), sym.f_lib, NULL, sym.f_name, ctx.f); } } else { @@ -2134,8 +2132,6 @@ jl_cgval_t function_sig_t::emit_a_ccall( Type *funcptype = functype->getPointerTo(0); llvmf = literal_static_pointer_val((void*)(uintptr_t)symarg.fptr, funcptype); setName(ctx.emission_context, llvmf, "ccall_fptr"); - if (ctx.emission_context.imaging_mode) - jl_printf(JL_STDERR,"WARNING: literal address used in ccall for %s; code cannot be statically compiled\n", symarg.f_name); } else if (!ctx.params->use_jlplt) { if ((symarg.f_lib && !((symarg.f_lib == JL_EXE_LIBNAME) || @@ -2152,7 +2148,7 @@ jl_cgval_t function_sig_t::emit_a_ccall( ++DeferredCCallLookups; llvmf = runtime_sym_lookup(ctx, funcptype, NULL, symarg.lib_expr, symarg.f_name, ctx.f); } - else /*if (ctx.emission_context.imaging) */{ + else { ++DeferredCCallLookups; // vararg requires musttail, // but musttail is incompatible with noreturn. diff --git a/src/codegen-stubs.c b/src/codegen-stubs.c index fe50af3f8e84d..5e243ddda28c9 100644 --- a/src/codegen-stubs.c +++ b/src/codegen-stubs.c @@ -46,11 +46,26 @@ JL_DLLEXPORT void jl_generate_fptr_for_unspecialized_fallback(jl_code_instance_t JL_DLLEXPORT int jl_compile_codeinst_fallback(jl_code_instance_t *unspec) { - // Do nothing. The caller will notice that we failed to provide a an ->invoke and trigger + // Do nothing. The caller will notice that we failed to provide an ->invoke and trigger // appropriate fallbacks. return 0; } +JL_DLLEXPORT void jl_emit_codeinst_to_jit_fallback(jl_code_instance_t *codeinst, jl_code_info_t *src) +{ + jl_value_t *inferred = jl_atomic_load_relaxed(&codeinst->inferred); + if (jl_is_code_info(inferred)) + return; + if (jl_is_svec(src->edges)) { + jl_atomic_store_release(&codeinst->inferred, (jl_value_t*)src->edges); + jl_gc_wb(codeinst, src->edges); + } + jl_atomic_store_release(&codeinst->debuginfo, src->debuginfo); + jl_gc_wb(codeinst, src->debuginfo); + jl_atomic_store_release(&codeinst->inferred, (jl_value_t*)src); + jl_gc_wb(codeinst, src); +} + JL_DLLEXPORT uint32_t jl_get_LLVM_VERSION_fallback(void) { return 0; @@ -70,7 +85,8 @@ JL_DLLEXPORT size_t jl_jit_total_bytes_fallback(void) return 0; } -JL_DLLEXPORT void *jl_create_native_fallback(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int _policy, int _imaging_mode, int _external_linkage, size_t _world, jl_codeinstance_lookup_t lookup) UNAVAILABLE +JL_DLLEXPORT void *jl_create_native_fallback(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, int _trim, int _external_linkage, size_t _world) UNAVAILABLE +JL_DLLEXPORT void *jl_emit_native_fallback(jl_array_t *codeinfos, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int _external_linkage) UNAVAILABLE JL_DLLEXPORT void jl_dump_compiles_fallback(void *s) { diff --git a/src/codegen.cpp b/src/codegen.cpp index ceaba9507e4c7..04253b67d6b6d 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6771,7 +6771,7 @@ static void emit_latestworld(jl_codectx_t &ctx) (void)store_world; } -// `expr` is not clobbered in JL_TRY +// `expr` is not actually clobbered in JL_TRY JL_GCC_IGNORE_START("-Wclobbered") static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_0based) { @@ -7297,10 +7297,10 @@ Function *emit_tojlinvoke(jl_code_instance_t *codeinst, StringRef theFptrName, M theFarg = literal_pointer_val(ctx, (jl_value_t*)codeinst); } else { - jl_method_instance_t *mi = codeinst->def; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure; theFunc = prepare_call(is_opaque_closure ? jlinvokeoc_func : jlinvoke_func); - theFarg = literal_pointer_val(ctx, (jl_value_t*)jl_get_ci_mi(codeinst)); + theFarg = literal_pointer_val(ctx, (jl_value_t*)mi); } theFarg = track_pjlvalue(ctx, theFarg); auto args = f->arg_begin(); @@ -7466,7 +7466,7 @@ static Function *gen_cfun_wrapper( jl_code_instance_t *codeinst = NULL; if (lam) { - // TODO: this isn't ideal to be unconditionally calling type inference (and compile) from here + // TODO: this isn't ideal to be unconditionally calling type inference from here codeinst = jl_type_infer(lam, world, SOURCE_MODE_NOT_REQUIRED); astrt = codeinst->rettype; if (astrt != (jl_value_t*)jl_bottom_type && @@ -9975,9 +9975,6 @@ static jl_llvm_functions_t // --- entry point --- -void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const DataLayout &DL); - -JL_GCC_IGNORE_START("-Wclobbered") jl_llvm_functions_t jl_emit_code( orc::ThreadSafeModule &m, jl_method_instance_t *li, @@ -10023,15 +10020,6 @@ jl_llvm_functions_t jl_emit_code( return decls; } -static int effects_foldable(uint32_t effects) -{ - // N.B.: This needs to be kept in sync with Core.Compiler.is_foldable(effects, true) - return ((effects & 0x7) == 0) && // is_consistent(effects) - (((effects >> 10) & 0x03) == 0) && // is_noub(effects) - (((effects >> 3) & 0x03) == 0) && // is_effect_free(effects) - ((effects >> 6) & 0x01); // is_terminates(effects) -} - static jl_llvm_functions_t jl_emit_oc_wrapper(orc::ThreadSafeModule &m, jl_codegen_params_t ¶ms, jl_method_instance_t *mi, jl_value_t *rettype) { jl_llvm_functions_t declarations; @@ -10082,67 +10070,8 @@ jl_llvm_functions_t jl_emit_codeinst( return jl_llvm_functions_t(); // failed } } - assert(jl_egal((jl_value_t*)jl_atomic_load_relaxed(&codeinst->debuginfo), (jl_value_t*)src->debuginfo) && "trying to generate code for a codeinst for an incompatible src"); + //assert(jl_egal((jl_value_t*)jl_atomic_load_relaxed(&codeinst->debuginfo), (jl_value_t*)src->debuginfo) && "trying to generate code for a codeinst for an incompatible src"); jl_llvm_functions_t decls = jl_emit_code(m, jl_get_ci_mi(codeinst), src, get_ci_abi(codeinst), params); - - const std::string &specf = decls.specFunctionObject; - const std::string &f = decls.functionObject; - if (params.cache && !f.empty()) { - // Prepare debug info to receive this function - // record that this function name came from this linfo, - // so we can build a reverse mapping for debug-info. - bool toplevel = !jl_is_method(jl_get_ci_mi(codeinst)->def.method); - if (!toplevel) { - //Safe b/c params holds context lock - const DataLayout &DL = m.getModuleUnlocked()->getDataLayout(); - // but don't remember toplevel thunks because - // they may not be rooted in the gc for the life of the program, - // and the runtime doesn't notify us when the code becomes unreachable :( - if (!specf.empty()) - jl_add_code_in_flight(specf, codeinst, DL); - if (!f.empty() && f != "jl_fptr_args" && f != "jl_fptr_sparam") - jl_add_code_in_flight(f, codeinst, DL); - } - - jl_value_t *inferred = jl_atomic_load_relaxed(&codeinst->inferred); - // don't change inferred state - if (inferred) { - jl_method_t *def = jl_get_ci_mi(codeinst)->def.method; - if (// keep code when keeping everything - !(JL_DELETE_NON_INLINEABLE) || - // aggressively keep code when debugging level >= 2 - // note that this uses the global jl_options.debug_level, not the local emission_ctx.debug_info_level - jl_options.debug_level > 1) { - // update the stored code - if (inferred != (jl_value_t*)src) { - // TODO: it is somewhat unclear what it means to be mutating this - if (jl_is_method(def)) { - src = (jl_code_info_t*)jl_compress_ir(def, src); - assert(jl_is_string(src)); - codeinst->relocatability = jl_string_data(src)[jl_string_len(src)-1]; - } - jl_atomic_store_release(&codeinst->inferred, (jl_value_t*)src); - jl_gc_wb(codeinst, src); - } - } - // delete non-inlineable code, since it won't be needed again - // because we already emitted LLVM code from it and the native - // Julia-level optimization will never need to see it - else if (jl_is_method(def) && // don't delete toplevel code - def->source != NULL && // don't delete code from optimized opaque closures that can't be reconstructed - inferred != jl_nothing && // and there is something to delete (test this before calling jl_ir_inlining_cost) - ((!effects_foldable(jl_atomic_load_relaxed(&codeinst->ipo_purity_bits)) && // don't delete code we may want for irinterp - (jl_ir_inlining_cost(inferred) == UINT16_MAX) && // don't delete inlineable code - !jl_generating_output()) || // don't delete code when generating a precompile file, trading memory in the short term for avoiding likely duplicating inference work for aotcompile - jl_atomic_load_relaxed(&codeinst->invoke) == jl_fptr_const_return_addr)) { // unless it is constant (although this shouldn't have had code in the first place) - // Never end up in a situation where the codeinst has no invoke, but also no source, so we never fall - // through the cracks of SOURCE_MODE_ABI. - jl_callptr_t expected = NULL; - jl_atomic_cmpswap_relaxed(&codeinst->invoke, &expected, jl_fptr_wait_for_compiled_addr); - jl_atomic_store_release(&codeinst->inferred, jl_nothing); - } - } - } JL_GC_POP(); return decls; } diff --git a/src/gf.c b/src/gf.c index 3a308ca6154fc..390ba72143f5d 100644 --- a/src/gf.c +++ b/src/gf.c @@ -343,8 +343,12 @@ jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_a // if inference doesn't occur (or can't finish), returns NULL instead jl_code_instance_t *jl_type_infer(jl_method_instance_t *mi, size_t world, uint8_t source_mode) { - if (jl_typeinf_func == NULL) - return jl_method_inferred_with_abi(mi, world); + if (jl_typeinf_func == NULL) { + if (source_mode == SOURCE_MODE_ABI) + return jl_method_inferred_with_abi(mi, world); + else + return NULL; + } jl_task_t *ct = jl_current_task; if (ct->reentrant_timing & 0b1000) { // We must avoid attempting to re-enter inference here @@ -366,6 +370,10 @@ jl_code_instance_t *jl_type_infer(jl_method_instance_t *mi, size_t world, uint8_ fargs[1] = (jl_value_t*)mi; fargs[2] = jl_box_ulong(world); fargs[3] = jl_box_uint8(source_mode); + int last_errno = errno; +#ifdef _OS_WINDOWS_ + DWORD last_error = GetLastError(); +#endif jl_timing_show_method_instance(mi, JL_TIMING_DEFAULT_BLOCK); #ifdef TRACE_INFERENCE @@ -374,10 +382,6 @@ jl_code_instance_t *jl_type_infer(jl_method_instance_t *mi, size_t world, uint8_ jl_static_show_func_sig(JL_STDERR, (jl_value_t*)mi->specTypes); jl_printf(JL_STDERR, "\n"); } -#endif - int last_errno = errno; -#ifdef _OS_WINDOWS_ - DWORD last_error = GetLastError(); #endif int last_pure = ct->ptls->in_pure_callback; ct->ptls->in_pure_callback = 0; @@ -2745,6 +2749,25 @@ void jl_read_codeinst_invoke(jl_code_instance_t *ci, uint8_t *specsigflags, jl_c jl_method_instance_t *jl_normalize_to_compilable_mi(jl_method_instance_t *mi JL_PROPAGATES_ROOT); +JL_DLLEXPORT void jl_add_codeinst_to_jit(jl_code_instance_t *codeinst, jl_code_info_t *src) +{ + assert(jl_is_code_info(src)); + jl_emit_codeinst_to_jit(codeinst, src); + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); + if (jl_generating_output() && jl_is_method(mi->def.method) && jl_atomic_load_relaxed(&codeinst->inferred) == jl_nothing) { + jl_value_t *compressed = jl_compress_ir(mi->def.method, src); + // These should already be compatible (and should be an assert), but make sure of it anyways + if (jl_is_svec(src->edges)) { + jl_atomic_store_release(&codeinst->edges, (jl_svec_t*)src->edges); + jl_gc_wb(codeinst, src->edges); + } + jl_atomic_store_release(&codeinst->debuginfo, src->debuginfo); + jl_gc_wb(codeinst, src->debuginfo); + jl_atomic_store_release(&codeinst->inferred, compressed); + jl_gc_wb(codeinst, compressed); + } +} + jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t world) { // quick check if we already have a compiled result @@ -2815,8 +2838,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t jl_method_instance_t *unspecmi = jl_atomic_load_relaxed(&def->unspecialized); if (unspecmi) { jl_code_instance_t *unspec = jl_atomic_load_relaxed(&unspecmi->cache); - jl_callptr_t unspec_invoke = NULL; - if (unspec && (unspec_invoke = jl_atomic_load_acquire(&unspec->invoke))) { + if (unspec && jl_atomic_load_acquire(&unspec->invoke) != NULL) { uint8_t specsigflags; jl_callptr_t invoke; void *fptr; @@ -2886,7 +2908,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t } if (codeinst) { - if (jl_atomic_load_acquire(&codeinst->invoke) != NULL) { + if (jl_is_compiled_codeinst(codeinst)) { jl_typeinf_timing_end(start, is_recompile); // Already compiled - e.g. constabi, or compiled by a different thread while we were waiting. return codeinst; @@ -2972,12 +2994,32 @@ jl_value_t *jl_fptr_wait_for_compiled(jl_value_t *f, jl_value_t **args, uint32_t { jl_callptr_t invoke = jl_atomic_load_acquire(&m->invoke); if (invoke == &jl_fptr_wait_for_compiled) { + int64_t last_alloc = jl_options.malloc_log ? jl_gc_diff_total_bytes() : 0; + int last_errno = errno; +#ifdef _OS_WINDOWS_ + DWORD last_error = GetLastError(); +#endif jl_compile_codeinst(m); +#ifdef _OS_WINDOWS_ + SetLastError(last_error); +#endif + errno = last_errno; + if (jl_options.malloc_log) + jl_gc_sync_total_bytes(last_alloc); // discard allocation count from compilation invoke = jl_atomic_load_acquire(&m->invoke); } return invoke(f, args, nargs, m); } +// test whether codeinst->invoke is usable already without further compilation needed +JL_DLLEXPORT int jl_is_compiled_codeinst(jl_code_instance_t *codeinst) +{ + jl_callptr_t invoke = jl_atomic_load_relaxed(&codeinst->invoke); + if (invoke == NULL || invoke == &jl_fptr_wait_for_compiled) + return 0; + return 1; +} + JL_DLLEXPORT const jl_callptr_t jl_fptr_args_addr = &jl_fptr_args; JL_DLLEXPORT const jl_callptr_t jl_fptr_const_return_addr = &jl_fptr_const_return; diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 139a5631d63c0..e2bf75d346613 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -272,7 +272,7 @@ static void finish_params(Module *M, jl_codegen_params_t ¶ms) JL_NOTSAFEPOIN // the fiction that we don't know what loads from the global will return. Thus, we // need to emit a separate module for the globals before any functions are compiled, // to ensure that the globals are defined when they are compiled. - if (params.imaging_mode) { + if (jl_options.image_codegen) { if (!params.global_targets.empty()) { void **globalslots = new void*[params.global_targets.size()]; void **slot = globalslots; @@ -304,7 +304,8 @@ static void finish_params(Module *M, jl_codegen_params_t ¶ms) JL_NOTSAFEPOIN // look for something with an egal ABI that is already in the JIT static jl_code_instance_t *jl_method_compiled_egal(jl_code_instance_t *ci JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT { - jl_method_instance_t *mi = ci->def; + jl_value_t *def = ci->def; + jl_method_instance_t *mi = jl_get_ci_mi(ci); jl_value_t *owner = ci->owner; jl_value_t *rettype = ci->rettype; size_t min_world = jl_atomic_load_relaxed(&ci->min_world); @@ -316,6 +317,7 @@ static jl_code_instance_t *jl_method_compiled_egal(jl_code_instance_t *ci JL_PRO jl_atomic_load_relaxed(&codeinst->invoke) != NULL && jl_atomic_load_relaxed(&codeinst->min_world) <= min_world && jl_atomic_load_relaxed(&codeinst->max_world) >= max_world && + jl_egal(codeinst->def, def) && jl_egal(codeinst->owner, owner) && jl_egal(codeinst->rettype, rettype)) { return codeinst; @@ -503,15 +505,6 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t return params.workqueue.size(); } -// test whether codeinst->invoke is usable already without further compilation needed -static bool jl_is_compiled_codeinst(jl_code_instance_t *codeinst) JL_NOTSAFEPOINT -{ - auto invoke = jl_atomic_load_relaxed(&codeinst->invoke); - if (invoke == nullptr || invoke == jl_fptr_wait_for_compiled_addr) - return false; - return true; -} - // move codeinst (and deps) from incompletemodules to emitted modules // and populate compileready from complete_graph static void prepare_compile(jl_code_instance_t *codeinst) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER @@ -732,10 +725,15 @@ static void jl_compile_codeinst_now(jl_code_instance_t *codeinst) } } -static void jl_emit_codeinst_to_jit( +void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const DataLayout &DL); + +extern "C" JL_DLLEXPORT_CODEGEN +void jl_emit_codeinst_to_jit_impl( jl_code_instance_t *codeinst, jl_code_info_t *src) { + if (jl_is_compiled_codeinst(codeinst)) + return; { // lock scope jl_unique_gcsafe_lock lock(engine_lock); if (invokenames.count(codeinst) || jl_is_compiled_codeinst(codeinst)) @@ -746,7 +744,7 @@ static void jl_emit_codeinst_to_jit( jl_codegen_params_t params(std::make_unique(), jl_ExecutionEngine->getDataLayout(), jl_ExecutionEngine->getTargetTriple()); // Locks the context params.getContext().setDiscardValueNames(true); params.cache = true; - params.imaging_mode = imaging_default(); + params.imaging_mode = 0; orc::ThreadSafeModule result_m = jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)), params.tsctx, params.DL, params.TargetTriple); params.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0); @@ -765,6 +763,24 @@ static void jl_emit_codeinst_to_jit( jl_unique_gcsafe_lock lock(engine_lock); if (invokenames.count(codeinst) || jl_is_compiled_codeinst(codeinst)) return; // destroy everything + const std::string &specf = decls.specFunctionObject; + const std::string &f = decls.functionObject; + assert(!f.empty()); + // Prepare debug info to receive this function + // record that this function name came from this linfo, + // so we can build a reverse mapping for debug-info. + bool toplevel = !jl_is_method(jl_get_ci_mi(codeinst)->def.method); + if (!toplevel) { + // don't remember toplevel thunks because + // they may not be rooted in the gc for the life of the program, + // and the runtime doesn't notify us when the code becomes unreachable :( + if (!specf.empty()) + jl_add_code_in_flight(specf, codeinst, params.DL); + if (f != "jl_fptr_args" && f != "jl_fptr_sparam") + jl_add_code_in_flight(f, codeinst, params.DL); + } + jl_callptr_t expected = NULL; + jl_atomic_cmpswap_relaxed(&codeinst->invoke, &expected, jl_fptr_wait_for_compiled_addr); invokenames[codeinst] = std::move(decls); complete_emit(codeinst); params.tsctx_lock = params.tsctx.getLock(); // re-acquire lock @@ -853,7 +869,7 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void * jl_codegen_params_t params(into->getContext(), DL, TargetTriple); if (pparams == NULL) { params.cache = p == NULL; - params.imaging_mode = imaging_default(); + params.imaging_mode = 0; params.tsctx.getContext()->setDiscardValueNames(true); pparams = ¶ms; } @@ -1425,7 +1441,7 @@ namespace { #endif #endif uint32_t target_flags = 0; - auto target = jl_get_llvm_target(imaging_default(), target_flags); + auto target = jl_get_llvm_target(jl_generating_output(), target_flags); auto &TheCPU = target.first; SmallVector targetFeatures(target.second.begin(), target.second.end()); std::string errorstr; diff --git a/src/jitlayers.h b/src/jitlayers.h index 342cb516debd7..b41f2e38bc470 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -68,8 +68,6 @@ using namespace llvm; -extern "C" jl_cgparams_t jl_default_cgparams; - DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::ThreadSafeContext, LLVMOrcThreadSafeContextRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::ThreadSafeModule, LLVMOrcThreadSafeModuleRef) @@ -78,10 +76,6 @@ void jl_merge_module(orc::ThreadSafeModule &dest, orc::ThreadSafeModule src) JL_ GlobalVariable *jl_emit_RTLD_DEFAULT_var(Module *M) JL_NOTSAFEPOINT; DataLayout jl_create_datalayout(TargetMachine &TM) JL_NOTSAFEPOINT; -static inline bool imaging_default() JL_NOTSAFEPOINT { - return jl_options.image_codegen || (jl_generating_output() && (!jl_options.incremental || jl_options.use_pkgimages)); -} - struct OptimizationOptions { bool lower_intrinsics; bool dump_native; @@ -265,7 +259,7 @@ struct jl_codegen_params_t { tsctx_lock(tsctx.getLock()), DL(std::move(DL)), TargetTriple(std::move(triple)), - imaging_mode(imaging_default()) + imaging_mode(1) { // LLVM's RISC-V back-end currently does not support the Swift calling convention if (TargetTriple.isRISCV()) diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index 71a78b1c20fc7..cb48cf6f9962c 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -240,7 +240,6 @@ XX(jl_has_typevar_from_unionall) \ XX(jl_hrtime) \ XX(jl_idtable_rehash) \ - XX(jl_infer_thunk) \ XX(jl_init) \ XX(jl_init_options) \ XX(jl_init_restored_module) \ @@ -517,6 +516,7 @@ #define JL_CODEGEN_EXPORTED_FUNCS(YY) \ YY(jl_dump_function_ir) \ YY(jl_dump_method_asm) \ + YY(jl_emit_codeinst_to_jit) \ YY(jl_extern_c) \ YY(jl_get_llvmf_defn) \ YY(jl_get_llvm_function) \ @@ -542,6 +542,7 @@ YY(jl_dump_emitted_mi_name) \ YY(jl_dump_llvm_opt) \ YY(jl_dump_fptr_asm) \ + YY(jl_emit_native) \ YY(jl_get_function_id) \ YY(jl_type_to_llvm) \ YY(jl_getUnwindInfo) \ diff --git a/src/julia.h b/src/julia.h index 9b8d090fe37cb..5cafc9bfa5232 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1580,6 +1580,7 @@ static inline int jl_field_isconst(jl_datatype_t *st, int i) JL_NOTSAFEPOINT #define jl_is_addrspacecore(v) jl_typetagis(v,jl_addrspacecore_type) #define jl_is_abioverride(v) jl_typetagis(v,jl_abioverride_type) #define jl_genericmemory_isbitsunion(a) (((jl_datatype_t*)jl_typetagof(a))->layout->flags.arrayelem_isunion) +#define jl_is_array_any(v) jl_typetagis(v,jl_array_any_type) JL_DLLEXPORT int jl_subtype(jl_value_t *a, jl_value_t *b); diff --git a/src/julia_internal.h b/src/julia_internal.h index f0debd31e2fec..7e91e23b9087d 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -400,7 +400,7 @@ extern arraylist_t eytzinger_image_tree; extern arraylist_t eytzinger_idxs; extern JL_DLLEXPORT size_t jl_page_size; -extern jl_function_t *jl_typeinf_func JL_GLOBALLY_ROOTED; +extern JL_DLLEXPORT jl_function_t *jl_typeinf_func JL_GLOBALLY_ROOTED; extern JL_DLLEXPORT size_t jl_typeinf_world; extern _Atomic(jl_typemap_entry_t*) call_cache[N_CALL_CACHE] JL_GLOBALLY_ROOTED; @@ -667,7 +667,6 @@ typedef union { // Also defined in typeinfer.jl - See documentation there. #define SOURCE_MODE_NOT_REQUIRED 0x0 #define SOURCE_MODE_ABI 0x1 -#define SOURCE_MODE_FORCE_SOURCE 0x2 JL_DLLEXPORT jl_code_instance_t *jl_engine_reserve(jl_method_instance_t *m, jl_value_t *owner); JL_DLLEXPORT void jl_engine_fulfill(jl_code_instance_t *ci, jl_code_info_t *src); @@ -683,6 +682,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred( JL_DLLEXPORT jl_method_instance_t *jl_get_unspecialized(jl_method_t *def JL_PROPAGATES_ROOT); JL_DLLEXPORT void jl_read_codeinst_invoke(jl_code_instance_t *ci, uint8_t *specsigflags, jl_callptr_t *invoke, void **specptr, int waitcompile); JL_DLLEXPORT jl_method_instance_t *jl_method_match_to_mi(jl_method_match_t *match, size_t world, size_t min_valid, size_t max_valid, int mt_cache); +JL_DLLEXPORT void jl_add_codeinst_to_jit(jl_code_instance_t *codeinst, jl_code_info_t *src); JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst_uninit(jl_method_instance_t *mi, jl_value_t *owner); JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( @@ -695,9 +695,11 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( STATIC_INLINE jl_method_instance_t *jl_get_ci_mi(jl_code_instance_t *ci JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT { - if (jl_is_abioverride(ci->def)) - return ((jl_abi_override_t*)ci->def)->def; - return (jl_method_instance_t*)ci->def; + jl_value_t *def = ci->def; + if (jl_is_abioverride(def)) + return ((jl_abi_override_t*)def)->def; + assert(jl_is_method_instance(def)); + return (jl_method_instance_t*)def; } JL_DLLEXPORT const char *jl_debuginfo_file(jl_debuginfo_t *debuginfo) JL_NOTSAFEPOINT; @@ -705,6 +707,7 @@ JL_DLLEXPORT const char *jl_debuginfo_file1(jl_debuginfo_t *debuginfo) JL_NOTSAF JL_DLLEXPORT jl_module_t *jl_debuginfo_module1(jl_value_t *debuginfo_def) JL_NOTSAFEPOINT; JL_DLLEXPORT const char *jl_debuginfo_name(jl_value_t *func) JL_NOTSAFEPOINT; +JL_DLLEXPORT int jl_is_compiled_codeinst(jl_code_instance_t *codeinst) JL_NOTSAFEPOINT; JL_DLLEXPORT void jl_compile_method_instance(jl_method_instance_t *mi, jl_tupletype_t *types, size_t world); JL_DLLEXPORT void jl_compile_method_sig(jl_method_t *m, jl_value_t *types, jl_svec_t *sparams, size_t world); JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types); @@ -1944,6 +1947,7 @@ JL_DLLEXPORT uint32_t jl_crc32c(uint32_t crc, const char *buf, size_t len); JL_DLLIMPORT void jl_generate_fptr_for_unspecialized(jl_code_instance_t *unspec); JL_DLLIMPORT int jl_compile_codeinst(jl_code_instance_t *unspec); JL_DLLIMPORT int jl_compile_extern_c(LLVMOrcThreadSafeModuleRef llvmmod, void *params, void *sysimg, jl_value_t *declrt, jl_value_t *sigt); +JL_DLLIMPORT void jl_emit_codeinst_to_jit(jl_code_instance_t *codeinst, jl_code_info_t *src); typedef struct { LLVMOrcThreadSafeModuleRef TSM; @@ -1958,7 +1962,8 @@ JL_DLLIMPORT jl_value_t *jl_dump_function_ir(jl_llvmf_dump_t *dump, char strip_i JL_DLLIMPORT jl_value_t *jl_dump_function_asm(jl_llvmf_dump_t *dump, char emit_mc, const char* asm_variant, const char *debuginfo, char binary, char raw); typedef jl_value_t *(*jl_codeinstance_lookup_t)(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t min_world, size_t max_world); -JL_DLLIMPORT void *jl_create_native(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int policy, int imaging_mode, int cache, size_t world, jl_codeinstance_lookup_t lookup); +JL_DLLIMPORT void *jl_create_native(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, int trim, int cache, size_t world); +JL_DLLIMPORT void *jl_emit_native(jl_array_t *codeinfos, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int _external_linkage); JL_DLLIMPORT void jl_dump_native(void *native_code, const char *bc_fname, const char *unopt_bc_fname, const char *obj_fname, const char *asm_fname, ios_t *z, ios_t *s, jl_emission_params_t *params); diff --git a/src/precompile_utils.c b/src/precompile_utils.c index f2777455c4ed1..8906b3eb586d3 100644 --- a/src/precompile_utils.c +++ b/src/precompile_utils.c @@ -203,8 +203,8 @@ static int precompile_enq_specialization_(jl_method_instance_t *mi, void *closur else if (jl_atomic_load_relaxed(&codeinst->invoke) != jl_fptr_const_return) { jl_value_t *inferred = jl_atomic_load_relaxed(&codeinst->inferred); if (inferred && - inferred != jl_nothing && - (jl_options.compile_enabled != JL_OPTIONS_COMPILE_ALL && jl_ir_inlining_cost(inferred) == UINT16_MAX)) { + (jl_options.compile_enabled == JL_OPTIONS_COMPILE_ALL || inferred == jl_nothing || + ((jl_is_string(inferred) || jl_is_code_info(inferred)) && jl_ir_inlining_cost(inferred) == UINT16_MAX))) { do_compile = 1; } else if (jl_atomic_load_relaxed(&codeinst->invoke) != NULL || jl_atomic_load_relaxed(&codeinst->precompile)) { @@ -275,9 +275,7 @@ static void *jl_precompile_(jl_array_t *m, int external_linkage) jl_array_ptr_1d_push(m2, item); } } - void *native_code = jl_create_native(m2, NULL, NULL, 0, 1, external_linkage, - jl_atomic_load_acquire(&jl_world_counter), - NULL); + void *native_code = jl_create_native(m2, NULL, 0, external_linkage, jl_atomic_load_acquire(&jl_world_counter)); JL_GC_POP(); return native_code; } @@ -372,8 +370,7 @@ static void *jl_precompile_trimmed(size_t world) jl_value_t *ccallable = NULL; JL_GC_PUSH2(&m, &ccallable); jl_method_instance_t *mi; - while (1) - { + while (1) { mi = (jl_method_instance_t*)arraylist_pop(jl_entrypoint_mis); if (mi == NULL) break; @@ -385,10 +382,7 @@ static void *jl_precompile_trimmed(size_t world) jl_array_ptr_1d_push(m, ccallable); } - jl_cgparams_t params = jl_default_cgparams; - params.trim = jl_options.trim; - void *native_code = jl_create_native(m, NULL, ¶ms, 0, /* imaging */ 1, 0, - world, NULL); + void *native_code = jl_create_native(m, NULL, jl_options.trim, 0, world); JL_GC_POP(); return native_code; } diff --git a/src/toplevel.c b/src/toplevel.c index 44b503d4e1463..11e1f9ad521a1 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -1054,7 +1054,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val size_t world = jl_atomic_load_acquire(&jl_world_counter); ct->world_age = world; if (!has_defs && jl_get_module_infer(m) != 0) { - (void)jl_type_infer(mfunc, world, SOURCE_MODE_NOT_REQUIRED); + (void)jl_type_infer(mfunc, world, SOURCE_MODE_ABI); } result = jl_invoke(/*func*/NULL, /*args*/NULL, /*nargs*/0, mfunc); ct->world_age = last_age; @@ -1138,20 +1138,6 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_in(jl_module_t *m, jl_value_t *ex) return v; } -JL_DLLEXPORT jl_value_t *jl_infer_thunk(jl_code_info_t *thk, jl_module_t *m) -{ - jl_method_instance_t *li = jl_method_instance_for_thunk(thk, m); - JL_GC_PUSH1(&li); - jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0); - jl_task_t *ct = jl_current_task; - jl_code_instance_t *ci = jl_type_infer(li, ct->world_age, SOURCE_MODE_NOT_REQUIRED); - JL_GC_POP(); - if (ci) - return ci->rettype; - return (jl_value_t*)jl_any_type; -} - - //------------------------------------------------------------------------------ // Code loading: combined parse+eval for include() diff --git a/test/precompile.jl b/test/precompile.jl index d9bbf524609c9..2d4a4d310b4e0 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -750,10 +750,9 @@ precompile_test_harness("code caching") do dir struct X end struct X2 end @noinline function f(d) - @noinline - d[X()] = nothing + @noinline d[X()] = nothing end - @noinline fpush(dest) = push!(dest, X()) + @noinline fpush(dest) = @noinline push!(dest, X()) function callboth() f(Dict{X,Any}()) fpush(X[]) @@ -797,18 +796,6 @@ precompile_test_harness("code caching") do dir end end @test hasspec - # Test that compilation adds to method roots with appropriate provenance - m = which(setindex!, (Dict{M.X,Any}, Any, M.X)) - @test Memory{M.X} ∈ m.roots - # Check that roots added outside of incremental builds get attributed to a moduleid of 0 - Base.invokelatest() do - Dict{M.X2,Any}()[M.X2()] = nothing - end - @test Memory{M.X2} ∈ m.roots - groups = group_roots(m) - @test Memory{M.X} ∈ groups[Mid] # attributed to M - @test Memory{M.X2} ∈ groups[0] # activate module is not known - @test !isempty(groups[Bid]) # Check that internal methods and their roots are accounted appropriately minternal = which(M.getelsize, (Vector,)) mi = minternal.specializations::Core.MethodInstance @@ -832,12 +819,12 @@ precompile_test_harness("code caching") do dir """ module $Cache_module2 struct Y end - @noinline f(dest) = push!(dest, Y()) + @noinline f(dest) = @noinline push!(dest, Y()) callf() = f(Y[]) callf() using $(Cache_module) struct Z end - @noinline g(dest) = push!(dest, Z()) + @noinline g(dest) = @noinline push!(dest, Z()) callg() = g(Z[]) callg() end @@ -1146,22 +1133,22 @@ precompile_test_harness("invoke") do dir call_getlast(x) = getlast(x) - # force precompilation + # force precompilation, force call so that inlining heuristics don't affect the result begin Base.Experimental.@force_compile - callf(3) - callg(3) - callh(3) - callq(3) - callqi(3) - callfnc(3) - callgnc(3) - callhnc(3) - callqnc(3) - callqnci(3) - internal(3) - internalnc(3) - call_getlast([1,2,3]) + @noinline callf(3) + @noinline callg(3) + @noinline callh(3) + @noinline callq(3) + @noinline callqi(3) + @noinline callfnc(3) + @noinline callgnc(3) + @noinline callhnc(3) + @noinline callqnc(3) + @noinline callqnci(3) + @noinline internal(3) + @noinline internalnc(3) + @noinline call_getlast([1,2,3]) end # Now that we've precompiled, invalidate with a new method that overrides the `invoke` dispatch @@ -1194,9 +1181,15 @@ precompile_test_harness("invoke") do dir for func in (M.f, M.g, M.internal, M.fnc, M.gnc, M.internalnc) m = get_method_for_type(func, Real) mi = m.specializations::Core.MethodInstance - @test length(mi.backedges) == 2 + @test length(mi.backedges) == 2 || length(mi.backedges) == 4 # internalnc might have a constprop edge @test mi.backedges[1] === Tuple{typeof(func), Real} @test isa(mi.backedges[2], Core.CodeInstance) + if length(mi.backedges) == 4 + @test mi.backedges[3] === Tuple{typeof(func), Real} + @test isa(mi.backedges[4], Core.CodeInstance) + @test mi.backedges[2] !== mi.backedges[4] + @test mi.backedges[2].def === mi.backedges[4].def + end @test mi.cache.max_world == typemax(mi.cache.max_world) end for func in (M.q, M.qnc) @@ -1215,7 +1208,7 @@ precompile_test_harness("invoke") do dir m = only(methods(M.callq)) @test nvalid(m.specializations::Core.MethodInstance) == 0 m = only(methods(M.callqnc)) - @test nvalid(m.specializations::Core.MethodInstance) == 0 + @test nvalid(m.specializations::Core.MethodInstance) == 1 m = only(methods(M.callqi)) @test (m.specializations::Core.MethodInstance).specTypes == Tuple{typeof(M.callqi), Int} m = only(methods(M.callqnci)) From 987682318bc1bad53620904ecbc71d131fce31e5 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Sat, 21 Dec 2024 03:09:51 +0000 Subject: [PATCH 115/198] delete unused code, so the jit no longer uses the inferred field at all --- src/codegen.cpp | 20 ++++--------- src/gf.c | 70 +++++++++++++++++++++++++++++++++----------- src/jitlayers.cpp | 68 +++++++++++------------------------------- src/julia_internal.h | 3 +- src/opaque_closure.c | 6 ++-- 5 files changed, 80 insertions(+), 87 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 04253b67d6b6d..540ee5ec74c4c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -10050,29 +10050,19 @@ jl_llvm_functions_t jl_emit_codeinst( { JL_TIMING(CODEGEN, CODEGEN_Codeinst); jl_timing_show_method_instance(jl_get_ci_mi(codeinst), JL_TIMING_DEFAULT_BLOCK); - JL_GC_PUSH1(&src); if (!src) { - src = (jl_code_info_t*)jl_atomic_load_relaxed(&codeinst->inferred); jl_method_instance_t *mi = jl_get_ci_mi(codeinst); - jl_method_t *def = mi->def.method; - // Check if this is the generic method for opaque closure wrappers - - // if so, this must compile specptr such that it holds the specptr -> invoke wrapper + // Assert that this this is the generic method for opaque closure wrappers: + // this signals to instead compile specptr such that it holds the specptr -> invoke wrapper // to satisfy the dispatching implementation requirements of jl_f_opaque_closure_call - if (def == jl_opaque_closure_method) { - JL_GC_POP(); + if (mi->def.method == jl_opaque_closure_method) { return jl_emit_oc_wrapper(m, params, mi, codeinst->rettype); } - if (src && (jl_value_t*)src != jl_nothing && jl_is_method(def)) - src = jl_uncompress_ir(def, codeinst, (jl_value_t*)src); - if (!src || !jl_is_code_info(src)) { - JL_GC_POP(); - m = orc::ThreadSafeModule(); - return jl_llvm_functions_t(); // failed - } + m = orc::ThreadSafeModule(); + return jl_llvm_functions_t(); // user error } //assert(jl_egal((jl_value_t*)jl_atomic_load_relaxed(&codeinst->debuginfo), (jl_value_t*)src->debuginfo) && "trying to generate code for a codeinst for an incompatible src"); jl_llvm_functions_t decls = jl_emit_code(m, jl_get_ci_mi(codeinst), src, get_ci_abi(codeinst), params); - JL_GC_POP(); return decls; } diff --git a/src/gf.c b/src/gf.c index 390ba72143f5d..48cb8003072ca 100644 --- a/src/gf.c +++ b/src/gf.c @@ -337,6 +337,59 @@ jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_a return dt; } +// only relevant for bootstrapping. otherwise fairly broken. +static int emit_codeinst_and_edges(jl_code_instance_t *codeinst) +{ + jl_value_t *code = jl_atomic_load_relaxed(&codeinst->inferred); + if (code) { + if (jl_atomic_load_relaxed(&codeinst->invoke) != NULL) + return 1; + if (code != jl_nothing) { + JL_GC_PUSH1(&code); + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); + jl_method_t *def = mi->def.method; + if (jl_is_string(code) && jl_is_method(def)) + code = (jl_value_t*)jl_uncompress_ir(def, codeinst, (jl_value_t*)code); + if (jl_is_code_info(code)) { + jl_emit_codeinst_to_jit(codeinst, (jl_code_info_t*)code); + if (0) { + // next emit all the invoke edges too (if this seems profitable) + jl_array_t *src = ((jl_code_info_t*)code)->code; + for (size_t i = 0; i < jl_array_dim0(src); i++) { + jl_value_t *stmt = jl_array_ptr_ref(src, i); + if (jl_is_expr(stmt) && ((jl_expr_t*)stmt)->head == jl_assign_sym) + stmt = jl_exprarg(stmt, 1); + if (jl_is_expr(stmt) && ((jl_expr_t*)stmt)->head == jl_invoke_sym) { + jl_value_t *invoke = jl_exprarg(stmt, 0); + if (jl_is_code_instance(invoke)) + emit_codeinst_and_edges((jl_code_instance_t*)invoke); + } + } + } + JL_GC_POP(); + return 1; + } + JL_GC_POP(); + } + } + return 0; +} + +// Opportunistic SOURCE_MODE_ABI cache lookup, only for bootstrapping. +static jl_code_instance_t *jl_method_inferred_with_abi(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world) +{ + jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache); + for (; codeinst; codeinst = jl_atomic_load_relaxed(&codeinst->next)) { + if (codeinst->owner != jl_nothing) + continue; + if (jl_atomic_load_relaxed(&codeinst->min_world) <= world && world <= jl_atomic_load_relaxed(&codeinst->max_world)) { + if (emit_codeinst_and_edges(codeinst)) + return codeinst; + } + } + return NULL; +} + // run type inference on lambda "mi" for given argument types. // returns the inferred source, and may cache the result in mi // if successful, also updates the mi argument to describe the validity of this src @@ -2571,23 +2624,6 @@ jl_code_instance_t *jl_method_compiled(jl_method_instance_t *mi, size_t world) return NULL; } -// Opportunistic SOURCE_MODE_ABI cache lookup. -jl_code_instance_t *jl_method_inferred_with_abi(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world) -{ - jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache); - for (; codeinst; codeinst = jl_atomic_load_relaxed(&codeinst->next)) { - if (codeinst->owner != jl_nothing) - continue; - - if (jl_atomic_load_relaxed(&codeinst->min_world) <= world && world <= jl_atomic_load_relaxed(&codeinst->max_world)) { - jl_value_t *code = jl_atomic_load_relaxed(&codeinst->inferred); - if (code && (code != jl_nothing || (jl_atomic_load_relaxed(&codeinst->invoke) != NULL))) - return codeinst; - } - } - return NULL; -} - jl_mutex_t precomp_statement_out_lock; _Atomic(uint8_t) jl_force_trace_compile_timing_enabled = 0; diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index e2bf75d346613..21d865891e45c 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -795,47 +795,6 @@ void jl_emit_codeinst_to_jit_impl( emittedmodules[codeinst] = std::move(result_m); } -static void recursive_compile_graph( - jl_code_instance_t *codeinst, - jl_code_info_t *src) -{ - jl_emit_codeinst_to_jit(codeinst, src); - DenseSet Seen; - SmallVector workqueue; - workqueue.push_back(codeinst); - // if any edges were incomplete, try to complete them now - while (!workqueue.empty()) { - auto this_code = workqueue.pop_back_val(); - if (Seen.insert(this_code).second) { - jl_code_instance_t *compiled_ci = jl_method_compiled_egal(codeinst); - if (!compiled_ci) { - if (this_code != codeinst) { - JL_GC_PROMISE_ROOTED(this_code); // rooted transitively from following edges from original argument - jl_emit_codeinst_to_jit(this_code, nullptr); // contains safepoints - } - jl_unique_gcsafe_lock lock(engine_lock); - auto edges = complete_graph.find(this_code); - if (edges != complete_graph.end()) { - workqueue.append(edges->second); - } - } - } - } -} - -// this generates llvm code for the lambda info -// and adds the result to the jitlayers -// (and the shadow module), -// and generates code for it -static void _jl_compile_codeinst( - jl_code_instance_t *codeinst, - jl_code_info_t *src) -{ - recursive_compile_graph(codeinst, src); - jl_compile_codeinst_now(codeinst); - assert(jl_is_compiled_codeinst(codeinst)); -} - const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t ¶ms); @@ -859,7 +818,6 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void * orc::ThreadSafeModule backing; bool success = true; const char *name = ""; - SmallVector dependencies; if (into == NULL) { ctx = pparams ? pparams->tsctx : jl_ExecutionEngine->makeContext(); backing = jl_create_ts_module("cextern", ctx, DL, TargetTriple); @@ -887,11 +845,16 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void * } params.tsctx_lock = params.tsctx.getLock(); // re-acquire lock if (success && params.cache) { - for (auto &it : params.workqueue) { + size_t newest_world = jl_atomic_load_acquire(&jl_world_counter); + for (auto &it : params.workqueue) { // really just zero or one, and just the ABI not the rest of the metadata jl_code_instance_t *codeinst = it.first; JL_GC_PROMISE_ROOTED(codeinst); - dependencies.push_back(codeinst); - recursive_compile_graph(codeinst, nullptr); + jl_code_instance_t *newest_ci = jl_type_infer(jl_get_ci_mi(codeinst), newest_world, SOURCE_MODE_ABI); + if (newest_ci) { + if (jl_egal(codeinst->rettype, newest_ci->rettype)) + it.first = codeinst; + jl_compile_codeinst_now(newest_ci); + } } jl_analyze_workqueue(nullptr, params, true); assert(params.workqueue.empty()); @@ -904,8 +867,6 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void * { // lock scope jl_unique_gcsafe_lock lock(extern_c_lock); if (!jl_ExecutionEngine->getGlobalValueAddress(name)) { - for (auto dep : dependencies) - jl_compile_codeinst_now(dep); { auto Lock = backing.getContext().getLock(); jl_ExecutionEngine->optimizeDLSyms(*backing.getModuleUnlocked()); // safepoint @@ -976,7 +937,7 @@ int jl_compile_codeinst_impl(jl_code_instance_t *ci) if (!jl_is_compiled_codeinst(ci)) { ++SpecFPtrCount; uint64_t start = jl_typeinf_timing_begin(); - _jl_compile_codeinst(ci, NULL); + jl_compile_codeinst_now(ci); jl_typeinf_timing_end(start, 0); newly_compiled = 1; } @@ -1007,8 +968,7 @@ void jl_generate_fptr_for_unspecialized_impl(jl_code_instance_t *unspec) } else { jl_method_instance_t *mi = jl_get_ci_mi(unspec); - jl_code_instance_t *uninferred = jl_cached_uninferred( - jl_atomic_load_relaxed(&mi->cache), 1); + jl_code_instance_t *uninferred = jl_cached_uninferred(jl_atomic_load_relaxed(&mi->cache), 1); assert(uninferred); src = (jl_code_info_t*)jl_atomic_load_relaxed(&uninferred->inferred); assert(src); @@ -1019,10 +979,16 @@ void jl_generate_fptr_for_unspecialized_impl(jl_code_instance_t *unspec) if (!jl_is_compiled_codeinst(unspec)) { assert(jl_is_code_info(src)); ++UnspecFPtrCount; + jl_svec_t *edges = (jl_svec_t*)src->edges; + if (jl_is_svec(edges)) { + jl_atomic_store_release(&unspec->edges, edges); // n.b. this assumes the field was always empty svec(), which is not entirely true + jl_gc_wb(unspec, edges); + } jl_debuginfo_t *debuginfo = src->debuginfo; jl_atomic_store_release(&unspec->debuginfo, debuginfo); // n.b. this assumes the field was previously NULL, which is not entirely true jl_gc_wb(unspec, debuginfo); - _jl_compile_codeinst(unspec, src); + jl_emit_codeinst_to_jit(unspec, src); + jl_compile_codeinst_now(unspec); } JL_UNLOCK(&jitlock); // Might GC } diff --git a/src/julia_internal.h b/src/julia_internal.h index 7e91e23b9087d..00103e9b00a48 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -673,7 +673,7 @@ JL_DLLEXPORT void jl_engine_fulfill(jl_code_instance_t *ci, jl_code_info_t *src) void jl_engine_sweep(jl_ptls_t *gc_all_tls_states) JL_NOTSAFEPOINT; int jl_engine_hasreserved(jl_method_instance_t *m, jl_value_t *owner) JL_NOTSAFEPOINT; -JL_DLLEXPORT jl_code_instance_t *jl_type_infer(jl_method_instance_t *li, size_t world, uint8_t source_mode); +JL_DLLEXPORT jl_code_instance_t *jl_type_infer(jl_method_instance_t *li JL_PROPAGATES_ROOT, size_t world, uint8_t source_mode); JL_DLLEXPORT jl_code_info_t *jl_gdbcodetyped1(jl_method_instance_t *mi, size_t world); JL_DLLEXPORT jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *meth JL_PROPAGATES_ROOT, size_t world); JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred( @@ -1210,7 +1210,6 @@ jl_method_instance_t *jl_get_specialized(jl_method_t *m, jl_value_t *types, jl_s JL_DLLEXPORT jl_value_t *jl_rettype_inferred(jl_value_t *owner, jl_method_instance_t *li JL_PROPAGATES_ROOT, size_t min_world, size_t max_world); JL_DLLEXPORT jl_value_t *jl_rettype_inferred_native(jl_method_instance_t *mi, size_t min_world, size_t max_world) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_code_instance_t *jl_method_compiled(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world) JL_NOTSAFEPOINT; -JL_DLLEXPORT jl_code_instance_t *jl_method_inferred_with_abi(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_methtable_t *mt JL_PROPAGATES_ROOT, jl_value_t *type, size_t world); JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo( jl_method_t *m JL_PROPAGATES_ROOT, jl_value_t *type, jl_svec_t *sparams); diff --git a/src/opaque_closure.c b/src/opaque_closure.c index 8a9dcac30a4f8..2d11d763be662 100644 --- a/src/opaque_closure.c +++ b/src/opaque_closure.c @@ -118,8 +118,10 @@ static jl_opaque_closure_t *new_opaque_closure(jl_tupletype_t *argt, jl_value_t // OC wrapper methods are not world dependent and have no edges or other info ci = jl_get_method_inferred(mi_generic, selected_rt, 1, ~(size_t)0, NULL, NULL); - if (!jl_atomic_load_acquire(&ci->invoke)) - jl_compile_codeinst(ci); // confusing this actually calls jl_emit_oc_wrapper and never actually compiles ci (which would be impossible since it cannot have source) + if (!jl_atomic_load_acquire(&ci->invoke)) { + jl_emit_codeinst_to_jit(ci, NULL); // confusing this actually calls jl_emit_oc_wrapper and never actually compiles ci (which would be impossible since it cannot have source) + jl_compile_codeinst(ci); + } specptr = jl_atomic_load_relaxed(&ci->specptr.fptr); } jl_opaque_closure_t *oc = (jl_opaque_closure_t*)jl_gc_alloc(ct->ptls, sizeof(jl_opaque_closure_t), oc_type); From 1e2758e753cf1b1f710492cdb558550b9982266f Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Fri, 3 Jan 2025 14:20:00 -0300 Subject: [PATCH 116/198] Make sure we don't promise alignments that are larger than the heap alignment to LLVM (#56938) Fixes https://github.com/JuliaLang/julia/issues/56937 --------- Co-authored-by: Oscar Smith --- Compiler/test/codegen.jl | 5 +++++ src/codegen.cpp | 2 ++ src/datatype.c | 2 ++ 3 files changed, 9 insertions(+) diff --git a/Compiler/test/codegen.jl b/Compiler/test/codegen.jl index 9ba268fe95be8..9b92f560c64fc 100644 --- a/Compiler/test/codegen.jl +++ b/Compiler/test/codegen.jl @@ -1036,3 +1036,8 @@ f56739(a) where {T} = a @test f56739(1) == 1 g56739(x) = @noinline f56739(x) @test g56739(1) == 1 + +struct Vec56937 x::NTuple{8, VecElement{Int}} end + +x56937 = Ref(Vec56937(ntuple(_->VecElement(1),8))) +@test x56937[].x[1] == VecElement{Int}(1) # shouldn't crash diff --git a/src/codegen.cpp b/src/codegen.cpp index 540ee5ec74c4c..1ca45a98b0620 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8927,6 +8927,8 @@ static jl_llvm_functions_t Type *RT = Arg->getParamStructRetType(); TypeSize sz = DL.getTypeAllocSize(RT); Align al = DL.getPrefTypeAlign(RT); + if (al > MAX_ALIGN) + al = Align(MAX_ALIGN); param.addAttribute(Attribute::NonNull); // The `dereferenceable` below does not imply `nonnull` for non addrspace(0) pointers. param.addDereferenceableAttr(sz); diff --git a/src/datatype.c b/src/datatype.c index c78b00fdd2245..fd25cca503676 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -769,6 +769,8 @@ void jl_compute_field_offsets(jl_datatype_t *st) if (al > alignm) alignm = al; } + if (alignm > MAX_ALIGN) + alignm = MAX_ALIGN; // We cannot guarantee alignments over 16 bytes because that's what our heap is aligned as if (LLT_ALIGN(sz, alignm) > sz) { haspadding = 1; sz = LLT_ALIGN(sz, alignm); From e757769cb5e14781012aba8c22763bcb79d19710 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Sat, 4 Jan 2025 09:18:29 -0500 Subject: [PATCH 117/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?NetworkOptions=20stdlib=20from=208eec5cb=20to=20c090626=20(#569?= =?UTF-8?q?49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: NetworkOptions URL: https://github.com/JuliaLang/NetworkOptions.jl.git Stdlib branch: master Julia branch: master Old commit: 8eec5cb New commit: c090626 Julia version: 1.12.0-DEV NetworkOptions version: 1.3.0(Does not match) Bump invoked by: @giordano Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaLang/NetworkOptions.jl/compare/8eec5cb0acec4591e6db3c017f7499426cd8e352...c090626d3feee6d6a5c476346d22d6147c9c6d2d ``` $ git log --oneline 8eec5cb..c090626 c090626 Enable OpenSSL certificates (#36) ``` --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/NetworkOptions.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/md5 delete mode 100644 deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/sha512 create mode 100644 deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/md5 create mode 100644 deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/sha512 diff --git a/deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/md5 b/deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/md5 deleted file mode 100644 index 7f391aac1e64d..0000000000000 --- a/deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -d2ccb9b91b0700bfb5ac7c01a03b4322 diff --git a/deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/sha512 b/deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/sha512 deleted file mode 100644 index b7db226225d75..0000000000000 --- a/deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -051223ab45dce692c0bbea0755cc0057bb3322a40659c092007799932a10cc23e80ee6b88fa0d86f28af5e7fe5a455cc9fb8267c76af0cd2b425cf2718629e91 diff --git a/deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/md5 b/deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/md5 new file mode 100644 index 0000000000000..87111ac121562 --- /dev/null +++ b/deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/md5 @@ -0,0 +1 @@ +b851cab503506c37af6e4c861d81b8ce diff --git a/deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/sha512 b/deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/sha512 new file mode 100644 index 0000000000000..79f9e269ff599 --- /dev/null +++ b/deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/sha512 @@ -0,0 +1 @@ +4cba5c531e5e7205bb6d7f0179da8b29ca7c4dcf42f27de5f70be7674efc1fa92ea22e134e6584743e2905edbd754838d8a02f6ba7811c7a5b99ab9db3bde596 diff --git a/stdlib/NetworkOptions.version b/stdlib/NetworkOptions.version index 221b9b934f1a1..69b56e03ed89e 100644 --- a/stdlib/NetworkOptions.version +++ b/stdlib/NetworkOptions.version @@ -1,4 +1,4 @@ NETWORKOPTIONS_BRANCH = master -NETWORKOPTIONS_SHA1 = 8eec5cb0acec4591e6db3c017f7499426cd8e352 +NETWORKOPTIONS_SHA1 = c090626d3feee6d6a5c476346d22d6147c9c6d2d NETWORKOPTIONS_GIT_URL := https://github.com/JuliaLang/NetworkOptions.jl.git NETWORKOPTIONS_TAR_URL = https://api.github.com/repos/JuliaLang/NetworkOptions.jl/tarball/$1 From eee709e8330a508d11729308dc3605fee89db143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Sat, 4 Jan 2025 16:03:47 +0100 Subject: [PATCH 118/198] [build] Fix value of `CMAKE_C{,XX}_ARG` when `CC_ARG` doesn't have args (#56920) The problem was that `cut` by default prints the entire line if the delimiter doesn't appear, unless the option `-s` is used, which means that if `CC_ARG` contains only `gcc` then `CMAKE_CC_ARG` also contains `gcc` instead of being empty. Before the PR: ```console $ make -C deps/ print-CC_ARG print-CMAKE_CC_ARG print-CMAKE_COMMON USECCACHE=1 make: Entering directory '/home/mose/repo/julia/deps' CC_ARG=gcc CMAKE_CC_ARG=gcc CMAKE_COMMON=-DCMAKE_INSTALL_PREFIX:PATH=/home/mose/repo/julia/usr -DCMAKE_PREFIX_PATH=/home/mose/repo/julia/usr -DLIB_INSTALL_DIR=/home/mose/repo/julia/usr/lib -DCMAKE_INSTALL_LIBDIR=/home/mose/repo/julia/usr/lib -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER="$(which gcc)" -DCMAKE_C_COMPILER_ARG1="gcc " -DCMAKE_CXX_COMPILER="$(which g++)" -DCMAKE_CXX_COMPILER_ARG1="g++ " -DCMAKE_LINKER="$(which ld)" -DCMAKE_AR="$(which ar)" -DCMAKE_RANLIB="$(which ranlib)" make: Leaving directory '/home/mose/repo/julia/deps' ``` After the PR ```console $ make -C deps/ print-CC_ARG print-CMAKE_CC_ARG print-CMAKE_COMMON USECCACHE=1 make: Entering directory '/home/mose/repo/julia/deps' CC_ARG=gcc CMAKE_CC_ARG= CMAKE_COMMON=-DCMAKE_INSTALL_PREFIX:PATH=/home/mose/repo/julia/usr -DCMAKE_PREFIX_PATH=/home/mose/repo/julia/usr -DLIB_INSTALL_DIR=/home/mose/repo/julia/usr/lib -DCMAKE_INSTALL_LIBDIR=/home/mose/repo/julia/usr/lib -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER="$(which gcc)" -DCMAKE_CXX_COMPILER="$(which g++)" -DCMAKE_LINKER="$(which ld)" -DCMAKE_AR="$(which ar)" -DCMAKE_RANLIB="$(which ranlib)" make: Leaving directory '/home/mose/repo/julia/deps' ``` as intended. --- deps/tools/common.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/tools/common.mk b/deps/tools/common.mk index 3cefc253cec3d..01b57316f9d1a 100644 --- a/deps/tools/common.mk +++ b/deps/tools/common.mk @@ -36,8 +36,8 @@ CMAKE_COMMON += -DCMAKE_C_COMPILER_LAUNCHER=ccache CMAKE_COMMON += -DCMAKE_CXX_COMPILER_LAUNCHER=ccache CMAKE_CC := "$$(which $(shell echo $(CC_ARG) | cut -d' ' -f1))" CMAKE_CXX := "$$(which $(shell echo $(CXX_ARG) | cut -d' ' -f1))" -CMAKE_CC_ARG := $(shell echo $(CC_ARG) | cut -d' ' -f2-) -CMAKE_CXX_ARG := $(shell echo $(CXX_ARG) | cut -d' ' -f2-) +CMAKE_CC_ARG := $(shell echo $(CC_ARG) | cut -s -d' ' -f2-) +CMAKE_CXX_ARG := $(shell echo $(CXX_ARG) | cut -s -d' ' -f2-) else CMAKE_CC := "$$(which $(CC_BASE))" CMAKE_CXX := "$$(which $(CXX_BASE))" From 638dacc9c0c49e9662fa0009eadbd10ab7af1fed Mon Sep 17 00:00:00 2001 From: Erik Schnetter Date: Sat, 4 Jan 2025 12:12:48 -0500 Subject: [PATCH 119/198] Switch from MbedTLS to OpenSSL (#56708) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on @fxcoudert's openssl branch and pull request at https://github.com/JuliaLang/julia/pull/53891. - diff re-applied to current Julia master (hence the new commit) - LibCURL, LibGit2, LibSSH2, OpenSSL updated to newest version - MbedTLS removed Fix #48799. --------- Co-authored-by: Zentrik Co-authored-by: Ian Butterworth Co-authored-by: Mosè Giordano <765740+giordano@users.noreply.github.com> Co-authored-by: Mosè Giordano --- Make.inc | 4 +- Makefile | 2 +- THIRDPARTY.md | 2 +- base/Makefile | 5 +- contrib/refresh_checksums.mk | 2 +- deps/Makefile | 12 +- deps/checksums/curl | 68 ++++++------ deps/checksums/libgit2 | 70 ++++++------ deps/checksums/libssh2 | 70 ++++++------ deps/checksums/mbedtls | 36 ------ deps/checksums/openssl | 36 ++++++ deps/curl.mk | 24 ++-- deps/curl.version | 5 +- deps/libgit2.mk | 6 +- deps/libgit2.version | 4 +- deps/libssh2.mk | 14 +-- deps/libssh2.version | 7 +- deps/mbedtls.mk | 97 ---------------- deps/openssl.mk | 102 +++++++++++++++++ deps/{mbedtls.version => openssl.version} | 5 +- deps/patches/curl-8.6.0-build.patch | 23 ---- deps/patches/curl-strdup.patch | 10 ++ deps/patches/libssh2-mbedtls-size_t.patch | 105 ------------------ deps/pcre.version | 1 + doc/Manifest.toml | 20 ++-- doc/src/devdocs/build/build.md | 4 +- julia.spdx.json | 16 +-- stdlib/LibCURL_jll/Project.toml | 4 +- stdlib/LibCURL_jll/src/LibCURL_jll.jl | 6 +- stdlib/LibGit2_jll/Project.toml | 4 +- stdlib/LibGit2_jll/src/LibGit2_jll.jl | 6 +- stdlib/LibGit2_jll/test/runtests.jl | 2 +- stdlib/LibSSH2_jll/Project.toml | 4 +- stdlib/LibSSH2_jll/src/LibSSH2_jll.jl | 6 +- stdlib/LibSSH2_jll/test/runtests.jl | 7 +- stdlib/Makefile | 2 +- stdlib/Manifest.toml | 22 ++-- stdlib/MbedTLS_jll/src/MbedTLS_jll.jl | 61 ---------- stdlib/MbedTLS_jll/test/runtests.jl | 10 -- .../{MbedTLS_jll => OpenSSL_jll}/Project.toml | 8 +- stdlib/OpenSSL_jll/src/OpenSSL_jll.jl | 58 ++++++++++ stdlib/OpenSSL_jll/test/runtests.jl | 10 ++ stdlib/Project.toml | 2 +- stdlib/stdlib.mk | 4 +- 44 files changed, 431 insertions(+), 535 deletions(-) delete mode 100644 deps/checksums/mbedtls create mode 100644 deps/checksums/openssl delete mode 100644 deps/mbedtls.mk create mode 100644 deps/openssl.mk rename deps/{mbedtls.version => openssl.version} (50%) delete mode 100644 deps/patches/curl-8.6.0-build.patch create mode 100644 deps/patches/curl-strdup.patch delete mode 100644 deps/patches/libssh2-mbedtls-size_t.patch delete mode 100644 stdlib/MbedTLS_jll/src/MbedTLS_jll.jl delete mode 100644 stdlib/MbedTLS_jll/test/runtests.jl rename stdlib/{MbedTLS_jll => OpenSSL_jll}/Project.toml (66%) create mode 100644 stdlib/OpenSSL_jll/src/OpenSSL_jll.jl create mode 100644 stdlib/OpenSSL_jll/test/runtests.jl diff --git a/Make.inc b/Make.inc index a60a95d21c3db..2f2ffcad754c4 100644 --- a/Make.inc +++ b/Make.inc @@ -51,7 +51,7 @@ USE_SYSTEM_MPFR:=0 USE_SYSTEM_LIBSUITESPARSE:=0 USE_SYSTEM_LIBUV:=0 USE_SYSTEM_UTF8PROC:=0 -USE_SYSTEM_MBEDTLS:=0 +USE_SYSTEM_OPENSSL:=0 USE_SYSTEM_LIBSSH2:=0 USE_SYSTEM_NGHTTP2:=0 USE_SYSTEM_CURL:=0 @@ -1355,7 +1355,7 @@ CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.33|GLIBCXX_3\.5\.|GLIBCXX_4\. # Note: we explicitly _do not_ define `CSL` here, since it requires some more # advanced techniques to decide whether it should be installed from a BB source # or not. See `deps/csl.mk` for more detail. -BB_PROJECTS := BLASTRAMPOLINE OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP MBEDTLS LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB P7ZIP LLD LIBTRACYCLIENT BOLT +BB_PROJECTS := BLASTRAMPOLINE OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP OPENSSL LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB P7ZIP LLD LIBTRACYCLIENT BOLT define SET_BB_DEFAULT # First, check to see if BB is disabled on a global setting ifeq ($$(USE_BINARYBUILDER),0) diff --git a/Makefile b/Makefile index f0b1dfaa708e4..20d131ee8524c 100644 --- a/Makefile +++ b/Makefile @@ -228,7 +228,7 @@ JL_PRIVATE_LIBS-$(USE_SYSTEM_GMP) += libgmp libgmpxx JL_PRIVATE_LIBS-$(USE_SYSTEM_MPFR) += libmpfr JL_PRIVATE_LIBS-$(USE_SYSTEM_LIBSSH2) += libssh2 JL_PRIVATE_LIBS-$(USE_SYSTEM_NGHTTP2) += libnghttp2 -JL_PRIVATE_LIBS-$(USE_SYSTEM_MBEDTLS) += libmbedtls libmbedcrypto libmbedx509 +JL_PRIVATE_LIBS-$(USE_SYSTEM_OPENSSL) += libcrypto libssl JL_PRIVATE_LIBS-$(USE_SYSTEM_CURL) += libcurl JL_PRIVATE_LIBS-$(USE_SYSTEM_LIBGIT2) += libgit2 JL_PRIVATE_LIBS-$(USE_SYSTEM_LIBUV) += libuv diff --git a/THIRDPARTY.md b/THIRDPARTY.md index 3a74afec4a283..f3f59ca4ff3f7 100644 --- a/THIRDPARTY.md +++ b/THIRDPARTY.md @@ -36,7 +36,7 @@ Julia's `stdlib` uses the following external libraries, which have their own lic - [LIBGIT2](https://github.com/libgit2/libgit2/blob/development/COPYING) [GPL2+ with unlimited linking exception] - [CURL](https://curl.haxx.se/docs/copyright.html) [MIT/X derivative] - [LIBSSH2](https://github.com/libssh2/libssh2/blob/master/COPYING) [BSD-3] -- [MBEDTLS](https://github.com/ARMmbed/mbedtls/blob/development/LICENSE) [Apache 2.0] +- [OPENSSL](https://www.openssl.org/source/license.html) [Apache 2.0] - [MPFR](https://www.mpfr.org/mpfr-current/mpfr.html#Copying) [LGPL3+] - [OPENBLAS](https://raw.github.com/xianyi/OpenBLAS/master/LICENSE) [BSD-3] - [LAPACK](https://netlib.org/lapack/LICENSE.txt) [BSD-3] diff --git a/base/Makefile b/base/Makefile index febee53a9ddfc..09f79e5b98611 100644 --- a/base/Makefile +++ b/base/Makefile @@ -264,9 +264,8 @@ $(eval $(call symlink_system_library,LAPACK,$(LIBLAPACKNAME))) endif $(eval $(call symlink_system_library,GMP,libgmp)) $(eval $(call symlink_system_library,MPFR,libmpfr)) -$(eval $(call symlink_system_library,MBEDTLS,libmbedtls)) -$(eval $(call symlink_system_library,MBEDTLS,libmbedcrypto)) -$(eval $(call symlink_system_library,MBEDTLS,libmbedx509)) +$(eval $(call symlink_system_library,OPENSSL,libcrypto)) +$(eval $(call symlink_system_library,OPENSSL,libssl)) $(eval $(call symlink_system_library,LIBSSH2,libssh2)) $(eval $(call symlink_system_library,NGHTTP2,libnghttp2)) $(eval $(call symlink_system_library,CURL,libcurl)) diff --git a/contrib/refresh_checksums.mk b/contrib/refresh_checksums.mk index e7bf2fd7c2efc..21ef72c26a03d 100644 --- a/contrib/refresh_checksums.mk +++ b/contrib/refresh_checksums.mk @@ -24,7 +24,7 @@ CLANG_TRIPLETS=$(filter %-darwin %-freebsd,$(TRIPLETS)) NON_CLANG_TRIPLETS=$(filter-out %-darwin %-freebsd,$(TRIPLETS)) # These are the projects currently using BinaryBuilder; both GCC-expanded and non-GCC-expanded: -BB_PROJECTS=mbedtls libssh2 nghttp2 mpfr curl libgit2 pcre libuv unwind llvmunwind dsfmt objconv p7zip zlib libsuitesparse openlibm blastrampoline libtracyclient +BB_PROJECTS=openssl libssh2 nghttp2 mpfr curl libgit2 pcre libuv unwind llvmunwind dsfmt objconv p7zip zlib libsuitesparse openlibm blastrampoline libtracyclient BB_GCC_EXPANDED_PROJECTS=openblas csl BB_CXX_EXPANDED_PROJECTS=gmp llvm clang llvm-tools lld # These are non-BB source-only deps diff --git a/deps/Makefile b/deps/Makefile index b87a3e1e58609..d4ef52646cfdc 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -22,9 +22,9 @@ BUILDDIR := $(BUILDDIR)$(MAYBE_HOST) # additionally all targets should be listed in the getall target for easier off-line compilation # if you are adding a new target, it can help to copy an similar, existing target # -# autoconf configure-driven scripts: pcre unwind gmp mpfr patchelf libuv curl +# autoconf configure-driven scripts: pcre unwind gmp mpfr patchelf libuv curl openssl # custom Makefile rules: openlibm dsfmt libsuitesparse lapack blastrampoline openblas utf8proc objconv libwhich -# CMake libs: llvm llvmunwind libgit2 libssh2 mbedtls libtracyclient +# CMake libs: llvm llvmunwind libgit2 libssh2 libtracyclient # # downloadable via git: llvm-svn, libuv, libopenlibm, utf8proc, libgit2, libssh2, libtracyclient # @@ -119,8 +119,8 @@ ifeq ($(USE_SYSTEM_GMP), 0) DEP_LIBS += gmp endif -ifeq ($(USE_SYSTEM_MBEDTLS), 0) -DEP_LIBS += mbedtls +ifeq ($(USE_SYSTEM_OPENSSL), 0) +DEP_LIBS += openssl endif ifeq ($(USE_SYSTEM_LIBSSH2), 0) @@ -200,7 +200,7 @@ DEP_LIBS_STAGED := $(DEP_LIBS) # list all targets DEP_LIBS_STAGED_ALL := llvm llvm-tools clang llvmunwind unwind libuv pcre \ openlibm dsfmt blastrampoline openblas lapack gmp mpfr patchelf utf8proc \ - objconv mbedtls libssh2 nghttp2 curl libgit2 libwhich zlib p7zip csl \ + objconv openssl libssh2 nghttp2 curl libgit2 libwhich zlib p7zip csl \ sanitizers libsuitesparse lld libtracyclient ittapi nvtx JuliaSyntax \ terminfo DEP_LIBS_ALL := $(DEP_LIBS_STAGED_ALL) @@ -256,7 +256,7 @@ include $(SRCDIR)/unwind.mk include $(SRCDIR)/gmp.mk include $(SRCDIR)/mpfr.mk include $(SRCDIR)/patchelf.mk -include $(SRCDIR)/mbedtls.mk +include $(SRCDIR)/openssl.mk include $(SRCDIR)/libssh2.mk include $(SRCDIR)/nghttp2.mk include $(SRCDIR)/curl.mk diff --git a/deps/checksums/curl b/deps/checksums/curl index e6f7989db33d7..f96fe5f1a15e3 100644 --- a/deps/checksums/curl +++ b/deps/checksums/curl @@ -1,36 +1,36 @@ LibCURL-a65b64f6eabc932f63c2c0a4a5fb5d75f3e688d0.tar.gz/md5/e8c53aa3fb963c80921787d5d565eb2c LibCURL-a65b64f6eabc932f63c2c0a4a5fb5d75f3e688d0.tar.gz/sha512/8e442ea834299df9c02acb87226c121395ad8e550025ac5ee1103df09c6ff43817e9e48dd1bcbc92c80331ef3ddff531962430269115179acbec2bab2de5b011 -LibCURL.v8.6.0+0.aarch64-apple-darwin.tar.gz/md5/83854e8cdd078ec1fc5f92da2816e379 -LibCURL.v8.6.0+0.aarch64-apple-darwin.tar.gz/sha512/f3b3cc5804d9a7986ed9ea7c3186caa8dba0f4d6bbcb9b5d2070b4e6412234f2ed7908446dbe217323510c6d3b042540e18ec7839093c2c3c66f3195937a6a3b -LibCURL.v8.6.0+0.aarch64-linux-gnu.tar.gz/md5/880014fface52bddaa1a0240e0668dde -LibCURL.v8.6.0+0.aarch64-linux-gnu.tar.gz/sha512/a29b923e14425ad729484648ce15577e717a97acf6138e0ec3d35a8000aeef17f27ce01d1fdc1642c6eda72d8d8b46642d79844ef9a50f30a0148e29452565c1 -LibCURL.v8.6.0+0.aarch64-linux-musl.tar.gz/md5/b84fcb98f1305803d941f7a5accbfdb1 -LibCURL.v8.6.0+0.aarch64-linux-musl.tar.gz/sha512/0880dc91109aedd9b108f2e28a25bf7091ac976a6f94e65000f647802c57a01e8111d421b91a91244c3cfb56990155af2c47b3499997be2af8ab93d344b8331d -LibCURL.v8.6.0+0.armv6l-linux-gnueabihf.tar.gz/md5/24249f42db0bc99c2dde4cf61d61f11f -LibCURL.v8.6.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/350443c86f7b6733fb6a28f8a2fe7a6c0e91462b9e4078fed3475059ec7e12fef5014e22d0d0babe44f172ace7258292de577a0ab90f90c65d825d74940c9c47 -LibCURL.v8.6.0+0.armv6l-linux-musleabihf.tar.gz/md5/375c01cef98204c4f63ac218b08c4c7b -LibCURL.v8.6.0+0.armv6l-linux-musleabihf.tar.gz/sha512/ed0981d458c6ddc9f380b90f1ec25cbaa6be910f0dab5d5485e4d1e9a33f8a918d210722a5e6685b4d3b917e0800194856f826164ee2e90b8a886ada7498a52b -LibCURL.v8.6.0+0.armv7l-linux-gnueabihf.tar.gz/md5/4c81aa99065cf797d6e09ce172dd2fa7 -LibCURL.v8.6.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/08bbb1bc80411a5fd65699a0d721fc70a9bba1005194f2937accc2e98f7f803bac4a704c88aa1fc1d72e54e7c327a113963f8a4c52ebb1e5921778d1dd549143 -LibCURL.v8.6.0+0.armv7l-linux-musleabihf.tar.gz/md5/6865b2f2d93754b5206d618048c32b57 -LibCURL.v8.6.0+0.armv7l-linux-musleabihf.tar.gz/sha512/c1a5891f4c487d5f7cf91db7cd2d85394d9686cda01c89cddaf7afba09782aa9f00713592d72ed8a0dd20439884dd75c1e001a9ecb16dd8ce5f08f79c194c7c8 -LibCURL.v8.6.0+0.i686-linux-gnu.tar.gz/md5/3f35cc6a2dc7e9dba5e3b4aeaf130160 -LibCURL.v8.6.0+0.i686-linux-gnu.tar.gz/sha512/b34c5ba2fee272e6ca848c42335ffa0c4d0c06337608504a3a2cfeb111e228da3f82d91c0c4387c76fc347babbf50b368992b5b8d5fda1a60ed5c0ce5d9242db -LibCURL.v8.6.0+0.i686-linux-musl.tar.gz/md5/0072b83eaf91d9da4a8d25ef65fd8ca8 -LibCURL.v8.6.0+0.i686-linux-musl.tar.gz/sha512/029552e3dac29857726988352a01a3b57859bfe5e327e7b759bd9968ed5af5498fd27ab490810d2d3ef05b1003c1a950fd092d1dbce7732a911f7cb6e5714303 -LibCURL.v8.6.0+0.i686-w64-mingw32.tar.gz/md5/d58ef948bc9a04a8c934a88b7ab5599d -LibCURL.v8.6.0+0.i686-w64-mingw32.tar.gz/sha512/1e1742ea39f2fe1f13b0aff5907f96401276e3fc469a8f09f2bc31fffc72367a92856973db66eb9b05d20fd708764ad9429e385913f6236ce8067ec4e11dbb33 -LibCURL.v8.6.0+0.powerpc64le-linux-gnu.tar.gz/md5/60ec16b6dfd3e30eb0655cf177b026c7 -LibCURL.v8.6.0+0.powerpc64le-linux-gnu.tar.gz/sha512/f591897972c8b01edf64701885f636fc1d5c04cce8fc63577d06108e14e5480bad74306d6ee31515911bd8ba3db10d1f2c733a6149aceae32aa4b77e263087c3 -LibCURL.v8.6.0+0.x86_64-apple-darwin.tar.gz/md5/c6bc0d9cd0a9f9c35ed2aac058ae332f -LibCURL.v8.6.0+0.x86_64-apple-darwin.tar.gz/sha512/038f55bfb06dce877540ea7d50f5a0b8fdc070539c505774139a7c23df276a5fc75b5cecabecbc2826417e091028382d79298a51ed73c3d776249b4ff35f9f26 -LibCURL.v8.6.0+0.x86_64-linux-gnu.tar.gz/md5/18bf9d909dd5eebc0554d23bf4a4ee0f -LibCURL.v8.6.0+0.x86_64-linux-gnu.tar.gz/sha512/35e60faa1ee072003fdd5cd510295bc310aa99375aee6ef94eee3ee2d5e0b7844145866a74927c588c14131939c1d9865d6f5128ac4f6b93606a68042a94f39f -LibCURL.v8.6.0+0.x86_64-linux-musl.tar.gz/md5/213190e1d79c9c291ff460e1648a61d3 -LibCURL.v8.6.0+0.x86_64-linux-musl.tar.gz/sha512/4ea063982520400c02dcdf44ed3f018dec19607ad20762231316eb745cdb1cd054b18677fee1b5c5fb0bd55eb845121a2113704c5301be1d76edfc8a4a09d93f -LibCURL.v8.6.0+0.x86_64-unknown-freebsd.tar.gz/md5/30dda5aaeb7977eb3563c603af08cd6c -LibCURL.v8.6.0+0.x86_64-unknown-freebsd.tar.gz/sha512/edf603a6c013d3f6e01fc4fd6f12caf93ff99df9baf14bc73b610638a5b5ff90ec3118b112d9a39221294f5f419f3bf12232c16eaf91b07a68d92342a5c56912 -LibCURL.v8.6.0+0.x86_64-w64-mingw32.tar.gz/md5/9a2c980db329393f5274d42f87c2aec6 -LibCURL.v8.6.0+0.x86_64-w64-mingw32.tar.gz/sha512/6b926a87a3470796eb111e448c459a8ff1267533513f14d58f6e08cbebfb3e838c114827fcf39298bcefe8d76b8578bb4d3903c848bfafb0590022e6a49b2a00 -curl-8.6.0.tar.bz2/md5/4418e0d94f29d352afafdab445e37a3d -curl-8.6.0.tar.bz2/sha512/726fe7e21f8a2a925ab4ab6fe4e4ad099105f00656bfdc702beec12e1549ba2cb63d908d1d19f43b90feeb1d950ae5a6ac9a72a27447f5acf1907df396d1823c +LibCURL.v8.9.1+0.aarch64-apple-darwin.tar.gz/md5/8a1929a2dc1a6682ff9ff7f66cda25f4 +LibCURL.v8.9.1+0.aarch64-apple-darwin.tar.gz/sha512/e491542103f6e1a34caf96cfae7f31ba12588c50517ca2c974be907c664cd873b554009e538fd7db7d31ebe46d68330da3fcf14ffe9fcbbda73b6d1919ea966d +LibCURL.v8.9.1+0.aarch64-linux-gnu.tar.gz/md5/eb5f8fdb31189047527af3b98c6959b0 +LibCURL.v8.9.1+0.aarch64-linux-gnu.tar.gz/sha512/6fd5e489f63edec29efd20165b0888e86d0b53a19d352bebbdb0afc00a1f6478eec524143797307ab7a799cf924d2c76bd5ece9d9fd8fdc9346ba3c739a1fe83 +LibCURL.v8.9.1+0.aarch64-linux-musl.tar.gz/md5/6202ec4890ae02cf2a7999fe5e24d77c +LibCURL.v8.9.1+0.aarch64-linux-musl.tar.gz/sha512/caf00ed30075d000efc638586520dac2e22f8ba04924d42dbe27bc1bd715aa7b2dbede062de296fc080a33d0aead6099a870f38d017a69693097413056629b1b +LibCURL.v8.9.1+0.armv6l-linux-gnueabihf.tar.gz/md5/5bd474f4e09b4fe7658b2497861a580e +LibCURL.v8.9.1+0.armv6l-linux-gnueabihf.tar.gz/sha512/ff6b58cfff9a7433d9191766e3fe652f0b5b10fbc6da8fb03ca04ed44a46a36158fb7d8096932617011389fb5505844d5c4ef2c29bcf1c8da811287def4e91f9 +LibCURL.v8.9.1+0.armv6l-linux-musleabihf.tar.gz/md5/8f071c5389ba1df7d4d22683f068b6de +LibCURL.v8.9.1+0.armv6l-linux-musleabihf.tar.gz/sha512/b8be3a8df717d0921ec225ce87dd9cd4fc9e13fd1f39c4906d02f30dcae24971f1798b017f3af346c603030cfa80869c117cdb5dff8e7762ee2e72c4027ef7a1 +LibCURL.v8.9.1+0.armv7l-linux-gnueabihf.tar.gz/md5/120e51d99907522150d79c44812decfa +LibCURL.v8.9.1+0.armv7l-linux-gnueabihf.tar.gz/sha512/b512a75cb3185904661375760250132c58678f43002a9ba0608de60dcca6afc1e2eef567a9f42f2d3dfa0be1ff01cb15f68980adebada220728521b13367b77d +LibCURL.v8.9.1+0.armv7l-linux-musleabihf.tar.gz/md5/e8a59894ccb325fb424a3e5861c854f7 +LibCURL.v8.9.1+0.armv7l-linux-musleabihf.tar.gz/sha512/3bb4afef9b7be04f17a4e2e20e020bcfbf5fb4a36bc699a90337d76a108f75600fff49c877652956431946a948f42054497621593f1c6c593a537fe08ceda1c2 +LibCURL.v8.9.1+0.i686-linux-gnu.tar.gz/md5/1034cd95f6369cd994979c8653786639 +LibCURL.v8.9.1+0.i686-linux-gnu.tar.gz/sha512/5f7f755d17770dc8b995f2bbc817fda96db23da751439e5929526482b8f854f4ed73c6e930df0dd1657756f8951edd4f3c41be80f3b812a793678b6ededd855e +LibCURL.v8.9.1+0.i686-linux-musl.tar.gz/md5/ad4a4cf21d15b48ce27275af67079075 +LibCURL.v8.9.1+0.i686-linux-musl.tar.gz/sha512/9e5c6d0d91d966154e3ecd8cd71c9b31841debc036b847dec684dcf3189ca617cd0bca4b73cf9440e55133e36ebafb02730c598c133dc33a9e164ba43c689506 +LibCURL.v8.9.1+0.i686-w64-mingw32.tar.gz/md5/300a71d7ba8c858f9ed85d761dfeef32 +LibCURL.v8.9.1+0.i686-w64-mingw32.tar.gz/sha512/a916f60a7c8ed41a56686d1145be73dc0162349ce1d098dbd12441fcc97a3f0bd4c5750d3e58e4cfe7e9ba7e0d3817bf592bd99a946cd6b45b296636c3220766 +LibCURL.v8.9.1+0.powerpc64le-linux-gnu.tar.gz/md5/0657e472b888b089c448695d200346d0 +LibCURL.v8.9.1+0.powerpc64le-linux-gnu.tar.gz/sha512/a81f25260c4204a069a87463d9ef58169d9286125daaf23b4e2295fc8108ef536049fd07248ca3f1caa2aac3eb0b376d2c64281d0302dfea6f0a782dfb3988fd +LibCURL.v8.9.1+0.x86_64-apple-darwin.tar.gz/md5/3638b3365e97dd516d1eaa6f03892fe6 +LibCURL.v8.9.1+0.x86_64-apple-darwin.tar.gz/sha512/4e6c76fde045134c869dbaab52b28dc809541209077aa54d2e870b9aa29f3d43a8040f3194e06e519642348fc4de6aa49fcb04880a4707bae4e55206ac70f01b +LibCURL.v8.9.1+0.x86_64-linux-gnu.tar.gz/md5/e48dd6fe9078600bf6db0fdd6f986b76 +LibCURL.v8.9.1+0.x86_64-linux-gnu.tar.gz/sha512/e6c33bdac80c9463d6d067f77cf7f2f595258e5f292fd133b5f5782e678004bed925c8bcbba1c708f2f535a0db7a0527fce9acef5250469a958ee11dff533c8f +LibCURL.v8.9.1+0.x86_64-linux-musl.tar.gz/md5/2d219b4c0ba83dfce64b93c1e4d6ef24 +LibCURL.v8.9.1+0.x86_64-linux-musl.tar.gz/sha512/5fb8bb08d357ea3b7c9e417838bf37198ae673185c4f4564ecd1a06ce0e72c4c804909e8c6ffeafefb3460ad151308f662b3128ab5d4149f035de0fa9890506b +LibCURL.v8.9.1+0.x86_64-unknown-freebsd.tar.gz/md5/66e715f6934f360398e527f534f6f5c5 +LibCURL.v8.9.1+0.x86_64-unknown-freebsd.tar.gz/sha512/64334fb156c15b7aa56e4ef81b9d81f93be6ee4c7a61d921bb09cb9951eeb3309197ac89150bde0187e7cecd6e53626e91b7bba14f0daaa0ba472563541c9ff1 +LibCURL.v8.9.1+0.x86_64-w64-mingw32.tar.gz/md5/672ffcacf3e1bc72d7cf244af0cbc5a2 +LibCURL.v8.9.1+0.x86_64-w64-mingw32.tar.gz/sha512/ea265d172a242026cbf7e6b991904aa403a7f491a1c55f91b444776782ad0ca2fdf4882735d1ed04e90df8b38a754f4d0181ad8c17f5fbd75b40a6b908ebbd36 +curl-8.9.1.tar.bz2/md5/8feb255a16590f2465926d7627f86583 +curl-8.9.1.tar.bz2/sha512/27e4b36550b676c42d1a533ade5b2b35ac7ca95e1998bd05cc34b5dfa3bdc9c0539ec7000481230b6431baa549e64da1b46b39d6ba1f112e37458d7b35948c2e diff --git a/deps/checksums/libgit2 b/deps/checksums/libgit2 index 629a5f0601fcd..0a8d2a39ffc86 100644 --- a/deps/checksums/libgit2 +++ b/deps/checksums/libgit2 @@ -1,34 +1,36 @@ -LibGit2.v1.8.0+0.aarch64-apple-darwin.tar.gz/md5/c19f3a4f6567b7504f607fc6f328312f -LibGit2.v1.8.0+0.aarch64-apple-darwin.tar.gz/sha512/0a776ab3eb4593abe0f2198a7371cbcf653ac5cf71ab7af9d5520c2bbbbbc981cf07ba3afa70f1ef6ea56f81e2d4b33b1be1482f9e215e61178b3dd1149ecb80 -LibGit2.v1.8.0+0.aarch64-linux-gnu.tar.gz/md5/8137d530bea16d41a614983068c1909d -LibGit2.v1.8.0+0.aarch64-linux-gnu.tar.gz/sha512/bdcb6249acd8df887a8af7c084d409132694a39f5e9f90bd70bba0f3eba2bad3eab6958cce9f060b2a4392d99352ccda8be92000f24ed4498c85ba55e0cbf13f -LibGit2.v1.8.0+0.aarch64-linux-musl.tar.gz/md5/4b9508ea58d4b1bd99f8471bd7c9a839 -LibGit2.v1.8.0+0.aarch64-linux-musl.tar.gz/sha512/e0996627a3d3ab9b3b1d103bbdd3e1179ede5479816f6b1be54471f120f76fe0495d3c7587c382985173c0614b634903b58c67ac3badbead82b4d797cc5915d7 -LibGit2.v1.8.0+0.armv6l-linux-gnueabihf.tar.gz/md5/02d6fae1745562cf724190929383688e -LibGit2.v1.8.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/11c14c5f395252143218a495c7dd2817c8f18f73320200a521f5ccd5f0c3c87403dee2c3b9e8166022fde1a67e83cbb83e6f222aac38b41efa43a6c0254548a9 -LibGit2.v1.8.0+0.armv6l-linux-musleabihf.tar.gz/md5/afa7b90751565b865f443b5a0a870d8b -LibGit2.v1.8.0+0.armv6l-linux-musleabihf.tar.gz/sha512/3594c223883a7da3bc0c78ae656fb15e47cc9dd196cf08f0abc0a1fb5f799842261e125440c07e92ba82896ad7427814bb43b63ba64d9b72ba38e9149132c26b -LibGit2.v1.8.0+0.armv7l-linux-gnueabihf.tar.gz/md5/ead27583a1cc5748c84d58a07fa6fc7e -LibGit2.v1.8.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/c81c3582fda7b299aaed72de07e9d0bd06c0c231aed73bb980c12c89b2b7593b2fb7990421bc2e45173f3d107ab50660842289675efa31f24ff752f0ebc63875 -LibGit2.v1.8.0+0.armv7l-linux-musleabihf.tar.gz/md5/71e38f112e8629682cc383c510f1f13f -LibGit2.v1.8.0+0.armv7l-linux-musleabihf.tar.gz/sha512/0b4b2677bdfc4f8e2a5ef3b9adf8fa2c0c1e76bd240b2173c268835b59cda29cbffc4241319fe36dcd63d1507ecf0e0e843f48fca80e3fbe4d3df53601ad7dec -LibGit2.v1.8.0+0.i686-linux-gnu.tar.gz/md5/b54cdd02201c1481746ab81db6f39aac -LibGit2.v1.8.0+0.i686-linux-gnu.tar.gz/sha512/0496a607b0d6841fc0c87477274b61eb95afa24d48d2624f8aaf230028a24d0248336902b01a326010fdbc45d8d73eecedb14c82313e1b1a94b3b6a4296e2607 -LibGit2.v1.8.0+0.i686-linux-musl.tar.gz/md5/b8946f9c1b83a7c22b2a8ca6da05b23b -LibGit2.v1.8.0+0.i686-linux-musl.tar.gz/sha512/931ff27da4e35749a5c020af72b750dce0b1d672cd98c04ad5a340f4f33ddb61c4df6711c36c6601063262fb733d45a3bb24eb1141e9d2fd2e0ab7b9bfbf54c8 -LibGit2.v1.8.0+0.i686-w64-mingw32.tar.gz/md5/cb9db0b590efe0c60f6e2f9558de4e5b -LibGit2.v1.8.0+0.i686-w64-mingw32.tar.gz/sha512/b9f637ec10cd751dfb2156e154a68809af400cdecbf0d25910792937c63ea56e60b703c7b78e3038ab34b1100bb20df79dce6346f40f1d24e5188fefe9517ccc -LibGit2.v1.8.0+0.powerpc64le-linux-gnu.tar.gz/md5/4ac1fa6b1ca43d3f6e97d590d1d27127 -LibGit2.v1.8.0+0.powerpc64le-linux-gnu.tar.gz/sha512/5cc3b9b9d85068bb3c6711c63ccb2672be765888a114147f70cae0eebf96f5bde00a40f163202c20e18a4cf4af2488fd1c304060daa3dd35748b30ab5a1fdb1d -LibGit2.v1.8.0+0.x86_64-apple-darwin.tar.gz/md5/26c2d1dcf68bc7b9919dfd24eb2fabc7 -LibGit2.v1.8.0+0.x86_64-apple-darwin.tar.gz/sha512/9c3ba94c438682f321cb2130f71028587a4a21b960f94f8c3f633dbe007210ff1b7b5e0b0bc4972e818458843a47a9e8d50d88f1bd3fb03a8fe129fa66332a38 -LibGit2.v1.8.0+0.x86_64-linux-gnu.tar.gz/md5/8d48ad388cca20d6338095cf8a36c3c9 -LibGit2.v1.8.0+0.x86_64-linux-gnu.tar.gz/sha512/9ddf4dc7420a9129ff8c34eb07ee94d9213c1a1c22700521199032a773353ab2413fd70d002b273a06dd951558128cd5577b7e917de6575d379911831d737bed -LibGit2.v1.8.0+0.x86_64-linux-musl.tar.gz/md5/5d9fd50bdf38ec99311e9627f254b95d -LibGit2.v1.8.0+0.x86_64-linux-musl.tar.gz/sha512/eae36cc70cb414e15924c22c9b03a98949b89fd8ca429fbe23fa215253266ed4cd11530adb2feccc9a19299ebf2048f1f5929c1faffba463b593b6c3e1808bee -LibGit2.v1.8.0+0.x86_64-unknown-freebsd.tar.gz/md5/af9e9d4bbe0df291f07f41416809a6f2 -LibGit2.v1.8.0+0.x86_64-unknown-freebsd.tar.gz/sha512/859786f13ba1fb5cd448dd5f22ebdf3381f5290d4875d65840fb31567ccd012f283a1849a82f2b2f58c3d73eda4c748d3da07d84a99665e0f50aeb39c37a4fb2 -LibGit2.v1.8.0+0.x86_64-w64-mingw32.tar.gz/md5/b51e3e238d776d52e396dd749f895e4f -LibGit2.v1.8.0+0.x86_64-w64-mingw32.tar.gz/sha512/2581d4b1d6fd4d0f15b406f050bd8a2a41e13dc2a1699a9b956e56426778beb994e6552988bf50ddad682349209a8694eace9450dab0570434cdfbed9c9f0b24 -libgit2-d74d491481831ddcd23575d376e56d2197e95910.tar.gz/md5/2420def04a290dd7ad0e67f93789f106 -libgit2-d74d491481831ddcd23575d376e56d2197e95910.tar.gz/sha512/496c6640d2453c58b66bc53c6e4e9e84f48d89eb8f240aefc1eea7e2d19b6c601614764590f2d2ca9e51e7e1de8fcdd5bf67f27f32bab628eae40d26ed382048 +LibGit2.v1.8.4+0.aarch64-apple-darwin.tar.gz/md5/a2bca9483d0468b6836304068a8f8d99 +LibGit2.v1.8.4+0.aarch64-apple-darwin.tar.gz/sha512/bbc150e8c330f3cd666136334e15cfbd1017174193b3ece49b1c701aebd2774ef1b23e5e59ec8b05f23788db2ed8a3f103d7ff0fac364966eb5b5b2d814ffd22 +LibGit2.v1.8.4+0.aarch64-linux-gnu.tar.gz/md5/55f133dbf3a1e5ad37c69df3ea6b2274 +LibGit2.v1.8.4+0.aarch64-linux-gnu.tar.gz/sha512/c6f5a25f9b47be391f438867f076ed5b2539ddbb6542119b8225d52c7767705cda499940007b1f33801288426408a2d5ca3feb743e898b747fe0051df5ca7ad4 +LibGit2.v1.8.4+0.aarch64-linux-musl.tar.gz/md5/660b58d4e23b5f142731ccfcffff7b39 +LibGit2.v1.8.4+0.aarch64-linux-musl.tar.gz/sha512/e5d3add19efbbb59c7b79298b83d6342f70b2ad9415ead9460d9e78e117f2a98417a96f49ebfec62e2c18cf9519114e829c2d492e08c45b501aa25552ed97722 +LibGit2.v1.8.4+0.aarch64-unknown-freebsd.tar.gz/md5/67797f9177f007617b2e027673277453 +LibGit2.v1.8.4+0.aarch64-unknown-freebsd.tar.gz/sha512/1dff62cf24e842d978638ca0df9d67e0ed11250b6cb432880aad4603f292c456fcca10b6af304ed19954c22d24bcd8d3fe32e48c45bc2ea348d58eaa0ba6a1ad +LibGit2.v1.8.4+0.armv6l-linux-gnueabihf.tar.gz/md5/cc3264f393d133f9d34d796a1ddccac2 +LibGit2.v1.8.4+0.armv6l-linux-gnueabihf.tar.gz/sha512/8479dda021511747c6ef432eb9a092a54b2fe402e9010b5500faf01be3f2c4f6121fbb45849d6ba5e6a0f57318d6065956c58a5b5ea849e38b056d011ea0588d +LibGit2.v1.8.4+0.armv6l-linux-musleabihf.tar.gz/md5/4427150daaa544d04c0fa59b1b326831 +LibGit2.v1.8.4+0.armv6l-linux-musleabihf.tar.gz/sha512/b2a3cfd08022d012bb27e17bc4d67a0a1c09561420043a96111d029e582be0fdc619fe5227532ab7a902a5d43b5ef4ba1048d2c437c5bc9ac347d80535b60d9a +LibGit2.v1.8.4+0.armv7l-linux-gnueabihf.tar.gz/md5/f8afd5a5b5702dd0015829753244d223 +LibGit2.v1.8.4+0.armv7l-linux-gnueabihf.tar.gz/sha512/986f45f15b66109f372b41a2af2a6c4a7e03edb11ec4ad1cefba0c4cf16a6ddf3b490ba7d60e92a1f2eae91bc550f8d792f1ce66df64e0e2b3c66fbb6ff94cf7 +LibGit2.v1.8.4+0.armv7l-linux-musleabihf.tar.gz/md5/02534a7e25196d3cd504a6ef2993d051 +LibGit2.v1.8.4+0.armv7l-linux-musleabihf.tar.gz/sha512/31ba2fa0c71da0812fdadcf056bfd235379dc4d6960624a9b487bfcef2dd3b0ef3a618e7ed72850fd9e401cae0a143158c0ac48f6526c4845d80d2397eb08fb8 +LibGit2.v1.8.4+0.i686-linux-gnu.tar.gz/md5/0e73f9c928a69a552539f6aab5d44b0c +LibGit2.v1.8.4+0.i686-linux-gnu.tar.gz/sha512/6cca444bcfdef691cbd8ea249328a9f066a20ff23ac71f238a62d32bf40d236d4b4f6cb6d48862652b97791bd199bbf7f8851361ec2778c779a59168b0e08c01 +LibGit2.v1.8.4+0.i686-linux-musl.tar.gz/md5/a6cdca1ca0926ceb5827205005e80759 +LibGit2.v1.8.4+0.i686-linux-musl.tar.gz/sha512/37a456b7a31ca9a482976d3a7aab463dedaebf48aba1d16be5aceae2dbd9051679a0287776a93eabed70f6e9bb89ed4084564a88ed83e1d6a085ec6e32111be5 +LibGit2.v1.8.4+0.i686-w64-mingw32.tar.gz/md5/5ffb5489354195b163c55a6a83d059f0 +LibGit2.v1.8.4+0.i686-w64-mingw32.tar.gz/sha512/81423290e6122210102166b5878e6a101fde2dcdd16de2dea016a682d8aeb13a9db04230d0b6358bec3a8fb8db543b89c3b720c5cdf3418471e41db74bdff993 +LibGit2.v1.8.4+0.powerpc64le-linux-gnu.tar.gz/md5/d99482bb86f1347c83c2795ec10ed551 +LibGit2.v1.8.4+0.powerpc64le-linux-gnu.tar.gz/sha512/a52b1141c1562f7ff55e29e41f95791645f4cca437a8ae09842239a2c132b3b4479edf24abb907d4674b04ceffdc0003dd5d8314697a96b73580ae0cebb59ac1 +LibGit2.v1.8.4+0.x86_64-apple-darwin.tar.gz/md5/f385317d44621ba48d296ffe39d74250 +LibGit2.v1.8.4+0.x86_64-apple-darwin.tar.gz/sha512/25d6fd31a4207d0890b93aa30f98c430d349cfa3c4759e3a81254c39ec095162c916a6fdc6d91ca4b3df3892ac8836209d0927c3ca18b4dfbe5b067f5d79cae9 +LibGit2.v1.8.4+0.x86_64-linux-gnu.tar.gz/md5/9f881bf0428bfbeed1fce06fce156a3c +LibGit2.v1.8.4+0.x86_64-linux-gnu.tar.gz/sha512/ea6e90997ae1dd77cdf73b65995682d3b2563e40215b7316f2cc17982f8a35ac8f40d194d8d25c1a7334cb8443ec028516d05e64b841559b0c5dc15ce289e238 +LibGit2.v1.8.4+0.x86_64-linux-musl.tar.gz/md5/349b44527421615d99c08dca5299bbb6 +LibGit2.v1.8.4+0.x86_64-linux-musl.tar.gz/sha512/809c53ba91a3643ed534c49b1e3352ef8e6cf642dbcd45e21b7d2a2e4edb8235d2d35245c4e891362a2597c9b724cee93ec885c50259763e3d06f2d82cdbe3ee +LibGit2.v1.8.4+0.x86_64-unknown-freebsd.tar.gz/md5/01bb75c5eda895d47a55b9a231c0977e +LibGit2.v1.8.4+0.x86_64-unknown-freebsd.tar.gz/sha512/ba4ba6e681faf3d768d6a09d6ad0f82934fcbf635d42d4e92a9f0a2d545733757cebff759a720d79981eac8046f278c17b9ea982db3a0b7b774af686b790960b +LibGit2.v1.8.4+0.x86_64-w64-mingw32.tar.gz/md5/37f1e39363db20979948f9a1ebdf312f +LibGit2.v1.8.4+0.x86_64-w64-mingw32.tar.gz/sha512/d74108deed353ec26a56d020f533bdc35a881d640d621292e08ab259461f132e19afbdfee0e21915e6f54b7f0debc9cf4f5959d711104534e0ec85d3fe3a0ac1 +libgit2-3f4182d15eab74a302718f2de454ffadb1995626.tar.gz/md5/c502ae54871bd3afc0bd593a5cf05d68 +libgit2-3f4182d15eab74a302718f2de454ffadb1995626.tar.gz/sha512/7381abb66b42d8b667be12afa360a855627149d1f293a3091c05f02a528fdcc9e44fd7a5adebba8b30ee4ac1f4d1f029a2f0d0b49ada97a751159e0a61f8a54e diff --git a/deps/checksums/libssh2 b/deps/checksums/libssh2 index 697601a037132..fa05f325fa6a7 100644 --- a/deps/checksums/libssh2 +++ b/deps/checksums/libssh2 @@ -1,34 +1,36 @@ -LibSSH2.v1.11.0+1.aarch64-apple-darwin.tar.gz/md5/462442a50f5dd719d251f65e7170dbf6 -LibSSH2.v1.11.0+1.aarch64-apple-darwin.tar.gz/sha512/8f0d9916c1e1abb8ba2d4baef0f850f9f5aa8d24f5eeefd7c7d30697b15d33180b32588f50328f4999e1d4136a2951c4e3319c5a5dca6f34a84fba30ac90518f -LibSSH2.v1.11.0+1.aarch64-linux-gnu.tar.gz/md5/63d8a681bcce23e76650719cf3c6999b -LibSSH2.v1.11.0+1.aarch64-linux-gnu.tar.gz/sha512/9dc722d866d27f378481e4787a5bb932facc0c7b828e75e812c9c875ac10e7194d090d94e01a46bb2b3c5624e18d013f0226c5f574269df96f1de0ed16897571 -LibSSH2.v1.11.0+1.aarch64-linux-musl.tar.gz/md5/e85cfee900145726857d3609b541f7b5 -LibSSH2.v1.11.0+1.aarch64-linux-musl.tar.gz/sha512/ad42ddf4674f6359e61fb23ef6fb5942e716c6f0cd50378e93b8c3af799b9b21cc9cefc471d27e19bc31686c7aa469a5ed81918ea9926d5d432c3c5f70e83fcb -LibSSH2.v1.11.0+1.armv6l-linux-gnueabihf.tar.gz/md5/acb3b46ec386e9d41dd73cb3c9b60d1e -LibSSH2.v1.11.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/bddc50ab698c280256d819cd7ea1a39a33366f2eb6004df6b66f6a45ce4b5bdb1525f724aee35f3b9796809f9e68db4a6dab01ab035c8a88bec291b59fd55854 -LibSSH2.v1.11.0+1.armv6l-linux-musleabihf.tar.gz/md5/d4efa89a3b4e1d3be80f6790e183ad07 -LibSSH2.v1.11.0+1.armv6l-linux-musleabihf.tar.gz/sha512/8da36af6514189b7bf3422ccbbbf69d271208e7d9b0af469cbbd476ddd3d62f2f9a0d25f38f22123a603e448c285936f0692a31d91d6d79dfc66baacb8af4522 -LibSSH2.v1.11.0+1.armv7l-linux-gnueabihf.tar.gz/md5/d4eeaf06f64997a4f46737798c15ccb0 -LibSSH2.v1.11.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/4cb24ec2b13c9f56220a6cd3bb0ea1dda687a7ebbf062caa8fad9d17c903a2982f12340b93e82b42567e29b4326acda373f81c0ebb4f4d968a12ff7807f5d066 -LibSSH2.v1.11.0+1.armv7l-linux-musleabihf.tar.gz/md5/319db985d453fc32a69eaad85bdbeac4 -LibSSH2.v1.11.0+1.armv7l-linux-musleabihf.tar.gz/sha512/5f7f35e3cb1362ecda3236c1686a211409937e90fdb29dd9e4032d541b8fe45c28f24067cd012edef879d668d7b1040e887ea594eac03ffe5412d5f2c49cc294 -LibSSH2.v1.11.0+1.i686-linux-gnu.tar.gz/md5/e7cb7d9d6db13b46250da30969f8504d -LibSSH2.v1.11.0+1.i686-linux-gnu.tar.gz/sha512/fe8983aa012787361cadb5a78df8eec6ac5640a514c3fe4b4ab23d584b018ba4fa7d3514f0951d2b687cf56bf9ee17e247049d99a4e9360aec4ecbb636d2a6f1 -LibSSH2.v1.11.0+1.i686-linux-musl.tar.gz/md5/d7c5d3e8ecd86e216d97d4912457a66c -LibSSH2.v1.11.0+1.i686-linux-musl.tar.gz/sha512/4d64996d837cfec15b42ca7f850cda32ee3b3a8f93001d24f95ff6f8c94b76517e5dfc7e525e8335fc8788ecf7e196bdb7cc64c8c53f536c592afb337d98ee82 -LibSSH2.v1.11.0+1.i686-w64-mingw32.tar.gz/md5/9562e41b5dda94c23150668559e9b123 -LibSSH2.v1.11.0+1.i686-w64-mingw32.tar.gz/sha512/d13d022ec9eb82f8afa3954c730bd1840a8d1bb16cdbd07a89fff6ce07b1c0c2ba6a9e934b2585abf7dddcb0522e1ba0f38df4385447c66986d5fcb6dddc2d15 -LibSSH2.v1.11.0+1.powerpc64le-linux-gnu.tar.gz/md5/4e2463eb11a5dde8c3e0d3fab6c58169 -LibSSH2.v1.11.0+1.powerpc64le-linux-gnu.tar.gz/sha512/d8794571d051cf206da87a4f7f0f71c8b41be061691b08333df7678c4e40fb9abbe63812a5ff5243fabca9eb2e599d81a69520cd854afbddbc16b44678fbe1b7 -LibSSH2.v1.11.0+1.x86_64-apple-darwin.tar.gz/md5/5729492b3a91e0d8e3fcc459de784157 -LibSSH2.v1.11.0+1.x86_64-apple-darwin.tar.gz/sha512/8e49b2ff1c9b5ae499f14be238776d7da2b64231592f1d46a6f769f200681342ff157d76102fa7c16b2972c7fe603919f7d2ce7c8a30b46c98ecaf2ef809fe3c -LibSSH2.v1.11.0+1.x86_64-linux-gnu.tar.gz/md5/0f7f2214d453f562107fe22af5004e8a -LibSSH2.v1.11.0+1.x86_64-linux-gnu.tar.gz/sha512/bd510f25dc26c05362ff204adcc356521bfdacd665411a99e07071ea0c4638274a2e78f009644cdf5e472a1d81c80e353f4673071d90411e6122b55160140f3e -LibSSH2.v1.11.0+1.x86_64-linux-musl.tar.gz/md5/ee98538d67b8b091c4ddcf632e72e7d1 -LibSSH2.v1.11.0+1.x86_64-linux-musl.tar.gz/sha512/38cbb59ffa420e4299db848b6ae95098e8e3e6e1334e05369089d17b04fcd0787ad22ba69465611f3e335a1efab228990db776916f40a937b21b18ca511a4484 -LibSSH2.v1.11.0+1.x86_64-unknown-freebsd.tar.gz/md5/0abe5a971abe63c3db4353e7e9b181e9 -LibSSH2.v1.11.0+1.x86_64-unknown-freebsd.tar.gz/sha512/8e8199bc0634a8ec51460cb8628c3b33d765b7060ca79aac3e80a0b29d55de5562cdbb36945b4a9feab5392f7f16d2dc48684e43d54c62a9fdb1f07f36b71810 -LibSSH2.v1.11.0+1.x86_64-w64-mingw32.tar.gz/md5/d30fc8e9b74388a1c642cb15ed33dba3 -LibSSH2.v1.11.0+1.x86_64-w64-mingw32.tar.gz/sha512/e278b87d081fbbe15f88bafa8870f0f294cea3ff8c8c1fc9a6c10228da91717aa3caa268cdb10f78c8e55651a90243962f85101eeb4433f85c1dfacc1461d96d -libssh2-1c3f1b7da588f2652260285529ec3c1f1125eb4e.tar.gz/md5/7b52de6ff70e16aa78cd699fee3e997a -libssh2-1c3f1b7da588f2652260285529ec3c1f1125eb4e.tar.gz/sha512/7c99d33e60862e2d89bbcc4a09ffff3fbfb921ed674e0d3166a255c72a8e0622a9c6be64f0eb2f8c12ddd80da0307b05d761615b876194bd854aa2c62e26f4ad +LibSSH2.v1.11.3+0.aarch64-apple-darwin.tar.gz/md5/87ba86e78421d6195aa6a46129ff61d4 +LibSSH2.v1.11.3+0.aarch64-apple-darwin.tar.gz/sha512/2b7129be9e9518337f59857474882a6a3448f358c931c66ab9f9ec67506c68d2356df591bd45925154844ca0d6f6e1f071d4c54d62039c5078b468fcb356187b +LibSSH2.v1.11.3+0.aarch64-linux-gnu.tar.gz/md5/84c6eb68e7797038d0863513fa4e292f +LibSSH2.v1.11.3+0.aarch64-linux-gnu.tar.gz/sha512/3012beb35fdf94136907037e8f5261a5cc94d102f461172321d4ed8f328da3789d521513dd03cb344c6fcb73675cd1d3ede606bf9a904fb811d40c43fd09d8aa +LibSSH2.v1.11.3+0.aarch64-linux-musl.tar.gz/md5/5a49057201e779f3427b794b72bf07a2 +LibSSH2.v1.11.3+0.aarch64-linux-musl.tar.gz/sha512/62a812efb4ad7b24bfeeb3bb89756004215c09a1cc01e0530f14ce4b8546f1dcbbac18155ac2ce08311c1790d659b14674e3bb3549ff68d1209d52b5e5986fff +LibSSH2.v1.11.3+0.aarch64-unknown-freebsd.tar.gz/md5/a5129167b7be7ac8ba2c873e164afb1b +LibSSH2.v1.11.3+0.aarch64-unknown-freebsd.tar.gz/sha512/f8d9cc5098a3b401fbbe98a24efaca0ea46f533ecaf11dbfe8f7e7e3853363af19914de62bd1cb5a573e55e90d5c6074532ddc6d64723c9e235b277f438ce6ef +LibSSH2.v1.11.3+0.armv6l-linux-gnueabihf.tar.gz/md5/5c59c95612bf9aa172e5d487002db509 +LibSSH2.v1.11.3+0.armv6l-linux-gnueabihf.tar.gz/sha512/5ba41e49365c2018d55c92e4a23d806ca9ab960a448593b08380527da21eec03f76cab89c34befbc56f4104002aa189d5cae6f655797f1447f395b51a14d40e2 +LibSSH2.v1.11.3+0.armv6l-linux-musleabihf.tar.gz/md5/4bc27411f0eddf82a787d1ede17ce2c3 +LibSSH2.v1.11.3+0.armv6l-linux-musleabihf.tar.gz/sha512/d6024b6949ac6867c56c66defbb99300a5661e0c73da6c330165bceba78d64063986c8851601ca74554b27944d5b02e3f602b1e71781097bbb8b12effc0cbbdb +LibSSH2.v1.11.3+0.armv7l-linux-gnueabihf.tar.gz/md5/40e1a0d323969b96ab121eb5a3ecc874 +LibSSH2.v1.11.3+0.armv7l-linux-gnueabihf.tar.gz/sha512/67ce15a5b1c1fe0fd1096ed5d2d9f44d83983de11c1bc651f5914d70d387a99ee6bde31716031b758f48981e2a9383599f077f02d61a5c783ee6d09a7bf445db +LibSSH2.v1.11.3+0.armv7l-linux-musleabihf.tar.gz/md5/9453c52394b1b06bd36c43e461a3b48f +LibSSH2.v1.11.3+0.armv7l-linux-musleabihf.tar.gz/sha512/c62068ecb1b88dbd08a2474e0b93cd313bdc4e1407a22cd9164a73b2d897564f12a3c34f6fc492b264af579b00e9335a0fe1fa853fbe0fbb18d8335b77d409b2 +LibSSH2.v1.11.3+0.i686-linux-gnu.tar.gz/md5/992453b1c59033aefa8d98b89f491ff6 +LibSSH2.v1.11.3+0.i686-linux-gnu.tar.gz/sha512/ebf14565d614086c4401e1a997a3aacc83f8e499ed836c429f87c4f95f1c8409713fad47f1c34a2b1cd23f90de3daf14caafba3c82b15642018592213607c874 +LibSSH2.v1.11.3+0.i686-linux-musl.tar.gz/md5/e0cb0566c724c107f4f04619080d4c0c +LibSSH2.v1.11.3+0.i686-linux-musl.tar.gz/sha512/af7d08dba5bb06eaf7ce8aeb12b69701d3c2829996a1c8e68510c106402a1166ad060687987df49365c26d30e8d6511c66f2a50ec810a493d2c090931ccf05a5 +LibSSH2.v1.11.3+0.i686-w64-mingw32.tar.gz/md5/c5e8d3145deb56d6df008522a5d3ea6f +LibSSH2.v1.11.3+0.i686-w64-mingw32.tar.gz/sha512/47f3c36747d2e42a4c0669ef468d395078328235d30056b7d67d76bd737b5118c1bbc720aef455c4d9017e7b9350e8cc043ed28264ea8a9ecb6833ca517f82aa +LibSSH2.v1.11.3+0.powerpc64le-linux-gnu.tar.gz/md5/12eba4aec5e320a4d0cf09225bca3f7c +LibSSH2.v1.11.3+0.powerpc64le-linux-gnu.tar.gz/sha512/d6b8413d77d8af3d29b867692f6c02b63e793f5e8f17c4777756d247c8e602b3ab87380031aefa60f2c3ddae5a3c7a1f1c739439f149db34a32c79f32e08048b +LibSSH2.v1.11.3+0.x86_64-apple-darwin.tar.gz/md5/f6e7cd35e16290b198c80c61a0fca5e5 +LibSSH2.v1.11.3+0.x86_64-apple-darwin.tar.gz/sha512/2c83814ef6ae78ec94a43f2997151dd7195c0a0f9cf456fcd3f780268bd1cbdd7ea55182fc5a1f8e1413c26889e54fccb01964b0b91dd4b925ecaa16b7df8d07 +LibSSH2.v1.11.3+0.x86_64-linux-gnu.tar.gz/md5/95aa96befc9f9007e6a000a95c1b7572 +LibSSH2.v1.11.3+0.x86_64-linux-gnu.tar.gz/sha512/6058dca6d933afb7fe5fc3374937b4432f202a5dfe3ebcc2f91f65777230c18d76801c38071f84f8362527ee08656a97f79da234ab5481265a7ccf29e94c20c5 +LibSSH2.v1.11.3+0.x86_64-linux-musl.tar.gz/md5/88b69d889d602bc3df420535dba30f9e +LibSSH2.v1.11.3+0.x86_64-linux-musl.tar.gz/sha512/7335954124074e7df786989db86e86e3bcf41f503b8e3b27d6ac18032c8025bec26180bd2c537b23349bcf5673eb67245531479b939670e620faf5aa13c8c4ab +LibSSH2.v1.11.3+0.x86_64-unknown-freebsd.tar.gz/md5/6d5f6e9455c35c5f6655cb4d46797db0 +LibSSH2.v1.11.3+0.x86_64-unknown-freebsd.tar.gz/sha512/9515d11bb5686e29eb5a37bbcb7ab07574da0869c82e5b3f0cf282bbc56792af31e6174521d58133968b997caa6db75ac9b195024144fd2c95fd1bbf689ebbf6 +LibSSH2.v1.11.3+0.x86_64-w64-mingw32.tar.gz/md5/e66cdac0c2d5ce2d160e482d780ad0c3 +LibSSH2.v1.11.3+0.x86_64-w64-mingw32.tar.gz/sha512/2dabb1e8da5ea496898751d5517ca37178e1a44c78c26fe33f87487a0b4acf7185f686ce8d6ea0e65e38a8fd56e5ff09fd70becda402a942b5e459707eb2a44e +libssh2-a312b43325e3383c865a87bb1d26cb52e3292641.tar.gz/md5/06d5e2881ac023583c7fd6665d628a87 +libssh2-a312b43325e3383c865a87bb1d26cb52e3292641.tar.gz/sha512/5dee8cce91853eb8c9968d7453b1ad0c3cd1411901d288f1731b7c7e4adf380313f61c2a66eee0d3b89eba79e420e13269bb3738bcf2c59f0b88276aa785fa8c diff --git a/deps/checksums/mbedtls b/deps/checksums/mbedtls deleted file mode 100644 index e52066b6f4bac..0000000000000 --- a/deps/checksums/mbedtls +++ /dev/null @@ -1,36 +0,0 @@ -MbedTLS.v2.28.6+1.aarch64-apple-darwin.tar.gz/md5/c97705b08c6bf695fa7a11a42167df94 -MbedTLS.v2.28.6+1.aarch64-apple-darwin.tar.gz/sha512/91825c3a495045ca74ceb5a23e3d7e9387701e401911b147d905a49892b1a5a9f22662a4f16a7f4468c5a807f2980b66e3409ea1ff7e04c6fdac0b105472e200 -MbedTLS.v2.28.6+1.aarch64-linux-gnu.tar.gz/md5/8ebaaeefd75c805227229086c262d0e7 -MbedTLS.v2.28.6+1.aarch64-linux-gnu.tar.gz/sha512/89983c1f9f9d7b901619522afcd12c6bc1996757edeb9f3012954992f82f3b36ae50f49dcf7731623fca197946e4281eecffdc29a5819f04e7f6203afd4eb93a -MbedTLS.v2.28.6+1.aarch64-linux-musl.tar.gz/md5/b40b2ba247f4ff755e15daad13c5a255 -MbedTLS.v2.28.6+1.aarch64-linux-musl.tar.gz/sha512/4cb4f2213b631dda0caa8baafa8effc9c8592c72a6a5b826fce060cd81f8f77c188c9ddc76595b47078db3c35b3043d9bf0cb891d822a940df87982de56dec44 -MbedTLS.v2.28.6+1.aarch64-unknown-freebsd.tar.gz/md5/51774d7907dc1a72d7c6e1b6cff02347 -MbedTLS.v2.28.6+1.aarch64-unknown-freebsd.tar.gz/sha512/b85292a75d4ba6fc3996ed497f0951f0dc0a3846e1df83f36b7d3ed3fc30687efdc1742848f6fb5a06e204fa9eb66837c8fbef16e6329f50763086bafef14fb7 -MbedTLS.v2.28.6+1.armv6l-linux-gnueabihf.tar.gz/md5/c6dd1cb1aba1075c73c41719a03c5ab5 -MbedTLS.v2.28.6+1.armv6l-linux-gnueabihf.tar.gz/sha512/981a8925dd90418150625e9467cc791e4a9d5223e7df6ead113ec41a279a5dd7e8ebcecb5b87611ef451fc6483fd6eb5bf984cf528037ad742e68b4be94e5c07 -MbedTLS.v2.28.6+1.armv6l-linux-musleabihf.tar.gz/md5/c30ed777bd74d269656f7e9bc8163765 -MbedTLS.v2.28.6+1.armv6l-linux-musleabihf.tar.gz/sha512/f04014181082561195caa4d3b178480bb5cce7f459d76aca8cdaa2f615d105b24871656ce4cbf8d9ec33f0424de35a16f12d4964a1f0fab9a416e5d18a468c94 -MbedTLS.v2.28.6+1.armv7l-linux-gnueabihf.tar.gz/md5/256f8327773ea2d0d6b4649541c34e84 -MbedTLS.v2.28.6+1.armv7l-linux-gnueabihf.tar.gz/sha512/ab4c9e82752386a0fd642a709bc90b712d6aaff78309968f1fdbf1121a790a9c0227ddd8e79373359cea9c75b21e762f600abea42036609571ba999531b50852 -MbedTLS.v2.28.6+1.armv7l-linux-musleabihf.tar.gz/md5/249ada3e9a7ad4eba08270e575ae68ec -MbedTLS.v2.28.6+1.armv7l-linux-musleabihf.tar.gz/sha512/0682e65f4257c3d237ba8cfc643be4430341888ec4cd17c2dc3018350aa7ff176e834a69ebc9d240b383a7aed439b34e45c237310ad66043956700b782323793 -MbedTLS.v2.28.6+1.i686-linux-gnu.tar.gz/md5/d0a176d2843ac780884395c90971bf68 -MbedTLS.v2.28.6+1.i686-linux-gnu.tar.gz/sha512/c2f96f314d0e5d9bffe46dc7d0adceb038db81e8c9d9a3c0fb0a237849d0d568d249e2df6c275d27a74a9122d0a53b38e5d8521807669a9c82bd67befbea169c -MbedTLS.v2.28.6+1.i686-linux-musl.tar.gz/md5/9c7501c6b04df53f8d56cd59dd42ae4c -MbedTLS.v2.28.6+1.i686-linux-musl.tar.gz/sha512/6fd35f9c2e1c5822920bc1d9315dc68b10694ee5507cc512868615c3d35dc389fa67038b9ab79fa86ea7ff6bf5f6f1eed053fafcc519080559057dcaff813ec5 -MbedTLS.v2.28.6+1.i686-w64-mingw32.tar.gz/md5/1eef46b3c89a81973778817a8856673c -MbedTLS.v2.28.6+1.i686-w64-mingw32.tar.gz/sha512/f202595cf971825601d5e12263eef0dd101e9be971d15592a12187f1d170fafaab358f02db89458f495ddc8922f66fbd662123b0d6df527fffa514e9f410784a -MbedTLS.v2.28.6+1.powerpc64le-linux-gnu.tar.gz/md5/fec1779ff02d71d5e94b3f1455453fc0 -MbedTLS.v2.28.6+1.powerpc64le-linux-gnu.tar.gz/sha512/e97ae38c555f6b45e33c023c7e07c982d36501f6c2dc36121bb73f2fb08db3fa3ab7f4ab0d9ecb622d25bfe1816eab3a6190d2034a05a66b7425c36a637623e0 -MbedTLS.v2.28.6+1.x86_64-apple-darwin.tar.gz/md5/6d44a0c126affaedad544460da9415ab -MbedTLS.v2.28.6+1.x86_64-apple-darwin.tar.gz/sha512/bf074429f32f51d954bc0c242fb4455ec6ead0e8337a3e5ab9e5b0df47d8a195947a488169f743db63d70b245be80084cd0d78f2211b6cd4b9524010b2c893cc -MbedTLS.v2.28.6+1.x86_64-linux-gnu.tar.gz/md5/95641af7a92c8c83d82264dd2275692c -MbedTLS.v2.28.6+1.x86_64-linux-gnu.tar.gz/sha512/3606ecd5a566e643cc03959a3eac9a45cb4c644006ee5820b852dfc22d40b85d75f5c018c46776954d92001986ecb49238058ca3d99340f9a689875b690aa6e7 -MbedTLS.v2.28.6+1.x86_64-linux-musl.tar.gz/md5/aee58ac107ca0d9e1eb5d7de8146ec8d -MbedTLS.v2.28.6+1.x86_64-linux-musl.tar.gz/sha512/86219aa5ba3280da39e91beded7455160c1ebc274c3158b9f0703a2c034756a9a9e51e5354d22ce983fcd026157d81f471446e6ee2743cae2663384e3e796176 -MbedTLS.v2.28.6+1.x86_64-unknown-freebsd.tar.gz/md5/67857ac031b10fb6a0620b453477653b -MbedTLS.v2.28.6+1.x86_64-unknown-freebsd.tar.gz/sha512/118f3c662580c88d092610be08b60236939c7fd7feab4cd524c7c1e2e2e1b557bddbd603902b697142695889ea6c0a8087982020cd5e7267c9c7c82b49622460 -MbedTLS.v2.28.6+1.x86_64-w64-mingw32.tar.gz/md5/1ca2c982712620941c4b0d731251dfff -MbedTLS.v2.28.6+1.x86_64-w64-mingw32.tar.gz/sha512/cef70c00c79e421ce92424bbfda259b4e233d7be3489db1b8cbac7e926d9429be6c88fb806664db60210427748810ea08117066480e8e17c60cb61485b639669 -mbedtls-2.28.6.tar.gz/md5/768932cee6c42f7f4751362091ac56d4 -mbedtls-2.28.6.tar.gz/sha512/a5c876489bf89908f34626c879f68e8f962d84b50756df17b6b75dfb93e08fe163ed3f32bf70e89bce9080d15257a4cbd2679b743bf8f2e2d7a04606c5811c05 diff --git a/deps/checksums/openssl b/deps/checksums/openssl new file mode 100644 index 0000000000000..4d56641b34c80 --- /dev/null +++ b/deps/checksums/openssl @@ -0,0 +1,36 @@ +OpenSSL.v3.0.15+1.aarch64-apple-darwin.tar.gz/md5/8495727a34f178bc474c970855b88e8d +OpenSSL.v3.0.15+1.aarch64-apple-darwin.tar.gz/sha512/2beb6003e0431d56fd4161a7739d0ea2e2238181b2a064f552d5083b59e7724904e8a991e5d0ecaeb05e21d17b56ca44f321c71ac477db4ddaa05d792cb61c9b +OpenSSL.v3.0.15+1.aarch64-linux-gnu.tar.gz/md5/652845c276f3403e8374111fd6654aa0 +OpenSSL.v3.0.15+1.aarch64-linux-gnu.tar.gz/sha512/5d7a20836fffd253eaf574eb461eb10dcbb3fcf0d4f3d763539ef02a922af944e4ff29e8f20cec210ed798a48c742684ea713d511c58c784f33793e167a98469 +OpenSSL.v3.0.15+1.aarch64-linux-musl.tar.gz/md5/52397b6264c156815cdf9de5709533ef +OpenSSL.v3.0.15+1.aarch64-linux-musl.tar.gz/sha512/f1e8c0a3a7bac3c8b78d68fce551c29e5d537f7289f51c297e75c5c7bc3678747dc19ed579387021def041f02bf08d0e7938c5498b4493438efeb4685e01a191 +OpenSSL.v3.0.15+1.aarch64-unknown-freebsd.tar.gz/md5/bbdbea23761b13821d99f9eb4ba5d198 +OpenSSL.v3.0.15+1.aarch64-unknown-freebsd.tar.gz/sha512/a1c3985658eaf38a901bc7de1e782101ab41638d4641fea3115c5020b229d3f6fba3e3709c5568b3395986f396d82feb32b804d343dfd05c2fa1e6eefe120e96 +OpenSSL.v3.0.15+1.armv6l-linux-gnueabihf.tar.gz/md5/ceeb288e5c8da5831047dc4b1c2a983e +OpenSSL.v3.0.15+1.armv6l-linux-gnueabihf.tar.gz/sha512/961c4ec351b69aaf42082b462623afd7315b6606c2a5fb98142ca1bc6ce0494c388f5020474eff5081e850fd34aed8b3ef2f881304872255236fcae0b0b641e4 +OpenSSL.v3.0.15+1.armv6l-linux-musleabihf.tar.gz/md5/e75d83ecf3876a595cfe36cf81853489 +OpenSSL.v3.0.15+1.armv6l-linux-musleabihf.tar.gz/sha512/3e113a275233f434df685b114342f2a59634282a9b68606d4c16da51e5173cbed26498512b22f84017100a18415cc1bb2d269f1ba0d44941d51b8d05c73950cc +OpenSSL.v3.0.15+1.armv7l-linux-gnueabihf.tar.gz/md5/fbe3bf8921cf9b679b60ea12e2d19458 +OpenSSL.v3.0.15+1.armv7l-linux-gnueabihf.tar.gz/sha512/294c91308eede14b8db255ff1b47fe5dba3b6441318e38e284446f276355b93d97b88e6c78d9ed6bb6623623c47be5c65ce6b2fa5ce5ea087a8bfaeb94830627 +OpenSSL.v3.0.15+1.armv7l-linux-musleabihf.tar.gz/md5/ab35b5d4f79e349d558742c69c775d34 +OpenSSL.v3.0.15+1.armv7l-linux-musleabihf.tar.gz/sha512/6a5c85e36ed609ad33d0d2466fa1732a47072af37226052456172d7b049b9d943ad48d94b444600ed1f859a4c016226fc1952fda7381f3aaa6229bcd15c72f78 +OpenSSL.v3.0.15+1.i686-linux-gnu.tar.gz/md5/99e76e6c5d50fd0a4e6218bb807f1062 +OpenSSL.v3.0.15+1.i686-linux-gnu.tar.gz/sha512/30235842672e3b854d38ffd3ba1812a9e81b1f9fcf285ed12d07622d386a5355b79f2264be3d0e84d0bec0e57a9f3e1ac6de898463c43f6d2e3290854205cb30 +OpenSSL.v3.0.15+1.i686-linux-musl.tar.gz/md5/adb2ed9a8ef34294643f7762de1c7842 +OpenSSL.v3.0.15+1.i686-linux-musl.tar.gz/sha512/56d56eb89ea0dcadafbfc92a3bd2032b6c934d217882f56ba47086783b7a5134816f43d391a569963fa978ab708bf695af5abf03cac11c709930752882c761b7 +OpenSSL.v3.0.15+1.i686-w64-mingw32.tar.gz/md5/4596a947bb22aab728ba585d2727053a +OpenSSL.v3.0.15+1.i686-w64-mingw32.tar.gz/sha512/6a1479036c7ccb170daf42ed7d6054d2c7f3a4115dbb01fe34e518efdf0a60929eb89771d5f7fdcb3d055ebf05351cbc82397606d49ea4bde44c465cdb60274e +OpenSSL.v3.0.15+1.powerpc64le-linux-gnu.tar.gz/md5/f36402387dde259a64b0bed2a0d2a3c9 +OpenSSL.v3.0.15+1.powerpc64le-linux-gnu.tar.gz/sha512/3011eec16c1abcbf3c452a2d8e4e7c5a3c280981ea57374a938e3f8843f25022e9b0beaa6a87a1e5f7547ae4abd614221cc2a0a51495869fe99a03f6b3f46d8e +OpenSSL.v3.0.15+1.x86_64-apple-darwin.tar.gz/md5/f4c82b74f80a3cda4ae409e4623b6615 +OpenSSL.v3.0.15+1.x86_64-apple-darwin.tar.gz/sha512/d4a08a914533e603f06e584b8d7e69f4fca9671635fe24e1a896a362bfd388eea2397b9b66b82aecc0ba751e72dfcfbd8b46c5a148349f5aaeb9c37bc257ed37 +OpenSSL.v3.0.15+1.x86_64-linux-gnu.tar.gz/md5/9868c286c6275581a5891167540def7d +OpenSSL.v3.0.15+1.x86_64-linux-gnu.tar.gz/sha512/5631aa288e0e174bd05d520d90a29423c743576eb2385e97a58ed45361e94e59daa3b3193e81ce649bfed21d07fd508c135a38b486b34120afc3af1b4f92451d +OpenSSL.v3.0.15+1.x86_64-linux-musl.tar.gz/md5/e118f2b842a3a1be539208aff17281ec +OpenSSL.v3.0.15+1.x86_64-linux-musl.tar.gz/sha512/1c6fa866bebf5c0c6cc5ea8a423d2a522b186e7f2590146e464813be22d66de0a9bc797449508fa5508d296309348b8dd3a881c0099e6fb77b8d28ff270fab35 +OpenSSL.v3.0.15+1.x86_64-unknown-freebsd.tar.gz/md5/03830b4a8735a7e704df444e9a4353ab +OpenSSL.v3.0.15+1.x86_64-unknown-freebsd.tar.gz/sha512/bfc9e4ca160a9e3d4232117d819ea37f3997d4c433cfc85a4055ced60e8c65e7df6009d58f6b94f6f2aa1b436a8ee9f08dcf5a21faf7106bfdb50ca9a05322c6 +OpenSSL.v3.0.15+1.x86_64-w64-mingw32.tar.gz/md5/5b2c640cb72115f417cdd7ec82a8336f +OpenSSL.v3.0.15+1.x86_64-w64-mingw32.tar.gz/sha512/d2224dd37205c7781be93f1581a08c4008f4c35cb3f457f3b4455a00805c1a20be7f7e29188a55164364c42a926ffa12527af379d1bc8d11f4351b07d8a5928b +openssl-3.0.15.tar.gz/md5/08f458c00fff496a52ef931c481045cd +openssl-3.0.15.tar.gz/sha512/acd80f2f7924d90c1416946a5c61eff461926ad60f4821bb6b08845ea18f8452fd5e88a2c2c5bd0d7590a792cb8341a3f3be042fd0a5b6c9c1b84a497c347bbf diff --git a/deps/curl.mk b/deps/curl.mk index ae2830c3cd4f2..29745448692c6 100644 --- a/deps/curl.mk +++ b/deps/curl.mk @@ -35,31 +35,35 @@ checksum-curl: $(SRCCACHE)/curl-$(CURL_VER).tar.bz2 ## xref: https://github.com/JuliaPackaging/Yggdrasil/blob/master/L/LibCURL/common.jl # Disable....almost everything -CURL_CONFIGURE_FLAGS := $(CONFIGURE_COMMON) \ - --without-gnutls --without-libidn2 --without-librtmp \ - --without-libpsl --without-libgsasl --without-fish-functions-dir \ - --disable-ares --disable-manual --disable-ldap --disable-ldaps --disable-static \ - --without-gssapi --without-brotli +CURL_CONFIGURE_FLAGS := $(CONFIGURE_COMMON) \ + --without-gnutls \ + --without-libidn2 --without-librtmp \ + --without-nss --without-libpsl \ + --disable-ares --disable-manual \ + --disable-ldap --disable-ldaps --without-zsh-functions-dir \ + --disable-static --without-libgsasl \ + --without-brotli # A few things we actually enable -CURL_CONFIGURE_FLAGS += --enable-versioned-symbols \ - --with-libssh2=${build_prefix} --with-zlib=${build_prefix} --with-nghttp2=${build_prefix} +CURL_CONFIGURE_FLAGS += \ + --with-libssh2=${build_prefix} --with-zlib=${build_prefix} --with-nghttp2=${build_prefix} \ + --enable-versioned-symbols # We use different TLS libraries on different platforms. # On Windows, we use schannel # On MacOS, we use SecureTransport -# On Linux, we use mbedTLS +# On Linux, we use OpenSSL ifeq ($(OS), WINNT) CURL_TLS_CONFIGURE_FLAGS := --with-schannel else ifeq ($(OS), Darwin) CURL_TLS_CONFIGURE_FLAGS := --with-secure-transport else -CURL_TLS_CONFIGURE_FLAGS := --with-mbedtls=$(build_prefix) +CURL_TLS_CONFIGURE_FLAGS := --with-openssl endif CURL_CONFIGURE_FLAGS += $(CURL_TLS_CONFIGURE_FLAGS) $(SRCCACHE)/curl-$(CURL_VER)/curl-8.6.0-build.patch-applied: $(SRCCACHE)/curl-$(CURL_VER)/source-extracted cd $(dir $@) && \ - patch -p1 -f < $(SRCDIR)/patches/curl-8.6.0-build.patch + patch -p1 -f < $(SRCDIR)/patches/curl-strdup.patch echo 1 > $@ $(SRCCACHE)/curl-$(CURL_VER)/source-patched: $(SRCCACHE)/curl-$(CURL_VER)/curl-8.6.0-build.patch-applied diff --git a/deps/curl.version b/deps/curl.version index 5ecfcc2b642a1..ff360676b335a 100644 --- a/deps/curl.version +++ b/deps/curl.version @@ -3,4 +3,7 @@ CURL_JLL_NAME := LibCURL ## source build -CURL_VER := 8.6.0 +# curl version 8.10 and later seem to be broken, probably due to a bug +# on Julia. See +# . +CURL_VER := 8.9.1 diff --git a/deps/libgit2.mk b/deps/libgit2.mk index 022582d48c78e..8b17ae6d70424 100644 --- a/deps/libgit2.mk +++ b/deps/libgit2.mk @@ -9,8 +9,8 @@ ifeq ($(USE_SYSTEM_LIBSSH2), 0) $(BUILDDIR)/$(LIBGIT2_SRC_DIR)/build-configured: | $(build_prefix)/manifest/libssh2 endif -ifeq ($(USE_SYSTEM_MBEDTLS), 0) -$(BUILDDIR)/$(LIBGIT2_SRC_DIR)/build-configured: | $(build_prefix)/manifest/mbedtls +ifeq ($(USE_SYSTEM_OPENSSL), 0) +$(BUILDDIR)/$(LIBGIT2_SRC_DIR)/build-configured: | $(build_prefix)/manifest/openssl endif LIBGIT2_OPTS := $(CMAKE_COMMON) -DCMAKE_BUILD_TYPE=Release -DUSE_THREADS=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON -DBUILD_CLI=OFF @@ -39,7 +39,7 @@ LIBGIT2_OPTS += -DCMAKE_C_FLAGS="-I/usr/local/include" endif ifneq (,$(findstring $(OS),Linux FreeBSD OpenBSD)) -LIBGIT2_OPTS += -DUSE_HTTPS="mbedTLS" -DUSE_SHA1="CollisionDetection" -DCMAKE_INSTALL_RPATH="\$$ORIGIN" +LIBGIT2_OPTS += -DUSE_HTTPS="OpenSSL" -DUSE_SHA1="CollisionDetection" -DCMAKE_INSTALL_RPATH="\$$ORIGIN" endif # use the bundled distribution of libpcre. we should consider linking against the diff --git a/deps/libgit2.version b/deps/libgit2.version index ae475f0b3644f..9b908cff803e3 100644 --- a/deps/libgit2.version +++ b/deps/libgit2.version @@ -3,8 +3,8 @@ LIBGIT2_JLL_NAME := LibGit2 ## source build -LIBGIT2_BRANCH=v1.8.0 -LIBGIT2_SHA1=d74d491481831ddcd23575d376e56d2197e95910 +LIBGIT2_BRANCH=v1.8.4 +LIBGIT2_SHA1=3f4182d15eab74a302718f2de454ffadb1995626 ## Other deps # Specify the version of the Mozilla CA Certificate Store to obtain. diff --git a/deps/libssh2.mk b/deps/libssh2.mk index c293d8309d2bc..3f802db15be6d 100644 --- a/deps/libssh2.mk +++ b/deps/libssh2.mk @@ -4,8 +4,8 @@ LIBSSH2_GIT_URL := https://github.com/libssh2/libssh2.git LIBSSH2_TAR_URL = https://api.github.com/repos/libssh2/libssh2/tarball/$1 $(eval $(call git-external,libssh2,LIBSSH2,CMakeLists.txt,,$(SRCCACHE))) -ifeq ($(USE_SYSTEM_MBEDTLS), 0) -$(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured: | $(build_prefix)/manifest/mbedtls +ifeq ($(USE_SYSTEM_OPENSSL), 0) +$(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured: | $(build_prefix)/manifest/openssl endif LIBSSH2_OPTS := $(CMAKE_COMMON) -DBUILD_SHARED_LIBS=ON -DBUILD_EXAMPLES=OFF \ @@ -21,7 +21,7 @@ ifeq ($(BUILD_OS),WINNT) LIBSSH2_OPTS += -G"MSYS Makefiles" endif else -LIBSSH2_OPTS += -DCRYPTO_BACKEND=mbedTLS -DENABLE_ZLIB_COMPRESSION=OFF +LIBSSH2_OPTS += -DCRYPTO_BACKEND=OpenSSL -DENABLE_ZLIB_COMPRESSION=OFF endif ifneq (,$(findstring $(OS),Linux FreeBSD OpenBSD)) @@ -34,14 +34,6 @@ endif LIBSSH2_SRC_PATH := $(SRCCACHE)/$(LIBSSH2_SRC_DIR) -$(LIBSSH2_SRC_PATH)/libssh2-mbedtls-size_t.patch-applied: $(LIBSSH2_SRC_PATH)/source-extracted - cd $(LIBSSH2_SRC_PATH) && \ - patch -p1 -f < $(SRCDIR)/patches/libssh2-mbedtls-size_t.patch - echo 1 > $@ - -$(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured: \ - $(LIBSSH2_SRC_PATH)/libssh2-mbedtls-size_t.patch-applied - $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured: $(LIBSSH2_SRC_PATH)/source-extracted mkdir -p $(dir $@) cd $(dir $@) && \ diff --git a/deps/libssh2.version b/deps/libssh2.version index 7fff90885f6a3..d6cc8a629c3bf 100644 --- a/deps/libssh2.version +++ b/deps/libssh2.version @@ -1,7 +1,8 @@ +# -*- makefile -*- ## jll artifact LIBSSH2_JLL_NAME := LibSSH2 ## source build -LIBSSH2_VER := 1.11.0 -LIBSSH2_BRANCH=libssh2-1.11.0 -LIBSSH2_SHA1=1c3f1b7da588f2652260285529ec3c1f1125eb4e +LIBSSH2_VER := 1.11.1 +LIBSSH2_BRANCH=libssh2-1.11.1 +LIBSSH2_SHA1=a312b43325e3383c865a87bb1d26cb52e3292641 diff --git a/deps/mbedtls.mk b/deps/mbedtls.mk deleted file mode 100644 index 39cf817d70658..0000000000000 --- a/deps/mbedtls.mk +++ /dev/null @@ -1,97 +0,0 @@ -## mbedtls -include $(SRCDIR)/mbedtls.version - -ifneq ($(USE_BINARYBUILDER_MBEDTLS), 1) -MBEDTLS_SRC = mbedtls-$(MBEDTLS_VER) -MBEDTLS_URL = https://github.com/Mbed-TLS/mbedtls/archive/v$(MBEDTLS_VER).tar.gz - -MBEDTLS_OPTS := $(CMAKE_COMMON) -DUSE_SHARED_MBEDTLS_LIBRARY=ON \ - -DUSE_STATIC_MBEDTLS_LIBRARY=OFF -DENABLE_PROGRAMS=OFF -DCMAKE_BUILD_TYPE=Release - -MBEDTLS_OPTS += -DENABLE_ZLIB_SUPPORT=OFF -DMBEDTLS_FATAL_WARNINGS=OFF -ifeq ($(BUILD_OS),WINNT) -MBEDTLS_OPTS += -G"MSYS Makefiles" -endif - -ifneq (,$(findstring $(OS),Linux FreeBSD OpenBSD)) -MBEDTLS_OPTS += -DCMAKE_INSTALL_RPATH="\$$ORIGIN" -endif - -$(SRCCACHE)/$(MBEDTLS_SRC).tar.gz: | $(SRCCACHE) - $(JLDOWNLOAD) $@ $(MBEDTLS_URL) - -$(SRCCACHE)/$(MBEDTLS_SRC)/source-extracted: $(SRCCACHE)/$(MBEDTLS_SRC).tar.gz - $(JLCHECKSUM) $< - mkdir -p $(dir $@) && \ - $(TAR) -C $(dir $@) --strip-components 1 -xf $< - # Force-enable MD4 - sed -i.org "s|//#define MBEDTLS_MD4_C|#define MBEDTLS_MD4_C|" $(SRCCACHE)/$(MBEDTLS_SRC)/include/mbedtls/config.h - touch -c $(SRCCACHE)/$(MBEDTLS_SRC)/CMakeLists.txt # old target - echo 1 > $@ - -checksum-mbedtls: $(SRCCACHE)/$(MBEDTLS_SRC).tar.gz - $(JLCHECKSUM) $< - -$(BUILDDIR)/$(MBEDTLS_SRC)/build-configured: $(SRCCACHE)/$(MBEDTLS_SRC)/source-extracted - mkdir -p $(dir $@) - cd $(dir $@) && \ - $(CMAKE) $(dir $<) $(MBEDTLS_OPTS) - echo 1 > $@ - -$(BUILDDIR)/$(MBEDTLS_SRC)/build-compiled: $(BUILDDIR)/$(MBEDTLS_SRC)/build-configured - $(MAKE) -C $(dir $<) - echo 1 > $@ - -$(BUILDDIR)/$(MBEDTLS_SRC)/build-checked: $(BUILDDIR)/$(MBEDTLS_SRC)/build-compiled -ifeq ($(OS),$(BUILD_OS)) - $(MAKE) -C $(dir $@) test -endif - echo 1 > $@ - -ifeq ($(OS),WINNT) -define MBEDTLS_INSTALL - mkdir -p $2/$$(build_shlibdir) - cp $1/library/libmbedcrypto.$$(SHLIB_EXT) $2/$$(build_shlibdir) - cp $1/library/libmbedx509.$$(SHLIB_EXT) $2/$$(build_shlibdir) - cp $1/library/libmbedtls.$$(SHLIB_EXT) $2/$$(build_shlibdir) -endef -else -define MBEDTLS_INSTALL - $(call MAKE_INSTALL,$1,$2,) -endef -endif -$(eval $(call staged-install, \ - mbedtls,$(MBEDTLS_SRC), \ - MBEDTLS_INSTALL,,, \ - $$(INSTALL_NAME_CMD)libmbedx509.$$(SHLIB_EXT) $$(build_shlibdir)/libmbedx509.$$(SHLIB_EXT) && \ - $$(INSTALL_NAME_CMD)libmbedtls.$$(SHLIB_EXT) $$(build_shlibdir)/libmbedtls.$$(SHLIB_EXT) && \ - $$(INSTALL_NAME_CHANGE_CMD) libmbedx509.1.dylib @rpath/libmbedx509.$$(SHLIB_EXT) $$(build_shlibdir)/libmbedtls.$$(SHLIB_EXT) && \ - $$(INSTALL_NAME_CHANGE_CMD) libmbedcrypto.7.dylib @rpath/libmbedcrypto.$$(SHLIB_EXT) $$(build_shlibdir)/libmbedtls.$$(SHLIB_EXT) && \ - $$(INSTALL_NAME_CHANGE_CMD) libmbedcrypto.7.dylib @rpath/libmbedcrypto.$$(SHLIB_EXT) $$(build_shlibdir)/libmbedx509.$$(SHLIB_EXT) && \ - $$(INSTALL_NAME_CMD)libmbedcrypto.$$(SHLIB_EXT) $$(build_shlibdir)/libmbedcrypto.$$(SHLIB_EXT))) - - -clean-mbedtls: - -rm -f $(BUILDDIR)/$(MBEDTLS_SRC)/build-configured \ - $(BUILDDIR)/$(MBEDTLS_SRC)/build-compiled - -$(MAKE) -C $(BUILDDIR)/$(MBEDTLS_SRC) clean - -distclean-mbedtls: - rm -rf $(SRCCACHE)/$(MBEDTLS_SRC).tar.gz \ - $(SRCCACHE)/$(MBEDTLS_SRC) \ - $(BUILDDIR)/$(MBEDTLS_SRC) - - -get-mbedtls: $(SRCCACHE)/$(MBEDTLS_SRC).tar.gz -extract-mbedtls: $(SRCCACHE)/$(MBEDTLS_SRC)/source-extracted -configure-mbedtls: $(BUILDDIR)/$(MBEDTLS_SRC)/build-configured -compile-mbedtls: $(BUILDDIR)/$(MBEDTLS_SRC)/build-compiled -# tests disabled since they are known to fail -fastcheck-mbedtls: #check-mbedtls -check-mbedtls: $(BUILDDIR)/$(MBEDTLS_SRC)/build-checked - -else # USE_BINARYBUILDER_MBEDTLS - -$(eval $(call bb-install,mbedtls,MBEDTLS,false)) - -endif diff --git a/deps/openssl.mk b/deps/openssl.mk new file mode 100644 index 0000000000000..0ced5737a49a2 --- /dev/null +++ b/deps/openssl.mk @@ -0,0 +1,102 @@ +## OpenSSL ## +include $(SRCDIR)/openssl.version + +ifneq ($(USE_BINARYBUILDER_OPENSSL),1) + +ifeq ($(OS),Darwin) +ifeq ($(APPLE_ARCH),arm64) +OPENSSL_TARGET := darwin64-arm64-cc +else +OPENSSL_TARGET := darwin64-x86_64-cc +endif +else ifeq ($(OS),WINNT) +ifeq ($(ARCH),x86_64) +OPENSSL_TARGET := mingw64 +else +OPENSSL_TARGET := mingw +endif +else ifeq ($(OS),FreeBSD) +ifeq ($(ARCH),aarch64) +OPENSSL_TARGET := BSD-aarch64 +else +OPENSSL_TARGET := BSD-x86_64 +endif +else ifeq ($(OS),Linux) +ifeq ($(ARCH),x86_64) +OPENSSL_TARGET := linux-x86_64 +else ifeq ($(ARCH),i686) +OPENSSL_TARGET := linux-x86 +else ifeq ($(ARCH),arm) +OPENSSL_TARGET := linux-armv4 +else ifeq ($(ARCH),aarch64) +OPENSSL_TARGET := linux-aarch64 +else ifeq ($(ARCH),ppc64le) +OPENSSL_TARGET := linux-ppc64le +else ifeq ($(ARCH),powerpc64le) +OPENSSL_TARGET := linux-ppc64le +endif +else +OPENSSL_TARGET := unknown +endif + +$(SRCCACHE)/openssl-$(OPENSSL_VER).tar.gz: | $(SRCCACHE) + $(JLDOWNLOAD) $@ https://www.openssl.org/source/$(notdir $@) + +$(SRCCACHE)/openssl-$(OPENSSL_VER)/source-extracted: $(SRCCACHE)/openssl-$(OPENSSL_VER).tar.gz + $(JLCHECKSUM) $< + cd $(dir $<) && $(TAR) -zxf $< + touch -c $(SRCCACHE)/openssl-$(OPENSSL_VER)/configure # old target + echo 1 > $@ + +checksum-openssl: $(SRCCACHE)/openssl-$(OPENSSL_VER).tar.gz + $(JLCHECKSUM) $< + +# We cannot use $(CONFIGURE_COMMON) in this step, because openssl's Configure scripts is picky +# and does not like that we pass make variables as arguments, it wants them in the environment +$(BUILDDIR)/openssl-$(OPENSSL_VER)/build-configured: $(SRCCACHE)/openssl-$(OPENSSL_VER)/source-extracted + mkdir -p $(dir $@) + cd $(dir $@) && \ + CC="$(CC) $(SANITIZE_OPTS)" CXX="$(CXX) $(SANITIZE_OPTS)" LDFLAGS="$(LDFLAGS) $(RPATH_ESCAPED_ORIGIN) $(SANITIZE_LDFLAGS)" \ + $(dir $<)/Configure shared --prefix=$(abspath $(build_prefix)) $(OPENSSL_TARGET) + echo 1 > $@ + +$(BUILDDIR)/openssl-$(OPENSSL_VER)/build-compiled: $(BUILDDIR)/openssl-$(OPENSSL_VER)/build-configured + $(MAKE) -C $(dir $<) + echo 1 > $@ + +$(BUILDDIR)/openssl-$(OPENSSL_VER)/build-checked: $(BUILDDIR)/openssl-$(OPENSSL_VER)/build-compiled +ifeq ($(OS),$(BUILD_OS)) + $(MAKE) -C $(dir $@) test +endif + echo 1 > $@ + +$(eval $(call staged-install, \ + openssl,openssl-$(OPENSSL_VER), \ + MAKE_INSTALL,,, \ + $$(WIN_MAKE_HARD_LINK) $(build_bindir)/libcrypto-*.dll $(build_bindir)/libcrypto.dll && \ + $$(WIN_MAKE_HARD_LINK) $(build_bindir)/libssl-*.dll $(build_bindir)/libssl.dll && \ + $$(INSTALL_NAME_CMD)libcrypto.$$(SHLIB_EXT) $$(build_shlibdir)/libcrypto.$$(SHLIB_EXT) && \ + $$(INSTALL_NAME_CMD)libssl.$$(SHLIB_EXT) $$(build_shlibdir)/libssl.$$(SHLIB_EXT) && \ + $$(INSTALL_NAME_CHANGE_CMD) $$(build_shlibdir)/libcrypto.3.dylib @rpath/libcrypto.$$(SHLIB_EXT) $$(build_shlibdir)/libssl.$$(SHLIB_EXT))) + +clean-openssl: + -rm -f $(BUILDDIR)/-openssl-$(OPENSSL_VER)/build-configured $(BUILDDIR)/-openssl-$(OPENSSL_VER)/build-compiled + -$(MAKE) -C $(BUILDDIR)/-openssl-$(OPENSSL_VER) clean + +distclean-openssl: + rm -rf $(SRCCACHE)/-openssl-$(OPENSSL_VER).tar.gz \ + $(SRCCACHE)/-openssl-$(OPENSSL_VER) \ + $(BUILDDIR)/-openssl-$(OPENSSL_VER) + +get-openssl: $(SRCCACHE)/openssl-$(OPENSSL_VER).tar.gz +extract-openssl: $(SRCCACHE)/openssl-$(OPENSSL_VER)/source-extracted +configure-openssl: $(BUILDDIR)/openssl-$(OPENSSL_VER)/build-configured +compile-openssl: $(BUILDDIR)/openssl-$(OPENSSL_VER)/build-compiled +fastcheck-openssl: check-openssl +check-openssl: $(BUILDDIR)/openssl-$(OPENSSL_VER)/build-checked + +else # USE_BINARYBUILDER_OPENSSL + +$(eval $(call bb-install,openssl,OPENSSL,false)) + +endif diff --git a/deps/mbedtls.version b/deps/openssl.version similarity index 50% rename from deps/mbedtls.version rename to deps/openssl.version index ef88b8109f68c..7253e063167db 100644 --- a/deps/mbedtls.version +++ b/deps/openssl.version @@ -1,7 +1,6 @@ # -*- makefile -*- - ## jll artifact -MBEDTLS_JLL_NAME := MbedTLS +OPENSSL_JLL_NAME := OpenSSL ## source build -MBEDTLS_VER := 2.28.6 +OPENSSL_VER := 3.0.15 diff --git a/deps/patches/curl-8.6.0-build.patch b/deps/patches/curl-8.6.0-build.patch deleted file mode 100644 index 827b02808d505..0000000000000 --- a/deps/patches/curl-8.6.0-build.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 5cc2b016c36aaf5a08e2feb7c068fca5bb0a8052 Mon Sep 17 00:00:00 2001 -From: Daniel Stenberg -Date: Mon, 5 Feb 2024 15:22:08 +0100 -Subject: [PATCH] md4: include strdup.h for the memdup proto - -Reported-by: Erik Schnetter -Fixes #12849 -Closes #12863 ---- - lib/md4.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/lib/md4.c b/lib/md4.c -index 067c211e420afd..58dd1166cf924f 100644 ---- a/lib/md4.c -+++ b/lib/md4.c -@@ -28,6 +28,7 @@ - - #include - -+#include "strdup.h" - #include "curl_md4.h" - #include "warnless.h" diff --git a/deps/patches/curl-strdup.patch b/deps/patches/curl-strdup.patch new file mode 100644 index 0000000000000..1cb389fdc4c17 --- /dev/null +++ b/deps/patches/curl-strdup.patch @@ -0,0 +1,10 @@ +--- a/lib/md4.c ++++ b/lib/md4.c +@@ -23,6 +23,7 @@ + ***************************************************************************/ + + #include "curl_setup.h" ++#include "strdup.h" + + #if defined(USE_CURL_NTLM_CORE) + diff --git a/deps/patches/libssh2-mbedtls-size_t.patch b/deps/patches/libssh2-mbedtls-size_t.patch deleted file mode 100644 index 502adf6bdf439..0000000000000 --- a/deps/patches/libssh2-mbedtls-size_t.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 6cad964056848d3d78ccc74600fbff6298baddcb Mon Sep 17 00:00:00 2001 -From: Viktor Szakats -Date: Tue, 30 May 2023 17:28:03 +0000 -Subject: [PATCH 1/1] mbedtls: use more size_t to sync up with crypto.h - -Ref: 5a96f494ee0b00282afb2db2e091246fc5e1774a #846 #879 - -Fixes #1053 -Closes #1054 ---- - src/mbedtls.c | 14 ++++++++------ - src/mbedtls.h | 13 ++++++------- - 2 files changed, 14 insertions(+), 13 deletions(-) - -diff --git a/src/mbedtls.c b/src/mbedtls.c -index e387cdb..cd14a4b 100644 ---- a/src/mbedtls.c -+++ b/src/mbedtls.c -@@ -186,7 +186,7 @@ _libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx) - int - _libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, - mbedtls_md_type_t mdtype, -- const unsigned char *key, unsigned long keylen) -+ const unsigned char *key, size_t keylen) - { - const mbedtls_md_info_t *md_info; - int ret, hmac; -@@ -221,7 +221,7 @@ _libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash) - } - - int --_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, -+_libssh2_mbedtls_hash(const unsigned char *data, size_t datalen, - mbedtls_md_type_t mdtype, unsigned char *hash) - { - const mbedtls_md_info_t *md_info; -@@ -497,8 +497,9 @@ int - _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx, - size_t hash_len, - const unsigned char *sig, -- unsigned long sig_len, -- const unsigned char *m, unsigned long m_len) -+ size_t sig_len, -+ const unsigned char *m, -+ size_t m_len) - { - int ret; - int md_type; -@@ -548,8 +549,9 @@ _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx, - int - _libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx * rsactx, - const unsigned char *sig, -- unsigned long sig_len, -- const unsigned char *m, unsigned long m_len) -+ size_t sig_len, -+ const unsigned char *m, -+ size_t m_len) - { - return _libssh2_mbedtls_rsa_sha2_verify(rsactx, SHA_DIGEST_LENGTH, - sig, sig_len, m, m_len); -diff --git a/src/mbedtls.h b/src/mbedtls.h -index d9592f7..03484da 100644 ---- a/src/mbedtls.h -+++ b/src/mbedtls.h -@@ -478,12 +478,12 @@ _libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx); - int - _libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, - mbedtls_md_type_t mdtype, -- const unsigned char *key, unsigned long keylen); -+ const unsigned char *key, size_t keylen); - - int - _libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash); - int --_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, -+_libssh2_mbedtls_hash(const unsigned char *data, size_t datalen, - mbedtls_md_type_t mdtype, unsigned char *hash); - - _libssh2_bn * -@@ -526,9 +526,8 @@ _libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, - int - _libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa, - const unsigned char *sig, -- unsigned long sig_len, -- const unsigned char *m, -- unsigned long m_len); -+ size_t sig_len, -+ const unsigned char *m, size_t m_len); - int - _libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session, - libssh2_rsa_ctx *rsa, -@@ -540,8 +539,8 @@ int - _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx, - size_t hash_len, - const unsigned char *sig, -- unsigned long sig_len, -- const unsigned char *m, unsigned long m_len); -+ size_t sig_len, -+ const unsigned char *m, size_t m_len); - int - _libssh2_mbedtls_rsa_sha2_sign(LIBSSH2_SESSION *session, - libssh2_rsa_ctx *rsa, --- -2.31.0 - diff --git a/deps/pcre.version b/deps/pcre.version index 681e97e197f51..78245a5777a0c 100644 --- a/deps/pcre.version +++ b/deps/pcre.version @@ -1,3 +1,4 @@ +# -*- makefile -*- ## jll artifact PCRE_JLL_NAME := PCRE2 diff --git a/doc/Manifest.toml b/doc/Manifest.toml index 490754c4c3068..e91958808828e 100644 --- a/doc/Manifest.toml +++ b/doc/Manifest.toml @@ -115,9 +115,9 @@ uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" version = "0.6.4" [[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.6.0+0" +version = "8.9.1+0" [[deps.LibGit2]] deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] @@ -125,14 +125,14 @@ uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" version = "1.11.0" [[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.8.0+0" +version = "1.8.4+0" [[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" +version = "1.11.3+0" [[deps.Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" @@ -159,11 +159,6 @@ git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" version = "0.1.2" -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.6+1" - [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" version = "1.11.0" @@ -177,8 +172,7 @@ uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" [[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "7493f61f55a6cce7325f197443aa80d32554ba10" +deps = ["Artifacts", "Libdl", "NetworkOptions"] uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" version = "3.0.15+1" diff --git a/doc/src/devdocs/build/build.md b/doc/src/devdocs/build/build.md index 966ef3d102d1c..5fe038959edf0 100644 --- a/doc/src/devdocs/build/build.md +++ b/doc/src/devdocs/build/build.md @@ -195,7 +195,7 @@ uses are listed in [`deps/$(libname).version`](https://github.com/JuliaLang/juli - **[libgit2]** — Git linkable library, used by Julia's package manager. - **[curl]** — libcurl provides download and proxy support. - **[libssh2]** — library for SSH transport, used by libgit2 for packages with SSH remotes. -- **[mbedtls]** — library used for cryptography and transport layer security, used by libssh2 +- **[OpenSSL]** — library used for cryptography and transport layer security, used by libgit2 and libssh2. - **[utf8proc]** — a library for processing UTF-8 encoded Unicode strings. - **[LLVM libunwind]** — LLVM's fork of [libunwind], a library that determines the call-chain of a program. - **[ITTAPI]** — Intel's Instrumentation and Tracing Technology and Just-In-Time API. @@ -230,7 +230,7 @@ uses are listed in [`deps/$(libname).version`](https://github.com/JuliaLang/juli [utf8proc]: https://julialang.org/utf8proc/ [libunwind]: https://www.nongnu.org/libunwind [libssh2]: https://www.libssh2.org -[mbedtls]: https://tls.mbed.org/ +[OpenSSL]: https://www.openssl.org/ [pkg-config]: https://www.freedesktop.org/wiki/Software/pkg-config/ [powershell]: https://docs.microsoft.com/en-us/powershell/scripting/wmf/overview [which]: https://carlowood.github.io/which/ diff --git a/julia.spdx.json b/julia.spdx.json index 0e0067f00efb1..0d7ab1df94688 100644 --- a/julia.spdx.json +++ b/julia.spdx.json @@ -231,16 +231,16 @@ "summary": "libssh2 is a library implementing the SSH2 protocol, available under the revised BSD license." }, { - "name": "mbedtls", - "SPDXID": "SPDXRef-mbedtls", - "downloadLocation": "git+https://github.com/ARMmbed/mbedtls.git", + "name": "OpenSSL", + "SPDXID": "SPDXRef-OpenSSL", + "downloadLocation": "git+https://github.com/openssl/openssl.git", "filesAnalyzed": false, - "homepage": "https://tls.mbed.org", - "sourceInfo": "The version in use can be found in the file deps/mbedtls.version", + "homepage": "https://www.openssl.org", + "sourceInfo": "The version in use can be found in the file deps/openssl.version", "licenseConcluded": "Apache-2.0", "licenseDeclared": "Apache-2.0", - "copyrightText": "NOASSERTION", - "summary": "An open source, portable, easy to use, readable and flexible SSL library." + "copyrightText": "Copyright (c) 1998-2024 The OpenSSL Project Authors. Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson.", + "summary": "OpenSSL is a robust, commercial-grade, full-featured Open Source Toolkit for the TLS (formerly SSL), DTLS and QUIC (currently client side only) protocols.", }, { "name": "mpfr", @@ -560,7 +560,7 @@ "relatedSpdxElement": "SPDXRef-JuliaMain" }, { - "spdxElementId": "SPDXRef-mbedtls", + "spdxElementId": "SPDXRef-OpenSSL", "relationshipType": "BUILD_DEPENDENCY_OF", "relatedSpdxElement": "SPDXRef-JuliaMain" }, diff --git a/stdlib/LibCURL_jll/Project.toml b/stdlib/LibCURL_jll/Project.toml index d17090a1e5c3b..e7dac4c687ab1 100644 --- a/stdlib/LibCURL_jll/Project.toml +++ b/stdlib/LibCURL_jll/Project.toml @@ -1,11 +1,11 @@ name = "LibCURL_jll" uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.6.0+0" +version = "8.9.1+0" [deps] LibSSH2_jll = "29816b5a-b9ab-546f-933c-edad1886dfa8" nghttp2_jll = "8e850ede-7688-5339-a07c-302acd2aaf8d" -MbedTLS_jll = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +OpenSSL_jll = "458c3c95-2e84-50aa-8efc-19380b2a3a95" Zlib_jll = "83775a58-1f1d-513f-b197-d71354ab007a" Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" diff --git a/stdlib/LibCURL_jll/src/LibCURL_jll.jl b/stdlib/LibCURL_jll/src/LibCURL_jll.jl index 3291c97d811cb..5c1c2aa14b23a 100644 --- a/stdlib/LibCURL_jll/src/LibCURL_jll.jl +++ b/stdlib/LibCURL_jll/src/LibCURL_jll.jl @@ -3,7 +3,11 @@ ## dummy stub for https://github.com/JuliaBinaryWrappers/LibCURL_jll.jl baremodule LibCURL_jll -using Base, Libdl, nghttp2_jll +using Base, Libdl, nghttp2_jll, LibSSH2_jll, Zlib_jll +if !(Sys.iswindows() || Sys.isapple()) + # On Windows and macOS we use system SSL/crypto libraries + using OpenSSL_jll +end const PATH_list = String[] const LIBPATH_list = String[] diff --git a/stdlib/LibGit2_jll/Project.toml b/stdlib/LibGit2_jll/Project.toml index ceeb394f26231..6d3a17bb02cf8 100644 --- a/stdlib/LibGit2_jll/Project.toml +++ b/stdlib/LibGit2_jll/Project.toml @@ -1,9 +1,9 @@ name = "LibGit2_jll" uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.8.0+0" +version = "1.8.4+0" [deps] -MbedTLS_jll = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +OpenSSL_jll = "458c3c95-2e84-50aa-8efc-19380b2a3a95" LibSSH2_jll = "29816b5a-b9ab-546f-933c-edad1886dfa8" Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" diff --git a/stdlib/LibGit2_jll/src/LibGit2_jll.jl b/stdlib/LibGit2_jll/src/LibGit2_jll.jl index 15d303dfea6ee..b7ed19a939c5e 100644 --- a/stdlib/LibGit2_jll/src/LibGit2_jll.jl +++ b/stdlib/LibGit2_jll/src/LibGit2_jll.jl @@ -3,7 +3,11 @@ ## dummy stub for https://github.com/JuliaBinaryWrappers/LibGit2_jll.jl baremodule LibGit2_jll -using Base, Libdl, MbedTLS_jll, LibSSH2_jll +using Base, Libdl, LibSSH2_jll +if !(Sys.iswindows() || Sys.isapple()) + # On Windows and macOS we use system SSL/crypto libraries + using OpenSSL_jll +end const PATH_list = String[] const LIBPATH_list = String[] diff --git a/stdlib/LibGit2_jll/test/runtests.jl b/stdlib/LibGit2_jll/test/runtests.jl index 5bc74760b1603..6cf2d2b8a568d 100644 --- a/stdlib/LibGit2_jll/test/runtests.jl +++ b/stdlib/LibGit2_jll/test/runtests.jl @@ -7,5 +7,5 @@ using Test, Libdl, LibGit2_jll minor = Ref{Cint}(0) patch = Ref{Cint}(0) @test ccall((:git_libgit2_version, libgit2), Cint, (Ref{Cint}, Ref{Cint}, Ref{Cint}), major, minor, patch) == 0 - @test VersionNumber(major[], minor[], patch[]) == v"1.8.0" + @test VersionNumber(major[], minor[], patch[]) == v"1.8.4" end diff --git a/stdlib/LibSSH2_jll/Project.toml b/stdlib/LibSSH2_jll/Project.toml index def4fb02e399c..c45d4fc6565b7 100644 --- a/stdlib/LibSSH2_jll/Project.toml +++ b/stdlib/LibSSH2_jll/Project.toml @@ -1,9 +1,9 @@ name = "LibSSH2_jll" uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" +version = "1.11.3+0" [deps] -MbedTLS_jll = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +OpenSSL_jll = "458c3c95-2e84-50aa-8efc-19380b2a3a95" Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" diff --git a/stdlib/LibSSH2_jll/src/LibSSH2_jll.jl b/stdlib/LibSSH2_jll/src/LibSSH2_jll.jl index 351cbe0e3729b..e9392fe34a918 100644 --- a/stdlib/LibSSH2_jll/src/LibSSH2_jll.jl +++ b/stdlib/LibSSH2_jll/src/LibSSH2_jll.jl @@ -3,7 +3,11 @@ ## dummy stub for https://github.com/JuliaBinaryWrappers/LibSSH2_jll.jl baremodule LibSSH2_jll -using Base, Libdl, MbedTLS_jll +using Base, Libdl +if !Sys.iswindows() + # On Windows we use system SSL/crypto libraries + using OpenSSL_jll +end const PATH_list = String[] const LIBPATH_list = String[] diff --git a/stdlib/LibSSH2_jll/test/runtests.jl b/stdlib/LibSSH2_jll/test/runtests.jl index 58cfd9ac024cc..9a05270317752 100644 --- a/stdlib/LibSSH2_jll/test/runtests.jl +++ b/stdlib/LibSSH2_jll/test/runtests.jl @@ -3,6 +3,9 @@ using Test, Libdl, LibSSH2_jll @testset "LibSSH2_jll" begin - # We use a `startswith()` here because when built from source, this returns "1.9.0_DEV" - vn = startswith(unsafe_string(ccall((:libssh2_version, libssh2), Cstring, (Cint,), 0)), "1.9.0") + vn = unsafe_string(ccall((:libssh2_version, libssh2), Cstring, (Cint,), 0)) + # Depending on how LibSSH2_jll was installed (downloaded from + # BinaryBuilder or built from source here), the version number is + # either "1.11.1" or "1.11.1_DEV", respectively. + @test startswith(vn, "1.11.1") end diff --git a/stdlib/Makefile b/stdlib/Makefile index a10503a3566c6..3975f24b7ae3b 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -17,7 +17,7 @@ VERSDIR := v$(shell cut -d. -f1-2 < $(JULIAHOME)/VERSION) DIRS := $(build_datarootdir)/julia/stdlib/$(VERSDIR) $(build_prefix)/manifest/$(VERSDIR) $(foreach dir,$(DIRS),$(eval $(call dir_target,$(dir)))) -JLLS = DSFMT GMP CURL LIBGIT2 LLVM LIBSSH2 LIBUV MBEDTLS MPFR NGHTTP2 \ +JLLS = DSFMT GMP CURL LIBGIT2 LLVM LIBSSH2 LIBUV OPENSSL MPFR NGHTTP2 \ BLASTRAMPOLINE OPENBLAS OPENLIBM P7ZIP PCRE LIBSUITESPARSE ZLIB \ LLVMUNWIND CSL UNWIND LLD diff --git a/stdlib/Manifest.toml b/stdlib/Manifest.toml index 8953aa93ce4b2..8c638415062b2 100644 --- a/stdlib/Manifest.toml +++ b/stdlib/Manifest.toml @@ -91,9 +91,9 @@ uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" version = "0.6.4" [[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.6.0+0" +version = "8.9.1+0" [[deps.LibGit2]] deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] @@ -101,14 +101,14 @@ uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" version = "1.11.0" [[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.8.0+0" +version = "1.8.4+0" [[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" +version = "1.11.3+0" [[deps.LibUV_jll]] deps = ["Artifacts", "Libdl"] @@ -143,11 +143,6 @@ deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" version = "1.11.0" -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.6+1" - [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" version = "1.11.0" @@ -170,6 +165,11 @@ deps = ["Artifacts", "Libdl"] uuid = "05823500-19ac-5b8b-9628-191a04bc5112" version = "0.8.1+3" +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl", "NetworkOptions"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.15+1" + [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" diff --git a/stdlib/MbedTLS_jll/src/MbedTLS_jll.jl b/stdlib/MbedTLS_jll/src/MbedTLS_jll.jl deleted file mode 100644 index 6367213e2c4ab..0000000000000 --- a/stdlib/MbedTLS_jll/src/MbedTLS_jll.jl +++ /dev/null @@ -1,61 +0,0 @@ -# This file is a part of Julia. License is MIT: https://julialang.org/license - -## dummy stub for https://github.com/JuliaBinaryWrappers/MbedTLS_jll.jl - -baremodule MbedTLS_jll -using Base, Libdl - -const PATH_list = String[] -const LIBPATH_list = String[] - -export libmbedcrypto, libmbedtls, libmbedx509 - -# These get calculated in __init__() -const PATH = Ref("") -const LIBPATH = Ref("") -artifact_dir::String = "" -libmbedcrypto_handle::Ptr{Cvoid} = C_NULL -libmbedcrypto_path::String = "" -libmbedtls_handle::Ptr{Cvoid} = C_NULL -libmbedtls_path::String = "" -libmbedx509_handle::Ptr{Cvoid} = C_NULL -libmbedx509_path::String = "" - -if Sys.iswindows() - const libmbedcrypto = "libmbedcrypto.dll" - const libmbedtls = "libmbedtls.dll" - const libmbedx509 = "libmbedx509.dll" -elseif Sys.isapple() - const libmbedcrypto = "@rpath/libmbedcrypto.7.dylib" - const libmbedtls = "@rpath/libmbedtls.14.dylib" - const libmbedx509 = "@rpath/libmbedx509.1.dylib" -else - const libmbedcrypto = "libmbedcrypto.so.7" - const libmbedtls = "libmbedtls.so.14" - const libmbedx509 = "libmbedx509.so.1" -end - -function __init__() - global libmbedcrypto_handle = dlopen(libmbedcrypto) - global libmbedcrypto_path = dlpath(libmbedcrypto_handle) - global libmbedtls_handle = dlopen(libmbedtls) - global libmbedtls_path = dlpath(libmbedtls_handle) - global libmbedx509_handle = dlopen(libmbedx509) - global libmbedx509_path = dlpath(libmbedx509_handle) - global artifact_dir = dirname(Sys.BINDIR) - LIBPATH[] = dirname(libmbedtls_path) - push!(LIBPATH_list, LIBPATH[]) -end - -# JLLWrappers API compatibility shims. Note that not all of these will really make sense. -# For instance, `find_artifact_dir()` won't actually be the artifact directory, because -# there isn't one. It instead returns the overall Julia prefix. -is_available() = true -find_artifact_dir() = artifact_dir -dev_jll() = error("stdlib JLLs cannot be dev'ed") -best_wrapper = nothing -get_libmbedcrypto_path() =libmbedcrypto_path -get_libmbedtls_path() = libmbedtls_path -get_libmbedx509_path() = libmbedx509_path - -end # module MbedTLS_jll diff --git a/stdlib/MbedTLS_jll/test/runtests.jl b/stdlib/MbedTLS_jll/test/runtests.jl deleted file mode 100644 index 5813a813a1e1f..0000000000000 --- a/stdlib/MbedTLS_jll/test/runtests.jl +++ /dev/null @@ -1,10 +0,0 @@ -# This file is a part of Julia. License is MIT: https://julialang.org/license - -using Test, Libdl, MbedTLS_jll - -@testset "MbedTLS_jll" begin - vstr = zeros(UInt8, 32) - ccall((:mbedtls_version_get_string, libmbedcrypto), Cvoid, (Ref{UInt8},), vstr) - vn = VersionNumber(unsafe_string(pointer(vstr))) - @test vn == v"2.28.6" -end diff --git a/stdlib/MbedTLS_jll/Project.toml b/stdlib/OpenSSL_jll/Project.toml similarity index 66% rename from stdlib/MbedTLS_jll/Project.toml rename to stdlib/OpenSSL_jll/Project.toml index 61f3ea0d8b4dc..df00f99b205c9 100644 --- a/stdlib/MbedTLS_jll/Project.toml +++ b/stdlib/OpenSSL_jll/Project.toml @@ -1,13 +1,13 @@ -name = "MbedTLS_jll" -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.6+1" +name = "OpenSSL_jll" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.15+1" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" [compat] -julia = "1.8" +julia = "1.6" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/stdlib/OpenSSL_jll/src/OpenSSL_jll.jl b/stdlib/OpenSSL_jll/src/OpenSSL_jll.jl new file mode 100644 index 0000000000000..bba9a0a299de9 --- /dev/null +++ b/stdlib/OpenSSL_jll/src/OpenSSL_jll.jl @@ -0,0 +1,58 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +## dummy stub for https://github.com/JuliaBinaryWrappers/OpenSSL_jll.jl + +baremodule OpenSSL_jll +using Base, Libdl, Base.BinaryPlatforms + +const PATH_list = String[] +const LIBPATH_list = String[] + +export libcrypto, libssl + +# These get calculated in __init__() +const PATH = Ref("") +const LIBPATH = Ref("") +artifact_dir::String = "" +libcrypto_handle::Ptr{Cvoid} = C_NULL +libcrypto_path::String = "" +libssl_handle::Ptr{Cvoid} = C_NULL +libssl_path::String = "" + +if Sys.iswindows() + if arch(HostPlatform()) == "x86_64" + const libcrypto = "libcrypto-3-x64.dll" + const libssl = "libssl-3-x64.dll" + else + const libcrypto = "libcrypto-3.dll" + const libssl = "libssl-3.dll" + end +elseif Sys.isapple() + const libcrypto = "@rpath/libcrypto.3.dylib" + const libssl = "@rpath/libssl.3.dylib" +else + const libcrypto = "libcrypto.so.3" + const libssl = "libssl.so.3" +end + +function __init__() + global libcrypto_handle = dlopen(libcrypto) + global libcrypto_path = dlpath(libcrypto_handle) + global libssl_handle = dlopen(libssl) + global libssl_path = dlpath(libssl_handle) + global artifact_dir = dirname(Sys.BINDIR) + LIBPATH[] = dirname(libssl_path) + push!(LIBPATH_list, LIBPATH[]) +end + +# JLLWrappers API compatibility shims. Note that not all of these will really make sense. +# For instance, `find_artifact_dir()` won't actually be the artifact directory, because +# there isn't one. It instead returns the overall Julia prefix. +is_available() = true +find_artifact_dir() = artifact_dir +dev_jll() = error("stdlib JLLs cannot be dev'ed") +best_wrapper = nothing +get_libcrypto_path() = libcrypto_path +get_libssl_path() = libssl_path + +end # module OpenSSL_jll diff --git a/stdlib/OpenSSL_jll/test/runtests.jl b/stdlib/OpenSSL_jll/test/runtests.jl new file mode 100644 index 0000000000000..35431d04bfcac --- /dev/null +++ b/stdlib/OpenSSL_jll/test/runtests.jl @@ -0,0 +1,10 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +using Test, Libdl, OpenSSL_jll + +@testset "OpenSSL_jll" begin + major = ccall((:OPENSSL_version_major, libcrypto), Cuint, ()) + minor = ccall((:OPENSSL_version_minor, libcrypto), Cuint, ()) + patch = ccall((:OPENSSL_version_patch, libcrypto), Cuint, ()) + @test VersionNumber(major, minor, patch) == v"3.0.15" +end diff --git a/stdlib/Project.toml b/stdlib/Project.toml index cc7ba99dd4e4f..92996cf017d0d 100644 --- a/stdlib/Project.toml +++ b/stdlib/Project.toml @@ -28,12 +28,12 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" MPFR_jll = "3a97d323-0669-5f0c-9066-3539efd106a3" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" -MbedTLS_jll = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" Mmap = "a63ad114-7e13-5084-954f-fe012c677804" MozillaCACerts_jll = "14a3606d-f60d-562e-9121-12d972cd8159" NetworkOptions = "ca575930-c2e3-43a9-ace4-1e988b2c1908" OpenBLAS_jll = "4536629a-c528-5b80-bd46-f80d51c5b363" OpenLibm_jll = "05823500-19ac-5b8b-9628-191a04bc5112" +OpenSSL_jll = "458c3c95-2e84-50aa-8efc-19380b2a3a95" PCRE2_jll = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" diff --git a/stdlib/stdlib.mk b/stdlib/stdlib.mk index b79059d3368b1..006b7a276a3b3 100644 --- a/stdlib/stdlib.mk +++ b/stdlib/stdlib.mk @@ -8,8 +8,8 @@ INDEPENDENT_STDLIBS := \ Markdown Mmap NetworkOptions Profile Printf Pkg REPL Serialization SharedArrays \ SparseArrays Statistics StyledStrings SuiteSparse_jll Tar Test TOML Unicode UUIDs \ dSFMT_jll GMP_jll libLLVM_jll LLD_jll LLVMLibUnwind_jll LibUnwind_jll LibUV_jll \ - LibCURL_jll LibSSH2_jll LibGit2_jll nghttp2_jll MozillaCACerts_jll MbedTLS_jll \ - MPFR_jll OpenLibm_jll PCRE2_jll p7zip_jll Zlib_jll + LibCURL_jll LibSSH2_jll LibGit2_jll nghttp2_jll MozillaCACerts_jll \ + MPFR_jll OpenLibm_jll OpenSSL_jll PCRE2_jll p7zip_jll Zlib_jll STDLIBS := $(STDLIBS_WITHIN_SYSIMG) $(INDEPENDENT_STDLIBS) VERSDIR := v$(shell cut -d. -f1-2 < $(JULIAHOME)/VERSION) From 9a20417b767c02554db3a1d67d7cc3b101cdf112 Mon Sep 17 00:00:00 2001 From: Neven Sajko <4944410+nsajko@users.noreply.github.com> Date: Sun, 5 Jan 2025 03:39:52 +0100 Subject: [PATCH 120/198] Compiler: fix `tmerge(Const(s), Const(t))` st. `(s !== t) && (s == t)` (#56915) Updates #56913 --- Compiler/src/typelimits.jl | 5 +---- Compiler/test/inference.jl | 7 +++++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Compiler/src/typelimits.jl b/Compiler/src/typelimits.jl index e420db030715b..11245fbaee9b0 100644 --- a/Compiler/src/typelimits.jl +++ b/Compiler/src/typelimits.jl @@ -587,7 +587,7 @@ end @nospecializeinfer function tmerge_partial_struct(𝕃::PartialsLattice, @nospecialize(typea), @nospecialize(typeb)) aty = widenconst(typea) bty = widenconst(typeb) - if aty === bty + if aty === bty && !isType(aty) if typea isa PartialStruct if typeb isa PartialStruct nflds = min(length(typea.fields), length(typeb.fields)) @@ -605,9 +605,6 @@ end for i = 1:nflds ai = getfield_tfunc(𝕃, typea, Const(i)) bi = getfield_tfunc(𝕃, typeb, Const(i)) - # N.B.: We're assuming here that !isType(aty), because that case - # only arises when typea === typeb, which should have been caught - # before calling this. ft = fieldtype(aty, i) if is_lattice_equal(𝕃, ai, bi) || is_lattice_equal(𝕃, ai, ft) # Since ai===bi, the given type has no restrictions on complexity. diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index 9301a2809daf3..21d29c376bb27 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -2295,6 +2295,7 @@ let 𝕃ᵢ = InferenceLattice(MustAliasesLattice(BaseInferenceLattice.instance) @test tmerge(MustAlias(2, AliasableField{Any}, 1, Int), Const(nothing)) === Union{Int,Nothing} @test tmerge(Const(nothing), MustAlias(2, AliasableField{Any}, 1, Any)) === Any @test tmerge(Const(nothing), MustAlias(2, AliasableField{Any}, 1, Int)) === Union{Int,Nothing} + tmerge(Const(AbstractVector{<:Any}), Const(AbstractVector{T} where {T})) # issue #56913 @test isa_tfunc(MustAlias(2, AliasableField{Any}, 1, Bool), Const(Bool)) === Const(true) @test isa_tfunc(MustAlias(2, AliasableField{Any}, 1, Bool), Type{Bool}) === Const(true) @test isa_tfunc(MustAlias(2, AliasableField{Any}, 1, Int), Type{Bool}) === Const(false) @@ -2302,6 +2303,12 @@ let 𝕃ᵢ = InferenceLattice(MustAliasesLattice(BaseInferenceLattice.instance) @test ifelse_tfunc(MustAlias(2, AliasableField{Any}, 1, Int), Int, Int) === Union{} end +@testset "issue #56913: `BoundsError` in type inference" begin + R = UnitRange{Int} + @test Type{AbstractVector} == Base.infer_return_type(Base.promote_typeof, Tuple{R, R, Vector{Any}, Vararg{R}}) + @test Type{AbstractVector} == Base.infer_return_type(Base.promote_typeof, Tuple{R, R, Vector{Any}, R, Vararg{R}}) +end + maybeget_mustalias_tmerge(x::AliasableField) = x.f maybeget_mustalias_tmerge(x) = x @test Base.return_types((Union{Nothing,AliasableField{Any}},); interp=MustAliasInterpreter()) do x From 468d5c2b07a0e065541e074cfcdf224029a61940 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Sat, 4 Jan 2025 23:13:23 -0500 Subject: [PATCH 121/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?Downloads=20stdlib=20from=20afd04be=20to=20e692e77=20(#56953)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: giordano <765740+giordano@users.noreply.github.com> --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/Downloads.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/md5 delete mode 100644 deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/sha512 create mode 100644 deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/md5 create mode 100644 deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/sha512 diff --git a/deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/md5 b/deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/md5 deleted file mode 100644 index f0d72ab470aeb..0000000000000 --- a/deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -9dbfa6c0a76d20b2ca8de844d08f3af4 diff --git a/deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/sha512 b/deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/sha512 deleted file mode 100644 index 7abbb06818d75..0000000000000 --- a/deps/checksums/Downloads-afd04be8aa94204c075c8aec83fca040ebb4ff98.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -f5d2469419f4a083f84c1f23e6e528f4115804e45bdfdbd897110bb346aaa70afc57c24f9166ae20fb4305c1d40f5a77de4cfed7b69aef93f09d0d4eff183e3d diff --git a/deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/md5 b/deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/md5 new file mode 100644 index 0000000000000..221a62b1cf231 --- /dev/null +++ b/deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/md5 @@ -0,0 +1 @@ +cdaea923f7fa855409e8456159251f54 diff --git a/deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/sha512 b/deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/sha512 new file mode 100644 index 0000000000000..b537ef2e9e1f6 --- /dev/null +++ b/deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/sha512 @@ -0,0 +1 @@ +e893fbe079a433c3038b79c4c2998d1ae9abaf92ff74152820a67e97ffee6f7f052085a7108410cbb1a3bd8cc6670736b0827c8b0608cc31941251dd6500d36a diff --git a/stdlib/Downloads.version b/stdlib/Downloads.version index 3d1da64bdfe11..40004d8337091 100644 --- a/stdlib/Downloads.version +++ b/stdlib/Downloads.version @@ -1,4 +1,4 @@ DOWNLOADS_BRANCH = master -DOWNLOADS_SHA1 = afd04be8aa94204c075c8aec83fca040ebb4ff98 +DOWNLOADS_SHA1 = e692e77fb5427bf3c6e81514b323c39a88217eec DOWNLOADS_GIT_URL := https://github.com/JuliaLang/Downloads.jl.git DOWNLOADS_TAR_URL = https://api.github.com/repos/JuliaLang/Downloads.jl/tarball/$1 From d848e2e9dafbdaf74000da5e109e2af8f49a4acd Mon Sep 17 00:00:00 2001 From: FX Coudert Date: Sun, 5 Jan 2025 11:24:25 +0100 Subject: [PATCH 122/198] Curl 8.11.1 and nghttp2 1.64.0 (#56951) Trying to update these two deps: Curl 8.11.1 and nghttp2 1.64.0 --- deps/checksums/curl | 70 ++++++++++++++-------------- deps/checksums/nghttp2 | 72 ++++++++++++++--------------- deps/curl.version | 5 +- deps/nghttp2.version | 2 +- stdlib/LibCURL_jll/Project.toml | 2 +- stdlib/Manifest.toml | 4 +- stdlib/nghttp2_jll/Project.toml | 2 +- stdlib/nghttp2_jll/test/runtests.jl | 2 +- 8 files changed, 79 insertions(+), 80 deletions(-) diff --git a/deps/checksums/curl b/deps/checksums/curl index f96fe5f1a15e3..5331e54d30d4a 100644 --- a/deps/checksums/curl +++ b/deps/checksums/curl @@ -1,36 +1,38 @@ LibCURL-a65b64f6eabc932f63c2c0a4a5fb5d75f3e688d0.tar.gz/md5/e8c53aa3fb963c80921787d5d565eb2c LibCURL-a65b64f6eabc932f63c2c0a4a5fb5d75f3e688d0.tar.gz/sha512/8e442ea834299df9c02acb87226c121395ad8e550025ac5ee1103df09c6ff43817e9e48dd1bcbc92c80331ef3ddff531962430269115179acbec2bab2de5b011 -LibCURL.v8.9.1+0.aarch64-apple-darwin.tar.gz/md5/8a1929a2dc1a6682ff9ff7f66cda25f4 -LibCURL.v8.9.1+0.aarch64-apple-darwin.tar.gz/sha512/e491542103f6e1a34caf96cfae7f31ba12588c50517ca2c974be907c664cd873b554009e538fd7db7d31ebe46d68330da3fcf14ffe9fcbbda73b6d1919ea966d -LibCURL.v8.9.1+0.aarch64-linux-gnu.tar.gz/md5/eb5f8fdb31189047527af3b98c6959b0 -LibCURL.v8.9.1+0.aarch64-linux-gnu.tar.gz/sha512/6fd5e489f63edec29efd20165b0888e86d0b53a19d352bebbdb0afc00a1f6478eec524143797307ab7a799cf924d2c76bd5ece9d9fd8fdc9346ba3c739a1fe83 -LibCURL.v8.9.1+0.aarch64-linux-musl.tar.gz/md5/6202ec4890ae02cf2a7999fe5e24d77c -LibCURL.v8.9.1+0.aarch64-linux-musl.tar.gz/sha512/caf00ed30075d000efc638586520dac2e22f8ba04924d42dbe27bc1bd715aa7b2dbede062de296fc080a33d0aead6099a870f38d017a69693097413056629b1b -LibCURL.v8.9.1+0.armv6l-linux-gnueabihf.tar.gz/md5/5bd474f4e09b4fe7658b2497861a580e -LibCURL.v8.9.1+0.armv6l-linux-gnueabihf.tar.gz/sha512/ff6b58cfff9a7433d9191766e3fe652f0b5b10fbc6da8fb03ca04ed44a46a36158fb7d8096932617011389fb5505844d5c4ef2c29bcf1c8da811287def4e91f9 -LibCURL.v8.9.1+0.armv6l-linux-musleabihf.tar.gz/md5/8f071c5389ba1df7d4d22683f068b6de -LibCURL.v8.9.1+0.armv6l-linux-musleabihf.tar.gz/sha512/b8be3a8df717d0921ec225ce87dd9cd4fc9e13fd1f39c4906d02f30dcae24971f1798b017f3af346c603030cfa80869c117cdb5dff8e7762ee2e72c4027ef7a1 -LibCURL.v8.9.1+0.armv7l-linux-gnueabihf.tar.gz/md5/120e51d99907522150d79c44812decfa -LibCURL.v8.9.1+0.armv7l-linux-gnueabihf.tar.gz/sha512/b512a75cb3185904661375760250132c58678f43002a9ba0608de60dcca6afc1e2eef567a9f42f2d3dfa0be1ff01cb15f68980adebada220728521b13367b77d -LibCURL.v8.9.1+0.armv7l-linux-musleabihf.tar.gz/md5/e8a59894ccb325fb424a3e5861c854f7 -LibCURL.v8.9.1+0.armv7l-linux-musleabihf.tar.gz/sha512/3bb4afef9b7be04f17a4e2e20e020bcfbf5fb4a36bc699a90337d76a108f75600fff49c877652956431946a948f42054497621593f1c6c593a537fe08ceda1c2 -LibCURL.v8.9.1+0.i686-linux-gnu.tar.gz/md5/1034cd95f6369cd994979c8653786639 -LibCURL.v8.9.1+0.i686-linux-gnu.tar.gz/sha512/5f7f755d17770dc8b995f2bbc817fda96db23da751439e5929526482b8f854f4ed73c6e930df0dd1657756f8951edd4f3c41be80f3b812a793678b6ededd855e -LibCURL.v8.9.1+0.i686-linux-musl.tar.gz/md5/ad4a4cf21d15b48ce27275af67079075 -LibCURL.v8.9.1+0.i686-linux-musl.tar.gz/sha512/9e5c6d0d91d966154e3ecd8cd71c9b31841debc036b847dec684dcf3189ca617cd0bca4b73cf9440e55133e36ebafb02730c598c133dc33a9e164ba43c689506 -LibCURL.v8.9.1+0.i686-w64-mingw32.tar.gz/md5/300a71d7ba8c858f9ed85d761dfeef32 -LibCURL.v8.9.1+0.i686-w64-mingw32.tar.gz/sha512/a916f60a7c8ed41a56686d1145be73dc0162349ce1d098dbd12441fcc97a3f0bd4c5750d3e58e4cfe7e9ba7e0d3817bf592bd99a946cd6b45b296636c3220766 -LibCURL.v8.9.1+0.powerpc64le-linux-gnu.tar.gz/md5/0657e472b888b089c448695d200346d0 -LibCURL.v8.9.1+0.powerpc64le-linux-gnu.tar.gz/sha512/a81f25260c4204a069a87463d9ef58169d9286125daaf23b4e2295fc8108ef536049fd07248ca3f1caa2aac3eb0b376d2c64281d0302dfea6f0a782dfb3988fd -LibCURL.v8.9.1+0.x86_64-apple-darwin.tar.gz/md5/3638b3365e97dd516d1eaa6f03892fe6 -LibCURL.v8.9.1+0.x86_64-apple-darwin.tar.gz/sha512/4e6c76fde045134c869dbaab52b28dc809541209077aa54d2e870b9aa29f3d43a8040f3194e06e519642348fc4de6aa49fcb04880a4707bae4e55206ac70f01b -LibCURL.v8.9.1+0.x86_64-linux-gnu.tar.gz/md5/e48dd6fe9078600bf6db0fdd6f986b76 -LibCURL.v8.9.1+0.x86_64-linux-gnu.tar.gz/sha512/e6c33bdac80c9463d6d067f77cf7f2f595258e5f292fd133b5f5782e678004bed925c8bcbba1c708f2f535a0db7a0527fce9acef5250469a958ee11dff533c8f -LibCURL.v8.9.1+0.x86_64-linux-musl.tar.gz/md5/2d219b4c0ba83dfce64b93c1e4d6ef24 -LibCURL.v8.9.1+0.x86_64-linux-musl.tar.gz/sha512/5fb8bb08d357ea3b7c9e417838bf37198ae673185c4f4564ecd1a06ce0e72c4c804909e8c6ffeafefb3460ad151308f662b3128ab5d4149f035de0fa9890506b -LibCURL.v8.9.1+0.x86_64-unknown-freebsd.tar.gz/md5/66e715f6934f360398e527f534f6f5c5 -LibCURL.v8.9.1+0.x86_64-unknown-freebsd.tar.gz/sha512/64334fb156c15b7aa56e4ef81b9d81f93be6ee4c7a61d921bb09cb9951eeb3309197ac89150bde0187e7cecd6e53626e91b7bba14f0daaa0ba472563541c9ff1 -LibCURL.v8.9.1+0.x86_64-w64-mingw32.tar.gz/md5/672ffcacf3e1bc72d7cf244af0cbc5a2 -LibCURL.v8.9.1+0.x86_64-w64-mingw32.tar.gz/sha512/ea265d172a242026cbf7e6b991904aa403a7f491a1c55f91b444776782ad0ca2fdf4882735d1ed04e90df8b38a754f4d0181ad8c17f5fbd75b40a6b908ebbd36 -curl-8.9.1.tar.bz2/md5/8feb255a16590f2465926d7627f86583 -curl-8.9.1.tar.bz2/sha512/27e4b36550b676c42d1a533ade5b2b35ac7ca95e1998bd05cc34b5dfa3bdc9c0539ec7000481230b6431baa549e64da1b46b39d6ba1f112e37458d7b35948c2e +LibCURL.v8.11.1+1.aarch64-apple-darwin.tar.gz/md5/890c65523227b4352344b78575cd4c5c +LibCURL.v8.11.1+1.aarch64-apple-darwin.tar.gz/sha512/fae539243adc805d8da0ac88cf67901ff1f12ae94e40293dc6a7e17072f8c0cb9f0a54b7e324bd52ad9361b764c8bc88728ff4495e0cd6dbf1eb93d2bae8994b +LibCURL.v8.11.1+1.aarch64-linux-gnu.tar.gz/md5/bf937fb6a8ea8a82b732821f3652641c +LibCURL.v8.11.1+1.aarch64-linux-gnu.tar.gz/sha512/230c9983e4c7810d3eee1a5eff7e8b8c44f76db7af8a8312a608609f87bc8a56031c337c06af00a536c10ed33725200aa137c3153ef6dcf6575cc7c350b3b461 +LibCURL.v8.11.1+1.aarch64-linux-musl.tar.gz/md5/b40ea4266dc48a1fbfa016fb8d0ca987 +LibCURL.v8.11.1+1.aarch64-linux-musl.tar.gz/sha512/032d6208ebe226da90d0ef1f1f2d20580fd4e37db68146d1e836a9be4c1fc5f7890f1b808337ca41f46a07a833b55f06f09a4a164f26d0824a649ea40b30233f +LibCURL.v8.11.1+1.aarch64-unknown-freebsd.tar.gz/md5/69097390c0bd3a32969e47608f24363f +LibCURL.v8.11.1+1.aarch64-unknown-freebsd.tar.gz/sha512/391019370a9c122e6425a3097edafe0980dc2077be015919e7914aa781ba10060e3af9ee1fa881d8536d0ca57783d0616a1b5735e2ae7e06ea4edfaee2994120 +LibCURL.v8.11.1+1.armv6l-linux-gnueabihf.tar.gz/md5/bc4ab567f8cc4cd88b2239123d103113 +LibCURL.v8.11.1+1.armv6l-linux-gnueabihf.tar.gz/sha512/0ecbf2380852744815a8f7e99e7c276c342f847907eb7b0d256905ba854ee59d37f83456fcdc8931dc39dbaed58f0949205b80d23e43e2b59195d18a539d4047 +LibCURL.v8.11.1+1.armv6l-linux-musleabihf.tar.gz/md5/18c896c544f02f7f2b976c03fc3772f1 +LibCURL.v8.11.1+1.armv6l-linux-musleabihf.tar.gz/sha512/e9a73670f1c3638c3a886055b32df5baadc41aad9829cfa0d4e05acd46d2d012464114ed6fd1e3d182a4adc266c1da97e9a683c7ba69e93f61592acf8567e336 +LibCURL.v8.11.1+1.armv7l-linux-gnueabihf.tar.gz/md5/4672f9d67ff357a2eda6f77d8f470659 +LibCURL.v8.11.1+1.armv7l-linux-gnueabihf.tar.gz/sha512/a2f2dc8d8e10c652a324a4da3d2337d2886626e1c417c68efbcfcefa443cb3ec81b52f2a212c4a7dbd6a5ae920e54d1bfdc02b68c2607d09784206cd4d11ffb0 +LibCURL.v8.11.1+1.armv7l-linux-musleabihf.tar.gz/md5/49d297563fd44a03f88f67bb7ea2a0be +LibCURL.v8.11.1+1.armv7l-linux-musleabihf.tar.gz/sha512/5cc3902571f04c96be38de53b5320876a3e7e54934090ff2a80304a7ca59a361ed9f3f328c3e3c06ef33550d221a8243e924b7ea49792753f839c12aceb1e979 +LibCURL.v8.11.1+1.i686-linux-gnu.tar.gz/md5/f05a86574278ecf7802edeffe1fee9ac +LibCURL.v8.11.1+1.i686-linux-gnu.tar.gz/sha512/e493b5836022a6280f21237fef423034a9701097cb271683e81d4b4e487a6289080d00016fbaaa8bddeb004d44626a0076fa7832835fe7f58b60af6798223f89 +LibCURL.v8.11.1+1.i686-linux-musl.tar.gz/md5/03340412ba27f231dbf2de58a1af871f +LibCURL.v8.11.1+1.i686-linux-musl.tar.gz/sha512/541fbdd5570432832d3835038b41df73aac8e0e7bc03f41c696dc12a57bd4784b4da1f485264fd1fba263fe9e520a7dbb0ef9a365275efc30dfc361ceab252f3 +LibCURL.v8.11.1+1.i686-w64-mingw32.tar.gz/md5/5f2071282d572bbb53dfcfb16d0d9608 +LibCURL.v8.11.1+1.i686-w64-mingw32.tar.gz/sha512/e4d6fbd518055e8f2a71b89ee9a33728e6e076729adeafc358fc40f47d032b739363c9b57df5bfb3c43244f7b833afc76ae255e70bcf43b81262d74278532a22 +LibCURL.v8.11.1+1.powerpc64le-linux-gnu.tar.gz/md5/806ee9b51c2bffd798c1682867a7a2a0 +LibCURL.v8.11.1+1.powerpc64le-linux-gnu.tar.gz/sha512/20ae5f47ad24e1fba8ecdc3a81aa81acb5c3c224041f12f8be48f9a0abd5ce44117b096a59fc8f861b6f8c6ad9e4177e3a3ba3e2dbecb2078d4bab19bdd4d239 +LibCURL.v8.11.1+1.x86_64-apple-darwin.tar.gz/md5/56cf7cf4ea22123e516843a5751eea17 +LibCURL.v8.11.1+1.x86_64-apple-darwin.tar.gz/sha512/5ae5569ade42cdf0a1aa8acfda7d1dd3df30d498637f83e93bd9f8be883ae777e789b417be24df83e42ebe32fb67cc328bedac3dc231d3569f585641175ed257 +LibCURL.v8.11.1+1.x86_64-linux-gnu.tar.gz/md5/a4a733fe879693e83e1f05b6ef742ea6 +LibCURL.v8.11.1+1.x86_64-linux-gnu.tar.gz/sha512/2767f49d4a528080a5c7fcdecd8374dd5498c5b1e0d65f58d027f6a9138cd00203732e5da1806b689efbaacb1ee905a6839a09eab35f0174279af314a34fca81 +LibCURL.v8.11.1+1.x86_64-linux-musl.tar.gz/md5/837a64073c3d8fd115cadf4af1b19235 +LibCURL.v8.11.1+1.x86_64-linux-musl.tar.gz/sha512/cf0559b65c213889ab0bad388ca6dc1699891e5cd2c5c34faf80cd60404b5f363eaa624d425fd463407d35c5cfd814c1a9964a2b3b638fa7e7a0a2919980ba8c +LibCURL.v8.11.1+1.x86_64-unknown-freebsd.tar.gz/md5/22726eb8caed9b279e6cddbfa328f2c6 +LibCURL.v8.11.1+1.x86_64-unknown-freebsd.tar.gz/sha512/b9e304575bb0e3241f938c545a91cc5b722e8dfc53d6ad270ea75b8fb05655ae8a03e5f844f5b8a75a84133d0883369bc6c46f0805be37ee840f2f1168994c37 +LibCURL.v8.11.1+1.x86_64-w64-mingw32.tar.gz/md5/aa5ce49a63d216776ef9fc11b6b3b012 +LibCURL.v8.11.1+1.x86_64-w64-mingw32.tar.gz/sha512/4e7fe5ff82ca9bafbaca476aa51273ee9590058350c889a6dd8a0eecaa024d19f0a26dd7078808d08dfdf2f5751daec51e88dc88253a4638274edb63ae93fd3c +curl-8.11.1.tar.bz2/md5/31dc730e6fff880a6ba92bdacead9d38 +curl-8.11.1.tar.bz2/sha512/30041e15b919684c46b6b3853950cba22e6fbc21157b1f682097277d2b20066ba71e51eb5d2c34bbd81b8bf4c2791255d6492ee21d49f606d71f66e211a6adde diff --git a/deps/checksums/nghttp2 b/deps/checksums/nghttp2 index e552dfe9329b0..6b4752d4e5527 100644 --- a/deps/checksums/nghttp2 +++ b/deps/checksums/nghttp2 @@ -1,36 +1,36 @@ -nghttp2-1.63.0.tar.bz2/md5/c29228929c3c323ecd0eae172f1eb9d5 -nghttp2-1.63.0.tar.bz2/sha512/a328b4642c6ca4395adfcaaf4e6eb6dbd39fa7bd86f872a76260af59a5a830e0ff5ad015865d6bc00e0baa8e4d0d9a67b4b97e9d78e5e05d1c53522364e5e235 -nghttp2.v1.63.0+1.aarch64-apple-darwin.tar.gz/md5/d11717d2fa4d04a374c55b86c790366a -nghttp2.v1.63.0+1.aarch64-apple-darwin.tar.gz/sha512/10dd24435818b66c92399941d3ea3280451f039e59112a866f973cdfe5602136e366f2bdb4638a1264f48fde737be4e50a49e44934971b4c69284377f4d9cf53 -nghttp2.v1.63.0+1.aarch64-linux-gnu.tar.gz/md5/5ebe2395d0d31b6481a4218468ec82a4 -nghttp2.v1.63.0+1.aarch64-linux-gnu.tar.gz/sha512/e7aff0eaa99be3b5e8539f160e1e5cf53bf1efa6b5f07d625796353a36ef12473946562731cedd570205229d263f81fd692b222a01297b09c89ce0e49edeff7a -nghttp2.v1.63.0+1.aarch64-linux-musl.tar.gz/md5/95c492eeca62b92baf8f8fa11a1da41f -nghttp2.v1.63.0+1.aarch64-linux-musl.tar.gz/sha512/10c0b3f560b1ff7ca9fe5cbc3340ec7789ecdeddf5d857d5c1245d1519074bd105f68c29714f36c8c9b688c5bf42133b30cbabed450410b79bb4f1f1d1474ef6 -nghttp2.v1.63.0+1.aarch64-unknown-freebsd.tar.gz/md5/c6fe5cea3d1386532f75f512e3641a7c -nghttp2.v1.63.0+1.aarch64-unknown-freebsd.tar.gz/sha512/20437e066e13b770f014e30b57830237bf38c3ecc56e716208c5103a7c242fec6cedcf78e641004891afa40ce945bfe1319d11aab4810a76ceeb6ff10373984c -nghttp2.v1.63.0+1.armv6l-linux-gnueabihf.tar.gz/md5/995dbd522109b882eaf7bedec84e8372 -nghttp2.v1.63.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/faf7ca13cd1d3050a5c693c61a5e92b560e1c0c2e30833162cc7aeefcd31c018b2015dbdbf543f38ddec2aefe78927af5f30f3938dc6a67b3b84fc399513c8cf -nghttp2.v1.63.0+1.armv6l-linux-musleabihf.tar.gz/md5/7bf7063ee64eb9b41212a6c39111de4f -nghttp2.v1.63.0+1.armv6l-linux-musleabihf.tar.gz/sha512/3091a4373508e1913e69d76688fd31d57d8e01e15c39c8859b025ac19ff23a0d396dc771fb0a2860ee1913866c0b0dbc4432fbcd0283b5cbecfb02235c738762 -nghttp2.v1.63.0+1.armv7l-linux-gnueabihf.tar.gz/md5/645de11170289308ce00ed089853271c -nghttp2.v1.63.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/bd974e629cd2626fc67a20b175e82e3a0dc742ee0c1b82b505395ebb7ce282def7d123b9bd8c4f7e3386db6c2c3d38d94475a00d96efb504a06fc2371db5a9e2 -nghttp2.v1.63.0+1.armv7l-linux-musleabihf.tar.gz/md5/8b5776769ec5577fde617814ccf57a7c -nghttp2.v1.63.0+1.armv7l-linux-musleabihf.tar.gz/sha512/7d463687abdfb600fcc11fd62b4973cdabdcfc076c5ace554af126ba6b0d925b9ff3eb3a9f730af6e4ef39d6ca1930084833a159d205a4230c88bbc82da7a3b6 -nghttp2.v1.63.0+1.i686-linux-gnu.tar.gz/md5/beb06b6d634fce5c15453c216c50d6b7 -nghttp2.v1.63.0+1.i686-linux-gnu.tar.gz/sha512/0616ffb2a98aa4cfdfbcaa408a6b33815a8e52af60417081854afb7b500e433f9fd63dff633df40507829217e96058f8b27184e50f442c175480e975f2387e13 -nghttp2.v1.63.0+1.i686-linux-musl.tar.gz/md5/ab15ac7ffaaeb7e69f7cad24ed3a6c4e -nghttp2.v1.63.0+1.i686-linux-musl.tar.gz/sha512/c9c18a6e255f4e3f81a9ee27b8ac58149507bce3dc9e79acbba8573ed66908c6cf3dcd29d9b989e47788977e6dec474c291f764fc1cfd718f20557001ca363c7 -nghttp2.v1.63.0+1.i686-w64-mingw32.tar.gz/md5/415858a5c10d7f2473174224e44ef3f6 -nghttp2.v1.63.0+1.i686-w64-mingw32.tar.gz/sha512/575c425df04c084980e8b9149579b787bf7ff38eecd958f38164db0bb0b4c331d4f9d6534f2c2cf1a105fc922ecba1d654a6a48a9a390f53bbcb4e8c2edbb0c7 -nghttp2.v1.63.0+1.powerpc64le-linux-gnu.tar.gz/md5/b2b8216a50aa7dd670e14ad47de31c3f -nghttp2.v1.63.0+1.powerpc64le-linux-gnu.tar.gz/sha512/c41570c8aa245fc2dce2a824cd73c4132ae2a65f9347d097462624917d637da34652c7f693e595a1f1ff1376171be4e2d48633d00dd6cafb00cd6cc974d9fa9e -nghttp2.v1.63.0+1.x86_64-apple-darwin.tar.gz/md5/878b3344f3656d663e33d7afc2fefb21 -nghttp2.v1.63.0+1.x86_64-apple-darwin.tar.gz/sha512/3f9cd4b20b149f8166f8411dc922c80a483113722f9a54c6274b3d4527dfd54bd5723fbd60535d8e90196f1d4e6e5c415f839b34cc4dc8c98eceee5466666471 -nghttp2.v1.63.0+1.x86_64-linux-gnu.tar.gz/md5/96fbea72cc42fa050fb0c9cb065588c8 -nghttp2.v1.63.0+1.x86_64-linux-gnu.tar.gz/sha512/47dd191ec2eb91b34ac9acd1802515778b2cea930c7c5876db3812566d3959e8a0e47bcee9601866180e40c9fd382d1599ca205a6229aaebdfa47e689f6ebd23 -nghttp2.v1.63.0+1.x86_64-linux-musl.tar.gz/md5/d68d6aac8629d95b2cd1b218152cc529 -nghttp2.v1.63.0+1.x86_64-linux-musl.tar.gz/sha512/fdac9dacd1392322cdc308997d7205b7194f897e21ff15fe4eda7c9c8a3b0b2b777cbc54723d884c341ef46467fc4fa056054ebff0f849090464ced031ff98f7 -nghttp2.v1.63.0+1.x86_64-unknown-freebsd.tar.gz/md5/61ecaf1d84e6b203ca7e601a91dc68e3 -nghttp2.v1.63.0+1.x86_64-unknown-freebsd.tar.gz/sha512/c25a017148ff7f01299a9a7cead87251f1a31fd404f4b1f5413fe9b09823ae471173f8d0828b096bb0ac7411e23d354f2c9e2596668d38d9a509831c6b4f5624 -nghttp2.v1.63.0+1.x86_64-w64-mingw32.tar.gz/md5/60ceb3ff3f5287b2782dfd98db4f1816 -nghttp2.v1.63.0+1.x86_64-w64-mingw32.tar.gz/sha512/971fd9e24c393fc594ae813caa7b14052320d924309bea0bd77c847ce0e86803cb803be051812ea029baf632deff6f9f8200dbc41f9bc143eba098adc294e757 +nghttp2-1.64.0.tar.bz2/md5/103421866471b6d5fc828189552d98a5 +nghttp2-1.64.0.tar.bz2/sha512/3b3d16168f6ea5a3e8a7b30b6545b86ff6be874771a1a8d502cbdc7c46f80195c1b8190b5279030aa2edea54fec40962cf245ce4fe89cdf89f06e3f091a34cda +nghttp2.v1.64.0+1.aarch64-apple-darwin.tar.gz/md5/67a5c302c3d1089682e2d6c251273f7b +nghttp2.v1.64.0+1.aarch64-apple-darwin.tar.gz/sha512/88abd96e47d85072abb74d65c0f4872134768b7703a9bb5e5e3f1fb8bdf4d0f6a9f07fbe76089c6746b22787774f362246092c3b2155e94345216aef9f67f2ac +nghttp2.v1.64.0+1.aarch64-linux-gnu.tar.gz/md5/f45a84bd28f598305002f154fb02e3da +nghttp2.v1.64.0+1.aarch64-linux-gnu.tar.gz/sha512/95e1034e1fcd5d96a5ed01e9870af27ee160cdcd624a196dbde31ad400768a55fae39ba11c22a868a5ec79e36e98dcf6a4f37c706e91e466fd01d9b8da868d78 +nghttp2.v1.64.0+1.aarch64-linux-musl.tar.gz/md5/a2680c3d4d94433c787fc1b75f4ab096 +nghttp2.v1.64.0+1.aarch64-linux-musl.tar.gz/sha512/8c02e4e3dfdefecc8c01b397ba8ece94be8f478aa63752d5310517728715b105101f371c281575de7e7c0678b31a7c7cfd021383d000b6f747992bbe47242047 +nghttp2.v1.64.0+1.aarch64-unknown-freebsd.tar.gz/md5/4d69a91c94fabf6af9f5197607639a58 +nghttp2.v1.64.0+1.aarch64-unknown-freebsd.tar.gz/sha512/8d679a0a9ee8a2136da71102eeaf511209c217c771a113fe2fa1736ac232a5637aeafa41ea53fb8ea2514857198cb907a4a8ea5667a325257f527cea4f2c5464 +nghttp2.v1.64.0+1.armv6l-linux-gnueabihf.tar.gz/md5/f44f3dde6ce2f4e34241a336c6f71934 +nghttp2.v1.64.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/02bda6e05712de74805a6895a2f8f29b5930af2c62fed2b3e8a8fcd210c3542484131a5442c8ff707a7ac20c16eae93752609aeb6123b2296346c6399a0369b6 +nghttp2.v1.64.0+1.armv6l-linux-musleabihf.tar.gz/md5/a4dd8ed38b411d4b7c2a3411e6d59b6e +nghttp2.v1.64.0+1.armv6l-linux-musleabihf.tar.gz/sha512/a0552be25160d1878bfb10b30da23381d9d7f9ee7c749b0fb18a0a98ea1e9dcd53b103512b3fe2c98752063385b51551efff0dd0d9190db0105550595cd61d5e +nghttp2.v1.64.0+1.armv7l-linux-gnueabihf.tar.gz/md5/f0f309affb5726efdd93cc4ed0ef25c3 +nghttp2.v1.64.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/55974dc62616e50d1cb1efda380edec6b69dfa175773abc48045ae34b545a19cc50b7a53b12b67dfd9bed9200fbba543875bb821d80e7c3dfcc2aaa3442a5a66 +nghttp2.v1.64.0+1.armv7l-linux-musleabihf.tar.gz/md5/ca090db026ea470523b8cb2c93eed8ac +nghttp2.v1.64.0+1.armv7l-linux-musleabihf.tar.gz/sha512/d2dccf74baa66abd5ecbb187efbd79bf8a43e0b920d7f4c94b6569dd71b74aa4eb6dfcd8d090bd8841496e3f4aa184028b907faf5a0ea3f91df3bb8e286a27c2 +nghttp2.v1.64.0+1.i686-linux-gnu.tar.gz/md5/aebffa8c32cc829f9fb7089ff972b215 +nghttp2.v1.64.0+1.i686-linux-gnu.tar.gz/sha512/f43e4d90f4ca755ea2b4fc90f10944562e9a7b9666b8469bb0fbe12df38c9db9625bfd6f4f4ec16d7da3cb5e3e9e3d85b1bffb56be18d746ae7be2c3dae9a306 +nghttp2.v1.64.0+1.i686-linux-musl.tar.gz/md5/64cc8696b37eeb2a225a02412d73e86d +nghttp2.v1.64.0+1.i686-linux-musl.tar.gz/sha512/2995ab7123630c2c7c606422b25a0a7761642d72177f26046b781209b13d7e90678923dacad35637df7cd171608d44f5d7d3c586768a1d4eaef0751a1f108c04 +nghttp2.v1.64.0+1.i686-w64-mingw32.tar.gz/md5/2ed9ff15d05f6cef7bf85bb19621a2fe +nghttp2.v1.64.0+1.i686-w64-mingw32.tar.gz/sha512/45f38653664cc7343b66561a9b5bfec341593504714afbcb35a856343e583d2e75cab8062b2ff23ebdf4625607748f5c70b1ae79cc047a4073eb8d01f8252338 +nghttp2.v1.64.0+1.powerpc64le-linux-gnu.tar.gz/md5/4622f699a44d02570298daf5864cf60b +nghttp2.v1.64.0+1.powerpc64le-linux-gnu.tar.gz/sha512/f2cc88fd537503ac138518b7f72a67c18508307c0dddca41d44c8496ca4dd8f15aa133e08f13e03b2fbb3c83272ea433456c9ebb929f648a7b2af13fcd048d71 +nghttp2.v1.64.0+1.x86_64-apple-darwin.tar.gz/md5/c6e5d0a179f065f4aab2b8661e6fc2d4 +nghttp2.v1.64.0+1.x86_64-apple-darwin.tar.gz/sha512/77073fecbdac780dea34c9cb42b019b7cfe8a125a1356cd7de2ffd3aebeb29aa6251008574efa8d0a017e86023248fdd93e50c4ed2952d8a23cb67e0cf557a74 +nghttp2.v1.64.0+1.x86_64-linux-gnu.tar.gz/md5/805f31fffc112ea45716b8a661911696 +nghttp2.v1.64.0+1.x86_64-linux-gnu.tar.gz/sha512/73ba29b4f65eeab2ea5c195cb17279d8234b6a650a1b58d0494a564725cd9c76c89321cd455280dd2627d6ba48e91a68be8bdcb5472eae9c3cfc3c2623892963 +nghttp2.v1.64.0+1.x86_64-linux-musl.tar.gz/md5/fbd3da6f5b100767ab7cb77ca6e6074b +nghttp2.v1.64.0+1.x86_64-linux-musl.tar.gz/sha512/493f632d1ba08a0e8114c883d7fef12e364b0b2556e57ed8fd8d8716c43251675f3f60808e32ec430949c4480d5eb052a7837abda2f3e7423ffc658b45805e41 +nghttp2.v1.64.0+1.x86_64-unknown-freebsd.tar.gz/md5/1dba5e39ebfa6c6aac668d5488fb0a41 +nghttp2.v1.64.0+1.x86_64-unknown-freebsd.tar.gz/sha512/259c7cac2cc45a5ebf0c9f90277d6aee68332fe37e8269f93a7d72fae40d41899e6ee63c211dcee81d6bcf056d81e89624e1d09f960039a950b8709b5966ee49 +nghttp2.v1.64.0+1.x86_64-w64-mingw32.tar.gz/md5/228fd64b1581ca3a8a45646b434bbf2a +nghttp2.v1.64.0+1.x86_64-w64-mingw32.tar.gz/sha512/c9ac17a35cd89e71c3a29165f29bb86bc589635bfafc70e64f7437200a886db8a74291ab40b255d977fa0b4bf8d88b12f75cf3ba75163dd906e08c30ec200b8f diff --git a/deps/curl.version b/deps/curl.version index ff360676b335a..fbbb55ffb17ea 100644 --- a/deps/curl.version +++ b/deps/curl.version @@ -3,7 +3,4 @@ CURL_JLL_NAME := LibCURL ## source build -# curl version 8.10 and later seem to be broken, probably due to a bug -# on Julia. See -# . -CURL_VER := 8.9.1 +CURL_VER := 8.11.1 diff --git a/deps/nghttp2.version b/deps/nghttp2.version index c9a39ea5ae757..a3cd46d457c2c 100644 --- a/deps/nghttp2.version +++ b/deps/nghttp2.version @@ -3,4 +3,4 @@ NGHTTP2_JLL_NAME := nghttp2 ## source build -NGHTTP2_VER := 1.63.0 +NGHTTP2_VER := 1.64.0 diff --git a/stdlib/LibCURL_jll/Project.toml b/stdlib/LibCURL_jll/Project.toml index e7dac4c687ab1..61d44beac14e1 100644 --- a/stdlib/LibCURL_jll/Project.toml +++ b/stdlib/LibCURL_jll/Project.toml @@ -1,6 +1,6 @@ name = "LibCURL_jll" uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.9.1+0" +version = "8.11.1+1" [deps] LibSSH2_jll = "29816b5a-b9ab-546f-933c-edad1886dfa8" diff --git a/stdlib/Manifest.toml b/stdlib/Manifest.toml index 8c638415062b2..63da40a5630f5 100644 --- a/stdlib/Manifest.toml +++ b/stdlib/Manifest.toml @@ -93,7 +93,7 @@ version = "0.6.4" [[deps.LibCURL_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.9.1+0" +version = "8.11.1+1" [[deps.LibGit2]] deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] @@ -292,7 +292,7 @@ version = "5.11.0+0" [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.63.0+1" +version = "1.64.0+1" [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] diff --git a/stdlib/nghttp2_jll/Project.toml b/stdlib/nghttp2_jll/Project.toml index acc9444ab4a26..030f4a8a0b9d1 100644 --- a/stdlib/nghttp2_jll/Project.toml +++ b/stdlib/nghttp2_jll/Project.toml @@ -1,6 +1,6 @@ name = "nghttp2_jll" uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.63.0+1" +version = "1.64.0+1" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/nghttp2_jll/test/runtests.jl b/stdlib/nghttp2_jll/test/runtests.jl index d667ce53e5252..13e7adaad9df6 100644 --- a/stdlib/nghttp2_jll/test/runtests.jl +++ b/stdlib/nghttp2_jll/test/runtests.jl @@ -11,5 +11,5 @@ end @testset "nghttp2_jll" begin info = unsafe_load(ccall((:nghttp2_version,libnghttp2), Ptr{nghttp2_info}, (Cint,), 0)) - @test VersionNumber(unsafe_string(info.version_str)) == v"1.63.0" + @test VersionNumber(unsafe_string(info.version_str)) == v"1.64.0" end From 3f0a5ae5f19c849ecaa8d7f4e76b07b2b64b19a9 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 5 Jan 2025 12:14:52 +0100 Subject: [PATCH 123/198] Fix running Compiler tests standalone (#56952) --- Compiler/src/bootstrap.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/Compiler/src/bootstrap.jl b/Compiler/src/bootstrap.jl index ea7510df313c7..26fcfde5f256f 100644 --- a/Compiler/src/bootstrap.jl +++ b/Compiler/src/bootstrap.jl @@ -15,6 +15,7 @@ function activate_codegen!() end) end +global bootstrapping_compiler::Bool = false function bootstrap!() global bootstrapping_compiler = true let time() = ccall(:jl_clock_now, Float64, ()) From bee56f434ce2b534a75dfc035bbe033dd2ad87be Mon Sep 17 00:00:00 2001 From: FX Coudert Date: Sun, 5 Jan 2025 14:16:51 +0100 Subject: [PATCH 124/198] curl: remove patch (#56957) This issue was fixed upstream in Curl 8.7.0 and later: https://github.com/curl/curl/commit/5cc2b016c36aaf5a08e2feb7c068fca5bb0a8052 --- deps/curl.mk | 10 +--------- deps/patches/curl-strdup.patch | 10 ---------- 2 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 deps/patches/curl-strdup.patch diff --git a/deps/curl.mk b/deps/curl.mk index 29745448692c6..3d478e786ca8a 100644 --- a/deps/curl.mk +++ b/deps/curl.mk @@ -61,15 +61,7 @@ CURL_TLS_CONFIGURE_FLAGS := --with-openssl endif CURL_CONFIGURE_FLAGS += $(CURL_TLS_CONFIGURE_FLAGS) -$(SRCCACHE)/curl-$(CURL_VER)/curl-8.6.0-build.patch-applied: $(SRCCACHE)/curl-$(CURL_VER)/source-extracted - cd $(dir $@) && \ - patch -p1 -f < $(SRCDIR)/patches/curl-strdup.patch - echo 1 > $@ - -$(SRCCACHE)/curl-$(CURL_VER)/source-patched: $(SRCCACHE)/curl-$(CURL_VER)/curl-8.6.0-build.patch-applied - echo 1 > $@ - -$(BUILDDIR)/curl-$(CURL_VER)/build-configured: $(SRCCACHE)/curl-$(CURL_VER)/source-patched +$(BUILDDIR)/curl-$(CURL_VER)/build-configured: $(SRCCACHE)/curl-$(CURL_VER)/source-extracted mkdir -p $(dir $@) cd $(dir $@) && \ $(dir $<)/configure $(CURL_CONFIGURE_FLAGS) \ diff --git a/deps/patches/curl-strdup.patch b/deps/patches/curl-strdup.patch deleted file mode 100644 index 1cb389fdc4c17..0000000000000 --- a/deps/patches/curl-strdup.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/lib/md4.c -+++ b/lib/md4.c -@@ -23,6 +23,7 @@ - ***************************************************************************/ - - #include "curl_setup.h" -+#include "strdup.h" - - #if defined(USE_CURL_NTLM_CORE) - From 5ec41e90c20ee3825d32d2d374920ce0df81f73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Sun, 5 Jan 2025 22:49:38 +0100 Subject: [PATCH 125/198] [deps] Update most jll stdlibs to newer builds (#56958) This is mainly to get checksums for `riscv64-linux-gnu` builds of many dependencies. We're only changing the build version for most packages, only packages upgraded to newer upstream versions are * libblastrampoline (only [change between v5.11.2 and v5.12.0](https://github.com/JuliaLinearAlgebra/libblastrampoline/compare/v5.11.2...v5.12.0) is the version number, for the rest it should be functionally equivalent) * openlibm: https://github.com/JuliaMath/openlibm/compare/v0.8.1...v0.8.4 Checksums updated with ``` make -f contrib/refresh_checksums.mk -j blastrampoline openlibm gmp libssh2 libuv pcre zlib dsfmt p7zip ``` --- contrib/refresh_checksums.mk | 2 +- deps/blastrampoline.version | 8 +- deps/checksums/blastrampoline | 74 ++++++------- deps/checksums/curl | 2 + deps/checksums/dsfmt | 70 ++++++------ deps/checksums/gmp | 124 +++++++++++----------- deps/checksums/libssh2 | 70 ++++++------ deps/checksums/libuv | 70 ++++++------ deps/checksums/nghttp2 | 2 + deps/checksums/openlibm | 74 ++++++------- deps/checksums/p7zip | 70 ++++++------ deps/checksums/pcre | 70 ++++++------ deps/checksums/zlib | 70 ++++++------ deps/openlibm.version | 8 +- stdlib/GMP_jll/Project.toml | 2 +- stdlib/LibSSH2_jll/Project.toml | 2 +- stdlib/LibUV_jll/Project.toml | 2 +- stdlib/OpenLibm_jll/Project.toml | 2 +- stdlib/PCRE2_jll/Project.toml | 2 +- stdlib/Zlib_jll/Project.toml | 2 +- stdlib/dSFMT_jll/Project.toml | 2 +- stdlib/libblastrampoline_jll/Project.toml | 2 +- stdlib/p7zip_jll/Project.toml | 2 +- 23 files changed, 380 insertions(+), 352 deletions(-) diff --git a/contrib/refresh_checksums.mk b/contrib/refresh_checksums.mk index 21ef72c26a03d..5a787b0b67cb1 100644 --- a/contrib/refresh_checksums.mk +++ b/contrib/refresh_checksums.mk @@ -19,7 +19,7 @@ all: checksum pack-checksum # Get this list via: # using BinaryBuilder # print("TRIPLETS=\"$(join(sort(triplet.(BinaryBuilder.supported_platforms(;experimental=true))), " "))\"") -TRIPLETS=aarch64-apple-darwin aarch64-linux-gnu aarch64-linux-musl aarch64-unknown-freebsd armv6l-linux-gnueabihf armv6l-linux-musleabihf armv7l-linux-gnueabihf armv7l-linux-musleabihf i686-linux-gnu i686-linux-musl i686-w64-mingw32 powerpc64le-linux-gnu x86_64-apple-darwin x86_64-linux-gnu x86_64-linux-musl x86_64-unknown-freebsd x86_64-w64-mingw32 +TRIPLETS=aarch64-apple-darwin aarch64-linux-gnu aarch64-linux-musl aarch64-unknown-freebsd armv6l-linux-gnueabihf armv6l-linux-musleabihf armv7l-linux-gnueabihf armv7l-linux-musleabihf i686-linux-gnu i686-linux-musl i686-w64-mingw32 powerpc64le-linux-gnu riscv64-linux-gnu x86_64-apple-darwin x86_64-linux-gnu x86_64-linux-musl x86_64-unknown-freebsd x86_64-w64-mingw32 CLANG_TRIPLETS=$(filter %-darwin %-freebsd,$(TRIPLETS)) NON_CLANG_TRIPLETS=$(filter-out %-darwin %-freebsd,$(TRIPLETS)) diff --git a/deps/blastrampoline.version b/deps/blastrampoline.version index 7e6dc61d1cbe7..1e4a75305a4dd 100644 --- a/deps/blastrampoline.version +++ b/deps/blastrampoline.version @@ -1,7 +1,9 @@ +# -*- makefile -*- + ## jll artifact BLASTRAMPOLINE_JLL_NAME := libblastrampoline ## source build -BLASTRAMPOLINE_VER := 5.11.2 -BLASTRAMPOLINE_BRANCH=v5.11.2 -BLASTRAMPOLINE_SHA1=c48da8a1225c2537ff311c28ef395152fb879eae +BLASTRAMPOLINE_VER := 5.12.0 +BLASTRAMPOLINE_BRANCH=v5.12.0 +BLASTRAMPOLINE_SHA1=b127bc8dd4758ffc064340fff2aef4ead552f386 diff --git a/deps/checksums/blastrampoline b/deps/checksums/blastrampoline index 987d4662e6cc7..9e007f6055cf9 100644 --- a/deps/checksums/blastrampoline +++ b/deps/checksums/blastrampoline @@ -1,36 +1,38 @@ -blastrampoline-c48da8a1225c2537ff311c28ef395152fb879eae.tar.gz/md5/0747a7c65427a5e6ff4820ea1079f095 -blastrampoline-c48da8a1225c2537ff311c28ef395152fb879eae.tar.gz/sha512/8d5c60ce84ae42e529506821b051e043c0d8861cd7e39780ebc858c2b8638d6628b2f9ceffd67c9ee18983c9c7e5a454f65cf14fb414907c28c90eb67e7de8fe -libblastrampoline.v5.11.2+0.aarch64-apple-darwin.tar.gz/md5/c0f71f80654d6025e29e763f7bf2de92 -libblastrampoline.v5.11.2+0.aarch64-apple-darwin.tar.gz/sha512/49a7f8f2aac286763d7ce2c086b60b84e9ed7eb9dbbd8ba00c5956840ea6c642f4b1d80cb69888045dfdce55dcde1ee2843df9fa63947d3ce8615faf1523a902 -libblastrampoline.v5.11.2+0.aarch64-linux-gnu.tar.gz/md5/7e9b45c623aa527d65f85edff7d056dd -libblastrampoline.v5.11.2+0.aarch64-linux-gnu.tar.gz/sha512/f41378f63a6513ca9b25febb8c01257711cd34e86303a081865696adadc41db5e39c1fd1fdf50ff1ea5d3224fe22ea7f8e571dc7001ee8708be2a27d41410eb5 -libblastrampoline.v5.11.2+0.aarch64-linux-musl.tar.gz/md5/1a2b0eafdaedc1870508948f4a8fd6d8 -libblastrampoline.v5.11.2+0.aarch64-linux-musl.tar.gz/sha512/5d9c8cce5a0abfa10b2907d9b44ad62e62cd9cd7c4c94c14b0ae93f83adff7c1c9f386c1b82dbc2f8f1f959c86c724663ae5dfdbcdd081cebcbf8a91be87da7b -libblastrampoline.v5.11.2+0.aarch64-unknown-freebsd.tar.gz/md5/3c518305add0202d56798c30cbd04345 -libblastrampoline.v5.11.2+0.aarch64-unknown-freebsd.tar.gz/sha512/ac292d999cd258052a95dd641bd06d22db3e6c0574077e9aecb63dca70c1810395921d9bc939a629cf38ece16de42d541dd03aef84d53cc6bd7b7d65bb743b66 -libblastrampoline.v5.11.2+0.armv6l-linux-gnueabihf.tar.gz/md5/fd47f376283002dc6821c4dac0127198 -libblastrampoline.v5.11.2+0.armv6l-linux-gnueabihf.tar.gz/sha512/e56b3e5b5f0bf2b3138484a49a922cb82608152de7dd972c52294eb8611cb76b95b06f33a1dc38f00dd02702ca1ef9b6f69572349b185695a55b269b91cf231f -libblastrampoline.v5.11.2+0.armv6l-linux-musleabihf.tar.gz/md5/70222a8dd72f03888401a2d0cf5a206c -libblastrampoline.v5.11.2+0.armv6l-linux-musleabihf.tar.gz/sha512/609894123a512831c9159312ea5f496de9361c60a838f9428ea5dc6aa9aa6bbb2b33856bf08868765e9af2548d8d386389747254d87d7ed403e492259d61ce32 -libblastrampoline.v5.11.2+0.armv7l-linux-gnueabihf.tar.gz/md5/966dfbf17d7eac1ff046b935e8202e7a -libblastrampoline.v5.11.2+0.armv7l-linux-gnueabihf.tar.gz/sha512/de173d9c17970bff612e1759dbcd9188f0bca0dffd21e0a98d2ed5b72a5ba60cc0097cec1e42cb2bc42f14c1c0bed3987b5bd4a04c7991c9e8d908f2aed231cd -libblastrampoline.v5.11.2+0.armv7l-linux-musleabihf.tar.gz/md5/90b43518c75e0071e4b2efe3aef344ec -libblastrampoline.v5.11.2+0.armv7l-linux-musleabihf.tar.gz/sha512/2bbb2676b381e588e6315576ed9a1d4cad4612aa6c1b5ec95fdd8434f0f0fcb07cc0b61162c0a1dac72217a008f01702f5bf63566a007622d7a3ab35461b6645 -libblastrampoline.v5.11.2+0.i686-linux-gnu.tar.gz/md5/ecf7b2fcdf8feb2114525290d09b99c7 -libblastrampoline.v5.11.2+0.i686-linux-gnu.tar.gz/sha512/10922aa2e567f1534340ec9422516ccf0ea625ae73a433ed864dc72926235fe1dc6c52c2ca716aca5eeac80544a99e76892a0f19fccd2c2b9103332fd2289980 -libblastrampoline.v5.11.2+0.i686-linux-musl.tar.gz/md5/6cf17a410bf50b3a87b9f2af0c6955e9 -libblastrampoline.v5.11.2+0.i686-linux-musl.tar.gz/sha512/30f78dd4948b26b14d04cf5e1821a381e9d8aa67c6b3547cf45a0d53a469829a98d7d47722c542699e65e1ae3411a86da094d8b354821ece1562288fa523b1f1 -libblastrampoline.v5.11.2+0.i686-w64-mingw32.tar.gz/md5/9c4c1fa7410f9e53687dbde1479deb3a -libblastrampoline.v5.11.2+0.i686-w64-mingw32.tar.gz/sha512/511eed07956b16555ab236905fe91c584d870e45d1a6b736b3b564f84ec66e8c12d9561efabad259ddc65b8965eb4cdc29b079d0a9a6a465b424b503399eae7b -libblastrampoline.v5.11.2+0.powerpc64le-linux-gnu.tar.gz/md5/816ee59bf7cc937399c273709882369b -libblastrampoline.v5.11.2+0.powerpc64le-linux-gnu.tar.gz/sha512/4e1095288ff02a9e0714f982be16782271643c1844100b38d5fcf02c2e2f62d0635457d52dd120792a59a62b905c60aa7e253a89c2f759d98c33d617c89e897f -libblastrampoline.v5.11.2+0.x86_64-apple-darwin.tar.gz/md5/9a4a86a441aa232e12e85bbf6e62f589 -libblastrampoline.v5.11.2+0.x86_64-apple-darwin.tar.gz/sha512/2d80b4c9149b8d62ae89fa3be32ccb297e815c9cd56b3481482c5f6ee253fc845d410807e099f4c1814a77e397c04511ebabc9d82352fc43ebe81a3306819ccc -libblastrampoline.v5.11.2+0.x86_64-linux-gnu.tar.gz/md5/45fbfd0422131044fff9ed44d12f13e1 -libblastrampoline.v5.11.2+0.x86_64-linux-gnu.tar.gz/sha512/c7e4f87aa0ab403be46b81967d40ebd4bd4b32af93a325cb16f64593c2261a365be3f338195cdfeada0cb6ecab8e33e4be1b380596ff0bb1c4a7b5e6aac3dccc -libblastrampoline.v5.11.2+0.x86_64-linux-musl.tar.gz/md5/161816fa857775d78bc671c444846844 -libblastrampoline.v5.11.2+0.x86_64-linux-musl.tar.gz/sha512/ba0ab54a9ccfb451b7b8fe46b2bd8e8a8135d2e1f2a896bfdf4bcc6e82812f56d93ef1e7b85671e58d388afe2876d79affdf59bfe7b1db5b76412008303a121e -libblastrampoline.v5.11.2+0.x86_64-unknown-freebsd.tar.gz/md5/aeaab847455f5a43c434155b09107cde -libblastrampoline.v5.11.2+0.x86_64-unknown-freebsd.tar.gz/sha512/24425c8bdc861404156bb5a8e950654904fb22ff6a5ebe52c873629e4dd1cfaccafaae74b779c2cb02370f012cf18c2142a105dd614938b2685db2cd7527c73d -libblastrampoline.v5.11.2+0.x86_64-w64-mingw32.tar.gz/md5/450afb701cc2899c7c083bd3f3e580a0 -libblastrampoline.v5.11.2+0.x86_64-w64-mingw32.tar.gz/sha512/e4d1785a06b051a4f16edd7343021eed61ac45cf45d26b4e3ef1e54cfaadb44da2e74b7d854e31b05a733dbb3004f3e85644967316c4f41d1ad64400fed126f2 +blastrampoline-b127bc8dd4758ffc064340fff2aef4ead552f386.tar.gz/md5/395f2035bcb52e886b55ac926a7bf183 +blastrampoline-b127bc8dd4758ffc064340fff2aef4ead552f386.tar.gz/sha512/9ae0fe2ca75dc0b2c784d5b7248caca29ed6d44258743ee2b32827032734757e9078dd6bcdf80a02b042deb5c7ca7b4e5be392be6700efde91427091fb53a03f +libblastrampoline.v5.12.0+0.aarch64-apple-darwin.tar.gz/md5/9a18b39bb575d0112834992043d302c0 +libblastrampoline.v5.12.0+0.aarch64-apple-darwin.tar.gz/sha512/4e406b155149414d3e4fd5db49ab56a87ed13577ebb399eaf8a251692c0b84e639c6e1a4eb20863e2638c31add0241ca916e57f91bb5a4aed07e2c56cc580870 +libblastrampoline.v5.12.0+0.aarch64-linux-gnu.tar.gz/md5/e100e93f0d6a104fc66c9f78a67150c5 +libblastrampoline.v5.12.0+0.aarch64-linux-gnu.tar.gz/sha512/f7e0c379e32d8163dbb4919b77e9637e1b16cf26618b9260222cf985bfab9ca3f36bebccd0e8360af68db925035c82127ba85d46b4a6578961dde6a049c7cf93 +libblastrampoline.v5.12.0+0.aarch64-linux-musl.tar.gz/md5/814a79e8cfe8744ca5a2a722f007fcaa +libblastrampoline.v5.12.0+0.aarch64-linux-musl.tar.gz/sha512/bc886b199500fc4245a95446d4c862fc636711e0875a9d5cf9aef661d819d00324adfd3e037d9c03e274be26034353d033fb041e7608ecef222e1d154f38337d +libblastrampoline.v5.12.0+0.aarch64-unknown-freebsd.tar.gz/md5/9b9a7fe0e45a73009bb9f8044f4a27a2 +libblastrampoline.v5.12.0+0.aarch64-unknown-freebsd.tar.gz/sha512/51d52afb13e326ef4750bdcad800aaf3db2c9e068b4c38bd148e312c63358b2228b81d23626d18b8983534a8a6f24df1b64b4e7121779d2535574ea907bd18ba +libblastrampoline.v5.12.0+0.armv6l-linux-gnueabihf.tar.gz/md5/1b6fd062d133b13e8efc63f08528fb51 +libblastrampoline.v5.12.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/78d525f425ee27068b94b94f89ef44a51ffac9f642ffe66e177434804e59b4ac3ba875190aceee386a8d740f7903e979e5b91f0973138d0fc7753061c6f5f26d +libblastrampoline.v5.12.0+0.armv6l-linux-musleabihf.tar.gz/md5/506be2b7669aa171efcc541388cb5444 +libblastrampoline.v5.12.0+0.armv6l-linux-musleabihf.tar.gz/sha512/2975136376c3f61b8f227676c4e1368d1847d85ff469dddbc0a330635eac77c00072c7544ae4aa9981d16a4ab04d494be54fc951b434a56fbf14003c42626579 +libblastrampoline.v5.12.0+0.armv7l-linux-gnueabihf.tar.gz/md5/99403eae880f52aa97884143e2ca7215 +libblastrampoline.v5.12.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/986dfcf5fe3ac731df3c71eb6b0bf3d7525511952d22cc9128ff35e6fcb330acf69e897aeb97920ebabd1ccccd1dd6ce9b6c16d0dbf661d39a103ce5b477462f +libblastrampoline.v5.12.0+0.armv7l-linux-musleabihf.tar.gz/md5/20adf8d2ef348f5362cb03e1a2780476 +libblastrampoline.v5.12.0+0.armv7l-linux-musleabihf.tar.gz/sha512/95068a3b5bcf17bd5f13373a2730a6508d3992f0aa83a91629527821cf038b9607327843cc44fb72730b63c01d3d70e2eb488eca8f48ed9444d7736f67745d02 +libblastrampoline.v5.12.0+0.i686-linux-gnu.tar.gz/md5/a56f833ad986fc3e9e64e5abdb16915f +libblastrampoline.v5.12.0+0.i686-linux-gnu.tar.gz/sha512/d478b4981dc17afb8aa8625fdbb23139f1c3edaa9aaa179e70d274984a056147b2e65e9f473b007733d094369f448823c33aa95fadd228016ecf9dfbf17f06bb +libblastrampoline.v5.12.0+0.i686-linux-musl.tar.gz/md5/8578119b3b3e84393e6324996e9506aa +libblastrampoline.v5.12.0+0.i686-linux-musl.tar.gz/sha512/b546de6687755ce43680f312008a23a8f9df422603098807f33e2ae969c9e9de0ca32a3319067d4f8fa1f782f21b6465638cd59e4c86fc6261fb4180f0ed116f +libblastrampoline.v5.12.0+0.i686-w64-mingw32.tar.gz/md5/b9e2800b8758d3fa0ac0597f738c399c +libblastrampoline.v5.12.0+0.i686-w64-mingw32.tar.gz/sha512/e0aa0ee2a750cfe702e0bd5861e352f97f433f67444dbc6e5814055fb32f571de318f640ac670c91bad233f8af85f0421daef71b7768a710de5b15febee28b27 +libblastrampoline.v5.12.0+0.powerpc64le-linux-gnu.tar.gz/md5/bab2048857c7c1ba4a6c3d540b9275c6 +libblastrampoline.v5.12.0+0.powerpc64le-linux-gnu.tar.gz/sha512/576026c970b19cc00480d7bb9439933c5bb432eec17def66b22f5c0dfd418bcf75bb10ccfc1b01fef48e8d504ebf953c5f6c63d504713315c43d9579ab5fa2e4 +libblastrampoline.v5.12.0+0.riscv64-linux-gnu.tar.gz/md5/f37e2849a948a8c8c8bfa6055e30909c +libblastrampoline.v5.12.0+0.riscv64-linux-gnu.tar.gz/sha512/89f30d52f1a1dcc0aa38b4b343534b7fadcff12d788f455172c043ea2511c03b2735fdacf8f794a6f62156cb5d82fb0e9e0edd04bb9c57a1ca3e680410456b17 +libblastrampoline.v5.12.0+0.x86_64-apple-darwin.tar.gz/md5/b07c42b602b91bf2229b1a5cfd8e37b3 +libblastrampoline.v5.12.0+0.x86_64-apple-darwin.tar.gz/sha512/ab064dff373826776f9b64a4a77e3418461d53d5119798a5e702967e4ac4f68c58cd8c3c0cc01bda3edeb613cf50b9d3171d9141c91ff9ef3a2c88a8e8f00a37 +libblastrampoline.v5.12.0+0.x86_64-linux-gnu.tar.gz/md5/c37b01242012e51e124711d5ad10cf97 +libblastrampoline.v5.12.0+0.x86_64-linux-gnu.tar.gz/sha512/3f9015bec4aaddc677cb3f3aebd432db8bad89b3f6e563634a37569afeb9fb0efa4f214166c984c2c1926831d5cd79fcd4d605d40675e0d1a7e494a76c066f02 +libblastrampoline.v5.12.0+0.x86_64-linux-musl.tar.gz/md5/c24e440a1757a45f087a2e1ac649fb45 +libblastrampoline.v5.12.0+0.x86_64-linux-musl.tar.gz/sha512/824b930d50df929fd22ead6dffad06593d2aad9fcb149f07f1c2f6d4b7b34911e89c2be5a1e9b8ad5ad8292ac29f9e5dbe6d7bb205d2b207432ade61ae5f8b68 +libblastrampoline.v5.12.0+0.x86_64-unknown-freebsd.tar.gz/md5/5721328a24473cefbb3e77ba85e46922 +libblastrampoline.v5.12.0+0.x86_64-unknown-freebsd.tar.gz/sha512/3537ea491828492f1cb68fa961dc5574b63a88b49abf19eb86f9d1a4544e1398fcd84d6338c6dcb9550ee3abcdcab0654f5cc2b85699c5ed5b3b31a1c35a199d +libblastrampoline.v5.12.0+0.x86_64-w64-mingw32.tar.gz/md5/450afb701cc2899c7c083bd3f3e580a0 +libblastrampoline.v5.12.0+0.x86_64-w64-mingw32.tar.gz/sha512/e4d1785a06b051a4f16edd7343021eed61ac45cf45d26b4e3ef1e54cfaadb44da2e74b7d854e31b05a733dbb3004f3e85644967316c4f41d1ad64400fed126f2 diff --git a/deps/checksums/curl b/deps/checksums/curl index 5331e54d30d4a..b0a223f42c5e2 100644 --- a/deps/checksums/curl +++ b/deps/checksums/curl @@ -24,6 +24,8 @@ LibCURL.v8.11.1+1.i686-w64-mingw32.tar.gz/md5/5f2071282d572bbb53dfcfb16d0d9608 LibCURL.v8.11.1+1.i686-w64-mingw32.tar.gz/sha512/e4d6fbd518055e8f2a71b89ee9a33728e6e076729adeafc358fc40f47d032b739363c9b57df5bfb3c43244f7b833afc76ae255e70bcf43b81262d74278532a22 LibCURL.v8.11.1+1.powerpc64le-linux-gnu.tar.gz/md5/806ee9b51c2bffd798c1682867a7a2a0 LibCURL.v8.11.1+1.powerpc64le-linux-gnu.tar.gz/sha512/20ae5f47ad24e1fba8ecdc3a81aa81acb5c3c224041f12f8be48f9a0abd5ce44117b096a59fc8f861b6f8c6ad9e4177e3a3ba3e2dbecb2078d4bab19bdd4d239 +LibCURL.v8.11.1+1.riscv64-linux-gnu.tar.gz/md5/2e029213e81955f39423733608c4ffa8 +LibCURL.v8.11.1+1.riscv64-linux-gnu.tar.gz/sha512/a634ae9de047bd8a93cbfaa3cd5375d895baf9917b5062653f15472527836b51eeb15006b5e1888251e3f09d8177b489ea9975580fe6d95bc759708fc9654fd1 LibCURL.v8.11.1+1.x86_64-apple-darwin.tar.gz/md5/56cf7cf4ea22123e516843a5751eea17 LibCURL.v8.11.1+1.x86_64-apple-darwin.tar.gz/sha512/5ae5569ade42cdf0a1aa8acfda7d1dd3df30d498637f83e93bd9f8be883ae777e789b417be24df83e42ebe32fb67cc328bedac3dc231d3569f585641175ed257 LibCURL.v8.11.1+1.x86_64-linux-gnu.tar.gz/md5/a4a733fe879693e83e1f05b6ef742ea6 diff --git a/deps/checksums/dsfmt b/deps/checksums/dsfmt index 99ba378adcd4c..9d5fa782663ec 100644 --- a/deps/checksums/dsfmt +++ b/deps/checksums/dsfmt @@ -1,36 +1,38 @@ -dSFMT.v2.2.5+1.aarch64-apple-darwin.tar.gz/md5/1ac287cb891e0bb758e5ae1195e661b7 -dSFMT.v2.2.5+1.aarch64-apple-darwin.tar.gz/sha512/c604d55fb955e9d707e26b654670f07f18ddd0dc93c1a2b678b9cea9b84a24e21c88eb49d39e3e74c930cdffa35e45f5a63e96ecb0a098e8ea538438dc7281bd -dSFMT.v2.2.5+1.aarch64-linux-gnu.tar.gz/md5/260e14855dbc7773a2ca906d58cc57f2 -dSFMT.v2.2.5+1.aarch64-linux-gnu.tar.gz/sha512/820ca4c6afde931e855b74015150f4ffbb513276c3fa7dbcc1ec8d34c02d4989fb7424a6e4f81f93d054811b5f54f8633d955b05acdb088387ee90f1c3b00915 -dSFMT.v2.2.5+1.aarch64-linux-musl.tar.gz/md5/7ddccbad6b5c9de4be187fe76637a0d8 -dSFMT.v2.2.5+1.aarch64-linux-musl.tar.gz/sha512/e3c225da00927096e3a6cd4abc681fba8f469cb74828e7054d4f5684d71dcb8e75c9a81f14fa10bfbb78f62f9567a31a92edcca8d797e5810a2a44a3fc17bc84 -dSFMT.v2.2.5+1.aarch64-unknown-freebsd.tar.gz/md5/84f560104ab5eac8f214559645235350 -dSFMT.v2.2.5+1.aarch64-unknown-freebsd.tar.gz/sha512/3668a37d2516c304b296e2dd7b93a45decb37774088b03438b6d7dec71766d98b2ca1d61c1b317f86ca118d078f53817b6bc86f0ed487185e18b5cc786060592 -dSFMT.v2.2.5+1.armv6l-linux-gnueabihf.tar.gz/md5/a70329e0a6c57009c6b6950fd34089f6 -dSFMT.v2.2.5+1.armv6l-linux-gnueabihf.tar.gz/sha512/4418c42165660adc050e872ef834f920c89ed6a0d2b816821672b1e862e947aad7efd023289da9bf05bb2eb9ec4b9d2561c403e2d5384d5314a4ba016b1f9cfc -dSFMT.v2.2.5+1.armv6l-linux-musleabihf.tar.gz/md5/6ffc798b8a0c847fa5cb93640bd66ab3 -dSFMT.v2.2.5+1.armv6l-linux-musleabihf.tar.gz/sha512/94e5ae07d0b1420abd7290519bce6f77deae634bbb4df31e3f02416bf509e555a9b1c9d19dd77ca76a308c2b86d5c9d4718b9ef83c13167b88a8181d8ca7e73a -dSFMT.v2.2.5+1.armv7l-linux-gnueabihf.tar.gz/md5/660d95aa08580ca1716a89c4d8b1eb24 -dSFMT.v2.2.5+1.armv7l-linux-gnueabihf.tar.gz/sha512/bc757a9f805047be5375f92c10a3f3eab69345a4ec5cc997f763e66be36144a74d414ff926df8e17b9d5a2394189269c3188c55e0b7c75a72495394d65510cef -dSFMT.v2.2.5+1.armv7l-linux-musleabihf.tar.gz/md5/78c487049092fe61949d506637c713bb -dSFMT.v2.2.5+1.armv7l-linux-musleabihf.tar.gz/sha512/03ddada4478f05eab7d2971b2deaf2cba91f084d7ce66fc8219bcb3cf5c308ea13959fed95568ca80f4ce11794e197092984919265716de8f2558e2cb30d94ce -dSFMT.v2.2.5+1.i686-linux-gnu.tar.gz/md5/11463fd3981a8c143d7aed691d18d4e0 -dSFMT.v2.2.5+1.i686-linux-gnu.tar.gz/sha512/db946a4fbd8a3163b8b1c25e02bfc4a841da7d2532892a99037bd48ac98e1840691e8cc0127d9457a82667a0131e4826cb4e9d0a13f127afc62da4eb68af5a3e -dSFMT.v2.2.5+1.i686-linux-musl.tar.gz/md5/a61405f72c9a3bba5718f078c68e61a5 -dSFMT.v2.2.5+1.i686-linux-musl.tar.gz/sha512/726f130bbbfd0dece4185b89a25a73f3b5b950ebfb7f86aea6e9cbcf9ae932e591d20b854de0b4985103dbf8b4b7cb3560661c5070af971cd2c1f3ec3e1ea7d2 -dSFMT.v2.2.5+1.i686-w64-mingw32.tar.gz/md5/3bc27ef8f26c7a26f096cf1d558d408d -dSFMT.v2.2.5+1.i686-w64-mingw32.tar.gz/sha512/ea3608d3ae3874ea57a1a08f69abe2a1638bc340db71c6fe3c4fd5637d8c54943bf16b099a46817387c1ed4cb5f3cd1c0ff19ae8a4ed85dd555555821af06374 -dSFMT.v2.2.5+1.powerpc64le-linux-gnu.tar.gz/md5/fd8c73961ef7c82201e6d86e8bf4324c -dSFMT.v2.2.5+1.powerpc64le-linux-gnu.tar.gz/sha512/1bd0ebd019cfc6f25f7ba007547c5ee297854655b93c55e90d8ead420875de5a087e38956693d5e901ff2abf667c72aa66fb34f587b82adf4b91b3d5d666b5c7 -dSFMT.v2.2.5+1.x86_64-apple-darwin.tar.gz/md5/c8c0cd02cb1aa5e363b0c28a3fc4cf65 -dSFMT.v2.2.5+1.x86_64-apple-darwin.tar.gz/sha512/ac29d4b8aae51349474c9191822f92f69105e19521afe2bd9fc6b16385256610ae31e34cd70d894ed03299f1fd155f0a1db79969d1ed35eea44d11521e2030ab -dSFMT.v2.2.5+1.x86_64-linux-gnu.tar.gz/md5/fa671f4ca14b171d53c8866d03f9162a -dSFMT.v2.2.5+1.x86_64-linux-gnu.tar.gz/sha512/2e242a1448da0508ea88cc1a106f1e74f8d7e7562cd82b80d86abf9a8b454653ad7612e25c30ce00c23757e8a5b7b5736253b00a52f9473af6c5d4df768138f2 -dSFMT.v2.2.5+1.x86_64-linux-musl.tar.gz/md5/c648294163882ec539ab646542c74880 -dSFMT.v2.2.5+1.x86_64-linux-musl.tar.gz/sha512/9e96a47d660854b6517364f0db40a2f4e0e3b814499a0349f7cf550b1c8d04589fca5eb4a75bf34f36d1b5d1b2277b3e9a961c887092abedd08f438e025329e7 -dSFMT.v2.2.5+1.x86_64-unknown-freebsd.tar.gz/md5/4960e4ab2ecb6ae1025f9e7bf4c9a7b8 -dSFMT.v2.2.5+1.x86_64-unknown-freebsd.tar.gz/sha512/a2e8bbe382a0ebdd7b69fafdc901f33767f53b9f8b37a89104f2ef897bb5ec27bc8d3bc21f5cff52ca4f29b3a6a10535f7e5f16ef917a9323858c75f1569ea60 -dSFMT.v2.2.5+1.x86_64-w64-mingw32.tar.gz/md5/386adb3b7593c222dc7a1060a1356b21 -dSFMT.v2.2.5+1.x86_64-w64-mingw32.tar.gz/sha512/fe2ab5021126807b37042e89a22ef9a869c6a0a028680df445773b2affd11c2b02148be07d53504ea3842bb38bb62fe039529688266c1cba3545a892bd4dc185 +dSFMT.v2.2.5+2.aarch64-apple-darwin.tar.gz/md5/4d9e6a1ed07d1fe1557845b763224eeb +dSFMT.v2.2.5+2.aarch64-apple-darwin.tar.gz/sha512/930e12a9b6ac82888f4122515a8a7cc3aa5d5363e500455b33c57efb7656041fe3f0fa68b02dd048b2a9f00abb56449415f1edf600ef09703aaed991e1d6f23d +dSFMT.v2.2.5+2.aarch64-linux-gnu.tar.gz/md5/260e14855dbc7773a2ca906d58cc57f2 +dSFMT.v2.2.5+2.aarch64-linux-gnu.tar.gz/sha512/820ca4c6afde931e855b74015150f4ffbb513276c3fa7dbcc1ec8d34c02d4989fb7424a6e4f81f93d054811b5f54f8633d955b05acdb088387ee90f1c3b00915 +dSFMT.v2.2.5+2.aarch64-linux-musl.tar.gz/md5/7ddccbad6b5c9de4be187fe76637a0d8 +dSFMT.v2.2.5+2.aarch64-linux-musl.tar.gz/sha512/e3c225da00927096e3a6cd4abc681fba8f469cb74828e7054d4f5684d71dcb8e75c9a81f14fa10bfbb78f62f9567a31a92edcca8d797e5810a2a44a3fc17bc84 +dSFMT.v2.2.5+2.aarch64-unknown-freebsd.tar.gz/md5/d592c490259f45acef2308fd61046404 +dSFMT.v2.2.5+2.aarch64-unknown-freebsd.tar.gz/sha512/4f4e100b4cd5301e815f29f911b3ddba845a90247f1d641ea11153f5845c700e6f94ccd4a1d46fbb9e64a0c5698c5419c52560f0629629ffd665cf9ddec24e17 +dSFMT.v2.2.5+2.armv6l-linux-gnueabihf.tar.gz/md5/a70329e0a6c57009c6b6950fd34089f6 +dSFMT.v2.2.5+2.armv6l-linux-gnueabihf.tar.gz/sha512/4418c42165660adc050e872ef834f920c89ed6a0d2b816821672b1e862e947aad7efd023289da9bf05bb2eb9ec4b9d2561c403e2d5384d5314a4ba016b1f9cfc +dSFMT.v2.2.5+2.armv6l-linux-musleabihf.tar.gz/md5/6ffc798b8a0c847fa5cb93640bd66ab3 +dSFMT.v2.2.5+2.armv6l-linux-musleabihf.tar.gz/sha512/94e5ae07d0b1420abd7290519bce6f77deae634bbb4df31e3f02416bf509e555a9b1c9d19dd77ca76a308c2b86d5c9d4718b9ef83c13167b88a8181d8ca7e73a +dSFMT.v2.2.5+2.armv7l-linux-gnueabihf.tar.gz/md5/660d95aa08580ca1716a89c4d8b1eb24 +dSFMT.v2.2.5+2.armv7l-linux-gnueabihf.tar.gz/sha512/bc757a9f805047be5375f92c10a3f3eab69345a4ec5cc997f763e66be36144a74d414ff926df8e17b9d5a2394189269c3188c55e0b7c75a72495394d65510cef +dSFMT.v2.2.5+2.armv7l-linux-musleabihf.tar.gz/md5/78c487049092fe61949d506637c713bb +dSFMT.v2.2.5+2.armv7l-linux-musleabihf.tar.gz/sha512/03ddada4478f05eab7d2971b2deaf2cba91f084d7ce66fc8219bcb3cf5c308ea13959fed95568ca80f4ce11794e197092984919265716de8f2558e2cb30d94ce +dSFMT.v2.2.5+2.i686-linux-gnu.tar.gz/md5/11463fd3981a8c143d7aed691d18d4e0 +dSFMT.v2.2.5+2.i686-linux-gnu.tar.gz/sha512/db946a4fbd8a3163b8b1c25e02bfc4a841da7d2532892a99037bd48ac98e1840691e8cc0127d9457a82667a0131e4826cb4e9d0a13f127afc62da4eb68af5a3e +dSFMT.v2.2.5+2.i686-linux-musl.tar.gz/md5/a61405f72c9a3bba5718f078c68e61a5 +dSFMT.v2.2.5+2.i686-linux-musl.tar.gz/sha512/726f130bbbfd0dece4185b89a25a73f3b5b950ebfb7f86aea6e9cbcf9ae932e591d20b854de0b4985103dbf8b4b7cb3560661c5070af971cd2c1f3ec3e1ea7d2 +dSFMT.v2.2.5+2.i686-w64-mingw32.tar.gz/md5/3bc27ef8f26c7a26f096cf1d558d408d +dSFMT.v2.2.5+2.i686-w64-mingw32.tar.gz/sha512/ea3608d3ae3874ea57a1a08f69abe2a1638bc340db71c6fe3c4fd5637d8c54943bf16b099a46817387c1ed4cb5f3cd1c0ff19ae8a4ed85dd555555821af06374 +dSFMT.v2.2.5+2.powerpc64le-linux-gnu.tar.gz/md5/fd8c73961ef7c82201e6d86e8bf4324c +dSFMT.v2.2.5+2.powerpc64le-linux-gnu.tar.gz/sha512/1bd0ebd019cfc6f25f7ba007547c5ee297854655b93c55e90d8ead420875de5a087e38956693d5e901ff2abf667c72aa66fb34f587b82adf4b91b3d5d666b5c7 +dSFMT.v2.2.5+2.riscv64-linux-gnu.tar.gz/md5/5c4981c2c016436faf6f33fa8df4204b +dSFMT.v2.2.5+2.riscv64-linux-gnu.tar.gz/sha512/9b56f0abbfb2731d23b99b5286b69c31bfc21eb14f49d88953680d5596c20c6b4d59520828f0a398915d56c82e169a36316f8e319dfe4e25a8e3f44f2aca4938 +dSFMT.v2.2.5+2.x86_64-apple-darwin.tar.gz/md5/e21e30097f1f02c5cc14cca3f73ce92f +dSFMT.v2.2.5+2.x86_64-apple-darwin.tar.gz/sha512/48b19706189eabcab2c823e6143ae22f4a330abb239c7a952913fe9973c5f750d72b113af32a82a1f6124c534495b26d1f81ccab407d8d15ee459dc83fb8d3cd +dSFMT.v2.2.5+2.x86_64-linux-gnu.tar.gz/md5/fa671f4ca14b171d53c8866d03f9162a +dSFMT.v2.2.5+2.x86_64-linux-gnu.tar.gz/sha512/2e242a1448da0508ea88cc1a106f1e74f8d7e7562cd82b80d86abf9a8b454653ad7612e25c30ce00c23757e8a5b7b5736253b00a52f9473af6c5d4df768138f2 +dSFMT.v2.2.5+2.x86_64-linux-musl.tar.gz/md5/c648294163882ec539ab646542c74880 +dSFMT.v2.2.5+2.x86_64-linux-musl.tar.gz/sha512/9e96a47d660854b6517364f0db40a2f4e0e3b814499a0349f7cf550b1c8d04589fca5eb4a75bf34f36d1b5d1b2277b3e9a961c887092abedd08f438e025329e7 +dSFMT.v2.2.5+2.x86_64-unknown-freebsd.tar.gz/md5/5a9b811be74f02202c57588f35582cb6 +dSFMT.v2.2.5+2.x86_64-unknown-freebsd.tar.gz/sha512/8dc6cae5cdf038fd5647cf86b85a15ac082d35b4532340e145b7e091839079ff47371aef6c3012a67692e492622b4f84db8f0ccf46049cc94926aed5c9cd9fb4 +dSFMT.v2.2.5+2.x86_64-w64-mingw32.tar.gz/md5/386adb3b7593c222dc7a1060a1356b21 +dSFMT.v2.2.5+2.x86_64-w64-mingw32.tar.gz/sha512/fe2ab5021126807b37042e89a22ef9a869c6a0a028680df445773b2affd11c2b02148be07d53504ea3842bb38bb62fe039529688266c1cba3545a892bd4dc185 dsfmt-2.2.5.tar.gz/md5/d22e476b52cdee7d5b90d2f289570073 dsfmt-2.2.5.tar.gz/sha512/951e8669350f750b8915a819e704eae0a9b9c9518b3e3b9a1905f9ca0d25cc4c2486cb479e258a4a114e9c26ceb73a6c4e9f1cc02ed19173aeb8f20189754f6b diff --git a/deps/checksums/gmp b/deps/checksums/gmp index c786fddafef5e..949e4d738a472 100644 --- a/deps/checksums/gmp +++ b/deps/checksums/gmp @@ -1,62 +1,66 @@ -GMP.v6.3.0+1.aarch64-apple-darwin.tar.gz/md5/70a730ecf64eefb5a13f4524e29a6388 -GMP.v6.3.0+1.aarch64-apple-darwin.tar.gz/sha512/51791b4ae0ede1db4c6e7759072d125ca56f6a3a3e43fd5970981a3b2d651f28fe0abefce4b3ad0589d3a46c143054d20fee801bbd423bd2a4c12ba97314c39c -GMP.v6.3.0+1.aarch64-linux-gnu-cxx03.tar.gz/md5/e2b0bf1317259972cdc4f0e6fc3c2bc8 -GMP.v6.3.0+1.aarch64-linux-gnu-cxx03.tar.gz/sha512/8de1dd5d6971c76693c67222725c9eb0a1d276a55a28cd49d94115123100bfe45144652421d4cde468dce67a5630736f4174c9491c8a6e2543aadcb44f1f2d12 -GMP.v6.3.0+1.aarch64-linux-gnu-cxx11.tar.gz/md5/2017b6215ed99c3aed8b04abe75cb3e9 -GMP.v6.3.0+1.aarch64-linux-gnu-cxx11.tar.gz/sha512/78b22106f96348f0d9222279fdf8d1e3f5bd400f771fb0c54dd4045985ee05b896e3097f788739eefab9a9ab09a885aad65c4adb31ae5ba59b7ab22ca10bb574 -GMP.v6.3.0+1.aarch64-linux-musl-cxx03.tar.gz/md5/6477f35f92203db871f56f047b99a1fe -GMP.v6.3.0+1.aarch64-linux-musl-cxx03.tar.gz/sha512/66a6d18979c1ee9a5d06323a717d0a5dd73efc196087349408e739d7aa0444e8ee1af4bd634f85dfd4cfa4c97c24dda4ba472b490f50409581aff967c81b0750 -GMP.v6.3.0+1.aarch64-linux-musl-cxx11.tar.gz/md5/4648558f1e42b8e679f5be494a910402 -GMP.v6.3.0+1.aarch64-linux-musl-cxx11.tar.gz/sha512/9b7ff68a412bccd423b3cffefbc6350db6db8f3f7657713767187c2c2ea3b09d835e1c80d34ab4407f79fccbec82594e024787def27b9ad2ee7ea01ef1607b53 -GMP.v6.3.0+1.aarch64-unknown-freebsd.tar.gz/md5/362bc3fdbcd6d74b9fddb8a4d640d99a -GMP.v6.3.0+1.aarch64-unknown-freebsd.tar.gz/sha512/8e560b4d1014382d784ccf7c9dc6365526566301ec6a28d115170c0be92b8e6033b6c08f922104e405cf978204579754f0740aae97d0a334e47ed6f684aa4af4 -GMP.v6.3.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/6cabb238d148b3e2e76e8527e65893cd -GMP.v6.3.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/07b5673b4680781b7d42399213ecd491ede8883bbf1825689ad6678986a76581f6c4e53f17353f63bec8db8df5ed3fbddc228694eecc54ae7fc949f106bb8f14 -GMP.v6.3.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/0257216ad4e96b404d456f07fcc30b09 -GMP.v6.3.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/ae8bbbbe3992f78186fe7535e450330e94e6630540eefbdfb51bb5014afd90feac0b1583e3fd2bbf226e61523647b3ec6324188bd6267c353a2a98594566c02b -GMP.v6.3.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/md5/48b949c062ea27dc0dbcc07ea5387821 -GMP.v6.3.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/03699c20b5c50dbd44f45a0f5f115c6b10b4e8de68d747bceba605c3090469c819b82ad7e57fe7702c1700c25aae6ab9394a22ded319bc58c80e9d20692b610e -GMP.v6.3.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/md5/847ba3116072a523e1ff4ce83e5a18a8 -GMP.v6.3.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/402548acd57f4112bf2435803f35ea93fd8d07f3df0e2f053b0bec6b08aa3dff4052990a724e2547ce35a29ee376b17d34b7e7e2ab45ecb4981ffc99c56f1a9f -GMP.v6.3.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/5cc75b66059c3b8b5fbf9b8fcb781b10 -GMP.v6.3.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/1ef583d014c825e1d4e6d5f7e2d84c3ba183ba9490410f5d424760e275b7032e98f8377d87ed349d4969c6ef8f9b961a1e8df6f40efb406d41983446a9510303 -GMP.v6.3.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/c0295c143bcb6b53d6184e2852ce35c5 -GMP.v6.3.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/3c74edb123a6f4147b416e5f7f25903bc859ac5f58f141bd463d3dff8cc2928fedf176f20869a1018a2731c1d7170444b3b3405c8f89c3fc22dc2edf9c036c24 -GMP.v6.3.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/md5/a67696b02a7f67405dd84252c908e071 -GMP.v6.3.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/73ba1809cfc68199401974f73e7a37b1fe00d4c0cf3e58ed85d161a8fbac4390aeb28591c3108fc503ef8fb5b131d027cb76dcf5d7731698997c2f377d929dce -GMP.v6.3.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/md5/484f00cd5b0beec20f63cd6734d02611 -GMP.v6.3.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/46fc56f945647f5c8577ad45f540a034f747604e5a89230d9d419b10d5f0571c7580e18e1138ea920efc08b25798c0c7110e15359de17dce3b6db7f07b8ceb3a -GMP.v6.3.0+1.i686-linux-gnu-cxx03.tar.gz/md5/d36d84638e2e5f927d15f07c55919f5f -GMP.v6.3.0+1.i686-linux-gnu-cxx03.tar.gz/sha512/61c62084ab90d25f7168281c7fb672f5bcafdf909afbf66847cfaa1077dd5474b2c27464eb76cac45f5e319aca0c4f7367fc238b83d2dde46ba90a7c1f396dfb -GMP.v6.3.0+1.i686-linux-gnu-cxx11.tar.gz/md5/d87627470bdcac981f7b004c27ac9a89 -GMP.v6.3.0+1.i686-linux-gnu-cxx11.tar.gz/sha512/2a34028687f75422b43f5365b0a8c9530b29473d41bfec4fb9822f074f813b8c6c1fc9efbfbb17a7e4d3d66f2549b5589b3fdbd08711a365330deb72be4958d0 -GMP.v6.3.0+1.i686-linux-musl-cxx03.tar.gz/md5/a2f2fc663bcacfc3e7d6aff29a52de23 -GMP.v6.3.0+1.i686-linux-musl-cxx03.tar.gz/sha512/a30a5d0ee78e747f074b3a5f0a26b9ba99b7553b3c83411a3cb9298814e605509194e9f0d8934caaa1cb7b78eef521805bbc86a297aebd06473ba80a20ffc443 -GMP.v6.3.0+1.i686-linux-musl-cxx11.tar.gz/md5/246b24935442815ff75a13b3dcf24756 -GMP.v6.3.0+1.i686-linux-musl-cxx11.tar.gz/sha512/ca351c4b93adf3f3e40f93c7b0cd61b33ec10049d39e8d33975f46d509efcded67600e6b19d8018a29ee893027d7a28edef0b19c1d70451d072a7a0989e9317d -GMP.v6.3.0+1.i686-w64-mingw32-cxx03.tar.gz/md5/c3b321ae48db0cb8dac4e09e2722e56c -GMP.v6.3.0+1.i686-w64-mingw32-cxx03.tar.gz/sha512/6a6feeb8baf6d499409a9010295b474a8c6de461fa0e34562d53e58190b66c50e278fae7560495cd85ea6f5b41f9e8c6e950ff4f451d26d0757e1d1696e8bca5 -GMP.v6.3.0+1.i686-w64-mingw32-cxx11.tar.gz/md5/3f633b0ff74c2a44350855fc6ce310b8 -GMP.v6.3.0+1.i686-w64-mingw32-cxx11.tar.gz/sha512/eecb17dec70fe84d90f47e1958672d273c865da9607ba3056c9c923a6ff9a3cab5b30414389d8f0c7f5ae5d87c05999964ed0900c80ae5afb525eaec00f401e2 -GMP.v6.3.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/md5/8b5f113ad7fd4a312229cfe8c2d1abca -GMP.v6.3.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/36525ffc0ac5c363810c47945c34c81daabf88cf1f9c60d236447249d06332d3f5a130b431ab2d1c0148eb5413a4fa66bdd50671f2e7fcb77858d9fcdf83a94c -GMP.v6.3.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/md5/7f1237e9668136b00dd719a5cad3b6aa -GMP.v6.3.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/46a6efe23173a12299da371121847d16d7950ffe5c87d1221b54c5e95dafbf723c4a327b1c2e832d4742a91254aa40fd5d8152d6d0801769b2efd4f83a042afd -GMP.v6.3.0+1.x86_64-apple-darwin.tar.gz/md5/cd2d1b309aea2c781a9c28470fd2f0eb -GMP.v6.3.0+1.x86_64-apple-darwin.tar.gz/sha512/d7f94d80f1ba170c9553601d1af323bef7bbb98575b80b58b3d7b37d69d81cdee0e132fb4fa20393a0e8719984c785d0c7e5c8ae2c29c62ffbd82b00375993d4 -GMP.v6.3.0+1.x86_64-linux-gnu-cxx03.tar.gz/md5/5be8efef65dafe52e5726ef24238ae36 -GMP.v6.3.0+1.x86_64-linux-gnu-cxx03.tar.gz/sha512/f4c303fe915c89fecdb5a333a30412e0cfb04e07b4f1bc2f726179243dbc61d60ae5b0773a6bd5da8a10cb8764e448bc88035a639ea88d2e06f04e55074d8551 -GMP.v6.3.0+1.x86_64-linux-gnu-cxx11.tar.gz/md5/66f9a3858d07591227f2bc057c3c988b -GMP.v6.3.0+1.x86_64-linux-gnu-cxx11.tar.gz/sha512/5611b9bfd24efac0a189bbd85533e1cd2bee7f833f5ae0a06343f2c1d92925e0d0f0758b99c43520293348ad61f98e1b470829514c35d208697988d8b469fc41 -GMP.v6.3.0+1.x86_64-linux-musl-cxx03.tar.gz/md5/edaa83f6432ff7e75e106d8bfd03d509 -GMP.v6.3.0+1.x86_64-linux-musl-cxx03.tar.gz/sha512/1587e7b91e387da9c23559826c161fa4d447250bd7b6565f0b9fedc36e7502dc2b59caa8157abcb7e7862d24d696470289bd650511b07e8711ecf5a462330b6d -GMP.v6.3.0+1.x86_64-linux-musl-cxx11.tar.gz/md5/e668c4f0c1246aa1510c36f246b1b483 -GMP.v6.3.0+1.x86_64-linux-musl-cxx11.tar.gz/sha512/cf4bd47a5ddb067a57e852855fbd637a93f3652c3327af256f74e9e265c9e0de7c5be78b3e7bcbf08a03916876ecdc05cc294149e2c3d472a30fedc2e6dded47 -GMP.v6.3.0+1.x86_64-unknown-freebsd.tar.gz/md5/4cbf56d2884aa357291321b182d07cb8 -GMP.v6.3.0+1.x86_64-unknown-freebsd.tar.gz/sha512/0c723b8e0f5fabf9e43945d3fb355c3d7b036662a8d6542629aaff27164f12d13b2a19f5c4964f165466705b231884b7f7193d7a01a0e9d3644da1d79af79631 -GMP.v6.3.0+1.x86_64-w64-mingw32-cxx03.tar.gz/md5/02e8f5d66c15731117cf805e0a4c4976 -GMP.v6.3.0+1.x86_64-w64-mingw32-cxx03.tar.gz/sha512/1f94805fe9f34f4e77c54e92625615d91ade617468483409037d0693c3bf106187916d9d21e92681673faae158b376133c0ede643f31bfc9f73ac29c9fd13bcc -GMP.v6.3.0+1.x86_64-w64-mingw32-cxx11.tar.gz/md5/10752137fccc73175872db07749d6f49 -GMP.v6.3.0+1.x86_64-w64-mingw32-cxx11.tar.gz/sha512/3a5d7e8125f3b538a2e59e9c6919db36c974575e6b1950451cb60307da68dc092c4ce21b8f49c40871aadf3bd07681b43eea9c7bf37ba383da9a0e80c30b176e +GMP.v6.3.0+2.aarch64-apple-darwin.tar.gz/md5/3fb601fcf70024fcc40889cf1b958441 +GMP.v6.3.0+2.aarch64-apple-darwin.tar.gz/sha512/7ecc97c1f22287e9d7f3e8073e1cc3c6b3c75aa4a350a55a0b6f92c5bf60339b52f8866994f5973077e1026b9d3b10a7bcd71ec2abf25c3cc1bf6ca1041c3e73 +GMP.v6.3.0+2.aarch64-linux-gnu-cxx03.tar.gz/md5/10581945c01bac319c9c2d76f1f7052c +GMP.v6.3.0+2.aarch64-linux-gnu-cxx03.tar.gz/sha512/3aa2799ef7783a4edb767a695bd2797776def8ce1b2dc471b2cc733371db9981d6c3f395fee2fb50b13c7ef74c1521d2787c29dc60a75e1b92652b94819b5364 +GMP.v6.3.0+2.aarch64-linux-gnu-cxx11.tar.gz/md5/c1f9765fccec8ec131faa5e31b7ac28f +GMP.v6.3.0+2.aarch64-linux-gnu-cxx11.tar.gz/sha512/aebde82400544dc7a2aef0a4531cee78f9abcac9352dfd5d86472a70d704b281de03325cc609583169ecbe4cb64623ab04a3d7fff9cf24c70991530fe530aa05 +GMP.v6.3.0+2.aarch64-linux-musl-cxx03.tar.gz/md5/b1f771c79f3b380555c1c96232074523 +GMP.v6.3.0+2.aarch64-linux-musl-cxx03.tar.gz/sha512/daca9d3b4179e99da8e61f4010f5965718c79d02627e0b3272e4d20c34dac0d933408dc7d760a6d6fa09546e436c800ad5da4a1d34283eac9558f3d2f97bebce +GMP.v6.3.0+2.aarch64-linux-musl-cxx11.tar.gz/md5/523c386457e9d48430b83f2db85ac10f +GMP.v6.3.0+2.aarch64-linux-musl-cxx11.tar.gz/sha512/18155dd92641bf6240606d23b0d3cab16bb9b63b6034a7c7c61f3728fb48a6b710fdc21c6477145c015c648557e97003b0cc6087b4b36a691daecb87272cd51a +GMP.v6.3.0+2.aarch64-unknown-freebsd.tar.gz/md5/7dd3f2813fd7e9e620a8123ae2340ab2 +GMP.v6.3.0+2.aarch64-unknown-freebsd.tar.gz/sha512/375b12dee41285b65b5cdd55f6b000a90fd431c3eeb788a928396a102594fb6fad257f2c4e707f11ce7d0e4d45bc82a77ac85d8a48fa0a42f969b48b8b2c1c23 +GMP.v6.3.0+2.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/7d23f84102362ec3974ca2d84da33c4a +GMP.v6.3.0+2.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/51e419159fad75ca0ab12c31db29259be6fa280e66e2b980df4c99a0558615297741f633322978a409fbc071ec71834214b12d27d04ced0c043c569438dabd12 +GMP.v6.3.0+2.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/5f809ffa56ec07cc04e3c4cb155faad0 +GMP.v6.3.0+2.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/e394afb93a2c0aebe0ac7887bb2610720cb926256f0f5e7b05f3b1a805d3f7967fb97f4227ccec049df554c6cd1c4d4e9414fc4fea33f201204dd87e207e33ff +GMP.v6.3.0+2.armv6l-linux-musleabihf-cxx03.tar.gz/md5/494564a56197edc5b8772c15eca7b117 +GMP.v6.3.0+2.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/a7bd8bc19a030c56edd4d91e3cff16d78d4a9c1c1bec99897e55cfaca7e14cb99cee32e220473e207b78f0b5e0c0bf188c679d1748c010380485fad4d89758c5 +GMP.v6.3.0+2.armv6l-linux-musleabihf-cxx11.tar.gz/md5/751c36d4975d6ff88eb968123afc1845 +GMP.v6.3.0+2.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/af471834ba32a970b4f358a263434b03e169dc48445aa5af412ec51e70668a41699f9c408d90f64b06dc9233360f70a03df859428fdc0d759e5696a3ae32f3f4 +GMP.v6.3.0+2.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/ea9c867ae191a29647e8ccfb67947bc6 +GMP.v6.3.0+2.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/d6c44c945d1ef869155be087320d7750be549399b186aad8c92bba32ff5312bf09cbb2fb57be91be237be7d50f8f6ef0aea67070f50c024e6f5302485f405d5e +GMP.v6.3.0+2.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/ee5becfac9fe3c448a5de322ddee66d7 +GMP.v6.3.0+2.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/bc9bb2ad83644cf0b9f2bb0bfce28938ee6e82dbc0de74d1f411a8eb5ab96c5ec00c648019384ec07f34a469bd984d6c62eac1bcb803eaa013b6c85547ec3277 +GMP.v6.3.0+2.armv7l-linux-musleabihf-cxx03.tar.gz/md5/23962e487398f02c8d660724d88bf7f6 +GMP.v6.3.0+2.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/4c561053f79ed976a698c7382c5c94ebcbcd25ed27c939016bbb4af59948fd6bfb82e494e18fc7b4969941a7756c33afd2f177b3158f1b3d659215c25c958d2c +GMP.v6.3.0+2.armv7l-linux-musleabihf-cxx11.tar.gz/md5/4734feb61dd3f2a4e6e395f9ac7ccf57 +GMP.v6.3.0+2.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/088a52c372681b4853fe7c4c70eb8625b58df6d79eea2a8982bd781458188930aa31dd9a121ff7a6d00cd8165f5d126155d7f931100aeff256b55a2281d44a90 +GMP.v6.3.0+2.i686-linux-gnu-cxx03.tar.gz/md5/e229a7a09d6c843f03028b036a54b786 +GMP.v6.3.0+2.i686-linux-gnu-cxx03.tar.gz/sha512/d92cccfdd7abe3ca5c6ee1eecfe3f7aebe875ca6b9f6257bf1181dc5ee9c873a930ebb2accc825596ee26dc45bd290a482f0405cfd7a3a1b0eb606f5ca897b70 +GMP.v6.3.0+2.i686-linux-gnu-cxx11.tar.gz/md5/01dbe43b15197cd39351dce91b3a62c9 +GMP.v6.3.0+2.i686-linux-gnu-cxx11.tar.gz/sha512/d6e7ea99f76e10b4f7733d8c7f4af3fb2fc09618510c222da1fb95e8b4c83b0aa7c5d2f896bb620546bf39041d6dc1b32ca74ddf5024ef1beb5526b374ba885c +GMP.v6.3.0+2.i686-linux-musl-cxx03.tar.gz/md5/ce2f8d8b59228888cb7f03da0c1aca70 +GMP.v6.3.0+2.i686-linux-musl-cxx03.tar.gz/sha512/cc024a2ca4b4f042c19f667c4c3c08e3041d9b9ea0279cc668a3c0212103e86444abbdb323304e05c506b44b3c1b32a55f90c04cc32e9d26ac013336821c9ac1 +GMP.v6.3.0+2.i686-linux-musl-cxx11.tar.gz/md5/c37741b3a03ef2e705d45124eae25afa +GMP.v6.3.0+2.i686-linux-musl-cxx11.tar.gz/sha512/c343ad2ea47d5775e6e4c50fd8d46745d39f3632f4ad479199f7583fd02b08a0126048625d3999b23a0534e4f5c2bf19d021436229689da7c794427102c7780b +GMP.v6.3.0+2.i686-w64-mingw32-cxx03.tar.gz/md5/52a773a2111f7b1f938e78263c4608b0 +GMP.v6.3.0+2.i686-w64-mingw32-cxx03.tar.gz/sha512/6ef89b7eda8f0709315c1080e4d57810f976939c755f160e34b04e4c199409c8c707036fae5a73fca3a16813cb4ceff8daca38d1ead73e36d7ff23506e5bb4b1 +GMP.v6.3.0+2.i686-w64-mingw32-cxx11.tar.gz/md5/88b1ff47d913fa301c95e9e2aecf42ce +GMP.v6.3.0+2.i686-w64-mingw32-cxx11.tar.gz/sha512/3d631ee81906627a8bd9194fa8f18b634467565c10e5e08db7d1a4b0943bae9391ae15a1c39533c9796edf24e1f0210d082e44dc7c1fbd9f93855f37e207da07 +GMP.v6.3.0+2.powerpc64le-linux-gnu-cxx03.tar.gz/md5/0b2c73cf7936500ce0f07577c4c76ba5 +GMP.v6.3.0+2.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/30e099bd6384e801fb28b4741810122f82ab0760a4e09d6ab28559b72feff278a48150579907cb2920a624fc85287a197743331bc1808353d0855c198341bfa1 +GMP.v6.3.0+2.powerpc64le-linux-gnu-cxx11.tar.gz/md5/f496279b474948435f836ba39291c708 +GMP.v6.3.0+2.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/c37d4fbba284af87fc16a24bf1fdfe80b42c84bd44f1859d1c9ee97fdbb489817b58db80a078729e19c8a5b8448f9234408a8e477fd15acf15521f3129e86acd +GMP.v6.3.0+2.riscv64-linux-gnu-cxx03.tar.gz/md5/f07fc6751104a407ea2515fda3f26880 +GMP.v6.3.0+2.riscv64-linux-gnu-cxx03.tar.gz/sha512/435b375da747d2dfba06a303b55118471c6ef705cc65afeabb5a59477cc98aa9a956b31c5e8b571126f63d922498b9a66510f8f6810a60f6a4fabba5ec368cdf +GMP.v6.3.0+2.riscv64-linux-gnu-cxx11.tar.gz/md5/493c24a7a7370f308f0da2955f40b5d5 +GMP.v6.3.0+2.riscv64-linux-gnu-cxx11.tar.gz/sha512/2e1a7562b759219d1a4283372e66fa1e907279c5b5feb8a858f6bd8de8b9c2ef3ddd09d5e812d93813fa781090574fd26d0cec85b211274db628681301a206f9 +GMP.v6.3.0+2.x86_64-apple-darwin.tar.gz/md5/c3bb785e10fe19cf1c47db6bc5e98fdd +GMP.v6.3.0+2.x86_64-apple-darwin.tar.gz/sha512/5280896654e1c7864d770ecbfc853a1c7837c2b1dd369047432d10f831762a26fdaeac4201ca419d8bf7c545c107800b892660f4484b5eb87bfaf42c919fb640 +GMP.v6.3.0+2.x86_64-linux-gnu-cxx03.tar.gz/md5/0fd62bb914554c3cb6b5dc0f5ec0d330 +GMP.v6.3.0+2.x86_64-linux-gnu-cxx03.tar.gz/sha512/78cdf0cdcdca4a0ddc87755f4afdb8f290fa946b3c5541a3e31145f8bd905884d59f38e9f5ee4fe96ceaedaf90881af795f4e3ecf1be922103b838964da101cf +GMP.v6.3.0+2.x86_64-linux-gnu-cxx11.tar.gz/md5/02f54f8895bae0d7a824374888300744 +GMP.v6.3.0+2.x86_64-linux-gnu-cxx11.tar.gz/sha512/83c865f6164400e56c28949c680cf92457daa270b745d89034e1bcc46af1eb93c96bce708561dee03b58162191f6448e4325e921daec11083bbc42dcf3a1ffda +GMP.v6.3.0+2.x86_64-linux-musl-cxx03.tar.gz/md5/8f3f26422f8bd0889b5c2ecd22d97101 +GMP.v6.3.0+2.x86_64-linux-musl-cxx03.tar.gz/sha512/680beb99936433bc1c3367e85f3a4129c5a99d4c4031a1da919293819f6d3f1b85be801a2f48af352c47d7cb6f394534333f1a0d0404ff41899952d55c4b1f75 +GMP.v6.3.0+2.x86_64-linux-musl-cxx11.tar.gz/md5/7ec0e3e9125c14a20d6d0044036f0996 +GMP.v6.3.0+2.x86_64-linux-musl-cxx11.tar.gz/sha512/c22e6a25ec854f9c199d5e76bc1dbcbe57c4cc219eb2b5f24418729252eee1a5c1d3e8bbf5b62d148cb408595e96f448f68a29a9425a902952bee666b6f051f6 +GMP.v6.3.0+2.x86_64-unknown-freebsd.tar.gz/md5/6782d7fd0bd15c189c4a1753ee0fb0eb +GMP.v6.3.0+2.x86_64-unknown-freebsd.tar.gz/sha512/04d7a95337e832f7ec228f160a09b74ed7908ef9cef1bd392555392a24ff63ce4a88b616b5426cd710dcb581e164bb94c04fe17f0b599adf3c3bc33106bcd886 +GMP.v6.3.0+2.x86_64-w64-mingw32-cxx03.tar.gz/md5/b4cb31e93c85cd453b7d8d392a365088 +GMP.v6.3.0+2.x86_64-w64-mingw32-cxx03.tar.gz/sha512/3bd84fa8f580b272eecb06077ef710ae8df661126e86afa2c901b298a2598975a07f840b922da0066dbf555f03376cba1b7e4915cd37617341fd420b6707276d +GMP.v6.3.0+2.x86_64-w64-mingw32-cxx11.tar.gz/md5/2342842254e7b47b26836366d29d6802 +GMP.v6.3.0+2.x86_64-w64-mingw32-cxx11.tar.gz/sha512/fb12be14433763d9de689a5df222802cd79d5c990da9a53855fd2f6f8e663a9838b444a310318c059cdb4962eb87d0d4cc2b54d163cf82b09377339c8e45510f gmp-6.3.0.tar.bz2/md5/c1cd6ef33085e9cb818b9b08371f9000 gmp-6.3.0.tar.bz2/sha512/3b684c9bcb9ede2b7e54d0ba4c9764bfa17c20d4f3000017c553b6f1e135b536949580ff37341680c25dc236cfe0ba1db8cfdfe619ce013656189ef0871b89f8 diff --git a/deps/checksums/libssh2 b/deps/checksums/libssh2 index fa05f325fa6a7..056d373656d98 100644 --- a/deps/checksums/libssh2 +++ b/deps/checksums/libssh2 @@ -1,36 +1,38 @@ -LibSSH2.v1.11.3+0.aarch64-apple-darwin.tar.gz/md5/87ba86e78421d6195aa6a46129ff61d4 -LibSSH2.v1.11.3+0.aarch64-apple-darwin.tar.gz/sha512/2b7129be9e9518337f59857474882a6a3448f358c931c66ab9f9ec67506c68d2356df591bd45925154844ca0d6f6e1f071d4c54d62039c5078b468fcb356187b -LibSSH2.v1.11.3+0.aarch64-linux-gnu.tar.gz/md5/84c6eb68e7797038d0863513fa4e292f -LibSSH2.v1.11.3+0.aarch64-linux-gnu.tar.gz/sha512/3012beb35fdf94136907037e8f5261a5cc94d102f461172321d4ed8f328da3789d521513dd03cb344c6fcb73675cd1d3ede606bf9a904fb811d40c43fd09d8aa -LibSSH2.v1.11.3+0.aarch64-linux-musl.tar.gz/md5/5a49057201e779f3427b794b72bf07a2 -LibSSH2.v1.11.3+0.aarch64-linux-musl.tar.gz/sha512/62a812efb4ad7b24bfeeb3bb89756004215c09a1cc01e0530f14ce4b8546f1dcbbac18155ac2ce08311c1790d659b14674e3bb3549ff68d1209d52b5e5986fff -LibSSH2.v1.11.3+0.aarch64-unknown-freebsd.tar.gz/md5/a5129167b7be7ac8ba2c873e164afb1b -LibSSH2.v1.11.3+0.aarch64-unknown-freebsd.tar.gz/sha512/f8d9cc5098a3b401fbbe98a24efaca0ea46f533ecaf11dbfe8f7e7e3853363af19914de62bd1cb5a573e55e90d5c6074532ddc6d64723c9e235b277f438ce6ef -LibSSH2.v1.11.3+0.armv6l-linux-gnueabihf.tar.gz/md5/5c59c95612bf9aa172e5d487002db509 -LibSSH2.v1.11.3+0.armv6l-linux-gnueabihf.tar.gz/sha512/5ba41e49365c2018d55c92e4a23d806ca9ab960a448593b08380527da21eec03f76cab89c34befbc56f4104002aa189d5cae6f655797f1447f395b51a14d40e2 -LibSSH2.v1.11.3+0.armv6l-linux-musleabihf.tar.gz/md5/4bc27411f0eddf82a787d1ede17ce2c3 -LibSSH2.v1.11.3+0.armv6l-linux-musleabihf.tar.gz/sha512/d6024b6949ac6867c56c66defbb99300a5661e0c73da6c330165bceba78d64063986c8851601ca74554b27944d5b02e3f602b1e71781097bbb8b12effc0cbbdb -LibSSH2.v1.11.3+0.armv7l-linux-gnueabihf.tar.gz/md5/40e1a0d323969b96ab121eb5a3ecc874 -LibSSH2.v1.11.3+0.armv7l-linux-gnueabihf.tar.gz/sha512/67ce15a5b1c1fe0fd1096ed5d2d9f44d83983de11c1bc651f5914d70d387a99ee6bde31716031b758f48981e2a9383599f077f02d61a5c783ee6d09a7bf445db -LibSSH2.v1.11.3+0.armv7l-linux-musleabihf.tar.gz/md5/9453c52394b1b06bd36c43e461a3b48f -LibSSH2.v1.11.3+0.armv7l-linux-musleabihf.tar.gz/sha512/c62068ecb1b88dbd08a2474e0b93cd313bdc4e1407a22cd9164a73b2d897564f12a3c34f6fc492b264af579b00e9335a0fe1fa853fbe0fbb18d8335b77d409b2 -LibSSH2.v1.11.3+0.i686-linux-gnu.tar.gz/md5/992453b1c59033aefa8d98b89f491ff6 -LibSSH2.v1.11.3+0.i686-linux-gnu.tar.gz/sha512/ebf14565d614086c4401e1a997a3aacc83f8e499ed836c429f87c4f95f1c8409713fad47f1c34a2b1cd23f90de3daf14caafba3c82b15642018592213607c874 -LibSSH2.v1.11.3+0.i686-linux-musl.tar.gz/md5/e0cb0566c724c107f4f04619080d4c0c -LibSSH2.v1.11.3+0.i686-linux-musl.tar.gz/sha512/af7d08dba5bb06eaf7ce8aeb12b69701d3c2829996a1c8e68510c106402a1166ad060687987df49365c26d30e8d6511c66f2a50ec810a493d2c090931ccf05a5 -LibSSH2.v1.11.3+0.i686-w64-mingw32.tar.gz/md5/c5e8d3145deb56d6df008522a5d3ea6f -LibSSH2.v1.11.3+0.i686-w64-mingw32.tar.gz/sha512/47f3c36747d2e42a4c0669ef468d395078328235d30056b7d67d76bd737b5118c1bbc720aef455c4d9017e7b9350e8cc043ed28264ea8a9ecb6833ca517f82aa -LibSSH2.v1.11.3+0.powerpc64le-linux-gnu.tar.gz/md5/12eba4aec5e320a4d0cf09225bca3f7c -LibSSH2.v1.11.3+0.powerpc64le-linux-gnu.tar.gz/sha512/d6b8413d77d8af3d29b867692f6c02b63e793f5e8f17c4777756d247c8e602b3ab87380031aefa60f2c3ddae5a3c7a1f1c739439f149db34a32c79f32e08048b -LibSSH2.v1.11.3+0.x86_64-apple-darwin.tar.gz/md5/f6e7cd35e16290b198c80c61a0fca5e5 -LibSSH2.v1.11.3+0.x86_64-apple-darwin.tar.gz/sha512/2c83814ef6ae78ec94a43f2997151dd7195c0a0f9cf456fcd3f780268bd1cbdd7ea55182fc5a1f8e1413c26889e54fccb01964b0b91dd4b925ecaa16b7df8d07 -LibSSH2.v1.11.3+0.x86_64-linux-gnu.tar.gz/md5/95aa96befc9f9007e6a000a95c1b7572 -LibSSH2.v1.11.3+0.x86_64-linux-gnu.tar.gz/sha512/6058dca6d933afb7fe5fc3374937b4432f202a5dfe3ebcc2f91f65777230c18d76801c38071f84f8362527ee08656a97f79da234ab5481265a7ccf29e94c20c5 -LibSSH2.v1.11.3+0.x86_64-linux-musl.tar.gz/md5/88b69d889d602bc3df420535dba30f9e -LibSSH2.v1.11.3+0.x86_64-linux-musl.tar.gz/sha512/7335954124074e7df786989db86e86e3bcf41f503b8e3b27d6ac18032c8025bec26180bd2c537b23349bcf5673eb67245531479b939670e620faf5aa13c8c4ab -LibSSH2.v1.11.3+0.x86_64-unknown-freebsd.tar.gz/md5/6d5f6e9455c35c5f6655cb4d46797db0 -LibSSH2.v1.11.3+0.x86_64-unknown-freebsd.tar.gz/sha512/9515d11bb5686e29eb5a37bbcb7ab07574da0869c82e5b3f0cf282bbc56792af31e6174521d58133968b997caa6db75ac9b195024144fd2c95fd1bbf689ebbf6 -LibSSH2.v1.11.3+0.x86_64-w64-mingw32.tar.gz/md5/e66cdac0c2d5ce2d160e482d780ad0c3 -LibSSH2.v1.11.3+0.x86_64-w64-mingw32.tar.gz/sha512/2dabb1e8da5ea496898751d5517ca37178e1a44c78c26fe33f87487a0b4acf7185f686ce8d6ea0e65e38a8fd56e5ff09fd70becda402a942b5e459707eb2a44e +LibSSH2.v1.11.3+1.aarch64-apple-darwin.tar.gz/md5/87ba86e78421d6195aa6a46129ff61d4 +LibSSH2.v1.11.3+1.aarch64-apple-darwin.tar.gz/sha512/2b7129be9e9518337f59857474882a6a3448f358c931c66ab9f9ec67506c68d2356df591bd45925154844ca0d6f6e1f071d4c54d62039c5078b468fcb356187b +LibSSH2.v1.11.3+1.aarch64-linux-gnu.tar.gz/md5/84c6eb68e7797038d0863513fa4e292f +LibSSH2.v1.11.3+1.aarch64-linux-gnu.tar.gz/sha512/3012beb35fdf94136907037e8f5261a5cc94d102f461172321d4ed8f328da3789d521513dd03cb344c6fcb73675cd1d3ede606bf9a904fb811d40c43fd09d8aa +LibSSH2.v1.11.3+1.aarch64-linux-musl.tar.gz/md5/5a49057201e779f3427b794b72bf07a2 +LibSSH2.v1.11.3+1.aarch64-linux-musl.tar.gz/sha512/62a812efb4ad7b24bfeeb3bb89756004215c09a1cc01e0530f14ce4b8546f1dcbbac18155ac2ce08311c1790d659b14674e3bb3549ff68d1209d52b5e5986fff +LibSSH2.v1.11.3+1.aarch64-unknown-freebsd.tar.gz/md5/a5129167b7be7ac8ba2c873e164afb1b +LibSSH2.v1.11.3+1.aarch64-unknown-freebsd.tar.gz/sha512/f8d9cc5098a3b401fbbe98a24efaca0ea46f533ecaf11dbfe8f7e7e3853363af19914de62bd1cb5a573e55e90d5c6074532ddc6d64723c9e235b277f438ce6ef +LibSSH2.v1.11.3+1.armv6l-linux-gnueabihf.tar.gz/md5/5c59c95612bf9aa172e5d487002db509 +LibSSH2.v1.11.3+1.armv6l-linux-gnueabihf.tar.gz/sha512/5ba41e49365c2018d55c92e4a23d806ca9ab960a448593b08380527da21eec03f76cab89c34befbc56f4104002aa189d5cae6f655797f1447f395b51a14d40e2 +LibSSH2.v1.11.3+1.armv6l-linux-musleabihf.tar.gz/md5/4bc27411f0eddf82a787d1ede17ce2c3 +LibSSH2.v1.11.3+1.armv6l-linux-musleabihf.tar.gz/sha512/d6024b6949ac6867c56c66defbb99300a5661e0c73da6c330165bceba78d64063986c8851601ca74554b27944d5b02e3f602b1e71781097bbb8b12effc0cbbdb +LibSSH2.v1.11.3+1.armv7l-linux-gnueabihf.tar.gz/md5/40e1a0d323969b96ab121eb5a3ecc874 +LibSSH2.v1.11.3+1.armv7l-linux-gnueabihf.tar.gz/sha512/67ce15a5b1c1fe0fd1096ed5d2d9f44d83983de11c1bc651f5914d70d387a99ee6bde31716031b758f48981e2a9383599f077f02d61a5c783ee6d09a7bf445db +LibSSH2.v1.11.3+1.armv7l-linux-musleabihf.tar.gz/md5/9453c52394b1b06bd36c43e461a3b48f +LibSSH2.v1.11.3+1.armv7l-linux-musleabihf.tar.gz/sha512/c62068ecb1b88dbd08a2474e0b93cd313bdc4e1407a22cd9164a73b2d897564f12a3c34f6fc492b264af579b00e9335a0fe1fa853fbe0fbb18d8335b77d409b2 +LibSSH2.v1.11.3+1.i686-linux-gnu.tar.gz/md5/992453b1c59033aefa8d98b89f491ff6 +LibSSH2.v1.11.3+1.i686-linux-gnu.tar.gz/sha512/ebf14565d614086c4401e1a997a3aacc83f8e499ed836c429f87c4f95f1c8409713fad47f1c34a2b1cd23f90de3daf14caafba3c82b15642018592213607c874 +LibSSH2.v1.11.3+1.i686-linux-musl.tar.gz/md5/e0cb0566c724c107f4f04619080d4c0c +LibSSH2.v1.11.3+1.i686-linux-musl.tar.gz/sha512/af7d08dba5bb06eaf7ce8aeb12b69701d3c2829996a1c8e68510c106402a1166ad060687987df49365c26d30e8d6511c66f2a50ec810a493d2c090931ccf05a5 +LibSSH2.v1.11.3+1.i686-w64-mingw32.tar.gz/md5/c5e8d3145deb56d6df008522a5d3ea6f +LibSSH2.v1.11.3+1.i686-w64-mingw32.tar.gz/sha512/47f3c36747d2e42a4c0669ef468d395078328235d30056b7d67d76bd737b5118c1bbc720aef455c4d9017e7b9350e8cc043ed28264ea8a9ecb6833ca517f82aa +LibSSH2.v1.11.3+1.powerpc64le-linux-gnu.tar.gz/md5/12eba4aec5e320a4d0cf09225bca3f7c +LibSSH2.v1.11.3+1.powerpc64le-linux-gnu.tar.gz/sha512/d6b8413d77d8af3d29b867692f6c02b63e793f5e8f17c4777756d247c8e602b3ab87380031aefa60f2c3ddae5a3c7a1f1c739439f149db34a32c79f32e08048b +LibSSH2.v1.11.3+1.riscv64-linux-gnu.tar.gz/md5/cc11dd403ecaa373241b3c30cd16bd24 +LibSSH2.v1.11.3+1.riscv64-linux-gnu.tar.gz/sha512/d195ad62cde58dfa1e3546efd70a5f6b8a0762a2a933c637120aa71eda45dc6dc4213e87f9f401e2e148bbd5fb10638e429ae514bcda5bada0940c70cb7ff15e +LibSSH2.v1.11.3+1.x86_64-apple-darwin.tar.gz/md5/f6e7cd35e16290b198c80c61a0fca5e5 +LibSSH2.v1.11.3+1.x86_64-apple-darwin.tar.gz/sha512/2c83814ef6ae78ec94a43f2997151dd7195c0a0f9cf456fcd3f780268bd1cbdd7ea55182fc5a1f8e1413c26889e54fccb01964b0b91dd4b925ecaa16b7df8d07 +LibSSH2.v1.11.3+1.x86_64-linux-gnu.tar.gz/md5/95aa96befc9f9007e6a000a95c1b7572 +LibSSH2.v1.11.3+1.x86_64-linux-gnu.tar.gz/sha512/6058dca6d933afb7fe5fc3374937b4432f202a5dfe3ebcc2f91f65777230c18d76801c38071f84f8362527ee08656a97f79da234ab5481265a7ccf29e94c20c5 +LibSSH2.v1.11.3+1.x86_64-linux-musl.tar.gz/md5/88b69d889d602bc3df420535dba30f9e +LibSSH2.v1.11.3+1.x86_64-linux-musl.tar.gz/sha512/7335954124074e7df786989db86e86e3bcf41f503b8e3b27d6ac18032c8025bec26180bd2c537b23349bcf5673eb67245531479b939670e620faf5aa13c8c4ab +LibSSH2.v1.11.3+1.x86_64-unknown-freebsd.tar.gz/md5/6d5f6e9455c35c5f6655cb4d46797db0 +LibSSH2.v1.11.3+1.x86_64-unknown-freebsd.tar.gz/sha512/9515d11bb5686e29eb5a37bbcb7ab07574da0869c82e5b3f0cf282bbc56792af31e6174521d58133968b997caa6db75ac9b195024144fd2c95fd1bbf689ebbf6 +LibSSH2.v1.11.3+1.x86_64-w64-mingw32.tar.gz/md5/e66cdac0c2d5ce2d160e482d780ad0c3 +LibSSH2.v1.11.3+1.x86_64-w64-mingw32.tar.gz/sha512/2dabb1e8da5ea496898751d5517ca37178e1a44c78c26fe33f87487a0b4acf7185f686ce8d6ea0e65e38a8fd56e5ff09fd70becda402a942b5e459707eb2a44e libssh2-a312b43325e3383c865a87bb1d26cb52e3292641.tar.gz/md5/06d5e2881ac023583c7fd6665d628a87 libssh2-a312b43325e3383c865a87bb1d26cb52e3292641.tar.gz/sha512/5dee8cce91853eb8c9968d7453b1ad0c3cd1411901d288f1731b7c7e4adf380313f61c2a66eee0d3b89eba79e420e13269bb3738bcf2c59f0b88276aa785fa8c diff --git a/deps/checksums/libuv b/deps/checksums/libuv index 49869af795d45..fb2904b308a90 100644 --- a/deps/checksums/libuv +++ b/deps/checksums/libuv @@ -1,36 +1,38 @@ -LibUV.v2.0.1+19.aarch64-apple-darwin.tar.gz/md5/f176c76e5e2096dea8443302cf9550b8 -LibUV.v2.0.1+19.aarch64-apple-darwin.tar.gz/sha512/4301b13953a08a758b86e30af3261fd9a291ce3829b4d98e71e2a2c040e322e284c5a6eb4bc7189cc352f4b1cf7041e2cfd3380d511d88c151df3101ad74594e -LibUV.v2.0.1+19.aarch64-linux-gnu.tar.gz/md5/c81515783363702a1bd4b65fd6d7f36b -LibUV.v2.0.1+19.aarch64-linux-gnu.tar.gz/sha512/011429365337f5a45e56ca7a42709866bb994c747a1170d870f5f3ddfff2d36138866ee9278ac01172bc71bde8dee404bcb9cae9c7b44222bf1cc883659df269 -LibUV.v2.0.1+19.aarch64-linux-musl.tar.gz/md5/e74d5ea4912dd326b2705638faa7b805 -LibUV.v2.0.1+19.aarch64-linux-musl.tar.gz/sha512/a26a9f2c9051816230324071c502321f7af3885d581a400615858a93a4cd457226048d15b0e7f6a73d12659763c705b5ab519e9f5b35c6d886b9fd5babbfe352 -LibUV.v2.0.1+19.aarch64-unknown-freebsd.tar.gz/md5/f2fe50ada3b6935af4f6b28fbc3940b2 -LibUV.v2.0.1+19.aarch64-unknown-freebsd.tar.gz/sha512/c4ba0190d21c6edb561062b2615792e9b4c2474dfc200d9dba12a3add44e1fbc0b74989748d85576f0a6e42d8e0bc02f6cb13b5963f3a56b00edffe6348a9f26 -LibUV.v2.0.1+19.armv6l-linux-gnueabihf.tar.gz/md5/6df38bcf5d0a61dee63d16b73d0c9a24 -LibUV.v2.0.1+19.armv6l-linux-gnueabihf.tar.gz/sha512/d5354a6532061de0a58965ce0e427bde52f9ae0ee39a98e1a33de4c414fddcba9ba139ddf91be7321a4ccc97bbf7a8a8357ff10cf60f83c0a6bff7d839d6d7a8 -LibUV.v2.0.1+19.armv6l-linux-musleabihf.tar.gz/md5/6f02a24cfbfae3032fadceaea1faed39 -LibUV.v2.0.1+19.armv6l-linux-musleabihf.tar.gz/sha512/7fd107eb9a5ea84b488ea02e4fbedc9fe13bb11be859986a47af38f40ad775dd9f738c790878a3503437bcac1eb26ad9fe26f4aa0d3cb45c980b4c5abc9aec99 -LibUV.v2.0.1+19.armv7l-linux-gnueabihf.tar.gz/md5/96b09dec72f7e9b7409fa2920e67c866 -LibUV.v2.0.1+19.armv7l-linux-gnueabihf.tar.gz/sha512/6a0f79fc15c944fabba5c65180b665bc9769c6ff25863e330049f48b3a4394b448492f5a9a76bb7f8dbd3ce44dfc6f9ccdc2c71c42e1c749e88070fe99b1db69 -LibUV.v2.0.1+19.armv7l-linux-musleabihf.tar.gz/md5/f44e4b2521a813181f943895bdb0dd3c -LibUV.v2.0.1+19.armv7l-linux-musleabihf.tar.gz/sha512/cda1413dca817f772e8b343db0c6de0ef6b8f269e9a6a2ef3403c2582aeab554f46281bbb1eb4659c259198ef47fe26aab648a281e66f80aaf2f2cda0a23ac05 -LibUV.v2.0.1+19.i686-linux-gnu.tar.gz/md5/1f231d89cf9c04515d2d107a5d786cc8 -LibUV.v2.0.1+19.i686-linux-gnu.tar.gz/sha512/089cb8a372cdee0cbc0e78fc201611bb9bafd99af9a78e09d6097a6b70e7c4aa001ebd86f944b0a885c072093c529bf86bcaa32bde4fc1934407a858c1a5a764 -LibUV.v2.0.1+19.i686-linux-musl.tar.gz/md5/01cfc2a9e2536dbd330267917abb19ce -LibUV.v2.0.1+19.i686-linux-musl.tar.gz/sha512/72f3588cb464a60e61f8998242aaa2abdf93df920a2feba5e1d66ef0f2498488df0ec415cbb499d7f75c47bdfc7e3a2fdda6a94383492e0ad13e464eb1314ff8 -LibUV.v2.0.1+19.i686-w64-mingw32.tar.gz/md5/8c6599aab9ed4c46e52f03683aac664e -LibUV.v2.0.1+19.i686-w64-mingw32.tar.gz/sha512/13f0565f7244a8bcf1ab43fac91a856dc86d214877033a3cefee8c2179c1a275dfd7dda32e9017763acac2ba42ab6799934a58f5feaa38fb6cf2253dd713f57a -LibUV.v2.0.1+19.powerpc64le-linux-gnu.tar.gz/md5/af0e43d9d0aa91dd82b63220d96991ef -LibUV.v2.0.1+19.powerpc64le-linux-gnu.tar.gz/sha512/9fabe3089e4fc60e910770c32d36300ce8ef36c28e8cc9c72fbecba6eb80285ee8174e84e4452fb4ce90ee7c7f94e99b03fce47d8c579bd614bfffd553f93666 -LibUV.v2.0.1+19.x86_64-apple-darwin.tar.gz/md5/871040e874eedae54553d8f1c91b9133 -LibUV.v2.0.1+19.x86_64-apple-darwin.tar.gz/sha512/d5eee08b65e4bb8b444c61ac277bec9ef944b9279dd7f0732b3cd91d47788c77938e5db71e019e01bbe7785a75df95faf14368764f700c6b7a6b9e4d96d6b4c2 -LibUV.v2.0.1+19.x86_64-linux-gnu.tar.gz/md5/d2d186952c6d017fe33f6a6bea63a3ea -LibUV.v2.0.1+19.x86_64-linux-gnu.tar.gz/sha512/15501534bf5721e6bb668aabe6dc6375349f7a284e28df0609d00982e7e456908bd6868722391afa7f44a5c82faedc8cf544f69a0e4fb9fb0d529b3ae3d44d78 -LibUV.v2.0.1+19.x86_64-linux-musl.tar.gz/md5/271d4d40a1ae53ed5b2376e5936cfcf9 -LibUV.v2.0.1+19.x86_64-linux-musl.tar.gz/sha512/1956f059ed01f66b72349d6561b04e6a89b7257c0f838d7fbdd2cee79bd126bb46b93bf944a042b5a6a235762a7a0cdd117207342dd55a0c58653a70b4a38d48 -LibUV.v2.0.1+19.x86_64-unknown-freebsd.tar.gz/md5/62fe8523948914fbe7e28bf0b8d73594 -LibUV.v2.0.1+19.x86_64-unknown-freebsd.tar.gz/sha512/e6486888028c96975f74bc9313cba9706f6bf2be085aa776c44cbb2886753b2eee62469a0be92eb0542df1d0f51db3b34c7ba5e46842e16c6ff1d20e11b75322 -LibUV.v2.0.1+19.x86_64-w64-mingw32.tar.gz/md5/ae103f24b6e1830cdbe02143826fe551 -LibUV.v2.0.1+19.x86_64-w64-mingw32.tar.gz/sha512/f814085c135815947f342ff24fa0e1015e283ccece84a5b8dd5ccec0f5928a129e5fd79100a33b131376ad696f70b5acadcc5a02a7e6544635ecf7e18003ba1c +LibUV.v2.0.1+20.aarch64-apple-darwin.tar.gz/md5/7b889e32bcb01afc19f9f3801b28a0fd +LibUV.v2.0.1+20.aarch64-apple-darwin.tar.gz/sha512/cfa58e835512957171c7f2dcc9171bd9ea1717f71ed6920b6cac2560da3c5b13440df0d14c5aee210df3346743d3605dec22d78891e8237f5c3867d5cb6d4f56 +LibUV.v2.0.1+20.aarch64-linux-gnu.tar.gz/md5/696ae3e79f9b838a98dae8152d980ff4 +LibUV.v2.0.1+20.aarch64-linux-gnu.tar.gz/sha512/74ac009cebfa3ec67209921296f5d395c2f888d825b0f3d3f3bad5432819deaf5ee758f88030e620530e94f4861734d7984b8ef981ae4eebc356d96e274d678d +LibUV.v2.0.1+20.aarch64-linux-musl.tar.gz/md5/d23a45e4d9cefad93e3e83cf990c095a +LibUV.v2.0.1+20.aarch64-linux-musl.tar.gz/sha512/80d06afae0b5ab657c5c743beeaff112c3cddabd2a2604f8fc16a50cab5db878b4ea8941496a11004c9464bcada13844528cc4fee209bdd8ba374d9b13351991 +LibUV.v2.0.1+20.aarch64-unknown-freebsd.tar.gz/md5/7957f7740cfe6dd5ccb4ff4cd2811b45 +LibUV.v2.0.1+20.aarch64-unknown-freebsd.tar.gz/sha512/923fc895d3fe41005e47d6af422ba450b32e94210c393065a891b44f83f016104d3073a9faa609cd7979bfeca9d0ed0c7164b37de5da92deeb4e8676311cc57f +LibUV.v2.0.1+20.armv6l-linux-gnueabihf.tar.gz/md5/c2ec51470a4d66e3bd23bed67c109cc9 +LibUV.v2.0.1+20.armv6l-linux-gnueabihf.tar.gz/sha512/d139d5a6a141933a83f0d10f8da9366d709013bd2ef005d2b783716fb13d165b87640b7d9f51dc2772a69fc6f63e8545901c96da2343506a2f940edf36332164 +LibUV.v2.0.1+20.armv6l-linux-musleabihf.tar.gz/md5/a1a432902cd687f692c5619e72de241b +LibUV.v2.0.1+20.armv6l-linux-musleabihf.tar.gz/sha512/209207dde41fa699adb72af9a6211d74366d393d335c9b0d4c9c9509c832123707bca27e8410c7b1c63f89fbae77dc15eba55031701e307f88d5c183b929d9f3 +LibUV.v2.0.1+20.armv7l-linux-gnueabihf.tar.gz/md5/bdb8124a2b3c9e42b1b9dc8ce813e664 +LibUV.v2.0.1+20.armv7l-linux-gnueabihf.tar.gz/sha512/2f8879b4f41aa6cab3b195a76dd02376bf5d47f51ac157541b0c8453d03cd2f51fac83f59b2cd2fa49a2395262d18d636251715f1a4912750aa3de56eab4d6f3 +LibUV.v2.0.1+20.armv7l-linux-musleabihf.tar.gz/md5/91ddead3be8fa8b06b37983cba074615 +LibUV.v2.0.1+20.armv7l-linux-musleabihf.tar.gz/sha512/3be790d1c580e2a69d76171b82cfd2f594135920e68f7f4ff7a6fdc42918130e628458492fa2a157947c25effd2de0a71d434fcc1c6fb1d741985bbbfcfac3c5 +LibUV.v2.0.1+20.i686-linux-gnu.tar.gz/md5/c906674ba1bffffb685f0f00189187c1 +LibUV.v2.0.1+20.i686-linux-gnu.tar.gz/sha512/c3e5b394959dc76e2abd51fe59f7e8bbb1755b3a008f019ad05c41ffe8fd9f42d0bf262a506b36f26a2f8f4b14c937eff70a9e1ba2c55f19fbc57e5ba9c2dacf +LibUV.v2.0.1+20.i686-linux-musl.tar.gz/md5/977204bc42355bbdb908693b3baa8e10 +LibUV.v2.0.1+20.i686-linux-musl.tar.gz/sha512/5fb2717575ee97545026b79c2acc0660eaa04827637138896aabbe69bffa0c11732de4f9aad9dd78ba68db265ccf5ff3aef244d7da0008cafc4a417423db361e +LibUV.v2.0.1+20.i686-w64-mingw32.tar.gz/md5/ae698bbab57855ad41bd850ef2ccc695 +LibUV.v2.0.1+20.i686-w64-mingw32.tar.gz/sha512/9c6530404babe8383c6a1db7fa1e81b40b08de0dc2d2be3507a6466c150acc842cca277e39680b21a6c7f5a6dbae618bd3f5c3ac8f11882898cc116d5e13e7d9 +LibUV.v2.0.1+20.powerpc64le-linux-gnu.tar.gz/md5/e68314bb638f210d2ec9326c617752ca +LibUV.v2.0.1+20.powerpc64le-linux-gnu.tar.gz/sha512/f74ce6b21cd2776cdf49b4c6c2ad551c0bf55951f8bd9090020e71d2b233f72907a3e145b9a95715c391b82ad36ab1a069bb9f87d54c219179021cc26902dd22 +LibUV.v2.0.1+20.riscv64-linux-gnu.tar.gz/md5/d8e1ffb730c784df14faff06027b724d +LibUV.v2.0.1+20.riscv64-linux-gnu.tar.gz/sha512/60e7699ac4dc353d0b9fbd34952bd68185ab301a449354b7e805b6759d3866ffa5906041cd9e6ff299cb9fe3f5a92f4c5bfd9c441210125d52f06d614afc84a5 +LibUV.v2.0.1+20.x86_64-apple-darwin.tar.gz/md5/15d8197dea20880edb96a8bf643fe95e +LibUV.v2.0.1+20.x86_64-apple-darwin.tar.gz/sha512/7d65d4d2e0720f997c164234b78a729f4d4239fbb0b01634f23081e2209ab010ef27deca1cc3824fd8e17630370efa86f1567aae035a246ab9f60a6c14ea6d3b +LibUV.v2.0.1+20.x86_64-linux-gnu.tar.gz/md5/013be6d2673a59cd00b2ea62d4e34e21 +LibUV.v2.0.1+20.x86_64-linux-gnu.tar.gz/sha512/f466af2a1f9ff83d887ecaa200d3042bd5685d6cd487af00bdf8c92bf1d4256017f2757084de3b7331071c473b254df43b03f580de09db3bb9268af759a5b0c7 +LibUV.v2.0.1+20.x86_64-linux-musl.tar.gz/md5/21099b0c3ad76c3d67fb24260ec39836 +LibUV.v2.0.1+20.x86_64-linux-musl.tar.gz/sha512/03279a4d29072246dd806d800b80d9db14b637235e211294d5840104056cd206b370a987a2b771216e762549d13b13432f1e1893510e4fba6c4b111bb3330a05 +LibUV.v2.0.1+20.x86_64-unknown-freebsd.tar.gz/md5/dfcce3d6c2c42f419987f8289b1ace02 +LibUV.v2.0.1+20.x86_64-unknown-freebsd.tar.gz/sha512/8ad3c51f43124b7ad43cbdfe92685ce448d3195eeff5838387ef3145f1bec89851106293eca501ab6f986c0714f9bf9ecbb5a7ef44935a76a95bbdecd4fd2fba +LibUV.v2.0.1+20.x86_64-w64-mingw32.tar.gz/md5/7c37d147586c06f00f6dea947d7e912d +LibUV.v2.0.1+20.x86_64-w64-mingw32.tar.gz/sha512/58762e5a7a8cfd4ee8f0c7ba2c2919fc3b922f673e9b6138ee3714062d8088cac8e3cd5bd244d262426260ac55cef609abb30c25b1a5e38123fb61476a522a53 libuv-af4172ec713ee986ba1a989b9e33993a07c60c9e.tar.gz/md5/c1a7d3c74ef3999052f3bfe426264353 libuv-af4172ec713ee986ba1a989b9e33993a07c60c9e.tar.gz/sha512/a3f16863b711ddeeb5ab8d135d7df7a4be19cc2b9821fc78c8cd3ba421231d39b7d8bd9965321455094fda01584842a58f60612d93082b4fe32210b8aa44d999 diff --git a/deps/checksums/nghttp2 b/deps/checksums/nghttp2 index 6b4752d4e5527..4520109441588 100644 --- a/deps/checksums/nghttp2 +++ b/deps/checksums/nghttp2 @@ -24,6 +24,8 @@ nghttp2.v1.64.0+1.i686-w64-mingw32.tar.gz/md5/2ed9ff15d05f6cef7bf85bb19621a2fe nghttp2.v1.64.0+1.i686-w64-mingw32.tar.gz/sha512/45f38653664cc7343b66561a9b5bfec341593504714afbcb35a856343e583d2e75cab8062b2ff23ebdf4625607748f5c70b1ae79cc047a4073eb8d01f8252338 nghttp2.v1.64.0+1.powerpc64le-linux-gnu.tar.gz/md5/4622f699a44d02570298daf5864cf60b nghttp2.v1.64.0+1.powerpc64le-linux-gnu.tar.gz/sha512/f2cc88fd537503ac138518b7f72a67c18508307c0dddca41d44c8496ca4dd8f15aa133e08f13e03b2fbb3c83272ea433456c9ebb929f648a7b2af13fcd048d71 +nghttp2.v1.64.0+1.riscv64-linux-gnu.tar.gz/md5/5ec27224b6a780e989479ae4b38e5b26 +nghttp2.v1.64.0+1.riscv64-linux-gnu.tar.gz/sha512/57cfc7297f1cd2b33578ccc5f0ae847ef4771c087fe1235edd541f6f07a9feb692c554c159a40118c619f16ec0bc3cc313af19a9e845240cc50427583505a9f0 nghttp2.v1.64.0+1.x86_64-apple-darwin.tar.gz/md5/c6e5d0a179f065f4aab2b8661e6fc2d4 nghttp2.v1.64.0+1.x86_64-apple-darwin.tar.gz/sha512/77073fecbdac780dea34c9cb42b019b7cfe8a125a1356cd7de2ffd3aebeb29aa6251008574efa8d0a017e86023248fdd93e50c4ed2952d8a23cb67e0cf557a74 nghttp2.v1.64.0+1.x86_64-linux-gnu.tar.gz/md5/805f31fffc112ea45716b8a661911696 diff --git a/deps/checksums/openlibm b/deps/checksums/openlibm index e8c17e1efd26e..172d8ed3fb413 100644 --- a/deps/checksums/openlibm +++ b/deps/checksums/openlibm @@ -1,36 +1,38 @@ -OpenLibm.v0.8.1+3.aarch64-apple-darwin.tar.gz/md5/9ce53048e8944f6edff44f75b731229c -OpenLibm.v0.8.1+3.aarch64-apple-darwin.tar.gz/sha512/3a14e28db0656b47a473e19ca0afae1f8b72dd01e108d6b6cb52dc24fc03e4a43db867616b375369e82177bb274fbcfeb8f24b488ee68871e8da8463e9090adf -OpenLibm.v0.8.1+3.aarch64-linux-gnu.tar.gz/md5/8b284fe2905c3e5315291f5e5f27ca8b -OpenLibm.v0.8.1+3.aarch64-linux-gnu.tar.gz/sha512/d326181349ee7f74b73611cd71f933e93c38c11d6db9a1cd4fee49d1ac06c7f244f4cfc6ab373dd52909064117405b3d4fa39e5c626464c066ab53f1cd26dc4a -OpenLibm.v0.8.1+3.aarch64-linux-musl.tar.gz/md5/dc40ad1f2e53a3b914dcca364b6ead77 -OpenLibm.v0.8.1+3.aarch64-linux-musl.tar.gz/sha512/3779d8cd23c5987a15666e2160e40f5a6fc5e7d350c9e3c86d8af8c99515a8cb1f3b5e8438dae0f3cf0b5e1cb2c0cb74c5dd5a06c65e0c2a2382d86dacfaf9fb -OpenLibm.v0.8.1+3.aarch64-unknown-freebsd.tar.gz/md5/f5e9441d81626b958396e585083e0bdb -OpenLibm.v0.8.1+3.aarch64-unknown-freebsd.tar.gz/sha512/1078823b0f5f48cd9f6dc753213b6b3f8112476c9df70192b042fd9bbb597fff34da009f376b6e67034681fcb07810a1a22b0dc83112fbbbaa60dac189164a41 -OpenLibm.v0.8.1+3.armv6l-linux-gnueabihf.tar.gz/md5/7c9e56f6124b85e7dee74601f8c16abd -OpenLibm.v0.8.1+3.armv6l-linux-gnueabihf.tar.gz/sha512/a78e15177992025462d334a9d5b10b9c7f6710d77ac36056fe7a1cc3bc3fada87f16696366578cfa5f325d5f746639c41c5d80b4885814014d29556d63bd4c7c -OpenLibm.v0.8.1+3.armv6l-linux-musleabihf.tar.gz/md5/78d9e3178fdf93a35f7d2b0b00753dc6 -OpenLibm.v0.8.1+3.armv6l-linux-musleabihf.tar.gz/sha512/ff7b78786f7035eaa08770ddf7d4eb2984595a318c3ac4dfbe4091ca398e00638df2e77bc2ab5fd159defd0927d4fe46b7e824cf055fbae4860bfa12347e8c5b -OpenLibm.v0.8.1+3.armv7l-linux-gnueabihf.tar.gz/md5/7c9e56f6124b85e7dee74601f8c16abd -OpenLibm.v0.8.1+3.armv7l-linux-gnueabihf.tar.gz/sha512/a78e15177992025462d334a9d5b10b9c7f6710d77ac36056fe7a1cc3bc3fada87f16696366578cfa5f325d5f746639c41c5d80b4885814014d29556d63bd4c7c -OpenLibm.v0.8.1+3.armv7l-linux-musleabihf.tar.gz/md5/78d9e3178fdf93a35f7d2b0b00753dc6 -OpenLibm.v0.8.1+3.armv7l-linux-musleabihf.tar.gz/sha512/ff7b78786f7035eaa08770ddf7d4eb2984595a318c3ac4dfbe4091ca398e00638df2e77bc2ab5fd159defd0927d4fe46b7e824cf055fbae4860bfa12347e8c5b -OpenLibm.v0.8.1+3.i686-linux-gnu.tar.gz/md5/69b0c561e8f70e12f78a47bbcc28d43f -OpenLibm.v0.8.1+3.i686-linux-gnu.tar.gz/sha512/916bedde7b75aaa10a7517aa6a24da924e896aa46159447722010aa60a8c0974da8c2aa847d0a5853d391e7f3b792371304aa18a6d72d998f38f2a00b7179c30 -OpenLibm.v0.8.1+3.i686-linux-musl.tar.gz/md5/0037f2e2113282d49967eba72f215c4b -OpenLibm.v0.8.1+3.i686-linux-musl.tar.gz/sha512/96666332a814232084340791384505acf964064dba4f7b62db51a7ae4416237decb40318dc07b9a041547fd4ff77f204f42bc5c7f029e590af1ee1dd6196d843 -OpenLibm.v0.8.1+3.i686-w64-mingw32.tar.gz/md5/a2a5ba90531660f1e758df91bb11c2f9 -OpenLibm.v0.8.1+3.i686-w64-mingw32.tar.gz/sha512/b177c124dbe2dd491b49bf01b58b639629e2039c60dbd8ef1acf42985a7bd5ac1c5950a803b19e3ed5436ebd0a83f1e7af505d5f90b270467600ecab3e8a5cda -OpenLibm.v0.8.1+3.powerpc64le-linux-gnu.tar.gz/md5/01997fb48464f94f59f4708bd26eabc3 -OpenLibm.v0.8.1+3.powerpc64le-linux-gnu.tar.gz/sha512/1e1d8901fd3aab0948be5c387b8d5bd0db12766fe00bf800ee3100aa0d5973c7aa03ef9c9b4e34942e5e2b46b64035d7f8d7b070113db031d4611f2a7dd02ca3 -OpenLibm.v0.8.1+3.x86_64-apple-darwin.tar.gz/md5/6cb5a472d6c1446acfca11bb8f7283d6 -OpenLibm.v0.8.1+3.x86_64-apple-darwin.tar.gz/sha512/e52f399002544d94536c3bda742d3cc5b0995929d656eeb0e808954fb800fd8e5cfc0ab57279fbccab44fc33a1207ab345d78e685d519ff7f02cca8f554b9c06 -OpenLibm.v0.8.1+3.x86_64-linux-gnu.tar.gz/md5/e1c7dc61e98d5b8aa68de3462a2620a4 -OpenLibm.v0.8.1+3.x86_64-linux-gnu.tar.gz/sha512/fe6d74a2522d75374b87ac9746d444d75a768e069f24f3fbfc6a140aa9d073fa54e8899861f839e647b9261e660c5f2b5555f52fab39ef84a74685b632e89df9 -OpenLibm.v0.8.1+3.x86_64-linux-musl.tar.gz/md5/5fe8eb59d21732a80f432720419324b3 -OpenLibm.v0.8.1+3.x86_64-linux-musl.tar.gz/sha512/0d1b22ca01eda89caa1832b63b1d7ddafe0fedf5906680e817100e2176cbbae95f576409706a9ea1834bc692b72009f4fd244586df30228d18e626bf25fc040a -OpenLibm.v0.8.1+3.x86_64-unknown-freebsd.tar.gz/md5/2bcdf32fdef91433763e32be029814d9 -OpenLibm.v0.8.1+3.x86_64-unknown-freebsd.tar.gz/sha512/97854736fc8c797abd5a5c331e5795dfa9124ac108a76fc2bcac518f5750a08884717d611bb98222b13387bcd27e1c3f4ec841547859e87fafbbe8c7dcd7381a -OpenLibm.v0.8.1+3.x86_64-w64-mingw32.tar.gz/md5/31a75f828f782130bf6a463521a11f04 -OpenLibm.v0.8.1+3.x86_64-w64-mingw32.tar.gz/sha512/d54f688940229a5fc3db958460556d362c81e2e0a7bac010537123e5ff102b17d84123ee2e164151d51fb8ee7524e0888531e14d2c5ebfb3d6847b03af0086ad -openlibm-ae2d91698508701c83cab83714d42a1146dccf85.tar.gz/md5/19408d70bf042a109e1c267a53740089 -openlibm-ae2d91698508701c83cab83714d42a1146dccf85.tar.gz/sha512/9597fdcbc4af8369e6eecc3f8e86f251661cc64d236578f3ee8a6b39e77a47951446e1a0fe1151513da153e7ed17bf39aa5a36c32153d0d0400232bed2839e22 +OpenLibm.v0.8.4+1.aarch64-apple-darwin.tar.gz/md5/5fcbd746e90712e396e76dc4e76724d0 +OpenLibm.v0.8.4+1.aarch64-apple-darwin.tar.gz/sha512/f4ac2bc38bdc723384b67119daa2974fb43da34b2e45cea2029ea48f92c84c4cad6dfb43521b09a1e89ddf8c5b8cc22a38fa4b78ba39ac7524fd6bd1ba897aa9 +OpenLibm.v0.8.4+1.aarch64-linux-gnu.tar.gz/md5/e24c967d04812058b69b8c561f0d9f2a +OpenLibm.v0.8.4+1.aarch64-linux-gnu.tar.gz/sha512/8100dd7cfd9e02c9cfeade7627eb6105e86e8f5eb99026462a9a5370f8dd99ad981024a8904d2d7c341b113730f1b2312909d9c9c2c9b48dce74d3e80b266947 +OpenLibm.v0.8.4+1.aarch64-linux-musl.tar.gz/md5/6f9454c31b548f9fd47fb6318aab9b12 +OpenLibm.v0.8.4+1.aarch64-linux-musl.tar.gz/sha512/1769348f3e2227f307923b8c5656ab4c797daa8bd8bed61fbdf4c72d84ba9b7ae097392cdafd5e0cee0004f846e2c2ddbf9b5e7edb2406606b37c5ed665cc693 +OpenLibm.v0.8.4+1.aarch64-unknown-freebsd.tar.gz/md5/acce062e568325b675a6ed6a7a8fabbd +OpenLibm.v0.8.4+1.aarch64-unknown-freebsd.tar.gz/sha512/8ade1ae5ded62622a5159a0e60a8f6ad8345debda0da3eff764ea1e8a9937e686055e253612d83c4ee0035aa3dd2d6267d2dbd687cfcffbaffc17a7d7879e05f +OpenLibm.v0.8.4+1.armv6l-linux-gnueabihf.tar.gz/md5/8fe0900a318393a290907f016bc654c3 +OpenLibm.v0.8.4+1.armv6l-linux-gnueabihf.tar.gz/sha512/167100a2d46e68462ef9a66915ced881d6358f05337bd38f2f77176f41cfd5be37e3c5226dd5d7d59147bd3e1aa7fb0893c1c81e9516134d3ab663b5752c4969 +OpenLibm.v0.8.4+1.armv6l-linux-musleabihf.tar.gz/md5/e8566719387984604f19dc5f9354a783 +OpenLibm.v0.8.4+1.armv6l-linux-musleabihf.tar.gz/sha512/532dd2b764fa15f7a838fb14cccafd2d4fe8fa4a132ea8394479a719c7aee11442f1b8a18e5d4a26ca820fa696d9d2afc7f5ec63dd96fa3b6763cea72b7026c3 +OpenLibm.v0.8.4+1.armv7l-linux-gnueabihf.tar.gz/md5/8fe0900a318393a290907f016bc654c3 +OpenLibm.v0.8.4+1.armv7l-linux-gnueabihf.tar.gz/sha512/167100a2d46e68462ef9a66915ced881d6358f05337bd38f2f77176f41cfd5be37e3c5226dd5d7d59147bd3e1aa7fb0893c1c81e9516134d3ab663b5752c4969 +OpenLibm.v0.8.4+1.armv7l-linux-musleabihf.tar.gz/md5/e8566719387984604f19dc5f9354a783 +OpenLibm.v0.8.4+1.armv7l-linux-musleabihf.tar.gz/sha512/532dd2b764fa15f7a838fb14cccafd2d4fe8fa4a132ea8394479a719c7aee11442f1b8a18e5d4a26ca820fa696d9d2afc7f5ec63dd96fa3b6763cea72b7026c3 +OpenLibm.v0.8.4+1.i686-linux-gnu.tar.gz/md5/9580d34e69d6067427b9c33db631cfd3 +OpenLibm.v0.8.4+1.i686-linux-gnu.tar.gz/sha512/46934f82791f69ac5f5da0dab7dcc6e3e9a4577c3bb529e9c0519c38f140c7b54517c55ff3579cd4ed4df68f0863e006aa98e51873f1dab452ce9f853996429a +OpenLibm.v0.8.4+1.i686-linux-musl.tar.gz/md5/66bfc9611d04c5d609e7824cb076d24b +OpenLibm.v0.8.4+1.i686-linux-musl.tar.gz/sha512/1bda2395d44c22aba3d1aab2b08ae06f763d3755037d454aa73f8e8134289a1ab5d65862bbc5a17a7a6b9f2918eb87e926b21527ddc4471e2ea20d605ba14e2d +OpenLibm.v0.8.4+1.i686-w64-mingw32.tar.gz/md5/0e97311b2f08b57d79085635f01ccced +OpenLibm.v0.8.4+1.i686-w64-mingw32.tar.gz/sha512/ae061ea406c06969332af58ed6fdfce2825326d771d30274d90775a1709b0361b7ca1dc7e6b0b76b93e4dd7a81d1842510a2c835251ee0a0978d6c839d96070e +OpenLibm.v0.8.4+1.powerpc64le-linux-gnu.tar.gz/md5/8ecfff7db76eee29591a654871e88855 +OpenLibm.v0.8.4+1.powerpc64le-linux-gnu.tar.gz/sha512/af03993b162316dd581f6ba5d1c23bca4c26cb22356ab229f326c42e111acbdf7ef45c9ad05894fe2d68794a63670cf89888653f788192a38b9255ce4bc72e28 +OpenLibm.v0.8.4+1.riscv64-linux-gnu.tar.gz/md5/2d6ae40b640f7d39c20ec7d151d6972d +OpenLibm.v0.8.4+1.riscv64-linux-gnu.tar.gz/sha512/3a9b69601e7e1013f236c0d9f7326f371d65d9c1231d5848995ebd822fd1eff0bd5f6b771fe2c21191076902e6a7c4febb4822f78cc0d15bb7f59396d9728236 +OpenLibm.v0.8.4+1.x86_64-apple-darwin.tar.gz/md5/bd671ab9fe01835cab3e42e7cfa790fb +OpenLibm.v0.8.4+1.x86_64-apple-darwin.tar.gz/sha512/8bf2e66df17effc1e8778453904ffc20127f785bf096873289e8fdd8b17069ca844faffbd9f7621b87a7cb0a0051037eb9402360f2a03cf8794fbac8f7719777 +OpenLibm.v0.8.4+1.x86_64-linux-gnu.tar.gz/md5/df7fab134fbce3b625e9a82376f23e79 +OpenLibm.v0.8.4+1.x86_64-linux-gnu.tar.gz/sha512/64d07434e0db79833f84a2225838456eb9532617d377a776b3a534a908b1673bc4f890903f95350e4045e05c29539d993a18ecadeb879761e279ec3947f74390 +OpenLibm.v0.8.4+1.x86_64-linux-musl.tar.gz/md5/ebef6bb7651d116b397e035f39adfb1b +OpenLibm.v0.8.4+1.x86_64-linux-musl.tar.gz/sha512/de9036073e5dba2721b4119ecbbd21a0c9f75b65aff9392b7e88e464da35b97135d62404477441d0dadd3a2f8d49f1082291b35bf4b626fb1096d36d401980bf +OpenLibm.v0.8.4+1.x86_64-unknown-freebsd.tar.gz/md5/bc09186ae191700d6cf9162796bb23ba +OpenLibm.v0.8.4+1.x86_64-unknown-freebsd.tar.gz/sha512/6b7198cd68418e370348c7011a5f9ccf910b62c9482334601dea0749b683724ddb7414bde3d8da7a5123c0fadc3f93d02274538070330db6428dabca5d007835 +OpenLibm.v0.8.4+1.x86_64-w64-mingw32.tar.gz/md5/b6b5335f4c83f7ebf0f74cf753358f00 +OpenLibm.v0.8.4+1.x86_64-w64-mingw32.tar.gz/sha512/e8351ddda305b757f337bb7ea26c441968843b23861676f0bdd7bcf83bb3969af790d4112307d3204eb87fac044dda9be305f349700ebe9ba2bfe3d6df24fde8 +openlibm-c4667caea25ae3487adf6760b4a1dcf32477a4b8.tar.gz/md5/287cf81f6c6b67177b322f7cb5cc8279 +openlibm-c4667caea25ae3487adf6760b4a1dcf32477a4b8.tar.gz/sha512/3c3efa8cb344719c2b6df45fbfe178efac6239cac12fc32dcc92074431d2e1a3039a60649cf3525424e0990081b6d40acb12176316c4ccb2940add0bb3a41e85 diff --git a/deps/checksums/p7zip b/deps/checksums/p7zip index 2fe4fb874bec4..6850967ace1b5 100644 --- a/deps/checksums/p7zip +++ b/deps/checksums/p7zip @@ -1,36 +1,38 @@ p7zip-17.05.tar.gz/md5/de921a08f37242a8eed8e4a758fbcb58 p7zip-17.05.tar.gz/sha512/97a7cfd15287998eb049c320548477be496c4ddf6b45c833c42adca4ab88719b07a442ae2e71cf2dc3b30a0777a3acab0a1a30f01fd85bacffa3fa9bd22c3f7d -p7zip.v17.5.0+1.aarch64-apple-darwin.tar.gz/md5/2a254e251901b3d1ddfd7aff23a6e5eb -p7zip.v17.5.0+1.aarch64-apple-darwin.tar.gz/sha512/8efb9a2c9bcab388e523adba3dc0b876e8ae34e2440c3eee01fd780eb87c8619c7a7bbdc46d703ccefff6aa6ad64c4e4b45b723136ab1f6fd6de4f52e75ebbbf -p7zip.v17.5.0+1.aarch64-linux-gnu.tar.gz/md5/bb1f3773fd409dbb91a10f7d9d2e99b5 -p7zip.v17.5.0+1.aarch64-linux-gnu.tar.gz/sha512/e95ccc342be644570d218d25403b91a7db9ee983fbf8cce3deff453355d68d426f9301eaac865a98691025b596b8cd77ebebf6184c0eaf8b2f294bc6763b9a4b -p7zip.v17.5.0+1.aarch64-linux-musl.tar.gz/md5/3fac518a6a70412294d71ca510958cf2 -p7zip.v17.5.0+1.aarch64-linux-musl.tar.gz/sha512/fc127790739bf8a8b918b2e83753d86f5e79ee8706bde4cc79d74d9f7d846aae99a109da4b2b3cc92ccedc1eef4d52a555a65a95f588e173e0fecc11f2ca21e6 -p7zip.v17.5.0+1.aarch64-unknown-freebsd.tar.gz/md5/4190f8d7d42572b3fdab0fa382417d43 -p7zip.v17.5.0+1.aarch64-unknown-freebsd.tar.gz/sha512/5b0cb08374b8561873f76cb2b8bcbb8de1ff4c91bde23222cc1b650c6ea2fff265e48b6190551ed136324a47d25e1d357a754295b674e74b4628b20223ad067d -p7zip.v17.5.0+1.armv6l-linux-gnueabihf.tar.gz/md5/355410848192de3b02d12fd663867f4b -p7zip.v17.5.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/8f103b41e755d157d70dacca89a0ef4610bea109686b4005e8edd5f79ed2e6419c00c2625d0ab90e6e33fa389e670490d8de263c0bdae952cc34cbbf440e275f -p7zip.v17.5.0+1.armv6l-linux-musleabihf.tar.gz/md5/34363b227306fce34a728af54b71064f -p7zip.v17.5.0+1.armv6l-linux-musleabihf.tar.gz/sha512/8dd7b37ce6223c9fedcaa999eb806eb6dec8c4a3133d3c07e2456cb8543b8e4f5b881c1bff2d2e25f19b1312b18673e9013aeff87d6a274eec6c451b1ba0d6b9 -p7zip.v17.5.0+1.armv7l-linux-gnueabihf.tar.gz/md5/dbb1fc0cf3bea674442ff8cc932a94cd -p7zip.v17.5.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/c4d71d905fa420391417786ed206a0c334475dd0df8baa1fc3f6560ce548db11805003d0d0b35bb622fe818c761f2b0abe0796d1cbfce2a922da69e697f056a2 -p7zip.v17.5.0+1.armv7l-linux-musleabihf.tar.gz/md5/d188b5dd453faedb616ba9c48fdeab6b -p7zip.v17.5.0+1.armv7l-linux-musleabihf.tar.gz/sha512/ea30a775370502ca9e271b87cbda528d0c51d63ce0df41883d4dbc1527a32f251d797f3692fcf9b883b5fbaaad80515b971a8f8fe09ba102978b19a0ecb58528 -p7zip.v17.5.0+1.i686-linux-gnu.tar.gz/md5/dc02bdde045a0b6b22cf14d6960e63ed -p7zip.v17.5.0+1.i686-linux-gnu.tar.gz/sha512/d2d0dd14a5fc1163fea2276e0925bfa8d075d5dba1d8018e4e3160977d3b09642b2e521d8e57d049abaf0e2ea391a846f0b0136b3c59e8b476c8c52ac5210447 -p7zip.v17.5.0+1.i686-linux-musl.tar.gz/md5/0b8658147938a8ec109ee2b3b0a0665f -p7zip.v17.5.0+1.i686-linux-musl.tar.gz/sha512/411b2950f5928c537b87ba0651c09c08e57afed765db9fee89eda8b12939ef0da94c8ba38c0a24ba46b4513a0e4cca798eb09f2b20a011099ed3cf14455dd19e -p7zip.v17.5.0+1.i686-w64-mingw32.tar.gz/md5/98bdd8767c77a35f71303ff490a3d363 -p7zip.v17.5.0+1.i686-w64-mingw32.tar.gz/sha512/14f08071af74297df8bfe1d9f7efa3c0212e62ace573848f17b729e4c36dc3861110f3c5cc9315364c318e5b040736443a24492e86d76161993653a309996eb3 -p7zip.v17.5.0+1.powerpc64le-linux-gnu.tar.gz/md5/b18c917b9852898a9b9d6d24bcc6863e -p7zip.v17.5.0+1.powerpc64le-linux-gnu.tar.gz/sha512/0148dc8a0bc9c95212d7f8e2f92ee24e968eb7290fe72c7ae02e286bf5c05dd6b1f10b32350a7ff37777ed5a8cc21f3303f464620f3394c7a4690ae98bf77299 -p7zip.v17.5.0+1.x86_64-apple-darwin.tar.gz/md5/da31752a2556644d39e48649bb0111de -p7zip.v17.5.0+1.x86_64-apple-darwin.tar.gz/sha512/0695ad111263d2fadfdf9a46ce7ee80def0bf60db7d1c2585ed2af6fc945fb169311a9f1ffc6f95fb43b0b03694d2d1be9136d3d78ba2ef2b19228987883a385 -p7zip.v17.5.0+1.x86_64-linux-gnu.tar.gz/md5/2fb55d86e4eaccb0488bd637d088b996 -p7zip.v17.5.0+1.x86_64-linux-gnu.tar.gz/sha512/38ac355157d59c09f308fc29964d0e9c1466c9633efd8d3c6ff3c738abce2af45ebc6b92a29f56d5e7baa4871f9f39b14ecfcbedd4e2f4ca7c0fe6627c6b13e7 -p7zip.v17.5.0+1.x86_64-linux-musl.tar.gz/md5/f0bd567a851d2dd9d306552ffafbca3a -p7zip.v17.5.0+1.x86_64-linux-musl.tar.gz/sha512/e60047a6e7e3496cb6658f87c8c88676f399cd9f3d0d7daa880b6be09cd5525f7f22776896f1375722b47555514ff8c018f02ce800ec3fd0ed922e16e8a6d657 -p7zip.v17.5.0+1.x86_64-unknown-freebsd.tar.gz/md5/d37bd26e39a3ec84f262636f70624341 -p7zip.v17.5.0+1.x86_64-unknown-freebsd.tar.gz/sha512/0604a880c19f9d72d5828edd75be641625c29f230b3a5e7d70ec3812c014c96b76ee7b45e0e80f49be63f109a48700e75d1e5be01b5ae7b46d42dafda9885e8c -p7zip.v17.5.0+1.x86_64-w64-mingw32.tar.gz/md5/f02c7b2481dee880b096340a8735350f -p7zip.v17.5.0+1.x86_64-w64-mingw32.tar.gz/sha512/08b717c1b072d1309f6af8973eb09b1a482abb7ae7d01fba79873d4310a7c11292e2e8779029f99cc60627ed0d064224bc87782e587c520f970b840b7b838052 +p7zip.v17.5.0+2.aarch64-apple-darwin.tar.gz/md5/2a254e251901b3d1ddfd7aff23a6e5eb +p7zip.v17.5.0+2.aarch64-apple-darwin.tar.gz/sha512/8efb9a2c9bcab388e523adba3dc0b876e8ae34e2440c3eee01fd780eb87c8619c7a7bbdc46d703ccefff6aa6ad64c4e4b45b723136ab1f6fd6de4f52e75ebbbf +p7zip.v17.5.0+2.aarch64-linux-gnu.tar.gz/md5/bb1f3773fd409dbb91a10f7d9d2e99b5 +p7zip.v17.5.0+2.aarch64-linux-gnu.tar.gz/sha512/e95ccc342be644570d218d25403b91a7db9ee983fbf8cce3deff453355d68d426f9301eaac865a98691025b596b8cd77ebebf6184c0eaf8b2f294bc6763b9a4b +p7zip.v17.5.0+2.aarch64-linux-musl.tar.gz/md5/3fac518a6a70412294d71ca510958cf2 +p7zip.v17.5.0+2.aarch64-linux-musl.tar.gz/sha512/fc127790739bf8a8b918b2e83753d86f5e79ee8706bde4cc79d74d9f7d846aae99a109da4b2b3cc92ccedc1eef4d52a555a65a95f588e173e0fecc11f2ca21e6 +p7zip.v17.5.0+2.aarch64-unknown-freebsd.tar.gz/md5/4190f8d7d42572b3fdab0fa382417d43 +p7zip.v17.5.0+2.aarch64-unknown-freebsd.tar.gz/sha512/5b0cb08374b8561873f76cb2b8bcbb8de1ff4c91bde23222cc1b650c6ea2fff265e48b6190551ed136324a47d25e1d357a754295b674e74b4628b20223ad067d +p7zip.v17.5.0+2.armv6l-linux-gnueabihf.tar.gz/md5/355410848192de3b02d12fd663867f4b +p7zip.v17.5.0+2.armv6l-linux-gnueabihf.tar.gz/sha512/8f103b41e755d157d70dacca89a0ef4610bea109686b4005e8edd5f79ed2e6419c00c2625d0ab90e6e33fa389e670490d8de263c0bdae952cc34cbbf440e275f +p7zip.v17.5.0+2.armv6l-linux-musleabihf.tar.gz/md5/34363b227306fce34a728af54b71064f +p7zip.v17.5.0+2.armv6l-linux-musleabihf.tar.gz/sha512/8dd7b37ce6223c9fedcaa999eb806eb6dec8c4a3133d3c07e2456cb8543b8e4f5b881c1bff2d2e25f19b1312b18673e9013aeff87d6a274eec6c451b1ba0d6b9 +p7zip.v17.5.0+2.armv7l-linux-gnueabihf.tar.gz/md5/dbb1fc0cf3bea674442ff8cc932a94cd +p7zip.v17.5.0+2.armv7l-linux-gnueabihf.tar.gz/sha512/c4d71d905fa420391417786ed206a0c334475dd0df8baa1fc3f6560ce548db11805003d0d0b35bb622fe818c761f2b0abe0796d1cbfce2a922da69e697f056a2 +p7zip.v17.5.0+2.armv7l-linux-musleabihf.tar.gz/md5/d188b5dd453faedb616ba9c48fdeab6b +p7zip.v17.5.0+2.armv7l-linux-musleabihf.tar.gz/sha512/ea30a775370502ca9e271b87cbda528d0c51d63ce0df41883d4dbc1527a32f251d797f3692fcf9b883b5fbaaad80515b971a8f8fe09ba102978b19a0ecb58528 +p7zip.v17.5.0+2.i686-linux-gnu.tar.gz/md5/dc02bdde045a0b6b22cf14d6960e63ed +p7zip.v17.5.0+2.i686-linux-gnu.tar.gz/sha512/d2d0dd14a5fc1163fea2276e0925bfa8d075d5dba1d8018e4e3160977d3b09642b2e521d8e57d049abaf0e2ea391a846f0b0136b3c59e8b476c8c52ac5210447 +p7zip.v17.5.0+2.i686-linux-musl.tar.gz/md5/0b8658147938a8ec109ee2b3b0a0665f +p7zip.v17.5.0+2.i686-linux-musl.tar.gz/sha512/411b2950f5928c537b87ba0651c09c08e57afed765db9fee89eda8b12939ef0da94c8ba38c0a24ba46b4513a0e4cca798eb09f2b20a011099ed3cf14455dd19e +p7zip.v17.5.0+2.i686-w64-mingw32.tar.gz/md5/98bdd8767c77a35f71303ff490a3d363 +p7zip.v17.5.0+2.i686-w64-mingw32.tar.gz/sha512/14f08071af74297df8bfe1d9f7efa3c0212e62ace573848f17b729e4c36dc3861110f3c5cc9315364c318e5b040736443a24492e86d76161993653a309996eb3 +p7zip.v17.5.0+2.powerpc64le-linux-gnu.tar.gz/md5/b18c917b9852898a9b9d6d24bcc6863e +p7zip.v17.5.0+2.powerpc64le-linux-gnu.tar.gz/sha512/0148dc8a0bc9c95212d7f8e2f92ee24e968eb7290fe72c7ae02e286bf5c05dd6b1f10b32350a7ff37777ed5a8cc21f3303f464620f3394c7a4690ae98bf77299 +p7zip.v17.5.0+2.riscv64-linux-gnu.tar.gz/md5/8d5f804091c2d21b2c35121d40d1024f +p7zip.v17.5.0+2.riscv64-linux-gnu.tar.gz/sha512/68042f32b8b9f8d422dc0390efa2502d4a1a816daf4adf1133128f9366ec93ee1c1dda699844c0c3c3649a6b55a16312bd6b8fe4aedd6780e6faf11509932a9a +p7zip.v17.5.0+2.x86_64-apple-darwin.tar.gz/md5/da31752a2556644d39e48649bb0111de +p7zip.v17.5.0+2.x86_64-apple-darwin.tar.gz/sha512/0695ad111263d2fadfdf9a46ce7ee80def0bf60db7d1c2585ed2af6fc945fb169311a9f1ffc6f95fb43b0b03694d2d1be9136d3d78ba2ef2b19228987883a385 +p7zip.v17.5.0+2.x86_64-linux-gnu.tar.gz/md5/2fb55d86e4eaccb0488bd637d088b996 +p7zip.v17.5.0+2.x86_64-linux-gnu.tar.gz/sha512/38ac355157d59c09f308fc29964d0e9c1466c9633efd8d3c6ff3c738abce2af45ebc6b92a29f56d5e7baa4871f9f39b14ecfcbedd4e2f4ca7c0fe6627c6b13e7 +p7zip.v17.5.0+2.x86_64-linux-musl.tar.gz/md5/f0bd567a851d2dd9d306552ffafbca3a +p7zip.v17.5.0+2.x86_64-linux-musl.tar.gz/sha512/e60047a6e7e3496cb6658f87c8c88676f399cd9f3d0d7daa880b6be09cd5525f7f22776896f1375722b47555514ff8c018f02ce800ec3fd0ed922e16e8a6d657 +p7zip.v17.5.0+2.x86_64-unknown-freebsd.tar.gz/md5/d37bd26e39a3ec84f262636f70624341 +p7zip.v17.5.0+2.x86_64-unknown-freebsd.tar.gz/sha512/0604a880c19f9d72d5828edd75be641625c29f230b3a5e7d70ec3812c014c96b76ee7b45e0e80f49be63f109a48700e75d1e5be01b5ae7b46d42dafda9885e8c +p7zip.v17.5.0+2.x86_64-w64-mingw32.tar.gz/md5/f02c7b2481dee880b096340a8735350f +p7zip.v17.5.0+2.x86_64-w64-mingw32.tar.gz/sha512/08b717c1b072d1309f6af8973eb09b1a482abb7ae7d01fba79873d4310a7c11292e2e8779029f99cc60627ed0d064224bc87782e587c520f970b840b7b838052 diff --git a/deps/checksums/pcre b/deps/checksums/pcre index 0c2732f8cc2b5..9e290c914baec 100644 --- a/deps/checksums/pcre +++ b/deps/checksums/pcre @@ -1,36 +1,38 @@ -PCRE2.v10.44.0+0.aarch64-apple-darwin.tar.gz/md5/14de26cfc0f6ff7635fac39e81e81a27 -PCRE2.v10.44.0+0.aarch64-apple-darwin.tar.gz/sha512/45079ecca5f4966a32895fcc63585f1dd60f306dc1cb5c098d42452fcff67f7f6b405c200a15747af4680151bb6a6374832a0119b8ddd743d2ed13d0beaef7c9 -PCRE2.v10.44.0+0.aarch64-linux-gnu.tar.gz/md5/3cf179ed36d37bff698ab81cf3d5797b -PCRE2.v10.44.0+0.aarch64-linux-gnu.tar.gz/sha512/db93e5a5c0c46b5536ed49515682d9bfe1d23f6ba8ae2468289ec8f2160140f39f5606a3c7095f45251f3663d8ccf2d6d7e5e8b1efb21c39bbf9a13b6ec60ef9 -PCRE2.v10.44.0+0.aarch64-linux-musl.tar.gz/md5/02baa415218f581a5ceeb7bf7fc0a090 -PCRE2.v10.44.0+0.aarch64-linux-musl.tar.gz/sha512/1685f37ed8f465ecc2f738fdf65d20bb1806934ff2c50194882282fb6c3900121c61c39210e4c0b89847493bfc3e15bb7b9136b0d968103b47c8662a78b412fe -PCRE2.v10.44.0+0.aarch64-unknown-freebsd.tar.gz/md5/4de065ea59ab4f622b46079df1d9d941 -PCRE2.v10.44.0+0.aarch64-unknown-freebsd.tar.gz/sha512/aa6df9edfb690d155a8b5a9390db7ca11622ac0020174cf070a33a075801bfe43bd4c80b8e28017989a8b7374d39897cdcf72ab0e1962e3e234239975f7ac0b4 -PCRE2.v10.44.0+0.armv6l-linux-gnueabihf.tar.gz/md5/f8a0907fbb20a06507fce849db098c4f -PCRE2.v10.44.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/3f5bcc1742380a31683a81740d55e198d7ec8d8ea5a13d6d0556d6603e4fadbf0dc648093c44e36dd6d3793c52a5e3dae6f2f459c73e3d3b5a005f3395d26772 -PCRE2.v10.44.0+0.armv6l-linux-musleabihf.tar.gz/md5/8854c24183441aa6fd21989c00888904 -PCRE2.v10.44.0+0.armv6l-linux-musleabihf.tar.gz/sha512/a74d9378f071dc4cb021e5171d66cd4ac5de3b348e993fc90d824ce5d2f554f7c8af7af55ec31d874d302aaba7d542b6505cc5963e53656c28026a06a53ed48b -PCRE2.v10.44.0+0.armv7l-linux-gnueabihf.tar.gz/md5/04960309ee7cf69a53e280878d5880ef -PCRE2.v10.44.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/a1644daf036daa3799368598427c87c23bcfdddac55a0d06adca08a2e9d617c893285855af562101b05129d0ed0d84d22f5a8a1703316ecd09aa1752b8330eef -PCRE2.v10.44.0+0.armv7l-linux-musleabihf.tar.gz/md5/1335defc6090be76c509840633f7cdfb -PCRE2.v10.44.0+0.armv7l-linux-musleabihf.tar.gz/sha512/9595052eeae4da413b930b14d7e89359a29220cd9e908325e0b7788c8f4a2feb2134e78a0d8f56007787f0fefadc9de31750db6104bbdd048fa50e1d785c2a8c -PCRE2.v10.44.0+0.i686-linux-gnu.tar.gz/md5/e2d6be1d19566c965c2afeb995aba52f -PCRE2.v10.44.0+0.i686-linux-gnu.tar.gz/sha512/4a9d981bb6aa9150b670db7c5d4d188c8391fcb2a16bc710ede7a84bf7ec546fc5fd9096a339720579d25b6dcb5674b2b5b28e9664e5ef589b1a5044ce38b6a7 -PCRE2.v10.44.0+0.i686-linux-musl.tar.gz/md5/23cf857bd3daea4f094fcec48a7712dc -PCRE2.v10.44.0+0.i686-linux-musl.tar.gz/sha512/534f0cfab0cd60db9498eff387f7280a8baaf893a98dd2e7a737e68ba6473ed8236e9da85116eefb9812ec5323c705a00fcaff010b1900f752de8bdff65ef3ad -PCRE2.v10.44.0+0.i686-w64-mingw32.tar.gz/md5/3d05764df2305f16e4ffab60031ad40c -PCRE2.v10.44.0+0.i686-w64-mingw32.tar.gz/sha512/3e21cc6b71849c1a361373de30567990dba13dfd8812e7a7b5e2734b572bf1d45aeb730289d329975e76932c4c40e476824be2ab8e80a40fb7a7e2f46159235a -PCRE2.v10.44.0+0.powerpc64le-linux-gnu.tar.gz/md5/596d7c29d1417ed8959ea3ae3b4df453 -PCRE2.v10.44.0+0.powerpc64le-linux-gnu.tar.gz/sha512/89e03bfd6890150e2c8dddc4e7d024f2e09421c25a3d0fef3b5cd7f6bab7d6402ec1e82b02ecb5d26d01dfa2fb6068d050513894c374b7f2244c8fcbf00d69e2 -PCRE2.v10.44.0+0.x86_64-apple-darwin.tar.gz/md5/18f13c78ff6388c601bd36788e526b31 -PCRE2.v10.44.0+0.x86_64-apple-darwin.tar.gz/sha512/7b43a289f54064fc3c292de98173ec91cde2e49402c99c7848cbdc0e6d90a23a86d41f521e3986fcc8d941ee070d09e29ddc89a4e23009b8e9333e577ae4a09c -PCRE2.v10.44.0+0.x86_64-linux-gnu.tar.gz/md5/9f45feca0955f81ceb898208b9c74e15 -PCRE2.v10.44.0+0.x86_64-linux-gnu.tar.gz/sha512/eac215838306f7b5adb2166c3f620a69ed52fbd752ef3673a887507963a826c305d9b078dbb5236dc9a45eaca0d34f77325aab41703745701a077c84822ec0d0 -PCRE2.v10.44.0+0.x86_64-linux-musl.tar.gz/md5/79f092c6e8e971027ac6c1f0987376fb -PCRE2.v10.44.0+0.x86_64-linux-musl.tar.gz/sha512/2c5655b0f719a7d442c89f1040f2973b03f8becd855a0cfd6c0a985a07b25de351a84e3b9daaebd952b62628db0d937de08a8d05ee4bcace7e72d6b5ce6b8435 -PCRE2.v10.44.0+0.x86_64-unknown-freebsd.tar.gz/md5/a0bc32a099a584d453458a76c892fe47 -PCRE2.v10.44.0+0.x86_64-unknown-freebsd.tar.gz/sha512/6649c1b9e9569a9decccf6ebaa61d44acdb9069208ec796777d8e70a908210f775be2142053f6a5762ebaa321e297f6d8b51db99629766bc702c498b5f772492 -PCRE2.v10.44.0+0.x86_64-w64-mingw32.tar.gz/md5/eeffb6164fba08b0d5c7f50afa081475 -PCRE2.v10.44.0+0.x86_64-w64-mingw32.tar.gz/sha512/f06db992a2070a88559c15224972aeb098d4291a4325970fc0fbbb7cdd539f4a2fd4f90c0de90a34fe454da6c38290f9e0c7fdf2fe8c441f687fe4491d652adc +PCRE2.v10.44.0+1.aarch64-apple-darwin.tar.gz/md5/14de26cfc0f6ff7635fac39e81e81a27 +PCRE2.v10.44.0+1.aarch64-apple-darwin.tar.gz/sha512/45079ecca5f4966a32895fcc63585f1dd60f306dc1cb5c098d42452fcff67f7f6b405c200a15747af4680151bb6a6374832a0119b8ddd743d2ed13d0beaef7c9 +PCRE2.v10.44.0+1.aarch64-linux-gnu.tar.gz/md5/3cf179ed36d37bff698ab81cf3d5797b +PCRE2.v10.44.0+1.aarch64-linux-gnu.tar.gz/sha512/db93e5a5c0c46b5536ed49515682d9bfe1d23f6ba8ae2468289ec8f2160140f39f5606a3c7095f45251f3663d8ccf2d6d7e5e8b1efb21c39bbf9a13b6ec60ef9 +PCRE2.v10.44.0+1.aarch64-linux-musl.tar.gz/md5/02baa415218f581a5ceeb7bf7fc0a090 +PCRE2.v10.44.0+1.aarch64-linux-musl.tar.gz/sha512/1685f37ed8f465ecc2f738fdf65d20bb1806934ff2c50194882282fb6c3900121c61c39210e4c0b89847493bfc3e15bb7b9136b0d968103b47c8662a78b412fe +PCRE2.v10.44.0+1.aarch64-unknown-freebsd.tar.gz/md5/4de065ea59ab4f622b46079df1d9d941 +PCRE2.v10.44.0+1.aarch64-unknown-freebsd.tar.gz/sha512/aa6df9edfb690d155a8b5a9390db7ca11622ac0020174cf070a33a075801bfe43bd4c80b8e28017989a8b7374d39897cdcf72ab0e1962e3e234239975f7ac0b4 +PCRE2.v10.44.0+1.armv6l-linux-gnueabihf.tar.gz/md5/f8a0907fbb20a06507fce849db098c4f +PCRE2.v10.44.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/3f5bcc1742380a31683a81740d55e198d7ec8d8ea5a13d6d0556d6603e4fadbf0dc648093c44e36dd6d3793c52a5e3dae6f2f459c73e3d3b5a005f3395d26772 +PCRE2.v10.44.0+1.armv6l-linux-musleabihf.tar.gz/md5/8854c24183441aa6fd21989c00888904 +PCRE2.v10.44.0+1.armv6l-linux-musleabihf.tar.gz/sha512/a74d9378f071dc4cb021e5171d66cd4ac5de3b348e993fc90d824ce5d2f554f7c8af7af55ec31d874d302aaba7d542b6505cc5963e53656c28026a06a53ed48b +PCRE2.v10.44.0+1.armv7l-linux-gnueabihf.tar.gz/md5/04960309ee7cf69a53e280878d5880ef +PCRE2.v10.44.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/a1644daf036daa3799368598427c87c23bcfdddac55a0d06adca08a2e9d617c893285855af562101b05129d0ed0d84d22f5a8a1703316ecd09aa1752b8330eef +PCRE2.v10.44.0+1.armv7l-linux-musleabihf.tar.gz/md5/1335defc6090be76c509840633f7cdfb +PCRE2.v10.44.0+1.armv7l-linux-musleabihf.tar.gz/sha512/9595052eeae4da413b930b14d7e89359a29220cd9e908325e0b7788c8f4a2feb2134e78a0d8f56007787f0fefadc9de31750db6104bbdd048fa50e1d785c2a8c +PCRE2.v10.44.0+1.i686-linux-gnu.tar.gz/md5/e2d6be1d19566c965c2afeb995aba52f +PCRE2.v10.44.0+1.i686-linux-gnu.tar.gz/sha512/4a9d981bb6aa9150b670db7c5d4d188c8391fcb2a16bc710ede7a84bf7ec546fc5fd9096a339720579d25b6dcb5674b2b5b28e9664e5ef589b1a5044ce38b6a7 +PCRE2.v10.44.0+1.i686-linux-musl.tar.gz/md5/23cf857bd3daea4f094fcec48a7712dc +PCRE2.v10.44.0+1.i686-linux-musl.tar.gz/sha512/534f0cfab0cd60db9498eff387f7280a8baaf893a98dd2e7a737e68ba6473ed8236e9da85116eefb9812ec5323c705a00fcaff010b1900f752de8bdff65ef3ad +PCRE2.v10.44.0+1.i686-w64-mingw32.tar.gz/md5/3d05764df2305f16e4ffab60031ad40c +PCRE2.v10.44.0+1.i686-w64-mingw32.tar.gz/sha512/3e21cc6b71849c1a361373de30567990dba13dfd8812e7a7b5e2734b572bf1d45aeb730289d329975e76932c4c40e476824be2ab8e80a40fb7a7e2f46159235a +PCRE2.v10.44.0+1.powerpc64le-linux-gnu.tar.gz/md5/596d7c29d1417ed8959ea3ae3b4df453 +PCRE2.v10.44.0+1.powerpc64le-linux-gnu.tar.gz/sha512/89e03bfd6890150e2c8dddc4e7d024f2e09421c25a3d0fef3b5cd7f6bab7d6402ec1e82b02ecb5d26d01dfa2fb6068d050513894c374b7f2244c8fcbf00d69e2 +PCRE2.v10.44.0+1.riscv64-linux-gnu.tar.gz/md5/8330a431f4da1d20cffdb64d2c270dfb +PCRE2.v10.44.0+1.riscv64-linux-gnu.tar.gz/sha512/a836d0b9feefd9ffd50cf29db72ab704e6ae442939322526e2a5613973eabc8e543c5546ce507b0c5f9e6f1ce324978aeb6e99f8833eb60fc90e74139e47c6d2 +PCRE2.v10.44.0+1.x86_64-apple-darwin.tar.gz/md5/18f13c78ff6388c601bd36788e526b31 +PCRE2.v10.44.0+1.x86_64-apple-darwin.tar.gz/sha512/7b43a289f54064fc3c292de98173ec91cde2e49402c99c7848cbdc0e6d90a23a86d41f521e3986fcc8d941ee070d09e29ddc89a4e23009b8e9333e577ae4a09c +PCRE2.v10.44.0+1.x86_64-linux-gnu.tar.gz/md5/9f45feca0955f81ceb898208b9c74e15 +PCRE2.v10.44.0+1.x86_64-linux-gnu.tar.gz/sha512/eac215838306f7b5adb2166c3f620a69ed52fbd752ef3673a887507963a826c305d9b078dbb5236dc9a45eaca0d34f77325aab41703745701a077c84822ec0d0 +PCRE2.v10.44.0+1.x86_64-linux-musl.tar.gz/md5/79f092c6e8e971027ac6c1f0987376fb +PCRE2.v10.44.0+1.x86_64-linux-musl.tar.gz/sha512/2c5655b0f719a7d442c89f1040f2973b03f8becd855a0cfd6c0a985a07b25de351a84e3b9daaebd952b62628db0d937de08a8d05ee4bcace7e72d6b5ce6b8435 +PCRE2.v10.44.0+1.x86_64-unknown-freebsd.tar.gz/md5/a0bc32a099a584d453458a76c892fe47 +PCRE2.v10.44.0+1.x86_64-unknown-freebsd.tar.gz/sha512/6649c1b9e9569a9decccf6ebaa61d44acdb9069208ec796777d8e70a908210f775be2142053f6a5762ebaa321e297f6d8b51db99629766bc702c498b5f772492 +PCRE2.v10.44.0+1.x86_64-w64-mingw32.tar.gz/md5/eeffb6164fba08b0d5c7f50afa081475 +PCRE2.v10.44.0+1.x86_64-w64-mingw32.tar.gz/sha512/f06db992a2070a88559c15224972aeb098d4291a4325970fc0fbbb7cdd539f4a2fd4f90c0de90a34fe454da6c38290f9e0c7fdf2fe8c441f687fe4491d652adc pcre2-10.44.tar.bz2/md5/9d1fe11e2e919c7b395e3e8f0a5c3eec pcre2-10.44.tar.bz2/sha512/ee91cc10a2962bc7818b03d368df3dd31f42ea9a7260ae51483ea8cd331b7431e36e63256b0adc213cc6d6741e7c90414fd420622308c0ae3fcb5dd878591be2 diff --git a/deps/checksums/zlib b/deps/checksums/zlib index f5e7353f32e3e..bd651003399b9 100644 --- a/deps/checksums/zlib +++ b/deps/checksums/zlib @@ -1,36 +1,38 @@ -Zlib.v1.3.1+1.aarch64-apple-darwin.tar.gz/md5/50b48e14f0b3578e3f398d130749a25d -Zlib.v1.3.1+1.aarch64-apple-darwin.tar.gz/sha512/d970e183035b3615b410f7b0da2c7a1d516234744491d65ed1ebc3800b55732f20bf00fcbb0cf91289b8b4660915282873fb23788896713cf8dfae2984a8fd85 -Zlib.v1.3.1+1.aarch64-linux-gnu.tar.gz/md5/ee42c0bae86fc39968c8cd6a77a801bf -Zlib.v1.3.1+1.aarch64-linux-gnu.tar.gz/sha512/5d21cbeab03d44008c6cbad114d45c917ebee2fe98de6b19686f4f6ba1fc67eeedf968b94ed1c2d4efb89e93be9efa342bcc8a57cb8a505085d177abae14bc2d -Zlib.v1.3.1+1.aarch64-linux-musl.tar.gz/md5/9091d1288736b218f7b016791dc1a9c8 -Zlib.v1.3.1+1.aarch64-linux-musl.tar.gz/sha512/b49cbfe734beb2af9ef8e847542d006765345cbb08aee0854779e35e03c98df25c93539b046547c6b66029987c49499ddf6cb207824b1e376900bfceaa79691a -Zlib.v1.3.1+1.aarch64-unknown-freebsd.tar.gz/md5/c73793872e3a2259519276b3ab2899ce -Zlib.v1.3.1+1.aarch64-unknown-freebsd.tar.gz/sha512/ce1e3ed5dfb01653471ace4c0cb2d8b521ccd02bc2a2c537e433a0dc497906ad21008645c645f2e0f2bb1f39c40e9a68d8cca0aeddc74ade0e188dc80748c2e8 -Zlib.v1.3.1+1.armv6l-linux-gnueabihf.tar.gz/md5/b686c85047b7dad2c2f08d1d16e7978a -Zlib.v1.3.1+1.armv6l-linux-gnueabihf.tar.gz/sha512/511fda619519dccedb264988e3b59a0e0fbf8f73d3ae290f238346209ebc0202a22f945257cea19afef64246574285e0322901a46bb48d7b48364c1e2eacd801 -Zlib.v1.3.1+1.armv6l-linux-musleabihf.tar.gz/md5/374be5cb926876f3f0492cfe0e193220 -Zlib.v1.3.1+1.armv6l-linux-musleabihf.tar.gz/sha512/4d3a2cc0c7c48146e63ed098da5a5acad75517197adc965550c123f7f8bcee0811a27be76fa37b6b0515eee4b5ba1c1a85c854e7b23bea36b5e21671805bedce -Zlib.v1.3.1+1.armv7l-linux-gnueabihf.tar.gz/md5/9febbc6a3d492e34c9ed53c95f3b799f -Zlib.v1.3.1+1.armv7l-linux-gnueabihf.tar.gz/sha512/4cee0e2cf572eb91028a09ef356e1aa6360949e046ceec03bd37574295ddcc4a7cefca9276f7565f152697d55b35f62af2ab107cdbf402b42846818629fea9c7 -Zlib.v1.3.1+1.armv7l-linux-musleabihf.tar.gz/md5/5d0d59a6cbbd1e63193ba6f7dbb755f9 -Zlib.v1.3.1+1.armv7l-linux-musleabihf.tar.gz/sha512/ee3f48b354168342ef63509b19a26aca3301fb3e5f4f6898afe2d3b44ee3380515efd6ced5d4e06e69736d851d19352deb9595bad82c051caccaee8c55e629d8 -Zlib.v1.3.1+1.i686-linux-gnu.tar.gz/md5/834350a64b2302a9caf0250a8f6068e5 -Zlib.v1.3.1+1.i686-linux-gnu.tar.gz/sha512/63dc158c4dfc42db97875893fcdd9784d9487af855bd576dbe04d1b967ad64510222df74a4cfb1b7e67386329d2a5686d7931b81720883fc1924f0d706a0a711 -Zlib.v1.3.1+1.i686-linux-musl.tar.gz/md5/e4f96efdeafa3d74c7c348059a8dc46a -Zlib.v1.3.1+1.i686-linux-musl.tar.gz/sha512/b47a571d94887ddcab8d7b50c6dce3afed3f56513a9d1859feaefebfad4a271d428b440df1d19ef3c2ed01ca4c8fd121ffc1572f5e252f27d0930f616cb47f18 -Zlib.v1.3.1+1.i686-w64-mingw32.tar.gz/md5/aaa1500c06b280d142e2900dbedf2a8f -Zlib.v1.3.1+1.i686-w64-mingw32.tar.gz/sha512/bc6668baf33bc8e130ae6a72f6cd89d9f1ccc95d2f3a3bcef20cde03ed7602de511f7646feed918918a24d8a2221a0be39eb2c0884c1adb6fe0d67b91cceb683 -Zlib.v1.3.1+1.powerpc64le-linux-gnu.tar.gz/md5/27dcad8557994cfd89d6fa7072bb843c -Zlib.v1.3.1+1.powerpc64le-linux-gnu.tar.gz/sha512/3b388dd286b273881d4344cff61c7da316c2bd2bab93072bf47ce4cb1cf9662158351b8febb0d5b1f8dfd9bc73cd32f7cae37fdd19b0ca91531bd3375df104bb -Zlib.v1.3.1+1.x86_64-apple-darwin.tar.gz/md5/9187319377191ae8b34162b375baa5db -Zlib.v1.3.1+1.x86_64-apple-darwin.tar.gz/sha512/895203434f161926978be52a223dd49a99454651a79c1c5e0529fa064f3f7ac2d7a069fed47a577b32523df22afadd6eb97d564dbd59c5d67ed90083add13c00 -Zlib.v1.3.1+1.x86_64-linux-gnu.tar.gz/md5/55d4d982d60cb643aa8688eb031b07ee -Zlib.v1.3.1+1.x86_64-linux-gnu.tar.gz/sha512/d8f94d22ffc37df027de23b2408c2000014c8b7b6c8539feca669ac1f2dbbe1679ca534c3be4d32c90fe38bbba27c795689226962fb067346b5ca213e64b9c4b -Zlib.v1.3.1+1.x86_64-linux-musl.tar.gz/md5/95d735bba178da4b8bee23903419919c -Zlib.v1.3.1+1.x86_64-linux-musl.tar.gz/sha512/370370f08133a720e3fbedcc434f102dc95225fda3ec8a399e782851bd4be57fb2b64a3ed62dc0559fb0c58d2e28db9b9e960efafd940982e4cb6652be0e81f1 -Zlib.v1.3.1+1.x86_64-unknown-freebsd.tar.gz/md5/df158f50fdb8ac1179fe6dad3bc62713 -Zlib.v1.3.1+1.x86_64-unknown-freebsd.tar.gz/sha512/f4ba4ccfeaf3fd2e172a2d5b3b1ae083ee9854022e71e062e29423e4179cb1fc49b2b99df49b3f5f231e2a0c5becc59b89644e9dcaf0fda9c97e83af7ea1c25d -Zlib.v1.3.1+1.x86_64-w64-mingw32.tar.gz/md5/9cc735c54ddf5d1ea0db60e05d6631ea -Zlib.v1.3.1+1.x86_64-w64-mingw32.tar.gz/sha512/8a2fd20944866cb7f717517ea0b80a134466e063f85bec87ffba56ca844f983f91060dfdc65f8faee1981d7329348c827b723aaad4fea36041e710b9e35c43de +Zlib.v1.3.1+2.aarch64-apple-darwin.tar.gz/md5/938c376c7513fa48d4b8b78cea741260 +Zlib.v1.3.1+2.aarch64-apple-darwin.tar.gz/sha512/ccece3f5618efe3e3699eb521167e2ee768932ea6f4e411d36619a941af3e9e32394beb260171d557930382f412f9be70f4c69215d3f7e448d4446b1690111ee +Zlib.v1.3.1+2.aarch64-linux-gnu.tar.gz/md5/44a14273caeea9c5cb34ce3e0ba9d1fc +Zlib.v1.3.1+2.aarch64-linux-gnu.tar.gz/sha512/8977bdc225404a01746fc14885e4823b4e2781c73a75e0ee0c8d9ca58b706c6cf9f98647b4e22bb09e7e09640caf4643e5210054a4624e06c76fc3eb2c2a2728 +Zlib.v1.3.1+2.aarch64-linux-musl.tar.gz/md5/dcef6c714555de9b2181b8c5b0a2c668 +Zlib.v1.3.1+2.aarch64-linux-musl.tar.gz/sha512/499701cc0fd1e52f3952da1b3c4377662c54390db9ebd6f5be82ecc0ba8754d2ca42b2f572b3a78ccdef30e527b7bed22c15511944f1299398587c529f8f4619 +Zlib.v1.3.1+2.aarch64-unknown-freebsd.tar.gz/md5/166f8a076a01a6f0979c712d7cec44e8 +Zlib.v1.3.1+2.aarch64-unknown-freebsd.tar.gz/sha512/7a1546b614cb5e2c0566774247269740d881c0a6d22ef6dca8010d77829b4e64594f4e609bb83299fa239d66909a4eb046d6d078268006723747f86e6c733e6b +Zlib.v1.3.1+2.armv6l-linux-gnueabihf.tar.gz/md5/1f0bcb50b545badbc9de1569f51c4668 +Zlib.v1.3.1+2.armv6l-linux-gnueabihf.tar.gz/sha512/1e4bea6fa41300ec770822dcd9335d1393c087db45d128e2c60d9315db01a69c984c98304b83af0725a99ae3a5cac4a273f4eea8a4213454608edbe0e55c74ce +Zlib.v1.3.1+2.armv6l-linux-musleabihf.tar.gz/md5/3a78103181bf8a74dfc0c6f7681bd3de +Zlib.v1.3.1+2.armv6l-linux-musleabihf.tar.gz/sha512/2a7c70266fd5928e46c8d71d95884054eaff2432d9fbce37eef67eb62af2b087f5f9fa3752a5d14f50cd058519d39a1b81450b30786a4f66eafbd16d18ef7b6b +Zlib.v1.3.1+2.armv7l-linux-gnueabihf.tar.gz/md5/4e202f829e7f478451e93da7be2b6f98 +Zlib.v1.3.1+2.armv7l-linux-gnueabihf.tar.gz/sha512/0734bc8a84b039b971a15620adb9b5da77d1b1992fb4c6adf9031fa8c592512645d424d2ce752efdda1f300f871c3d4f3b159794c3725fd113e1acd5512aed59 +Zlib.v1.3.1+2.armv7l-linux-musleabihf.tar.gz/md5/5000d1941b7e32dec4a2d125bbd22fff +Zlib.v1.3.1+2.armv7l-linux-musleabihf.tar.gz/sha512/6abd69ef6878fa6cdcf7fe94e4d7aedaae58d961122e131a414f3aea43b401a3812d9d847ab4b1690e9faf89d577935d7f547484edb6cb2814cbc1156159e8ed +Zlib.v1.3.1+2.i686-linux-gnu.tar.gz/md5/7a5de529294b9d8dba4ac1eeb4cbcbdc +Zlib.v1.3.1+2.i686-linux-gnu.tar.gz/sha512/72d52c4e2f01fe1436b22c854efff83068f6a65a9280556018c77bb843f81902c0c96f30132123d4dd6a66041e9391a418ceec227b2b2411f99a26df76d21c74 +Zlib.v1.3.1+2.i686-linux-musl.tar.gz/md5/d18b442e4d108397482fd852deb4241e +Zlib.v1.3.1+2.i686-linux-musl.tar.gz/sha512/6c367f7c522167db510cf42a84dfcce75fc129bb49800c05b90dfdfa5fb31fa20ed020e165f1b283b81f4568c9bf79d4c41f7ad4e42a3513cb13149a50707114 +Zlib.v1.3.1+2.i686-w64-mingw32.tar.gz/md5/b2c8af112298ae9e635054e4ba22e5ae +Zlib.v1.3.1+2.i686-w64-mingw32.tar.gz/sha512/0a28076fc8cf8daa925f4be76dd0025d01d8ad6bc269f87164749da0c3bea6f4b404ef097a2907ce2c009211d9f8387f844fe5e5b1bd2f6d77c9b35b2b1c7548 +Zlib.v1.3.1+2.powerpc64le-linux-gnu.tar.gz/md5/9ae4feb621ae088c323ff12235bdf5db +Zlib.v1.3.1+2.powerpc64le-linux-gnu.tar.gz/sha512/912134f741fe96217d1b8465510ac82d238d3d8a21519534fb88c568092dcc9eb8e51ef66b7ca56a2a7a881474f04edb7a6f7bf1ebf06bfff7708b3edd3487c0 +Zlib.v1.3.1+2.riscv64-linux-gnu.tar.gz/md5/43b61473a02e492f932ce60f726966a8 +Zlib.v1.3.1+2.riscv64-linux-gnu.tar.gz/sha512/4742503831da6a6b7945c6e5efd96bd6b03b8a63b73e68181e961b6f326ac5d805350219c43f4537165d1af0ac2ed496d5a72edd0c1d11e012ef12385a8f2e5f +Zlib.v1.3.1+2.x86_64-apple-darwin.tar.gz/md5/347a92686d81ed7c022d2e7310babb77 +Zlib.v1.3.1+2.x86_64-apple-darwin.tar.gz/sha512/a59b9c4f63124c893a2a11b886bbe03bfc75846599eb21997652bd62a2f28afe754d16127e964683552423bf1c0da160e46c32d0b584ed07e28f4e91904b9c67 +Zlib.v1.3.1+2.x86_64-linux-gnu.tar.gz/md5/0630f603e35ab56efdef331e29db436b +Zlib.v1.3.1+2.x86_64-linux-gnu.tar.gz/sha512/b936c328fad685c22473ff4cbfcc8bc48772ed9927c5b29c5d0503b95888efd0ca8d891f53cca45da7b5768ed4a1f6994f9e211167f4704c15c688cced90cac5 +Zlib.v1.3.1+2.x86_64-linux-musl.tar.gz/md5/252d8542bb5a53c479f4ffc067847e27 +Zlib.v1.3.1+2.x86_64-linux-musl.tar.gz/sha512/449809acbbff1fcbd89b9689e803f69d1f9cb49860f0b508b69c560cfcb51232640fcff17ede6ea75d9906edb5a8f38139afd890f18a34260ef5dbb5d167af36 +Zlib.v1.3.1+2.x86_64-unknown-freebsd.tar.gz/md5/79fa906629dff81c38b93001a7798040 +Zlib.v1.3.1+2.x86_64-unknown-freebsd.tar.gz/sha512/53dbcce99b2d6ec82ef86d76f3f574db304ab90f1b131c49b2c06f89bd2426afa4a31bfa8455e2ecdad64d4da71fef1b2d79f471efd55a8bbdc29e95c952a289 +Zlib.v1.3.1+2.x86_64-w64-mingw32.tar.gz/md5/92b083205ca44db131b7cf6b9c09eb21 +Zlib.v1.3.1+2.x86_64-w64-mingw32.tar.gz/sha512/1c3b7b414f09b1896c5a08f156c5e55f07ee012cf3f6fe50d5ba116405dcd9a80e5004ee7c774f7cc981e4d1b099efee85e16b8417cef2734cb7c12ec440d09a zlib-51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf.tar.gz/md5/7ce1b2766499af7d948130113b649028 zlib-51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf.tar.gz/sha512/79d032b8c93260ce6b9806f2289cdccce67e9d80865b5bb39ac46dadffc8ee009da51c551eead59c56249c7adfa164c1d5ebcf2b10a8645e0b11b5650176cb24 diff --git a/deps/openlibm.version b/deps/openlibm.version index f35b291260380..13129a0c0a860 100644 --- a/deps/openlibm.version +++ b/deps/openlibm.version @@ -1,7 +1,9 @@ +# -*- makefile -*- + ## jll artifact OPENLIBM_JLL_NAME := OpenLibm ## source build -OPENLIBM_VER := 0.8.1 -OPENLIBM_BRANCH=v0.8.1 -OPENLIBM_SHA1=ae2d91698508701c83cab83714d42a1146dccf85 +OPENLIBM_VER := 0.8.4 +OPENLIBM_BRANCH=v0.8.4 +OPENLIBM_SHA1=c4667caea25ae3487adf6760b4a1dcf32477a4b8 diff --git a/stdlib/GMP_jll/Project.toml b/stdlib/GMP_jll/Project.toml index 3a6fa12c95aef..a31688d0a9c07 100644 --- a/stdlib/GMP_jll/Project.toml +++ b/stdlib/GMP_jll/Project.toml @@ -1,6 +1,6 @@ name = "GMP_jll" uuid = "781609d7-10c4-51f6-84f2-b8444358ff6d" -version = "6.3.0+1" +version = "6.3.0+2" [deps] Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" diff --git a/stdlib/LibSSH2_jll/Project.toml b/stdlib/LibSSH2_jll/Project.toml index c45d4fc6565b7..09f07b559344c 100644 --- a/stdlib/LibSSH2_jll/Project.toml +++ b/stdlib/LibSSH2_jll/Project.toml @@ -1,6 +1,6 @@ name = "LibSSH2_jll" uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.3+0" +version = "1.11.3+1" [deps] OpenSSL_jll = "458c3c95-2e84-50aa-8efc-19380b2a3a95" diff --git a/stdlib/LibUV_jll/Project.toml b/stdlib/LibUV_jll/Project.toml index 74aae1c9249df..c6ec3ae228647 100644 --- a/stdlib/LibUV_jll/Project.toml +++ b/stdlib/LibUV_jll/Project.toml @@ -1,6 +1,6 @@ name = "LibUV_jll" uuid = "183b4373-6708-53ba-ad28-60e28bb38547" -version = "2.0.1+19" +version = "2.0.1+20" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/OpenLibm_jll/Project.toml b/stdlib/OpenLibm_jll/Project.toml index a4c559e1ff4ef..1d52749032fa4 100644 --- a/stdlib/OpenLibm_jll/Project.toml +++ b/stdlib/OpenLibm_jll/Project.toml @@ -1,6 +1,6 @@ name = "OpenLibm_jll" uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+3" +version = "0.8.4+1" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/PCRE2_jll/Project.toml b/stdlib/PCRE2_jll/Project.toml index fee83c7ce552c..24ac196a3b8a9 100644 --- a/stdlib/PCRE2_jll/Project.toml +++ b/stdlib/PCRE2_jll/Project.toml @@ -1,6 +1,6 @@ name = "PCRE2_jll" uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" -version = "10.44.0+0" +version = "10.44.0+1" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/Zlib_jll/Project.toml b/stdlib/Zlib_jll/Project.toml index dfe9ce845c8e0..40acd335c2327 100644 --- a/stdlib/Zlib_jll/Project.toml +++ b/stdlib/Zlib_jll/Project.toml @@ -1,6 +1,6 @@ name = "Zlib_jll" uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.3.1+1" +version = "1.3.1+2" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/dSFMT_jll/Project.toml b/stdlib/dSFMT_jll/Project.toml index ca51184b75264..30209421a9994 100644 --- a/stdlib/dSFMT_jll/Project.toml +++ b/stdlib/dSFMT_jll/Project.toml @@ -1,6 +1,6 @@ name = "dSFMT_jll" uuid = "05ff407c-b0c1-5878-9df8-858cc2e60c36" -version = "2.2.5+1" +version = "2.2.5+2" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/libblastrampoline_jll/Project.toml b/stdlib/libblastrampoline_jll/Project.toml index 8d5a3b7b20bcc..d1dde4c6074a7 100644 --- a/stdlib/libblastrampoline_jll/Project.toml +++ b/stdlib/libblastrampoline_jll/Project.toml @@ -1,6 +1,6 @@ name = "libblastrampoline_jll" uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.11.2+0" +version = "5.12.0+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/p7zip_jll/Project.toml b/stdlib/p7zip_jll/Project.toml index 09a39880af418..214c5b19a8a4b 100644 --- a/stdlib/p7zip_jll/Project.toml +++ b/stdlib/p7zip_jll/Project.toml @@ -1,6 +1,6 @@ name = "p7zip_jll" uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.5.0+1" +version = "17.5.0+2" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" From 89afe2026671dee633747a7eeeb4db721395835b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Sun, 5 Jan 2025 23:50:15 +0100 Subject: [PATCH 126/198] [deps] Fix build systems of curl and openssl (#56960) * Curl was missing a dependency on OpenSSL after #56708 * openssl is missing configuration target for riscv64 --- deps/curl.mk | 4 ++++ deps/openssl.mk | 2 ++ 2 files changed, 6 insertions(+) diff --git a/deps/curl.mk b/deps/curl.mk index 3d478e786ca8a..6232d56e5e333 100644 --- a/deps/curl.mk +++ b/deps/curl.mk @@ -1,6 +1,10 @@ ## CURL ## include $(SRCDIR)/curl.version +ifeq ($(USE_SYSTEM_OPENSSL), 0) +$(BUILDDIR)/curl-$(CURL_VER)/build-configured: | $(build_prefix)/manifest/openssl +endif + ifeq ($(USE_SYSTEM_LIBSSH2), 0) $(BUILDDIR)/curl-$(CURL_VER)/build-configured: | $(build_prefix)/manifest/libssh2 endif diff --git a/deps/openssl.mk b/deps/openssl.mk index 0ced5737a49a2..6f96717b2fb74 100644 --- a/deps/openssl.mk +++ b/deps/openssl.mk @@ -34,6 +34,8 @@ else ifeq ($(ARCH),ppc64le) OPENSSL_TARGET := linux-ppc64le else ifeq ($(ARCH),powerpc64le) OPENSSL_TARGET := linux-ppc64le +else ifeq ($(ARCH),riscv64) +OPENSSL_TARGET := linux64-riscv64 endif else OPENSSL_TARGET := unknown From a3f336fd713ff9723073f4543dd5b7c43cfb399e Mon Sep 17 00:00:00 2001 From: Neven Sajko <4944410+nsajko@users.noreply.github.com> Date: Mon, 6 Jan 2025 07:16:47 +0100 Subject: [PATCH 127/198] fix handling of unknown setting in `@constprop`, fix error message (#56946) Co-authored-by: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> --- base/expr.jl | 3 ++- test/misc.jl | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/base/expr.jl b/base/expr.jl index 354fae3f0a592..84078829f77ed 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -401,13 +401,14 @@ macro constprop(setting) end function constprop_setting(@nospecialize setting) + s = setting isa(setting, QuoteNode) && (setting = setting.value) if setting === :aggressive return :aggressive_constprop elseif setting === :none return :no_constprop end - throw(ArgumentError(LazyString("@constprop "), setting, "not supported")) + throw(ArgumentError(LazyString("`Base.@constprop ", s, "` not supported"))) end """ diff --git a/test/misc.jl b/test/misc.jl index 5bbc2c3c65fa2..7070fd49f5f36 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -1612,3 +1612,15 @@ let errs = IOBuffer() '`, devnull, stdout, errs) @test occursin("disable_new_worlds", String(take!(errs))) end + +@testset "`@constprop`, `@assume_effects` handling of an unknown setting" begin + for x ∈ ("constprop", "assume_effects") + try + eval(Meta.parse("Base.@$x :unknown f() = 3")) + error("unexpectedly reached") + catch e + e::LoadError + @test e.error isa ArgumentError + end + end +end From c4825b064369ae406858541205ad4215a7e5e47f Mon Sep 17 00:00:00 2001 From: FX Coudert Date: Mon, 6 Jan 2025 10:18:41 +0100 Subject: [PATCH 128/198] Update LibGit2 to 1.9.0 (#56955) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New version: https://github.com/libgit2/libgit2/releases/tag/v1.9.0 --------- Co-authored-by: Mosè Giordano Co-authored-by: Antonio Rojas --- deps/checksums/libgit2 | 74 ++++++++++++++------------- deps/libgit2.version | 4 +- stdlib/LibGit2/src/consts.jl | 4 +- stdlib/LibGit2/src/types.jl | 36 +++++++++++-- stdlib/LibGit2/test/libgit2-tests.jl | 1 + stdlib/LibGit2_jll/Project.toml | 2 +- stdlib/LibGit2_jll/src/LibGit2_jll.jl | 4 +- stdlib/LibGit2_jll/test/runtests.jl | 2 +- stdlib/Manifest.toml | 2 +- 9 files changed, 81 insertions(+), 48 deletions(-) diff --git a/deps/checksums/libgit2 b/deps/checksums/libgit2 index 0a8d2a39ffc86..c1906c995cc73 100644 --- a/deps/checksums/libgit2 +++ b/deps/checksums/libgit2 @@ -1,36 +1,38 @@ -LibGit2.v1.8.4+0.aarch64-apple-darwin.tar.gz/md5/a2bca9483d0468b6836304068a8f8d99 -LibGit2.v1.8.4+0.aarch64-apple-darwin.tar.gz/sha512/bbc150e8c330f3cd666136334e15cfbd1017174193b3ece49b1c701aebd2774ef1b23e5e59ec8b05f23788db2ed8a3f103d7ff0fac364966eb5b5b2d814ffd22 -LibGit2.v1.8.4+0.aarch64-linux-gnu.tar.gz/md5/55f133dbf3a1e5ad37c69df3ea6b2274 -LibGit2.v1.8.4+0.aarch64-linux-gnu.tar.gz/sha512/c6f5a25f9b47be391f438867f076ed5b2539ddbb6542119b8225d52c7767705cda499940007b1f33801288426408a2d5ca3feb743e898b747fe0051df5ca7ad4 -LibGit2.v1.8.4+0.aarch64-linux-musl.tar.gz/md5/660b58d4e23b5f142731ccfcffff7b39 -LibGit2.v1.8.4+0.aarch64-linux-musl.tar.gz/sha512/e5d3add19efbbb59c7b79298b83d6342f70b2ad9415ead9460d9e78e117f2a98417a96f49ebfec62e2c18cf9519114e829c2d492e08c45b501aa25552ed97722 -LibGit2.v1.8.4+0.aarch64-unknown-freebsd.tar.gz/md5/67797f9177f007617b2e027673277453 -LibGit2.v1.8.4+0.aarch64-unknown-freebsd.tar.gz/sha512/1dff62cf24e842d978638ca0df9d67e0ed11250b6cb432880aad4603f292c456fcca10b6af304ed19954c22d24bcd8d3fe32e48c45bc2ea348d58eaa0ba6a1ad -LibGit2.v1.8.4+0.armv6l-linux-gnueabihf.tar.gz/md5/cc3264f393d133f9d34d796a1ddccac2 -LibGit2.v1.8.4+0.armv6l-linux-gnueabihf.tar.gz/sha512/8479dda021511747c6ef432eb9a092a54b2fe402e9010b5500faf01be3f2c4f6121fbb45849d6ba5e6a0f57318d6065956c58a5b5ea849e38b056d011ea0588d -LibGit2.v1.8.4+0.armv6l-linux-musleabihf.tar.gz/md5/4427150daaa544d04c0fa59b1b326831 -LibGit2.v1.8.4+0.armv6l-linux-musleabihf.tar.gz/sha512/b2a3cfd08022d012bb27e17bc4d67a0a1c09561420043a96111d029e582be0fdc619fe5227532ab7a902a5d43b5ef4ba1048d2c437c5bc9ac347d80535b60d9a -LibGit2.v1.8.4+0.armv7l-linux-gnueabihf.tar.gz/md5/f8afd5a5b5702dd0015829753244d223 -LibGit2.v1.8.4+0.armv7l-linux-gnueabihf.tar.gz/sha512/986f45f15b66109f372b41a2af2a6c4a7e03edb11ec4ad1cefba0c4cf16a6ddf3b490ba7d60e92a1f2eae91bc550f8d792f1ce66df64e0e2b3c66fbb6ff94cf7 -LibGit2.v1.8.4+0.armv7l-linux-musleabihf.tar.gz/md5/02534a7e25196d3cd504a6ef2993d051 -LibGit2.v1.8.4+0.armv7l-linux-musleabihf.tar.gz/sha512/31ba2fa0c71da0812fdadcf056bfd235379dc4d6960624a9b487bfcef2dd3b0ef3a618e7ed72850fd9e401cae0a143158c0ac48f6526c4845d80d2397eb08fb8 -LibGit2.v1.8.4+0.i686-linux-gnu.tar.gz/md5/0e73f9c928a69a552539f6aab5d44b0c -LibGit2.v1.8.4+0.i686-linux-gnu.tar.gz/sha512/6cca444bcfdef691cbd8ea249328a9f066a20ff23ac71f238a62d32bf40d236d4b4f6cb6d48862652b97791bd199bbf7f8851361ec2778c779a59168b0e08c01 -LibGit2.v1.8.4+0.i686-linux-musl.tar.gz/md5/a6cdca1ca0926ceb5827205005e80759 -LibGit2.v1.8.4+0.i686-linux-musl.tar.gz/sha512/37a456b7a31ca9a482976d3a7aab463dedaebf48aba1d16be5aceae2dbd9051679a0287776a93eabed70f6e9bb89ed4084564a88ed83e1d6a085ec6e32111be5 -LibGit2.v1.8.4+0.i686-w64-mingw32.tar.gz/md5/5ffb5489354195b163c55a6a83d059f0 -LibGit2.v1.8.4+0.i686-w64-mingw32.tar.gz/sha512/81423290e6122210102166b5878e6a101fde2dcdd16de2dea016a682d8aeb13a9db04230d0b6358bec3a8fb8db543b89c3b720c5cdf3418471e41db74bdff993 -LibGit2.v1.8.4+0.powerpc64le-linux-gnu.tar.gz/md5/d99482bb86f1347c83c2795ec10ed551 -LibGit2.v1.8.4+0.powerpc64le-linux-gnu.tar.gz/sha512/a52b1141c1562f7ff55e29e41f95791645f4cca437a8ae09842239a2c132b3b4479edf24abb907d4674b04ceffdc0003dd5d8314697a96b73580ae0cebb59ac1 -LibGit2.v1.8.4+0.x86_64-apple-darwin.tar.gz/md5/f385317d44621ba48d296ffe39d74250 -LibGit2.v1.8.4+0.x86_64-apple-darwin.tar.gz/sha512/25d6fd31a4207d0890b93aa30f98c430d349cfa3c4759e3a81254c39ec095162c916a6fdc6d91ca4b3df3892ac8836209d0927c3ca18b4dfbe5b067f5d79cae9 -LibGit2.v1.8.4+0.x86_64-linux-gnu.tar.gz/md5/9f881bf0428bfbeed1fce06fce156a3c -LibGit2.v1.8.4+0.x86_64-linux-gnu.tar.gz/sha512/ea6e90997ae1dd77cdf73b65995682d3b2563e40215b7316f2cc17982f8a35ac8f40d194d8d25c1a7334cb8443ec028516d05e64b841559b0c5dc15ce289e238 -LibGit2.v1.8.4+0.x86_64-linux-musl.tar.gz/md5/349b44527421615d99c08dca5299bbb6 -LibGit2.v1.8.4+0.x86_64-linux-musl.tar.gz/sha512/809c53ba91a3643ed534c49b1e3352ef8e6cf642dbcd45e21b7d2a2e4edb8235d2d35245c4e891362a2597c9b724cee93ec885c50259763e3d06f2d82cdbe3ee -LibGit2.v1.8.4+0.x86_64-unknown-freebsd.tar.gz/md5/01bb75c5eda895d47a55b9a231c0977e -LibGit2.v1.8.4+0.x86_64-unknown-freebsd.tar.gz/sha512/ba4ba6e681faf3d768d6a09d6ad0f82934fcbf635d42d4e92a9f0a2d545733757cebff759a720d79981eac8046f278c17b9ea982db3a0b7b774af686b790960b -LibGit2.v1.8.4+0.x86_64-w64-mingw32.tar.gz/md5/37f1e39363db20979948f9a1ebdf312f -LibGit2.v1.8.4+0.x86_64-w64-mingw32.tar.gz/sha512/d74108deed353ec26a56d020f533bdc35a881d640d621292e08ab259461f132e19afbdfee0e21915e6f54b7f0debc9cf4f5959d711104534e0ec85d3fe3a0ac1 -libgit2-3f4182d15eab74a302718f2de454ffadb1995626.tar.gz/md5/c502ae54871bd3afc0bd593a5cf05d68 -libgit2-3f4182d15eab74a302718f2de454ffadb1995626.tar.gz/sha512/7381abb66b42d8b667be12afa360a855627149d1f293a3091c05f02a528fdcc9e44fd7a5adebba8b30ee4ac1f4d1f029a2f0d0b49ada97a751159e0a61f8a54e +LibGit2.v1.9.0+0.aarch64-apple-darwin.tar.gz/md5/1e22c2cf3e6003addd9bf16026ac4a06 +LibGit2.v1.9.0+0.aarch64-apple-darwin.tar.gz/sha512/78d5e5d246534164e1d70cf69dea273bbb8386df24c13fc3c3571762df15f2714307e7ff4cae6f977eee9def121c94cfe33cfcd44a60905a8161d65d17565e90 +LibGit2.v1.9.0+0.aarch64-linux-gnu.tar.gz/md5/70bfe9da256442ea2c295a016a89d3b9 +LibGit2.v1.9.0+0.aarch64-linux-gnu.tar.gz/sha512/14916a5521aa1281b443e61beee2573bc55b76d88810a3bec8bdea677d95763da82f1a527975cdabcdaa213e69aa1640201a03656bdb505b886906795aad0c74 +LibGit2.v1.9.0+0.aarch64-linux-musl.tar.gz/md5/62f6e885de29a345cc5ee3e773c74471 +LibGit2.v1.9.0+0.aarch64-linux-musl.tar.gz/sha512/09e793209505ea954e608c609138b8865d8a1630340fa8ff032a55234bfb8277d2c3c31f26048ae4993bf8c3d8f165abd0b4ccd80526c61efca0807f634572df +LibGit2.v1.9.0+0.aarch64-unknown-freebsd.tar.gz/md5/6fcba6e43265aa7a1ea5bba85977d622 +LibGit2.v1.9.0+0.aarch64-unknown-freebsd.tar.gz/sha512/34b836d3c22436e74963141dbe1f9372cb7ee695ebb2054ee0af1353d4401e1dfb855e91341a1d06a24ce18d57caaa3aa1e2bc7063000fa4f9be40130eb6ff95 +LibGit2.v1.9.0+0.armv6l-linux-gnueabihf.tar.gz/md5/75ede2c2c7312adf06a2a9859cd6310f +LibGit2.v1.9.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/9de567bee3aad33eebac51ad5b57b4fefaa4b778ce8510b2524a55cd223bfaf3051fd48c8713741e799d1464b308469580716dcb847a6eb97fd632727ca22a7d +LibGit2.v1.9.0+0.armv6l-linux-musleabihf.tar.gz/md5/e5341f0c76c89273c465cb43cbf0f284 +LibGit2.v1.9.0+0.armv6l-linux-musleabihf.tar.gz/sha512/1029d47c82ce20223b1c108da77a1a32ef0b91b9645040c1d941e7abdd161011736a81f4ad25006b32d83d4c07c548fcf1c8a3326cf3cb91d56fd443e2e9ced7 +LibGit2.v1.9.0+0.armv7l-linux-gnueabihf.tar.gz/md5/03191a1c4ff1c1ae764092b26c941783 +LibGit2.v1.9.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/6bb113c722b550fb28fc84033a3a38565ed5305a7fa193eeb4949b979fcf4599b84c748f50dad2ad47481827138a6e405eaf727f719d219984a809088bbb2948 +LibGit2.v1.9.0+0.armv7l-linux-musleabihf.tar.gz/md5/1678d6e57aa887963b27917c884cbf36 +LibGit2.v1.9.0+0.armv7l-linux-musleabihf.tar.gz/sha512/52590e9ca4118e0dec70191353b2c76155363df77df6c0bb5741dfb3f333539a8ad75339796748a744c342b51c15869726cfe9bbf6ca78d524e7d2ccce4a4622 +LibGit2.v1.9.0+0.i686-linux-gnu.tar.gz/md5/3fc50746cb80e0455f8e7c7622cd433a +LibGit2.v1.9.0+0.i686-linux-gnu.tar.gz/sha512/20c97e1a816456267a16759378a5e968e6bca122d1e0dc7cc282cad2bf2a8e3929e90373752065d91dfb6688e39ac6db660d9bdbb3277f1b9cb04b5d3f46fd8c +LibGit2.v1.9.0+0.i686-linux-musl.tar.gz/md5/fadb5e051e3b21e68a61b2a3049f65c7 +LibGit2.v1.9.0+0.i686-linux-musl.tar.gz/sha512/369c8c64df89149e9ed600028c1ac96db24e7b2c1977146667b8aeba93aa7a3b4787a49734411448680654188ece33e740fa475108b80b876a5082edad722925 +LibGit2.v1.9.0+0.i686-w64-mingw32.tar.gz/md5/610da247e41070b73e71df7e41267846 +LibGit2.v1.9.0+0.i686-w64-mingw32.tar.gz/sha512/d5b61c885133e3002e48e0fc37ceed0bfeef070e8fc6b2d78ec5f3069ad80966ea5b3a2b3aeae1ca478e9a2f839309fd67c3a186ecf751f4642ff4cb4ca3cb38 +LibGit2.v1.9.0+0.powerpc64le-linux-gnu.tar.gz/md5/f05f5f07de55fd297c564b6cd4e54747 +LibGit2.v1.9.0+0.powerpc64le-linux-gnu.tar.gz/sha512/57b740ca3ef6b18994386d74f1cf39c97c1f58f5a63e749c1a0dcef8c43a915f13cc093a8e1d06cef1d1c60cf484ba0e38d20a96344df69dfc997daa63ee1137 +LibGit2.v1.9.0+0.riscv64-linux-gnu.tar.gz/md5/b043226b10e5cbbe4914be3392f5bf72 +LibGit2.v1.9.0+0.riscv64-linux-gnu.tar.gz/sha512/a580795dd9a7ee237cd1d51d55f5079588686b1adfe391a017de743946e1bd4e7d5e4f8b79a6f84f0ce165733ca1b67ea740d06fa18547c29616df2f73e3f289 +LibGit2.v1.9.0+0.x86_64-apple-darwin.tar.gz/md5/bad8607d4997ef82cd43edfc7579d0fb +LibGit2.v1.9.0+0.x86_64-apple-darwin.tar.gz/sha512/c7359d79949a6727973b1df2264b672bfcd1617b6d4c74d281ef70ac93bcadfe47f99f7a5d031eed36b65077668ba12f2b31bbe6d491542b6938816659070317 +LibGit2.v1.9.0+0.x86_64-linux-gnu.tar.gz/md5/21e5fd214a6358f643477973c22ec70c +LibGit2.v1.9.0+0.x86_64-linux-gnu.tar.gz/sha512/9e68cb6d25d85ad272fcb0d77deedce2daa9c62d7ce2fd7e9221647d021aa00e372f490ad29211d7ca2b5ddefb4addcc4733e25e3df038aaf26fe3cb269d8f56 +LibGit2.v1.9.0+0.x86_64-linux-musl.tar.gz/md5/e9ad320825b22ee378b33856ca266b12 +LibGit2.v1.9.0+0.x86_64-linux-musl.tar.gz/sha512/bd33b4d31a7622a0440bd0979ecc7bbdef7ba7a52bfc911f880c9430d57d2b9ea1c6c4e57697b5a2b63c2e00e07673b3dad6feac056a4f345ed6e3b0ef7aef77 +LibGit2.v1.9.0+0.x86_64-unknown-freebsd.tar.gz/md5/501c63c8810616e6764ff80c23fff0b5 +LibGit2.v1.9.0+0.x86_64-unknown-freebsd.tar.gz/sha512/109e5676899ba6992a68fcff6d7503f49cc3b748b4b0faffcf951f318f9730e242914b57a7848111e229642070fdbce29bc181cbc79ac2e794c6ef489bb27293 +LibGit2.v1.9.0+0.x86_64-w64-mingw32.tar.gz/md5/4e76fa8356407a7065b50298817ad462 +LibGit2.v1.9.0+0.x86_64-w64-mingw32.tar.gz/sha512/01204b29ff2f90a9204d2e91fb7d48a3b6bea008a77984e3e67423a04f630690073d648a7200168809999aa5885fa6035c5b099256724b0379229c257ef19b9f +libgit2-338e6fb681369ff0537719095e22ce9dc602dbf0.tar.gz/md5/0ce4a212921ef1752ea057a3be45e384 +libgit2-338e6fb681369ff0537719095e22ce9dc602dbf0.tar.gz/sha512/4eb018a85a59c6ac0514f09f19a40813d8a4bc5ea230bf54897aa2ef5f584796e8c680a27ac68985a3457e1ea1f554ba4af803b430d67a9065cf51ff317d7a89 diff --git a/deps/libgit2.version b/deps/libgit2.version index 9b908cff803e3..57744b6c96d8e 100644 --- a/deps/libgit2.version +++ b/deps/libgit2.version @@ -3,8 +3,8 @@ LIBGIT2_JLL_NAME := LibGit2 ## source build -LIBGIT2_BRANCH=v1.8.4 -LIBGIT2_SHA1=3f4182d15eab74a302718f2de454ffadb1995626 +LIBGIT2_BRANCH=v1.9.0 +LIBGIT2_SHA1=338e6fb681369ff0537719095e22ce9dc602dbf0 ## Other deps # Specify the version of the Mozilla CA Certificate Store to obtain. diff --git a/stdlib/LibGit2/src/consts.jl b/stdlib/LibGit2/src/consts.jl index 8c140e8c2aa30..1a523b381982b 100644 --- a/stdlib/LibGit2/src/consts.jl +++ b/stdlib/LibGit2/src/consts.jl @@ -45,8 +45,7 @@ const BLAME_USE_MAILMAP = Cuint(1 << 5) const BLAME_IGNORE_WHITESPACE = Cuint(1 << 6) # checkout -const CHECKOUT_NONE = Cuint(0) -const CHECKOUT_SAFE = Cuint(1 << 0) +const CHECKOUT_SAFE = Cuint(0) const CHECKOUT_FORCE = Cuint(1 << 1) const CHECKOUT_RECREATE_MISSING = Cuint(1 << 2) const CHECKOUT_ALLOW_CONFLICTS = Cuint(1 << 4) @@ -67,6 +66,7 @@ const CHECKOUT_DONT_REMOVE_EXISTING = Cuint(1 << 22) const CHECKOUT_DONT_WRITE_INDEX = Cuint(1 << 23) const CHECKOUT_DRY_RUN = Cuint(1 << 24) const CHECKOUT_CONFLICT_STYLE_ZDIFF3 = Cuint(1 << 25) +const CHECKOUT_NONE = Cuint(1 << 30) const CHECKOUT_UPDATE_SUBMODULES = Cuint(1 << 16) const CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = Cuint(1 << 17) diff --git a/stdlib/LibGit2/src/types.jl b/stdlib/LibGit2/src/types.jl index 9228bec175737..181baa4991a9b 100644 --- a/stdlib/LibGit2/src/types.jl +++ b/stdlib/LibGit2/src/types.jl @@ -237,6 +237,9 @@ Matches the [`git_remote_callbacks`](https://libgit2.org/libgit2/#HEAD/type/git_ @static if LibGit2.VERSION >= v"0.99.0" resolve_url::Ptr{Cvoid} = C_NULL end + @static if LibGit2.VERSION >= v"1.9.0" + update_refs::Ptr{Cvoid} = C_NULL + end end @assert Base.allocatedinline(RemoteCallbacks) @@ -924,7 +927,9 @@ struct ConfigEntry end include_depth::Cuint level::GIT_CONFIG - free::Ptr{Cvoid} + @static if LibGit2.VERSION < v"1.9.0" + free::Ptr{Cvoid} + end @static if LibGit2.VERSION < v"1.8.0" # In 1.8.0, the unused payload value has been removed payload::Ptr{Cvoid} @@ -936,6 +941,17 @@ function Base.show(io::IO, ce::ConfigEntry) print(io, "ConfigEntry(\"", unsafe_string(ce.name), "\", \"", unsafe_string(ce.value), "\")") end +""" + LibGit2.ConfigBackendEntry + +Matches the [`git_config_backend_entry`](https://libgit2.org/libgit2/#HEAD/type/git_config_backend_entry) struct. +""" +struct ConfigBackendEntry + entry::ConfigEntry + free::Ptr{Cvoid} +end +@assert Base.allocatedinline(ConfigBackendEntry) + """ LibGit2.split_cfg_entry(ce::LibGit2.ConfigEntry) -> Tuple{String,String,String,String} @@ -1138,15 +1154,20 @@ The fields represent: * `final_commit_id`: the [`GitHash`](@ref) of the commit where this section was last changed. * `final_start_line_number`: the *one based* line number in the file where the hunk starts, in the *final* version of the file. - * `final_signature`: the signature of the person who last modified this hunk. You will + * `final_signature`: the signature of the author of `final_commit_id`. You will + need to pass this to `Signature` to access its fields. + * `final_committer`: the signature of the committer of `final_commit_id`. You will need to pass this to `Signature` to access its fields. * `orig_commit_id`: the [`GitHash`](@ref) of the commit where this hunk was first found. * `orig_path`: the path to the file where the hunk originated. This may be different than the current/final path, for instance if the file has been moved. * `orig_start_line_number`: the *one based* line number in the file where the hunk starts, in the *original* version of the file at `orig_path`. - * `orig_signature`: the signature of the person who introduced this hunk. You will + * `orig_signature`: the signature of the author who introduced this hunk. You will + need to pass this to `Signature` to access its fields. + * `orig_committer`: the signature of the committer who introduced this hunk. You will need to pass this to `Signature` to access its fields. + * `summary`: a string summary. * `boundary`: `'1'` if the original commit is a "boundary" commit (for instance, if it's equal to an oldest commit set in `options`). """ @@ -1156,12 +1177,21 @@ The fields represent: final_commit_id::GitHash = GitHash() final_start_line_number::Csize_t = Csize_t(0) final_signature::Ptr{SignatureStruct} = Ptr{SignatureStruct}(C_NULL) + @static if LibGit2.VERSION >= v"1.9.0" + final_committer::Ptr{SignatureStruct} = Ptr{SignatureStruct}(C_NULL) + end orig_commit_id::GitHash = GitHash() orig_path::Cstring = Cstring(C_NULL) orig_start_line_number::Csize_t = Csize_t(0) orig_signature::Ptr{SignatureStruct} = Ptr{SignatureStruct}(C_NULL) + @static if LibGit2.VERSION >= v"1.9.0" + orig_committer::Ptr{SignatureStruct} = Ptr{SignatureStruct}(C_NULL) + end + @static if LibGit2.VERSION >= v"1.9.0" + summary::Cstring = Cstring(C_NULL) + end boundary::Char = '\0' end @assert Base.allocatedinline(BlameHunk) diff --git a/stdlib/LibGit2/test/libgit2-tests.jl b/stdlib/LibGit2/test/libgit2-tests.jl index 1dfa5429368b6..b186f67c65cf1 100644 --- a/stdlib/LibGit2/test/libgit2-tests.jl +++ b/stdlib/LibGit2/test/libgit2-tests.jl @@ -1152,6 +1152,7 @@ mktempdir() do dir function setup_clone_repo(cache_repo::AbstractString, path::AbstractString; name="AAAA", email="BBBB@BBBB.COM") repo = LibGit2.clone(cache_repo, path) + LibGit2.fetch(repo) # need to set this for merges to succeed cfg = LibGit2.GitConfig(repo) LibGit2.set!(cfg, "user.name", name) diff --git a/stdlib/LibGit2_jll/Project.toml b/stdlib/LibGit2_jll/Project.toml index 6d3a17bb02cf8..216fe9c3c6b41 100644 --- a/stdlib/LibGit2_jll/Project.toml +++ b/stdlib/LibGit2_jll/Project.toml @@ -1,6 +1,6 @@ name = "LibGit2_jll" uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.8.4+0" +version = "1.9.0+0" [deps] OpenSSL_jll = "458c3c95-2e84-50aa-8efc-19380b2a3a95" diff --git a/stdlib/LibGit2_jll/src/LibGit2_jll.jl b/stdlib/LibGit2_jll/src/LibGit2_jll.jl index b7ed19a939c5e..c69deb4a9d932 100644 --- a/stdlib/LibGit2_jll/src/LibGit2_jll.jl +++ b/stdlib/LibGit2_jll/src/LibGit2_jll.jl @@ -24,9 +24,9 @@ libgit2_path::String = "" if Sys.iswindows() const libgit2 = "libgit2.dll" elseif Sys.isapple() - const libgit2 = "@rpath/libgit2.1.8.dylib" + const libgit2 = "@rpath/libgit2.1.9.dylib" else - const libgit2 = "libgit2.so.1.8" + const libgit2 = "libgit2.so.1.9" end function __init__() diff --git a/stdlib/LibGit2_jll/test/runtests.jl b/stdlib/LibGit2_jll/test/runtests.jl index 6cf2d2b8a568d..06edefe335a2f 100644 --- a/stdlib/LibGit2_jll/test/runtests.jl +++ b/stdlib/LibGit2_jll/test/runtests.jl @@ -7,5 +7,5 @@ using Test, Libdl, LibGit2_jll minor = Ref{Cint}(0) patch = Ref{Cint}(0) @test ccall((:git_libgit2_version, libgit2), Cint, (Ref{Cint}, Ref{Cint}, Ref{Cint}), major, minor, patch) == 0 - @test VersionNumber(major[], minor[], patch[]) == v"1.8.4" + @test VersionNumber(major[], minor[], patch[]) == v"1.9.0" end diff --git a/stdlib/Manifest.toml b/stdlib/Manifest.toml index 63da40a5630f5..07807ecd454a0 100644 --- a/stdlib/Manifest.toml +++ b/stdlib/Manifest.toml @@ -103,7 +103,7 @@ version = "1.11.0" [[deps.LibGit2_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.8.4+0" +version = "1.9.0+0" [[deps.LibSSH2_jll]] deps = ["Artifacts", "Libdl", "OpenSSL_jll"] From 4750dc2e6f574cbf5d47603b52e8881eff40bf88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:44:43 +0100 Subject: [PATCH 129/198] [build] Enable Intel JIT events only on x86_64 (#56964) Currently we are enabling it for all Linux systems, but [Intel VTune supports only x86_64](https://www.intel.com/content/www/us/en/developer/articles/system-requirements/vtune-profiler-system-requirements.html) and building LLVM with ITTAPI support is problematic on some platforms (e.g. riscv64, ref: https://github.com/JuliaPackaging/Yggdrasil/pull/10204). --- Make.inc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Make.inc b/Make.inc index 2f2ffcad754c4..1c08f4a947b1c 100644 --- a/Make.inc +++ b/Make.inc @@ -486,11 +486,15 @@ endif # Set to 1 to enable profiling with perf ifeq ("$(OS)", "Linux") USE_PERF_JITEVENTS ?= 1 +ifeq ($(ARCH),x86_64) USE_INTEL_JITEVENTS ?= 1 -else +else # ARCH x86_64 +USE_INTEL_JITEVENTS ?= 0 +endif # ARCH x86_64 +else # OS Linux USE_PERF_JITEVENTS ?= 0 USE_INTEL_JITEVENTS ?= 0 -endif +endif # OS Linux JULIACODEGEN := LLVM From 10e20f12679a549d82337af14a2caa709e03b88b Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Mon, 6 Jan 2025 09:55:15 -0500 Subject: [PATCH 130/198] REPL: Limit method lookup when completing kwargs (#56963) --- stdlib/REPL/src/REPLCompletions.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 0bffb1a1015cd..2c03c6d563c1e 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -1077,7 +1077,7 @@ function complete_keyword_argument(partial::String, last_idx::Int, context_modul kwargs_flag == 2 && return fail # one of the previous kwargs is invalid methods = Completion[] - complete_methods!(methods, funct, Any[Vararg{Any}], kwargs_ex, -1, kwargs_flag == 1) + complete_methods!(methods, funct, Any[Vararg{Any}], kwargs_ex, shift ? -1 : MAX_METHOD_COMPLETIONS, kwargs_flag == 1) # TODO: use args_ex instead of Any[Vararg{Any}] and only provide kwarg completion for # method calls compatible with the current arguments. From 7801351fb1b67251b8da6b9bae5aa83286865b1b Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Mon, 6 Jan 2025 11:05:02 -0600 Subject: [PATCH 131/198] optimize constant length `memorynew` intrinsic (take 2) (#56847) replaces https://github.com/JuliaLang/julia/pull/55913 (the rebase was more annoying than starting from scratch) This allows the compiler to better understand what's going on for `memorynew` with compile-time constant length, allowing for LLVM level escape analysis in some cases. There is more room to grow this (currently this only optimizes for fairly small Memory since bigger ones would require writing some more LLVM code, and we probably want a size limit on putting Memory on the stack to avoid stackoverflow. For larger ones, we could potentially inline the free so the Memory doesn't have to be swept by the GC, etc. ``` julia> function g() m = Memory{Int}(undef, 2) for i in 1:2 m[i] = i end m[1]+m[2] end julia> @btime g() 9.735 ns (1 allocation: 48 bytes) #before 1.719 ns (0 allocations: 0 bytes) #after ``` --- src/cgutils.cpp | 141 +++++++++++++++++++++++++++---------- src/codegen.cpp | 23 ++++-- src/llvm-alloc-helpers.cpp | 4 +- src/llvm-alloc-opt.cpp | 10 +-- src/pipeline.cpp | 1 + test/boundscheck_exec.jl | 50 +++++++++++++ 6 files changed, 182 insertions(+), 47 deletions(-) diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 6aabc459d2c91..295dd93e869ba 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -3321,7 +3321,7 @@ static Value *emit_genericmemoryptr(jl_codectx_t &ctx, Value *mem, const jl_data LoadInst *LI = ctx.builder.CreateAlignedLoad(PPT, addr, Align(sizeof(char*))); LI->setOrdering(AtomicOrdering::NotAtomic); LI->setMetadata(LLVMContext::MD_nonnull, MDNode::get(ctx.builder.getContext(), None)); - jl_aliasinfo_t aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); + jl_aliasinfo_t aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memoryptr); aliasinfo.decorateInst(LI); Value *ptr = LI; if (AS) { @@ -3347,7 +3347,7 @@ static Value *emit_genericmemoryowner(jl_codectx_t &ctx, Value *t) return emit_guarded_test(ctx, foreign, t, [&] { addr = ctx.builder.CreateConstInBoundsGEP1_32(ctx.types().T_jlgenericmemory, m, 1); LoadInst *owner = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, addr, Align(sizeof(void*))); - jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); + jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memoryptr); ai.decorateInst(owner); return ctx.builder.CreateSelect(ctx.builder.CreateIsNull(owner), t, owner); }); @@ -4432,6 +4432,105 @@ static int compare_cgparams(const jl_cgparams_t *a, const jl_cgparams_t *b) } #endif +static auto *emit_genericmemory_unchecked(jl_codectx_t &ctx, Value *cg_nbytes, Value *cg_typ) +{ + auto ptls = get_current_ptls(ctx); + auto call = prepare_call(jl_alloc_genericmemory_unchecked_func); + auto *alloc = ctx.builder.CreateCall(call, { ptls, cg_nbytes, cg_typ}); + alloc->setAttributes(call->getAttributes()); + alloc->addRetAttr(Attribute::getWithAlignment(alloc->getContext(), Align(JL_HEAP_ALIGNMENT))); + call->addRetAttr(Attribute::getWithDereferenceableBytes(call->getContext(), sizeof(jl_genericmemory_t))); + return alloc; +} + +static void emit_memory_zeroinit_and_stores(jl_codectx_t &ctx, jl_datatype_t *typ, Value* alloc, Value* nbytes, Value* nel, int zi) +{ + auto arg_typename = [&] JL_NOTSAFEPOINT { + std::string type_str; + auto eltype = jl_tparam1(typ); + if (jl_is_datatype(eltype)) + type_str = jl_symbol_name(((jl_datatype_t*)eltype)->name->name); + else if (jl_is_uniontype(eltype)) + type_str = "Union"; + else + type_str = ""; + return "Memory{" + type_str + "}[]"; + }; + setName(ctx.emission_context, alloc, arg_typename); + // set length (jl_alloc_genericmemory_unchecked_func doesn't have it) + Value *decay_alloc = decay_derived(ctx, alloc); + Value *len_field = ctx.builder.CreateStructGEP(ctx.types().T_jlgenericmemory, decay_alloc, 0); + auto len_store = ctx.builder.CreateAlignedStore(nel, len_field, Align(sizeof(void*))); + auto aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memorylen); + aliasinfo.decorateInst(len_store); + //This avoids the length store from being deleted which is illegal + ctx.builder.CreateFence(AtomicOrdering::Release, SyncScope::SingleThread); + // zeroinit pointers and unions + if (zi) { + Value *memory_ptr = ctx.builder.CreateStructGEP(ctx.types().T_jlgenericmemory, decay_alloc, 1); + auto *load = ctx.builder.CreateAlignedLoad(ctx.types().T_ptr, memory_ptr, Align(sizeof(void*))); + aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memoryptr); + aliasinfo.decorateInst(load); + auto int8t = getInt8Ty(ctx.builder.getContext()); + ctx.builder.CreateMemSet(load, ConstantInt::get(int8t, 0), nbytes, Align(sizeof(void*))); + } + return; +} + + +static jl_cgval_t emit_const_len_memorynew(jl_codectx_t &ctx, jl_datatype_t *typ, size_t nel, jl_genericmemory_t *inst) +{ + if (nel == 0) { + Value *empty_alloc = track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)inst)); + return mark_julia_type(ctx, empty_alloc, true, typ); + } + const jl_datatype_layout_t *layout = ((jl_datatype_t*)typ)->layout; + assert(((jl_datatype_t*)typ)->has_concrete_subtype && layout != NULL); + size_t elsz = layout->size; + int isboxed = layout->flags.arrayelem_isboxed; + int isunion = layout->flags.arrayelem_isunion; + int zi = ((jl_datatype_t*)typ)->zeroinit; + if (isboxed) + elsz = sizeof(void*); + size_t nbytes; + bool overflow = __builtin_mul_overflow(nel, elsz, &nbytes); + if (isunion) { + // an extra byte for each isbits union memory element, stored at m->ptr + m->length + overflow |= __builtin_add_overflow(nbytes, nel, &nbytes); + } + // overflow if signed size is too big or nel is too big (the latter matters iff elsz==0) + ssize_t tmp=1; + overflow |= __builtin_add_overflow(nel, 1, &tmp) || __builtin_add_overflow(nbytes, 1, &tmp); + if (overflow) + emit_error(ctx, prepare_call(jlargumenterror_func), "invalid GenericMemory size: the number of elements is either negative or too large for system address width"); + + auto T_size = ctx.types().T_size; + auto cg_typ = literal_pointer_val(ctx, (jl_value_t*) typ); + auto cg_nbytes = ConstantInt::get(T_size, nbytes); + auto cg_nel = ConstantInt::get(T_size, nel); + size_t tot = nbytes + LLT_ALIGN(sizeof(jl_genericmemory_t),JL_SMALL_BYTE_ALIGNMENT); + // if allocation fits within GC pools + int pooled = tot <= GC_MAX_SZCLASS; + Value *alloc, *decay_alloc, *memory_ptr; + jl_aliasinfo_t aliasinfo; + if (pooled) { + alloc = emit_allocobj(ctx, tot, cg_typ, false, JL_SMALL_BYTE_ALIGNMENT); + decay_alloc = decay_derived(ctx, alloc); + memory_ptr = ctx.builder.CreateStructGEP(ctx.types().T_jlgenericmemory, decay_alloc, 1); + setName(ctx.emission_context, memory_ptr, "memory_ptr"); + auto objref = emit_pointer_from_objref(ctx, alloc); + Value *memory_data = emit_ptrgep(ctx, objref, JL_SMALL_BYTE_ALIGNMENT); + auto *store = ctx.builder.CreateAlignedStore(memory_data, memory_ptr, Align(sizeof(void*))); + aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memoryptr); + aliasinfo.decorateInst(store); + setName(ctx.emission_context, memory_data, "memory_data"); + } else { // just use the dynamic length version since the malloc will be slow anyway + alloc = emit_genericmemory_unchecked(ctx, cg_nbytes, cg_typ); + } + emit_memory_zeroinit_and_stores(ctx, typ, alloc, cg_nbytes, cg_nel, zi); + return mark_julia_type(ctx, alloc, true, typ); +} + static jl_cgval_t emit_memorynew(jl_codectx_t &ctx, jl_datatype_t *typ, jl_cgval_t nel, jl_genericmemory_t *inst) { emit_typecheck(ctx, nel, (jl_value_t*)jl_long_type, "memorynew"); @@ -4448,9 +4547,7 @@ static jl_cgval_t emit_memorynew(jl_codectx_t &ctx, jl_datatype_t *typ, jl_cgval if (isboxed) elsz = sizeof(void*); - auto ptls = get_current_ptls(ctx); auto T_size = ctx.types().T_size; - auto int8t = getInt8Ty(ctx.builder.getContext()); BasicBlock *emptymemBB, *nonemptymemBB, *retvalBB; emptymemBB = BasicBlock::Create(ctx.builder.getContext(), "emptymem"); nonemptymemBB = BasicBlock::Create(ctx.builder.getContext(), "nonemptymem"); @@ -4466,18 +4563,7 @@ static jl_cgval_t emit_memorynew(jl_codectx_t &ctx, jl_datatype_t *typ, jl_cgval ctx.builder.CreateBr(retvalBB); nonemptymemBB->insertInto(ctx.f); ctx.builder.SetInsertPoint(nonemptymemBB); - // else actually allocate mem - auto arg_typename = [&] JL_NOTSAFEPOINT { - std::string type_str; - auto eltype = jl_tparam1(typ); - if (jl_is_datatype(eltype)) - type_str = jl_symbol_name(((jl_datatype_t*)eltype)->name->name); - else if (jl_is_uniontype(eltype)) - type_str = "Union"; - else - type_str = ""; - return "Memory{" + type_str + "}[]"; - }; + auto cg_typ = literal_pointer_val(ctx, (jl_value_t*) typ); auto cg_elsz = ConstantInt::get(T_size, elsz); @@ -4501,27 +4587,10 @@ static jl_cgval_t emit_memorynew(jl_codectx_t &ctx, jl_datatype_t *typ, jl_cgval overflow = ctx.builder.CreateOr(overflow, tobignel); Value *notoverflow = ctx.builder.CreateNot(overflow); error_unless(ctx, prepare_call(jlargumenterror_func), notoverflow, "invalid GenericMemory size: the number of elements is either negative or too large for system address width"); - // actually allocate - auto call = prepare_call(jl_alloc_genericmemory_unchecked_func); - Value *alloc = ctx.builder.CreateCall(call, { ptls, nbytes, cg_typ}); - // set length (jl_alloc_genericmemory_unchecked_func doesn't have it) - Value *decay_alloc = decay_derived(ctx, alloc); - Value *len_field = ctx.builder.CreateStructGEP(ctx.types().T_jlgenericmemory, decay_alloc, 0); - auto len_store = ctx.builder.CreateAlignedStore(nel_unboxed, len_field, Align(sizeof(void*))); - auto aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memorylen); - aliasinfo.decorateInst(len_store); - //This avoids the length store from being deleted which is illegal - ctx.builder.CreateFence(AtomicOrdering::Release, SyncScope::SingleThread); - // zeroinit pointers and unions - if (zi) { - Value *memory_ptr = ctx.builder.CreateStructGEP(ctx.types().T_jlgenericmemory, decay_alloc, 1); - auto *load = ctx.builder.CreateAlignedLoad(ctx.types().T_ptr, memory_ptr, Align(sizeof(void*))); - aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memoryptr); - aliasinfo.decorateInst(load); - ctx.builder.CreateMemSet(load, ConstantInt::get(int8t, 0), nbytes, Align(sizeof(void*))); - } + // actually allocate the memory - setName(ctx.emission_context, alloc, arg_typename); + Value *alloc = emit_genericmemory_unchecked(ctx, nbytes, cg_typ); + emit_memory_zeroinit_and_stores(ctx, typ, alloc, nbytes, nel_unboxed, zi); ctx.builder.CreateBr(retvalBB); nonemptymemBB = ctx.builder.GetInsertBlock(); // phi node to choose which side of branch diff --git a/src/codegen.cpp b/src/codegen.cpp index 1ca45a98b0620..4b5676cc8216e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -408,9 +408,9 @@ struct jl_tbaacache_t { tbaa_arrayptr = tbaa_make_child(mbuilder, "jtbaa_arrayptr", tbaa_array_scalar).first; tbaa_arraysize = tbaa_make_child(mbuilder, "jtbaa_arraysize", tbaa_array_scalar).first; tbaa_arrayselbyte = tbaa_make_child(mbuilder, "jtbaa_arrayselbyte", tbaa_array_scalar).first; - tbaa_memoryptr = tbaa_make_child(mbuilder, "jtbaa_memoryptr", tbaa_array_scalar, true).first; - tbaa_memorylen = tbaa_make_child(mbuilder, "jtbaa_memorylen", tbaa_array_scalar, true).first; - tbaa_memoryown = tbaa_make_child(mbuilder, "jtbaa_memoryown", tbaa_array_scalar, true).first; + tbaa_memoryptr = tbaa_make_child(mbuilder, "jtbaa_memoryptr", tbaa_array_scalar).first; + tbaa_memorylen = tbaa_make_child(mbuilder, "jtbaa_memorylen", tbaa_array_scalar).first; + tbaa_memoryown = tbaa_make_child(mbuilder, "jtbaa_memoryown", tbaa_array_scalar).first; tbaa_const = tbaa_make_child(mbuilder, "jtbaa_const", nullptr, true).first; } }; @@ -1179,6 +1179,7 @@ static const auto jl_alloc_genericmemory_unchecked_func = new JuliaFunction{ AttrBuilder FnAttrs(C); FnAttrs.addMemoryAttr(MemoryEffects::none()); FnAttrs.addAttribute(Attribute::NoUnwind); + FnAttrs.addAttribute(Attribute::Speculatable); + FnAttrs.addAttribute(Attribute::WillReturn); + FnAttrs.addAttribute(Attribute::NoRecurse); + FnAttrs.addAttribute(Attribute::NoSync); return AttributeList::get(C, AttributeSet::get(C, FnAttrs), Attributes(C, {Attribute::NonNull}), @@ -4470,7 +4475,17 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, jl_genericmemory_t *inst = (jl_genericmemory_t*)((jl_datatype_t*)typ)->instance; if (inst == NULL) return false; - *ret = emit_memorynew(ctx, typ, argv[2], inst); + if (argv[2].constant) { + if (!jl_is_long(argv[2].constant)) + return false; + size_t nel = jl_unbox_long(argv[2].constant); + if (nel < 0) + return false; + *ret = emit_const_len_memorynew(ctx, typ, nel, inst); + } + else { + *ret = emit_memorynew(ctx, typ, argv[2], inst); + } return true; } diff --git a/src/llvm-alloc-helpers.cpp b/src/llvm-alloc-helpers.cpp index 59fce1235e14e..194c6837860ca 100644 --- a/src/llvm-alloc-helpers.cpp +++ b/src/llvm-alloc-helpers.cpp @@ -250,8 +250,8 @@ void jl_alloc::runEscapeAnalysis(llvm::CallInst *I, EscapeAnalysisRequiredArgs r return true; } if (required.pass.gc_loaded_func == callee) { - required.use_info.haspreserve = true; - required.use_info.hasload = true; + // TODO add manual load->store forwarding + push_inst(inst); return true; } if (required.pass.typeof_func == callee) { diff --git a/src/llvm-alloc-opt.cpp b/src/llvm-alloc-opt.cpp index a9e1b1e02da42..7dd794a4d8847 100644 --- a/src/llvm-alloc-opt.cpp +++ b/src/llvm-alloc-opt.cpp @@ -752,11 +752,11 @@ void Optimizer::moveToStack(CallInst *orig_inst, size_t sz, bool has_ref, AllocF call->eraseFromParent(); return; } - //if (pass.gc_loaded_func == callee) { - // call->replaceAllUsesWith(new_i); - // call->eraseFromParent(); - // return; - //} + if (pass.gc_loaded_func == callee) { + // TODO: handle data pointer forwarding, length forwarding, and fence removal + user->replaceUsesOfWith(orig_i, Constant::getNullValue(orig_i->getType())); + return; + } if (pass.typeof_func == callee) { ++RemovedTypeofs; call->replaceAllUsesWith(tag); diff --git a/src/pipeline.cpp b/src/pipeline.cpp index 8c9054c0d65ff..39f896ba656d2 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -527,6 +527,7 @@ static void buildIntrinsicLoweringPipeline(ModulePassManager &MPM, PassBuilder * JULIA_PASS(FPM.addPass(LateLowerGCPass())); JULIA_PASS(FPM.addPass(FinalLowerGCPass())); if (O.getSpeedupLevel() >= 2) { + FPM.addPass(DSEPass()); FPM.addPass(GVNPass()); FPM.addPass(SCCPPass()); FPM.addPass(DCEPass()); diff --git a/test/boundscheck_exec.jl b/test/boundscheck_exec.jl index 10f46eb4a8031..85df1d64017b4 100644 --- a/test/boundscheck_exec.jl +++ b/test/boundscheck_exec.jl @@ -297,4 +297,54 @@ end typeintersect(Int, Integer) end |> only === Type{Int} +if bc_opt == bc_default +@testset "Array/Memory escape analysis" begin + function no_allocate(T::Type{<:Union{Memory, Vector}}) + v = T(undef, 2) + v[1] = 2 + v[2] = 3 + return v[1] + v[2] + end + function test_alloc(::Type{T}; broken=false) where T + @test (@allocated no_allocate(T)) == 0 broken=broken + end + @testset "$T" for T in [Memory, Vector] + @testset "$ET" for ET in [Int, Float32, Union{Int, Float64}] + no_allocate(T{ET}) #compile + # allocations aren't removed for Union eltypes which they theoretically could be eventually + test_alloc(T{ET}, broken=(ET==Union{Int, Float64})) + end + end + function f() # this was causing a bug on an in progress version of #55913. + m = Memory{Float64}(undef, 4) + m .= 1.0 + s = 0.0 + for x ∈ m + s += x + end + s + end + @test f() === 4.0 + function confuse_alias_analysis() + mem0 = Memory{Int}(undef, 1) + mem1 = Memory{Int}(undef, 1) + @inbounds mem0[1] = 3 + for width in 1:2 + @inbounds mem1[1] = mem0[1] + mem0 = mem1 + end + mem0[1] + end + @test confuse_alias_analysis() == 3 + @test (@allocated confuse_alias_analysis()) == 0 + function no_alias_prove(n) + m1 = Memory{Int}(undef,n) + m2 = Memory{Int}(undef,n) + m1 === m2 + end + no_alias_prove(1) + @test_broken (@allocated no_alias_prove(5)) == 0 +end +end + end From 5058dbad0462f0142f0a18be0a9aa1d62c76d2d0 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Mon, 6 Jan 2025 12:29:36 -0600 Subject: [PATCH 132/198] Add compat annotation for sorting NTuples. (#56961) Thanks @stevengj for pointing this out https://github.com/JuliaLang/julia/pull/54494#discussion_r1903267695 --- base/sort.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/base/sort.jl b/base/sort.jl index e1680d545bdc6..8254f56b3f952 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -1739,10 +1739,13 @@ function sort!(v::AbstractVector{T}; end """ - sort(v; alg::Base.Sort.Algorithm=Base.Sort.defalg(v), lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward) + sort(v::Union{AbstractVector, NTuple}; alg::Base.Sort.Algorithm=Base.Sort.defalg(v), lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward) Variant of [`sort!`](@ref) that returns a sorted copy of `v` leaving `v` itself unmodified. +!!! compat "Julia 1.12" + Sorting `NTuple`s requires Julia 1.12 or later. + # Examples ```jldoctest julia> v = [3, 1, 2]; From 36472a70b3f19ff49831c29bbe244211948cf955 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Mon, 6 Jan 2025 13:58:32 -0500 Subject: [PATCH 133/198] gc: fix assertion / ASAN violation in gc_big_object_link (#56944) We somehow just got (un)lucky that `DFS!` at Compiler/src/ssair/domtree.jl:184 just happened to store exactly the same value as this pointer in this particular memory location previously, so that this branch on `undef` hit exactly the right value to fail. What are the odds? Seen on a CI run (with rr) The odds of this happening seem somewhere around 2^60 against, to 1 for each time. So that seems impressive we hit this even this once. But we did, and the proof is here, caught in rr: https://buildkite.com/julialang/julia-master/builds/43366#019425d7-67fd-4f33-a025-6d7cd6181649 ``` From worker 6: julia: /cache/build/tester-amdci5-10/julialang/julia-master/src/gc-stock.h:492: gc_big_object_link: Assertion `node->header != gc_bigval_sentinel_tag' failed. 2025-01-02 07:47:22 UTC From worker 6: 2025-01-02 07:47:22 UTC From worker 6: [3877] signal 6 (-6): Aborted 2025-01-02 07:47:22 UTC From worker 6: in expression starting at none:1 2025-01-02 07:47:22 UTC From worker 6: gsignal at /lib/x86_64-linux-gnu/libc.so.6 (unknown line) 2025-01-02 07:47:22 UTC From worker 6: abort at /lib/x86_64-linux-gnu/libc.so.6 (unknown line) 2025-01-02 07:47:22 UTC From worker 6: unknown function (ip: 0x7fb9a4b5040e) at /lib/x86_64-linux-gnu/libc.so.6 2025-01-02 07:47:22 UTC From worker 6: __assert_fail at /lib/x86_64-linux-gnu/libc.so.6 (unknown line) 2025-01-02 07:47:22 UTC From worker 6: gc_big_object_link at /cache/build/tester-amdci5-10/julialang/julia-master/src/gc-stock.h:492 [inlined] 2025-01-02 07:47:22 UTC From worker 6: gc_setmark_big at /cache/build/tester-amdci5-10/julialang/julia-master/src/gc-stock.c:276 2025-01-02 07:47:22 UTC From worker 6: jl_gc_big_alloc_inner at /cache/build/tester-amdci5-10/julialang/julia-master/src/gc-stock.h:491 ``` --- src/gc-stock.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gc-stock.c b/src/gc-stock.c index c1bc1d64ae199..1f6b58d71da3a 100644 --- a/src/gc-stock.c +++ b/src/gc-stock.c @@ -423,7 +423,7 @@ STATIC_INLINE void jl_batch_accum_free_size(jl_ptls_t ptls, uint64_t sz) JL_NOTS // big value list -// Size includes the tag and the tag is not cleared!! +// Size includes the tag and the tag field is undefined on return (must be set before the next GC safepoint) STATIC_INLINE jl_value_t *jl_gc_big_alloc_inner(jl_ptls_t ptls, size_t sz) { maybe_collect(ptls); @@ -448,6 +448,9 @@ STATIC_INLINE jl_value_t *jl_gc_big_alloc_inner(jl_ptls_t ptls, size_t sz) memset(v, 0xee, allocsz); #endif v->sz = allocsz; +#ifndef NDEBUG + v->header = 0; // must be initialized (and not gc_bigval_sentinel_tag) or gc_big_object_link assertions will get confused +#endif gc_big_object_link(ptls->gc_tls.heap.young_generation_of_bigvals, v); return jl_valueof(&v->header); } From a23a6dee7dcfda81c037c9e689944503d8f6135d Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Mon, 6 Jan 2025 15:46:30 -0500 Subject: [PATCH 134/198] fix handling of experimental module compile flag (#56945) Add a new `finish!` function which skips any inference/optimization and just directly uses the (uninferred) source as the result, setting all fields correctly assuming they might have come from a generated function in the very unlikely case it set some of them, and making sure this is now correctly synchronized with the cache lookup and insertion calls once again. This code feature was added without any tests in #37041, so I cannot guarantee there aren't any mistakes still lurking here, either mine or original. Fixes #53431 --- Compiler/src/typeinfer.jl | 72 ++++++++++++++++++++++++++++++++------- src/aotcompile.cpp | 6 ++-- src/gf.c | 27 +++++++++++++++ src/jitlayers.cpp | 30 ++-------------- src/julia_internal.h | 2 +- 5 files changed, 92 insertions(+), 45 deletions(-) diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index 45df4707e4caa..e2821f79cca0c 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -173,6 +173,39 @@ function finish!(interp::AbstractInterpreter, caller::InferenceState) return nothing end +function finish!(interp::AbstractInterpreter, mi::MethodInstance, ci::CodeInstance, src::CodeInfo) + user_edges = src.edges + edges = user_edges isa SimpleVector ? user_edges : user_edges === nothing ? Core.svec() : Core.svec(user_edges...) + relocatability = 0x1 + const_flag = false + di = src.debuginfo + rettype = Any + exctype = Any + rettype_const = nothing + const_flags = 0x0 + ipo_effects = zero(UInt32) + min_world = src.min_world + max_world = src.max_world + if max_world >= get_world_counter() + max_world = typemax(UInt) + end + if max_world == typemax(UInt) + # if we can record all of the backedges in the global reverse-cache, + # we can now widen our applicability in the global cache too + store_backedges(ci, edges) + end + ccall(:jl_fill_codeinst, Cvoid, (Any, Any, Any, Any, Int32, UInt, UInt, UInt32, Any, Any, Any), + ci, rettype, exctype, nothing, const_flags, min_world, max_world, ipo_effects, nothing, di, edges) + ccall(:jl_update_codeinst, Cvoid, (Any, Any, Int32, UInt, UInt, UInt32, Any, UInt8, Any, Any), + ci, nothing, const_flag, min_world, max_world, ipo_effects, nothing, relocatability, di, edges) + code_cache(interp)[mi] = ci + if isdefined(interp, :codegen) + interp.codegen[ci] = src + end + engine_reject(interp, ci) + return nothing +end + function finish_nocycle(::AbstractInterpreter, frame::InferenceState) finishinfer!(frame, frame.interp) opt = frame.result.src @@ -826,7 +859,7 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize end end end - if ccall(:jl_get_module_infer, Cint, (Any,), method.module) == 0 && !generating_output(#=incremental=#false) + if ccall(:jl_get_module_infer, Cint, (Any,), method.module) == 0 add_remark!(interp, caller, "[typeinf_edge] Inference is disabled for the target module") return Future(MethodCallResult(interp, caller, method, Any, Any, Effects(), nothing, edgecycle, edgelimited)) end @@ -1096,15 +1129,6 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance, source_mod end end def = mi.def - if isa(def, Method) - if ccall(:jl_get_module_infer, Cint, (Any,), def.module) == 0 && !generating_output(#=incremental=#false) - src = retrieve_code_info(mi, get_inference_world(interp)) - src isa CodeInfo || return nothing - return CodeInstance(mi, cache_owner(interp), Any, Any, nothing, src, Int32(0), - get_inference_world(interp), get_inference_world(interp), - UInt32(0), nothing, UInt8(0), src.debuginfo, src.edges) - end - end ci = engine_reserve(interp, mi) # check cache again if it is still new after reserving in the engine let code = get(code_cache(interp), mi, nothing) @@ -1117,11 +1141,22 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance, source_mod end end end + if isa(def, Method) && ccall(:jl_get_module_infer, Cint, (Any,), def.module) == 0 + src = retrieve_code_info(mi, get_inference_world(interp)) + if src isa CodeInfo + finish!(interp, mi, ci, src) + else + engine_reject(interp, ci) + end + ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) + return ci + end result = InferenceResult(mi, typeinf_lattice(interp)) result.ci = ci frame = InferenceState(result, #=cache_mode=#:global, interp) if frame === nothing engine_reject(interp, ci) + ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) return nothing end typeinf(interp, frame) @@ -1263,18 +1298,29 @@ function typeinf_ext_toplevel(methods::Vector{Any}, worlds::Vector{UInt}, trim:: callee in inspected && continue push!(inspected, callee) # now make sure everything has source code, if desired - # TODO: typeinf_code could return something with different edges/ages (needing an update to callee), which we don't handle here + mi = get_ci_mi(callee) + def = mi.def if use_const_api(callee) - src = codeinfo_for_const(interp, callee.def, code.rettype_const) + src = codeinfo_for_const(interp, mi, code.rettype_const) elseif haskey(interp.codegen, callee) src = interp.codegen[callee] + elseif isa(def, Method) && ccall(:jl_get_module_infer, Cint, (Any,), def.module) == 0 && !trim + src = retrieve_code_info(mi, get_inference_world(interp)) else - src = typeinf_code(interp, callee.def, true) + # TODO: typeinf_code could return something with different edges/ages/owner/abi (needing an update to callee), which we don't handle here + src = typeinf_code(interp, mi, true) end if src isa CodeInfo collectinvokes!(tocompile, src) + # It is somewhat ambiguous if typeinf_ext might have callee in the caches, + # but for the purpose of native compile, we always want them put there. + if iszero(ccall(:jl_mi_cache_has_ci, Cint, (Any, Any), mi, callee)) + code_cache(interp)[mi] = callee + end push!(codeinfos, callee) push!(codeinfos, src) + elseif trim + println("warning: failed to get code for ", mi) end end end diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index 0600106c41aa6..b839ced8336da 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -429,7 +429,7 @@ static void resolve_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root } } else if (params.params->trim) { - jl_safe_printf("warning: no code provided for function"); + jl_safe_printf("warning: no code provided for function "); jl_(codeinst->def); if (params.params->trim) abort(); @@ -441,7 +441,7 @@ static void resolve_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root Function *pinvoke = nullptr; if (preal_decl.empty()) { if (invokeName.empty() && params.params->trim) { - jl_safe_printf("warning: bailed out to invoke when compiling:"); + jl_safe_printf("warning: bailed out to invoke when compiling: "); jl_(codeinst->def); abort(); } @@ -658,7 +658,7 @@ void *jl_emit_native_impl(jl_array_t *codeinfos, LLVMOrcThreadSafeModuleRef llvm else if (params.params->trim) { // if we're building a small image, we need to compile everything // to ensure that we have all the information we need. - jl_safe_printf("codegen failed to compile code root"); + jl_safe_printf("codegen failed to compile code root "); jl_(mi); abort(); } diff --git a/src/gf.c b/src/gf.c index 48cb8003072ca..d5fbcfc7dcd6a 100644 --- a/src/gf.c +++ b/src/gf.c @@ -581,6 +581,33 @@ JL_DLLEXPORT int jl_mi_cache_has_ci(jl_method_instance_t *mi, return 0; } +// look for something with an egal ABI and properties that is already in the JIT (compiled=true) or simply in the cache (compiled=false) +JL_DLLEXPORT jl_code_instance_t *jl_get_ci_equiv(jl_code_instance_t *ci JL_PROPAGATES_ROOT, int compiled) JL_NOTSAFEPOINT +{ + jl_value_t *def = ci->def; + jl_method_instance_t *mi = jl_get_ci_mi(ci); + jl_value_t *owner = ci->owner; + jl_value_t *rettype = ci->rettype; + size_t min_world = jl_atomic_load_relaxed(&ci->min_world); + size_t max_world = jl_atomic_load_relaxed(&ci->max_world); + jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache); + while (codeinst) { + if (codeinst != ci && + jl_atomic_load_relaxed(&codeinst->inferred) != NULL && + (!compiled || jl_atomic_load_relaxed(&codeinst->invoke) != NULL) && + jl_atomic_load_relaxed(&codeinst->min_world) <= min_world && + jl_atomic_load_relaxed(&codeinst->max_world) >= max_world && + jl_egal(codeinst->def, def) && + jl_egal(codeinst->owner, owner) && + jl_egal(codeinst->rettype, rettype)) { + return codeinst; + } + codeinst = jl_atomic_load_relaxed(&codeinst->next); + } + return (jl_code_instance_t*)jl_nothing; +} + + JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_method_instance_t *mi, jl_value_t *owner, jl_value_t *rettype, jl_value_t *exctype, diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 21d865891e45c..396a42505188a 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -301,32 +301,6 @@ static void finish_params(Module *M, jl_codegen_params_t ¶ms) JL_NOTSAFEPOIN } } -// look for something with an egal ABI that is already in the JIT -static jl_code_instance_t *jl_method_compiled_egal(jl_code_instance_t *ci JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT -{ - jl_value_t *def = ci->def; - jl_method_instance_t *mi = jl_get_ci_mi(ci); - jl_value_t *owner = ci->owner; - jl_value_t *rettype = ci->rettype; - size_t min_world = jl_atomic_load_relaxed(&ci->min_world); - size_t max_world = jl_atomic_load_relaxed(&ci->max_world); - jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache); - while (codeinst) { - if (codeinst != ci && - jl_atomic_load_relaxed(&codeinst->inferred) != NULL && - jl_atomic_load_relaxed(&codeinst->invoke) != NULL && - jl_atomic_load_relaxed(&codeinst->min_world) <= min_world && - jl_atomic_load_relaxed(&codeinst->max_world) >= max_world && - jl_egal(codeinst->def, def) && - jl_egal(codeinst->owner, owner) && - jl_egal(codeinst->rettype, rettype)) { - return codeinst; - } - codeinst = jl_atomic_load_relaxed(&codeinst->next); - } - return codeinst; -} - static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t ¶ms, bool forceall=false) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER { jl_task_t *ct = jl_current_task; @@ -377,8 +351,8 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t } if (preal_decl.empty()) { // there may be an equivalent method already compiled (or at least registered with the JIT to compile), in which case we should be using that instead - jl_code_instance_t *compiled_ci = jl_method_compiled_egal(codeinst); - if (compiled_ci) { + jl_code_instance_t *compiled_ci = jl_get_ci_equiv(codeinst, 1); + if ((jl_value_t*)compiled_ci != jl_nothing) { codeinst = compiled_ci; uint8_t specsigflags; void *fptr; diff --git a/src/julia_internal.h b/src/julia_internal.h index 00103e9b00a48..446e313fbe03d 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -692,6 +692,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( int32_t const_flags, size_t min_world, size_t max_world, uint32_t effects, jl_value_t *analysis_results, uint8_t relocatability, jl_debuginfo_t *di, jl_svec_t *edges /* , int absolute_max*/); +JL_DLLEXPORT jl_code_instance_t *jl_get_ci_equiv(jl_code_instance_t *ci JL_PROPAGATES_ROOT, int compiled) JL_NOTSAFEPOINT; STATIC_INLINE jl_method_instance_t *jl_get_ci_mi(jl_code_instance_t *ci JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT { @@ -1221,7 +1222,6 @@ JL_DLLEXPORT void jl_mi_cache_insert(jl_method_instance_t *mi JL_ROOTING_ARGUMEN JL_DLLEXPORT int jl_mi_try_insert(jl_method_instance_t *mi JL_ROOTING_ARGUMENT, jl_code_instance_t *expected_ci, jl_code_instance_t *ci JL_ROOTED_ARGUMENT JL_MAYBE_UNROOTED); -JL_DLLEXPORT int jl_mi_cache_has_ci(jl_method_instance_t *mi, jl_code_instance_t *ci) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_code_instance_t *jl_cached_uninferred(jl_code_instance_t *codeinst, size_t world); JL_DLLEXPORT jl_code_instance_t *jl_cache_uninferred(jl_method_instance_t *mi, jl_code_instance_t *checked, size_t world, jl_code_instance_t *newci JL_MAYBE_UNROOTED); JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst_for_uninferred(jl_method_instance_t *mi, jl_code_info_t *src); From ad5533cbda01015424851c77f672a540b08ca74c Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Mon, 6 Jan 2025 22:28:41 +0100 Subject: [PATCH 135/198] Add "mea culpa" to foreign module assignment error. (#56956) As requested in #56933, acknowledge that this error was missing in Julia 1.9 and 1.10 and provide a reference to the issue so that people have an easier starting point. --- src/module.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/module.c b/src/module.c index 38f4b980a72fd..df90180901f2c 100644 --- a/src/module.c +++ b/src/module.c @@ -290,7 +290,11 @@ JL_DLLEXPORT jl_binding_t *jl_get_binding_wr(jl_module_t *m JL_PROPAGATES_ROOT, if (decode_restriction_kind(pku) != BINDING_KIND_DECLARED) { check_safe_newbinding(m, var); if (!alloc) - jl_errorf("Global %s.%s does not exist and cannot be assigned. Declare it using `global` before attempting assignment.", jl_symbol_name(m->name), jl_symbol_name(var)); + jl_errorf("Global %s.%s does not exist and cannot be assigned.\n" + "Note: Julia 1.9 and 1.10 inadvertently omitted this error check (#56933).\n" + "Hint: Declare it using `global %s` inside `%s` before attempting assignment.", + jl_symbol_name(m->name), jl_symbol_name(var), + jl_symbol_name(var), jl_symbol_name(m->name)); } jl_ptr_kind_union_t new_pku = encode_restriction((jl_value_t*)jl_any_type, BINDING_KIND_GLOBAL); if (!jl_atomic_cmpswap(&bpart->restriction, &pku, new_pku)) From 0787a62091f886b39537386c3d1eaba72cb673ed Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Mon, 6 Jan 2025 16:33:16 -0500 Subject: [PATCH 136/198] Make `Timer(f, ...)` tasks match the stickiness of the parent task. Add `spawn` kwarg. (#56745) --- NEWS.md | 2 ++ base/asyncevent.jl | 13 +++++++++++-- test/channels.jl | 7 +++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index 8f02045a213d6..1708866609427 100644 --- a/NEWS.md +++ b/NEWS.md @@ -112,6 +112,8 @@ New library features * New `ltruncate`, `rtruncate` and `ctruncate` functions for truncating strings to text width, accounting for char widths ([#55351]) * `isless` (and thus `cmp`, sorting, etc.) is now supported for zero-dimensional `AbstractArray`s ([#55772]) * `invoke` now supports passing a Method instead of a type signature making this interface somewhat more flexible for certain uncommon use cases ([#56692]). +* `Timer(f, ...)` will now match the stickiness of the parent task when creating timer tasks, which can be overridden + by the new `spawn` kwarg. This avoids the issue where sticky tasks i.e. `@async` make their parent sticky ([#56745]) * `invoke` now supports passing a CodeInstance instead of a type, which can enable certain compiler plugin workflows ([#56660]). * `sort` now supports `NTuple`s ([#54494]) diff --git a/base/asyncevent.jl b/base/asyncevent.jl index c6cb3d3fa73bb..8c708455976e2 100644 --- a/base/asyncevent.jl +++ b/base/asyncevent.jl @@ -275,7 +275,7 @@ end # timer with repeated callback """ - Timer(callback::Function, delay; interval = 0) + Timer(callback::Function, delay; interval = 0, spawn::Union{Nothing,Bool}=nothing) Create a timer that runs the function `callback` at each timer expiration. @@ -285,6 +285,13 @@ callback is only run once. The function `callback` is called with a single argum itself. Stop a timer by calling `close`. The `callback` may still be run one final time, if the timer has already expired. +If `spawn` is `true`, the created task will be spawned, meaning that it will be allowed +to move thread, which avoids the side-effect of forcing the parent task to get stuck to the thread +it is on. If `spawn` is `nothing` (default), the task will be spawned if the parent task isn't sticky. + +!!! compat "Julia 1.12" + The `spawn` argument was introduced in Julia 1.12. + # Examples Here the first number is printed after a delay of two seconds, then the following numbers are @@ -304,7 +311,8 @@ julia> begin 3 ``` """ -function Timer(cb::Function, timeout; kwargs...) +function Timer(cb::Function, timeout; spawn::Union{Nothing,Bool}=nothing, kwargs...) + sticky = spawn === nothing ? current_task().sticky : !spawn timer = Timer(timeout; kwargs...) t = @task begin unpreserve_handle(timer) @@ -319,6 +327,7 @@ function Timer(cb::Function, timeout; kwargs...) isopen(timer) || return end end + t.sticky = sticky # here we are mimicking parts of _trywait, in coordination with task `t` preserve_handle(timer) @lock timer.cond begin diff --git a/test/channels.jl b/test/channels.jl index eed7a7ecc0566..f3e5381a62e94 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -550,8 +550,11 @@ end # make sure 1-shot timers work let a = [] Timer(t -> push!(a, 1), 0.01, interval = 0) - sleep(0.2) - @test a == [1] + @test timedwait(() -> a == [1], 10) === :ok +end +let a = [] + Timer(t -> push!(a, 1), 0.01, interval = 0, spawn = true) + @test timedwait(() -> a == [1], 10) === :ok end # make sure that we don't accidentally create a one-shot timer From 0d6bd8cbe4673e7c7eb6237cc18de968b9bbdf63 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Mon, 6 Jan 2025 23:20:15 -0500 Subject: [PATCH 137/198] Update stdlib manifest (#56972) --- stdlib/Manifest.toml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/stdlib/Manifest.toml b/stdlib/Manifest.toml index 07807ecd454a0..6743d357fb8b3 100644 --- a/stdlib/Manifest.toml +++ b/stdlib/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.12.0-DEV" manifest_format = "2.0" -project_hash = "d3a1f6b706609fe0c59521e1d770be6e2b8c489d" +project_hash = "1cb1aede0b4f0a2f12806233b9f188a63d6acf04" [[deps.ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" @@ -58,7 +58,7 @@ version = "1.11.0" [[deps.GMP_jll]] deps = ["Artifacts", "Libdl"] uuid = "781609d7-10c4-51f6-84f2-b8444358ff6d" -version = "6.3.0+1" +version = "6.3.0+2" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -78,7 +78,7 @@ version = "18.1.7+3" [[deps.LLVMLibUnwind_jll]] deps = ["Artifacts", "Libdl"] uuid = "47c5dbc3-30ba-59ef-96a6-123e260183d9" -version = "12.0.1+0" +version = "19.1.4+0" [[deps.LazyArtifacts]] deps = ["Artifacts", "Pkg"] @@ -108,12 +108,12 @@ version = "1.9.0+0" [[deps.LibSSH2_jll]] deps = ["Artifacts", "Libdl", "OpenSSL_jll"] uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.3+0" +version = "1.11.3+1" [[deps.LibUV_jll]] deps = ["Artifacts", "Libdl"] uuid = "183b4373-6708-53ba-ad28-60e28bb38547" -version = "2.0.1+19" +version = "2.0.1+20" [[deps.LibUnwind_jll]] deps = ["Artifacts", "Libdl"] @@ -149,11 +149,11 @@ version = "1.11.0" [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2024.3.11" +version = "2024.11.26" [[deps.NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" +version = "1.3.0" [[deps.OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] @@ -163,17 +163,17 @@ version = "0.3.28+3" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+3" +version = "0.8.4+1" [[deps.OpenSSL_jll]] -deps = ["Artifacts", "Libdl", "NetworkOptions"] +deps = ["Artifacts", "Libdl"] uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" version = "3.0.15+1" [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" -version = "10.43.0+1" +version = "10.44.0+1" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] @@ -272,12 +272,12 @@ version = "1.11.0" [[deps.Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.3.1+1" +version = "1.3.1+2" [[deps.dSFMT_jll]] deps = ["Artifacts", "Libdl"] uuid = "05ff407c-b0c1-5878-9df8-858cc2e60c36" -version = "2.2.5+1" +version = "2.2.5+2" [[deps.libLLVM_jll]] deps = ["Artifacts", "Libdl"] @@ -287,7 +287,7 @@ version = "18.1.7+3" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.11.0+0" +version = "5.12.0+0" [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] @@ -297,4 +297,4 @@ version = "1.64.0+1" [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.5.0+1" +version = "17.5.0+2" From 22134ca28e92df321bdd08502ddd86ad2d6d614f Mon Sep 17 00:00:00 2001 From: Eduardo Souza Date: Wed, 8 Jan 2025 01:11:27 +1100 Subject: [PATCH 138/198] Adding support for MMTk (non-moving immix) (#56288) This PR adds the possibility of building/running Julia using MMTk, running non-moving immix. The binding code (Rust) associated with it is in https://github.com/mmtk/mmtk-julia/tree/upstream-ready/immix. Instructions on how to build/run Julia with MMTk are described in the [`README`](https://github.com/mmtk/mmtk-julia/tree/upstream-ready/immix?tab=readme-ov-file#an-mmtk-binding-for-the-julia-programming-language) file inside the binding repo. --- Make.inc | 43 + base/timing.jl | 17 +- deps/Makefile | 11 +- .../md5 | 1 + .../sha512 | 1 + deps/mmtk_julia.mk | 71 + deps/mmtk_julia.version | 4 + src/Makefile | 46 +- src/gc-common.c | 50 + src/gc-common.h | 35 + src/gc-interface.h | 12 +- src/gc-mmtk.c | 1180 +++++++++++++++++ src/gc-stacks.c | 97 -- src/gc-stock.c | 193 ++- src/gc-stock.h | 26 +- src/gc-tls-mmtk.h | 23 + src/{gc-tls.h => gc-tls-stock.h} | 0 src/julia_internal.h | 2 +- src/julia_locks.h | 2 +- src/julia_threads.h | 6 +- src/llvm-gc-interface-passes.h | 3 + src/llvm-late-gc-lowering-mmtk.cpp | 96 ++ src/llvm-late-gc-lowering-stock.cpp | 9 + src/llvm-late-gc-lowering.cpp | 26 + src/staticdata.c | 2 + src/threading.c | 4 + .../InteractiveUtils/src/InteractiveUtils.jl | 1 + 27 files changed, 1751 insertions(+), 210 deletions(-) create mode 100644 deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5 create mode 100644 deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512 create mode 100644 deps/mmtk_julia.mk create mode 100644 deps/mmtk_julia.version create mode 100644 src/gc-mmtk.c create mode 100644 src/gc-tls-mmtk.h rename src/{gc-tls.h => gc-tls-stock.h} (100%) create mode 100644 src/llvm-late-gc-lowering-mmtk.cpp create mode 100644 src/llvm-late-gc-lowering-stock.cpp diff --git a/Make.inc b/Make.inc index 1c08f4a947b1c..216fc6fd7adde 100644 --- a/Make.inc +++ b/Make.inc @@ -80,6 +80,9 @@ HAVE_SSP := 0 WITH_GC_VERIFY := 0 WITH_GC_DEBUG_ENV := 0 +# Use stock if MMTK_PLAN hasn't been defined +MMTK_PLAN ?= None + # Enable DTrace support WITH_DTRACE := 0 @@ -833,6 +836,31 @@ JCXXFLAGS += -DGC_DEBUG_ENV JCFLAGS += -DGC_DEBUG_ENV endif +ifneq (${MMTK_PLAN},None) +JCXXFLAGS += -DMMTK_GC +JCFLAGS += -DMMTK_GC +# Do a release build on the binding by default +MMTK_BUILD ?= release +ifeq (${MMTK_PLAN},Immix) +JCXXFLAGS += -DMMTK_PLAN_IMMIX +JCFLAGS += -DMMTK_PLAN_IMMIX +else +$(error "Unsupported MMTk plan: $(MMTK_PLAN)") +endif + +# Location of mmtk-julia binding +# (needed for api/*.h and .so file) +MMTK_JULIA_DIR ?= $(BUILDROOT)/usr/lib/mmtk_julia + +MMTK_DIR = ${MMTK_JULIA_DIR}/mmtk +MMTK_API_INC = ${MMTK_DIR}/api + +MMTK_LIB := -lmmtk_julia +else +MMTK_JULIA_INC := +MMTK_LIB := +endif + ifeq ($(WITH_DTRACE), 1) JCXXFLAGS += -DUSE_DTRACE JCFLAGS += -DUSE_DTRACE @@ -933,6 +961,21 @@ ARCH := $(BUILD_OS) endif endif +# MMTk is only available on x86_64 Linux for now +ifneq (${MMTK_PLAN},None) + +ifeq ($(OS),Linux) +MMTK_LIB_NAME := libmmtk_julia.so +else +$(error "Unsupported OS for MMTk") +endif + +ifneq ($(ARCH),x86_64) +$(error "Unsupported build architecture for MMTk") +endif + +endif + # Detect common pre-SSE2 JULIA_CPU_TARGET values known not to work (#7185) ifeq ($(MARCH),) ifneq ($(findstring $(ARCH),i386 i486 i586 i686),) diff --git a/base/timing.jl b/base/timing.jl index 1de3727756829..0088f8bb77eca 100644 --- a/base/timing.jl +++ b/base/timing.jl @@ -106,9 +106,14 @@ function gc_page_utilization_data() return Base.unsafe_wrap(Array, page_utilization_raw, JL_GC_N_MAX_POOLS, own=false) end + +const USING_STOCK_GC = occursin("stock", unsafe_string(ccall(:jl_gc_active_impl, Ptr{UInt8}, ()))) +# Full sweep reasons are currently only available for the stock GC +@static if USING_STOCK_GC # must be kept in sync with `src/gc-stock.h`` const FULL_SWEEP_REASONS = [:FULL_SWEEP_REASON_SWEEP_ALWAYS_FULL, :FULL_SWEEP_REASON_FORCED_FULL_SWEEP, :FULL_SWEEP_REASON_USER_MAX_EXCEEDED, :FULL_SWEEP_REASON_LARGE_PROMOTION_RATE] +end """ Base.full_sweep_reasons() @@ -124,11 +129,15 @@ The reasons are: Note that the set of reasons is not guaranteed to be stable across minor versions of Julia. """ function full_sweep_reasons() - reason = cglobal(:jl_full_sweep_reasons, UInt64) - reasons_as_array = Base.unsafe_wrap(Vector{UInt64}, reason, length(FULL_SWEEP_REASONS), own=false) d = Dict{Symbol, Int64}() - for (i, r) in enumerate(FULL_SWEEP_REASONS) - d[r] = reasons_as_array[i] + # populate the dictionary according to the reasons above for the stock GC + # otherwise return an empty dictionary for now + @static if USING_STOCK_GC + reason = cglobal(:jl_full_sweep_reasons, UInt64) + reasons_as_array = Base.unsafe_wrap(Vector{UInt64}, reason, length(FULL_SWEEP_REASONS), own=false) + for (i, r) in enumerate(FULL_SWEEP_REASONS) + d[r] = reasons_as_array[i] + end end return d end diff --git a/deps/Makefile b/deps/Makefile index d4ef52646cfdc..396b1021c2ddd 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -26,7 +26,7 @@ BUILDDIR := $(BUILDDIR)$(MAYBE_HOST) # custom Makefile rules: openlibm dsfmt libsuitesparse lapack blastrampoline openblas utf8proc objconv libwhich # CMake libs: llvm llvmunwind libgit2 libssh2 libtracyclient # -# downloadable via git: llvm-svn, libuv, libopenlibm, utf8proc, libgit2, libssh2, libtracyclient +# downloadable via git: llvm-svn, libuv, libopenlibm, utf8proc, libgit2, libssh2, libtracyclient, mmtk_julia # # to debug 'define' rules, replace eval at the usage site with info or error @@ -195,6 +195,10 @@ DEP_LIBS += libwhich endif endif +ifneq (${MMTK_PLAN},None) +DEP_LIBS += mmtk_julia +endif + DEP_LIBS_STAGED := $(DEP_LIBS) # list all targets @@ -202,7 +206,7 @@ DEP_LIBS_STAGED_ALL := llvm llvm-tools clang llvmunwind unwind libuv pcre \ openlibm dsfmt blastrampoline openblas lapack gmp mpfr patchelf utf8proc \ objconv openssl libssh2 nghttp2 curl libgit2 libwhich zlib p7zip csl \ sanitizers libsuitesparse lld libtracyclient ittapi nvtx JuliaSyntax \ - terminfo + terminfo mmtk_julia DEP_LIBS_ALL := $(DEP_LIBS_STAGED_ALL) ifneq ($(USE_BINARYBUILDER_OPENBLAS),0) @@ -266,6 +270,9 @@ include $(SRCDIR)/p7zip.mk include $(SRCDIR)/libtracyclient.mk include $(SRCDIR)/terminfo.mk +# MMTk +include $(SRCDIR)/mmtk_julia.mk + # vendored Julia libs include $(SRCDIR)/JuliaSyntax.mk diff --git a/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5 b/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5 new file mode 100644 index 0000000000000..fc6955c8f2e7b --- /dev/null +++ b/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5 @@ -0,0 +1 @@ +1911cf084d26c48e2ed58af3d268b4b6 diff --git a/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512 b/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512 new file mode 100644 index 0000000000000..ea916976895a3 --- /dev/null +++ b/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512 @@ -0,0 +1 @@ +75beab54398989c46b62e714b242cf6705d88d220f40c21e494e0f29161437f5fbe9ba05b543d2353a1ad76f4239ac4025b476be0be864649f310f14935289fe diff --git a/deps/mmtk_julia.mk b/deps/mmtk_julia.mk new file mode 100644 index 0000000000000..ccf638e9211bb --- /dev/null +++ b/deps/mmtk_julia.mk @@ -0,0 +1,71 @@ +## MMTK ## + +# Both MMTK_MOVING and MMTK_PLAN should be specified in the Make.user file. +# At this point, since we only support non-moving this is always set to 0 +# FIXME: change it to `?:` when introducing moving plans +MMTK_MOVING := 0 +MMTK_VARS := MMTK_PLAN=$(MMTK_PLAN) MMTK_MOVING=$(MMTK_MOVING) + +# Download the binding, build it from source +ifeq (${MMTK_JULIA_DIR},$(BUILDROOT)/usr/lib/mmtk_julia) +$(eval $(call git-external,mmtk_julia,MMTK_JULIA,,,$(BUILDDIR))) + +MMTK_JULIA_DIR=$(BUILDROOT)/deps/$(BUILDDIR)/$(MMTK_JULIA_SRC_DIR) +MMTK_JULIA_LIB_PATH=$(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD) +PROJECT_DIRS := JULIA_PATH=$(JULIAHOME) JULIA_BUILDROOT=$(BUILDROOT) MMTK_JULIA_DIR=$(MMTK_JULIA_DIR) + +$(BUILDDIR)/$(MMTK_JULIA_SRC_DIR)/build-compiled: $(BUILDROOT)/usr/lib/libmmtk_julia.so + @echo 1 > $@ + +# NB: use the absolute dir when creating the symlink +$(BUILDROOT)/usr/lib/libmmtk_julia.so: $(MMTK_JULIA_LIB_PATH)/libmmtk_julia.so + @ln -sf $(MMTK_JULIA_LIB_PATH)/libmmtk_julia.so $@ + +$(MMTK_JULIA_LIB_PATH)/libmmtk_julia.so: $(BUILDDIR)/$(MMTK_JULIA_SRC_DIR)/source-extracted + @$(PROJECT_DIRS) $(MMTK_VARS) $(MAKE) -C $(MMTK_JULIA_DIR) $(MMTK_BUILD) + +get-mmtk_julia: $(MMTK_JULIA_SRC_FILE) +extract-mmtk_julia: $(BUILDDIR)/$(MMTK_JULIA_SRC_DIR)/source-extracted +configure-mmtk_julia: extract-mmtk_julia +compile-mmtk_julia: $(BUILDROOT)/usr/lib/libmmtk_julia.so +fastcheck-mmtk_julia: #none +check-mmtk_julia: compile-mmtk_julia + +$(eval $(call symlink_install,mmtk_julia,$$(MMTK_JULIA_SRC_DIR),$$(BUILDROOT)/usr/lib)) + +# In this case, there is a custom version of the binding in MMTK_JULIA_DIR +# Build it and symlink libmmtk_julia.so file into $(BUILDROOT)/usr/lib +else + +PROJECT_DIRS := JULIA_PATH=$(JULIAHOME) JULIA_BUILDROOT=$(BUILDROOT) MMTK_JULIA_DIR=$(MMTK_JULIA_DIR) +MMTK_JULIA_LIB_PATH=$(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD) + +install-mmtk_julia: compile-mmtk_julia $(build_prefix)/manifest/mmtk_julia + +compile-mmtk_julia: $(BUILDROOT)/usr/lib/libmmtk_julia.so + +version-check-mmtk_julia: $(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)/libmmtk_julia.so + +# NB: This will NOT run `cargo build` if there are changes in the Rust source files +# inside the binding repo. However the target below should remake the symlink if there +# are changes in the libmmtk_julia.so from the custom MMTK_JULIA_DIR folder +$(BUILDROOT)/usr/lib/libmmtk_julia.so: $(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)/libmmtk_julia.so + @ln -sf $(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)/libmmtk_julia.so $@ + +$(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)/libmmtk_julia.so: + @$(PROJECT_DIRS) $(MMTK_VARS) $(MAKE) -C $(MMTK_JULIA_DIR) $(MMTK_BUILD) + +MMTK_JULIA_VER := mmtk_julia_custom + +UNINSTALL_mmtk_julia := $(MMTK_JULIA_VER) manual_mmtk_julia + +define manual_mmtk_julia +uninstall-mmtk_julia: + -rm -f $(build_prefix)/manifest/mmtk_julia + -rm -f $(BUILDROOT)/usr/lib/libmmtk_julia.so +endef + +$(build_prefix)/manifest/mmtk_julia: $(BUILDROOT)/usr/lib/libmmtk_julia.so + @echo $(UNINSTALL_mmtk_julia) > $@ + +endif # MMTK_JULIA_DIR diff --git a/deps/mmtk_julia.version b/deps/mmtk_julia.version new file mode 100644 index 0000000000000..60f7cffe7b4de --- /dev/null +++ b/deps/mmtk_julia.version @@ -0,0 +1,4 @@ +MMTK_JULIA_BRANCH = master +MMTK_JULIA_SHA1 = b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214 +MMTK_JULIA_GIT_URL := https://github.com/mmtk/mmtk-julia.git +MMTK_JULIA_TAR_URL = https://github.com/mmtk/mmtk-julia/archive/refs/tags/v0.30.2.tar.gz diff --git a/src/Makefile b/src/Makefile index 9355ca2c4c675..b49d27e05ff28 100644 --- a/src/Makefile +++ b/src/Makefile @@ -29,6 +29,10 @@ ifeq ($(USECLANG),1) FLAGS += -Wno-return-type-c-linkage -Wno-atomic-alignment endif +ifneq (${MMTK_PLAN},None) +FLAGS += -I$(MMTK_API_INC) +endif + FLAGS += -DJL_BUILD_ARCH='"$(ARCH)"' ifeq ($(OS),WINNT) FLAGS += -DJL_BUILD_UNAME='"NT"' @@ -40,23 +44,41 @@ ifeq ($(OS),FreeBSD) FLAGS += -I$(LOCALBASE)/include endif +# GC source code. It depends on which GC implementation to use. +GC_SRCS := gc-common gc-stacks gc-alloc-profiler gc-heap-snapshot +ifneq (${MMTK_PLAN},None) +GC_SRCS += gc-mmtk +else +GC_SRCS += gc-stock gc-debug gc-pages gc-page-profiler +endif + SRCS := \ jltypes gf typemap smallintset ast builtins module interpreter symbol \ dlload sys init task array genericmemory staticdata toplevel jl_uv datatype \ simplevector runtime_intrinsics precompile jloptions mtarraylist \ - threading scheduler stackwalk gc-common gc-stock gc-debug gc-pages gc-stacks gc-alloc-profiler gc-page-profiler method \ - jlapi signal-handling safepoint timing subtype rtutils gc-heap-snapshot \ - crc32c APInt-C processor ircode opaque_closure codegen-stubs coverage runtime_ccall engine + threading scheduler stackwalk \ + method jlapi signal-handling safepoint timing subtype rtutils \ + crc32c APInt-C processor ircode opaque_closure codegen-stubs coverage runtime_ccall engine \ + $(GC_SRCS) RT_LLVMLINK := CG_LLVMLINK := ifeq ($(JULIACODEGEN),LLVM) +# Currently these files are used by both GCs. But we should make the list specific to stock, and MMTk should have its own implementation. +GC_CODEGEN_SRCS := llvm-final-gc-lowering llvm-late-gc-lowering llvm-gc-invariant-verifier +ifneq (${MMTK_PLAN},None) +FLAGS += -I$(MMTK_API_INC) +GC_CODEGEN_SRCS += llvm-late-gc-lowering-mmtk +else +GC_CODEGEN_SRCS += llvm-late-gc-lowering-stock +endif CODEGEN_SRCS := codegen jitlayers aotcompile debuginfo disasm llvm-simdloop \ - llvm-final-gc-lowering llvm-pass-helpers llvm-late-gc-lowering llvm-ptls \ - llvm-lower-handlers llvm-gc-invariant-verifier llvm-propagate-addrspaces \ + llvm-pass-helpers llvm-ptls \ + llvm-lower-handlers llvm-propagate-addrspaces \ llvm-multiversioning llvm-alloc-opt llvm-alloc-helpers cgmemmgr llvm-remove-addrspaces \ - llvm-remove-ni llvm-julia-licm llvm-demote-float16 llvm-cpufeatures pipeline llvm_api + llvm-remove-ni llvm-julia-licm llvm-demote-float16 llvm-cpufeatures pipeline llvm_api \ + $(GC_CODEGEN_SRCS) FLAGS += -I$(shell $(LLVM_CONFIG_HOST) --includedir) CG_LLVM_LIBS := all ifeq ($(USE_POLLY),1) @@ -99,7 +121,12 @@ ifeq ($(USE_SYSTEM_LIBUV),0) UV_HEADERS += uv.h UV_HEADERS += uv/*.h endif -PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,work-stealing-queue.h gc-interface.h gc-tls.h gc-tls-common.h julia.h julia_assert.h julia_threads.h julia_fasttls.h julia_locks.h julia_atomics.h jloptions.h) +PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,work-stealing-queue.h gc-interface.h gc-tls-common.h julia.h julia_assert.h julia_threads.h julia_fasttls.h julia_locks.h julia_atomics.h jloptions.h) +ifneq (${MMTK_PLAN},None) + PUBLIC_HEADERS += $(addprefix $(SRCDIR)/,gc-tls-mmtk.h) +else + PUBLIC_HEADERS += $(addprefix $(SRCDIR)/,gc-tls-stock.h) +endif ifeq ($(OS),WINNT) PUBLIC_HEADERS += $(addprefix $(SRCDIR)/,win32_ucontext.h) endif @@ -164,8 +191,8 @@ LIBJULIA_PATH_REL := libjulia endif COMMON_LIBPATHS := -L$(build_libdir) -L$(build_shlibdir) -RT_LIBS := $(WHOLE_ARCHIVE) $(LIBUV) $(WHOLE_ARCHIVE) $(LIBUTF8PROC) $(NO_WHOLE_ARCHIVE) $(LIBUNWIND) $(RT_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI) -CG_LIBS := $(LIBUNWIND) $(CG_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI) +RT_LIBS := $(WHOLE_ARCHIVE) $(LIBUV) $(WHOLE_ARCHIVE) $(LIBUTF8PROC) $(NO_WHOLE_ARCHIVE) $(LIBUNWIND) $(RT_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI) $(MMTK_LIB) +CG_LIBS := $(LIBUNWIND) $(CG_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI) $(MMTK_LIB) RT_DEBUG_LIBS := $(COMMON_LIBPATHS) $(WHOLE_ARCHIVE) $(BUILDDIR)/flisp/libflisp-debug.a $(WHOLE_ARCHIVE) $(BUILDDIR)/support/libsupport-debug.a -ljulia-debug $(RT_LIBS) CG_DEBUG_LIBS := $(COMMON_LIBPATHS) $(CG_LIBS) -ljulia-debug -ljulia-internal-debug RT_RELEASE_LIBS := $(COMMON_LIBPATHS) $(WHOLE_ARCHIVE) $(BUILDDIR)/flisp/libflisp.a $(WHOLE_ARCHIVE) $(BUILDDIR)/support/libsupport.a -ljulia $(RT_LIBS) @@ -314,6 +341,7 @@ $(BUILDDIR)/debuginfo.o $(BUILDDIR)/debuginfo.dbg.obj: $(addprefix $(SRCDIR)/,de $(BUILDDIR)/disasm.o $(BUILDDIR)/disasm.dbg.obj: $(SRCDIR)/debuginfo.h $(SRCDIR)/processor.h $(BUILDDIR)/gc-debug.o $(BUILDDIR)/gc-debug.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h $(BUILDDIR)/gc-pages.o $(BUILDDIR)/gc-pages.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h +$(BUILDDIR)/gc-mmtk.o $(BUILDDIR)/gc-mmtk.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-heap-snapshot.h $(SRCDIR)/gc-alloc-profiler.h $(BUILDDIR)/gc-stacks.o $(BUILDDIR)/gc-stacks.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h $(BUILDDIR)/gc-stock.o $(BUILDDIR)/gc.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h $(SRCDIR)/gc-heap-snapshot.h $(SRCDIR)/gc-alloc-profiler.h $(SRCDIR)/gc-page-profiler.h $(BUILDDIR)/gc-heap-snapshot.o $(BUILDDIR)/gc-heap-snapshot.dbg.obj: $(SRCDIR)/gc-heap-snapshot.h diff --git a/src/gc-common.c b/src/gc-common.c index 3d578b81578b1..c07b707b17709 100644 --- a/src/gc-common.c +++ b/src/gc-common.c @@ -540,6 +540,38 @@ JL_DLLEXPORT jl_value_t *(jl_gc_alloc)(jl_ptls_t ptls, size_t sz, void *ty) return jl_gc_alloc_(ptls, sz, ty); } +JL_DLLEXPORT void *jl_malloc(size_t sz) +{ + return jl_gc_counted_malloc(sz); +} + +//_unchecked_calloc does not check for potential overflow of nm*sz +STATIC_INLINE void *_unchecked_calloc(size_t nm, size_t sz) { + size_t nmsz = nm*sz; + return jl_gc_counted_calloc(nmsz, 1); +} + +JL_DLLEXPORT void *jl_calloc(size_t nm, size_t sz) +{ + if (nm > SSIZE_MAX/sz) + return NULL; + return _unchecked_calloc(nm, sz); +} + +JL_DLLEXPORT void jl_free(void *p) +{ + if (p != NULL) { + size_t sz = memory_block_usable_size(p, 0); + return jl_gc_counted_free_with_size(p, sz); + } +} + +JL_DLLEXPORT void *jl_realloc(void *p, size_t sz) +{ + size_t old = p ? memory_block_usable_size(p, 0) : 0; + return jl_gc_counted_realloc_with_old_size(p, old, sz); +} + // =========================================================================== // // Generic Memory // =========================================================================== // @@ -668,6 +700,24 @@ JL_DLLEXPORT void jl_throw_out_of_memory_error(void) jl_throw(jl_memory_exception); } +// Sweeping mtarraylist_buffers: +// These buffers are made unreachable via `mtarraylist_resizeto` from mtarraylist.c +// and are freed at the end of GC via jl_gc_sweep_stack_pools_and_mtarraylist_buffers +void sweep_mtarraylist_buffers(void) JL_NOTSAFEPOINT +{ + for (int i = 0; i < gc_n_threads; i++) { + jl_ptls_t ptls = gc_all_tls_states[i]; + if (ptls == NULL) { + continue; + } + small_arraylist_t *buffers = &ptls->lazily_freed_mtarraylist_buffers; + void *buf; + while ((buf = small_arraylist_pop(buffers)) != NULL) { + free(buf); + } + } +} + #ifdef __cplusplus } #endif diff --git a/src/gc-common.h b/src/gc-common.h index 1745df17950f9..ca5e21084209e 100644 --- a/src/gc-common.h +++ b/src/gc-common.h @@ -24,6 +24,31 @@ extern "C" { #endif +// =========================================================================== // +// GC Big objects +// =========================================================================== // + +JL_EXTENSION typedef struct _bigval_t { + struct _bigval_t *next; + struct _bigval_t *prev; + size_t sz; +#ifdef _P64 // Add padding so that the value is 64-byte aligned + // (8 pointers of 8 bytes each) - (4 other pointers in struct) + void *_padding[8 - 4]; +#else + // (16 pointers of 4 bytes each) - (4 other pointers in struct) + void *_padding[16 - 4]; +#endif + //struct jl_taggedvalue_t <>; + union { + uintptr_t header; + struct { + uintptr_t gc:2; + } bits; + }; + // must be 64-byte aligned here, in 32 & 64 bit modes +} bigval_t; + // =========================================================================== // // GC Callbacks // =========================================================================== // @@ -187,4 +212,14 @@ extern jl_ptls_t* gc_all_tls_states; extern int gc_logging_enabled; +// =========================================================================== // +// MISC +// =========================================================================== // + +// number of stacks to always keep available per pool +#define MIN_STACK_MAPPINGS_PER_POOL 5 + +void _jl_free_stack(jl_ptls_t ptls, void *stkbuf, size_t bufsz) JL_NOTSAFEPOINT; +void sweep_mtarraylist_buffers(void) JL_NOTSAFEPOINT; + #endif // JL_GC_COMMON_H diff --git a/src/gc-interface.h b/src/gc-interface.h index eb6687d52d9ab..e4a27782f7520 100644 --- a/src/gc-interface.h +++ b/src/gc-interface.h @@ -98,6 +98,13 @@ JL_DLLEXPORT void jl_gc_set_max_memory(uint64_t max_mem); JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t collection); // Returns whether the thread with `tid` is a collector thread JL_DLLEXPORT int gc_is_collector_thread(int tid) JL_NOTSAFEPOINT; +// Returns which GC implementation is being used and possibly its version according to the list of supported GCs +// NB: it should clearly identify the GC by including e.g. ‘stock’ or ‘mmtk’ as a substring. +JL_DLLEXPORT const char* jl_gc_active_impl(void); +// Sweep Julia's stack pools and mtarray buffers. Note that this function has been added to the interface as +// each GC should implement it but it will most likely not be used by other code in the runtime. +// It still needs to be annotated with JL_DLLEXPORT since it is called from Rust by MMTk. +JL_DLLEXPORT void jl_gc_sweep_stack_pools_and_mtarraylist_buffers(jl_ptls_t ptls) JL_NOTSAFEPOINT; // ========================================================================= // // Metrics @@ -138,7 +145,6 @@ JL_DLLEXPORT uint64_t jl_gc_total_hrtime(void); // **must** also set the type of the returning object to be `ty`. The type `ty` may also be used to record // an allocation of that type in the allocation profiler. struct _jl_value_t *jl_gc_alloc_(struct _jl_tls_states_t * ptls, size_t sz, void *ty); - // Allocates small objects and increments Julia allocation counterst. Size of the object // header must be included in the object size. The (possibly unused in some implementations) // offset to the arena in which we're allocating is passed in the second parameter, and the @@ -198,6 +204,10 @@ JL_DLLEXPORT void *jl_gc_perm_alloc(size_t sz, int zero, unsigned align, // the allocated object. All objects stored in fields of this object // must be either permanently allocated or have other roots. struct _jl_value_t *jl_gc_permobj(size_t sz, void *ty) JL_NOTSAFEPOINT; +// This function notifies the GC about memory addresses that are set when loading the boot image. +// The GC may use that information to, for instance, determine that such objects should +// be treated as marked and belonged to the old generation in nursery collections. +void jl_gc_notify_image_load(const char* img_data, size_t len); // ========================================================================= // // Runtime Write-Barriers diff --git a/src/gc-mmtk.c b/src/gc-mmtk.c new file mode 100644 index 0000000000000..78882c8eb0225 --- /dev/null +++ b/src/gc-mmtk.c @@ -0,0 +1,1180 @@ +#include "gc-common.h" +#include "gc-tls-mmtk.h" +#include "mmtkMutator.h" +#include "threading.h" + +// File exists in the binding +#include "mmtk.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// ========================================================================= // +// Julia specific +// ========================================================================= // + +extern jl_value_t *cmpswap_names JL_GLOBALLY_ROOTED; +extern const unsigned pool_sizes[]; +extern jl_mutex_t finalizers_lock; + +// FIXME: Should the values below be shared between both GC's? +// Note that MMTk uses a hard max heap limit, which is set by default +// as 70% of the free available memory. The min heap is set as the +// default_collect_interval variable below. + +// max_total_memory is a suggestion. We try very hard to stay +// under this limit, but we will go above it rather than halting. +#ifdef _P64 +typedef uint64_t memsize_t; +static const size_t default_collect_interval = 5600 * 1024 * sizeof(void*); +// We expose this to the user/ci as jl_gc_set_max_memory +static memsize_t max_total_memory = (memsize_t) 2 * 1024 * 1024 * 1024 * 1024 * 1024; +#else +typedef uint32_t memsize_t; +static const size_t default_collect_interval = 3200 * 1024 * sizeof(void*); +// Work really hard to stay within 2GB +// Alternative is to risk running out of address space +// on 32 bit architectures. +#define MAX32HEAP 1536 * 1024 * 1024 +static memsize_t max_total_memory = (memsize_t) MAX32HEAP; +#endif + +// ========================================================================= // +// Defined by the binding +// ========================================================================= // + +extern void mmtk_julia_copy_stack_check(int copy_stack); +extern void mmtk_gc_init(uintptr_t min_heap_size, uintptr_t max_heap_size, uintptr_t n_gcthreads, uintptr_t header_size, uintptr_t tag); +extern void mmtk_object_reference_write_post(void* mutator, const void* parent, const void* ptr); +extern void mmtk_object_reference_write_slow(void* mutator, const void* parent, const void* ptr); +extern void* mmtk_alloc(void* mutator, size_t size, size_t align, size_t offset, int allocator); +extern void mmtk_post_alloc(void* mutator, void* refer, size_t bytes, int allocator); +extern void mmtk_store_obj_size_c(void* obj, size_t size); +extern const void* MMTK_SIDE_LOG_BIT_BASE_ADDRESS; +extern const void* MMTK_SIDE_VO_BIT_BASE_ADDRESS; + +// ========================================================================= // +// GC Initialization and Control +// ========================================================================= // + +void jl_gc_init(void) { + // TODO: use jl_options.heap_size_hint to set MMTk's fixed heap size? (see issue: https://github.com/mmtk/mmtk-julia/issues/167) + JL_MUTEX_INIT(&finalizers_lock, "finalizers_lock"); + + arraylist_new(&to_finalize, 0); + arraylist_new(&finalizer_list_marked, 0); + + gc_num.allocd = 0; + gc_num.max_pause = 0; + gc_num.max_memory = 0; + + long long min_heap_size; + long long max_heap_size; + char* min_size_def = getenv("MMTK_MIN_HSIZE"); + char* min_size_gb = getenv("MMTK_MIN_HSIZE_G"); + + char* max_size_def = getenv("MMTK_MAX_HSIZE"); + char* max_size_gb = getenv("MMTK_MAX_HSIZE_G"); + + // default min heap currently set as Julia's default_collect_interval + if (min_size_def != NULL) { + char *p; + double min_size = strtod(min_size_def, &p); + min_heap_size = (long) 1024 * 1024 * min_size; + } else if (min_size_gb != NULL) { + char *p; + double min_size = strtod(min_size_gb, &p); + min_heap_size = (long) 1024 * 1024 * 1024 * min_size; + } else { + min_heap_size = default_collect_interval; + } + + // default max heap currently set as 70% the free memory in the system + if (max_size_def != NULL) { + char *p; + double max_size = strtod(max_size_def, &p); + max_heap_size = (long) 1024 * 1024 * max_size; + } else if (max_size_gb != NULL) { + char *p; + double max_size = strtod(max_size_gb, &p); + max_heap_size = (long) 1024 * 1024 * 1024 * max_size; + } else { + max_heap_size = uv_get_free_memory() * 70 / 100; + } + + // Assert that the number of stock GC threads is 0; MMTK uses the number of threads in jl_options.ngcthreads + assert(jl_n_gcthreads == 0); + + // Check that the julia_copy_stack rust feature has been defined when the COPY_STACK has been defined + int copy_stacks; + +#ifdef COPY_STACKS + copy_stacks = 1; +#else + copy_stacks = 0; +#endif + + mmtk_julia_copy_stack_check(copy_stacks); + + // if only max size is specified initialize MMTk with a fixed size heap + // TODO: We just assume mark threads means GC threads, and ignore the number of concurrent sweep threads. + // If the two values are the same, we can use either. Otherwise, we need to be careful. + uintptr_t gcthreads = jl_options.nmarkthreads; + if (max_size_def != NULL || (max_size_gb != NULL && (min_size_def == NULL && min_size_gb == NULL))) { + mmtk_gc_init(0, max_heap_size, gcthreads, (sizeof(jl_taggedvalue_t)), jl_buff_tag); + } else { + mmtk_gc_init(min_heap_size, max_heap_size, gcthreads, (sizeof(jl_taggedvalue_t)), jl_buff_tag); + } +} + +void jl_start_gc_threads(void) { + jl_ptls_t ptls = jl_current_task->ptls; + mmtk_initialize_collection((void *)ptls); +} + +void jl_init_thread_heap(struct _jl_tls_states_t *ptls) JL_NOTSAFEPOINT { + jl_thread_heap_common_t *heap = &ptls->gc_tls_common.heap; + small_arraylist_new(&heap->weak_refs, 0); + small_arraylist_new(&heap->live_tasks, 0); + for (int i = 0; i < JL_N_STACK_POOLS; i++) + small_arraylist_new(&heap->free_stacks[i], 0); + small_arraylist_new(&heap->mallocarrays, 0); + arraylist_new(&ptls->finalizers, 0); + // Initialize `lazily_freed_mtarraylist_buffers` + small_arraylist_new(&ptls->lazily_freed_mtarraylist_buffers, 0); + // Clear the malloc sz count + jl_atomic_store_relaxed(&ptls->gc_tls.malloc_sz_since_last_poll, 0); + // Create mutator + MMTk_Mutator mmtk_mutator = mmtk_bind_mutator((void *)ptls, ptls->tid); + // Copy the mutator to the thread local storage + memcpy(&ptls->gc_tls.mmtk_mutator, mmtk_mutator, sizeof(MMTkMutatorContext)); + // Call post_bind to maintain a list of active mutators and to reclaim the old mutator (which is no longer needed) + mmtk_post_bind_mutator(&ptls->gc_tls.mmtk_mutator, mmtk_mutator); + memset(&ptls->gc_tls_common.gc_num, 0, sizeof(ptls->gc_tls_common.gc_num)); +} + +void jl_free_thread_gc_state(struct _jl_tls_states_t *ptls) { + mmtk_destroy_mutator(&ptls->gc_tls.mmtk_mutator); +} + +JL_DLLEXPORT void jl_gc_set_max_memory(uint64_t max_mem) { + // MMTk currently does not allow setting the heap size at runtime +} + +STATIC_INLINE void maybe_collect(jl_ptls_t ptls) +{ + // Just do a safe point for general maybe_collect + jl_gc_safepoint_(ptls); +} + +// This is only used for malloc. We need to know if we need to do GC. However, keeping checking with MMTk (mmtk_gc_poll), +// is expensive. So we only check for every few allocations. +static inline void malloc_maybe_collect(jl_ptls_t ptls, size_t sz) +{ + // We do not need to carefully maintain malloc_sz_since_last_poll. We just need to + // avoid using mmtk_gc_poll too frequently, and try to be precise on our heap usage + // as much as we can. + if (ptls->gc_tls.malloc_sz_since_last_poll > 4096) { + jl_atomic_store_relaxed(&ptls->gc_tls.malloc_sz_since_last_poll, 0); + mmtk_gc_poll(ptls); + } else { + size_t curr = jl_atomic_load_relaxed(&ptls->gc_tls.malloc_sz_since_last_poll); + jl_atomic_store_relaxed(&ptls->gc_tls.malloc_sz_since_last_poll, curr + sz); + jl_gc_safepoint_(ptls); + } +} + +// This is called when the user calls for a GC with Gc.gc() +JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t collection) { + jl_task_t *ct = jl_current_task; + jl_ptls_t ptls = ct->ptls; + if (jl_atomic_load_acquire(&jl_gc_disable_counter)) { + size_t localbytes = jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + gc_num.interval; + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, -(int64_t)gc_num.interval); + static_assert(sizeof(_Atomic(uint64_t)) == sizeof(gc_num.deferred_alloc), ""); + jl_atomic_fetch_add_relaxed((_Atomic(uint64_t)*)&gc_num.deferred_alloc, localbytes); + return; + } + mmtk_handle_user_collection_request(ptls, collection); +} + + +// Based on jl_gc_collect from gc-stock.c +// called when stopping the thread in `mmtk_block_for_gc` +JL_DLLEXPORT void jl_gc_prepare_to_collect(void) +{ + // FIXME: set to JL_GC_AUTO since we're calling it from mmtk + // maybe just remove this? + JL_PROBE_GC_BEGIN(JL_GC_AUTO); + + jl_task_t *ct = jl_current_task; + jl_ptls_t ptls = ct->ptls; + if (jl_atomic_load_acquire(&jl_gc_disable_counter)) { + size_t localbytes = jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + gc_num.interval; + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, -(int64_t)gc_num.interval); + static_assert(sizeof(_Atomic(uint64_t)) == sizeof(gc_num.deferred_alloc), ""); + jl_atomic_fetch_add_relaxed((_Atomic(uint64_t)*)&gc_num.deferred_alloc, localbytes); + return; + } + + int8_t old_state = jl_atomic_load_relaxed(&ptls->gc_state); + jl_atomic_store_release(&ptls->gc_state, JL_GC_STATE_WAITING); + // `jl_safepoint_start_gc()` makes sure only one thread can run the GC. + uint64_t t0 = jl_hrtime(); + if (!jl_safepoint_start_gc(ct)) { + jl_gc_state_set(ptls, old_state, JL_GC_STATE_WAITING); + jl_safepoint_wait_thread_resume(ct); // block in thread-suspend now if requested, after clearing the gc_state + return; + } + + JL_TIMING_SUSPEND_TASK(GC, ct); + JL_TIMING(GC, GC); + + int last_errno = errno; +#ifdef _OS_WINDOWS_ + DWORD last_error = GetLastError(); +#endif + // Now we are ready to wait for other threads to hit the safepoint, + // we can do a few things that doesn't require synchronization. + // + // We must sync here with the tls_lock operations, so that we have a + // seq-cst order between these events now we know that either the new + // thread must run into our safepoint flag or we must observe the + // existence of the thread in the jl_n_threads count. + // + // TODO: concurrently queue objects + jl_fence(); + gc_n_threads = jl_atomic_load_acquire(&jl_n_threads); + gc_all_tls_states = jl_atomic_load_relaxed(&jl_all_tls_states); + jl_gc_wait_for_the_world(gc_all_tls_states, gc_n_threads); + JL_PROBE_GC_STOP_THE_WORLD(); + + uint64_t t1 = jl_hrtime(); + uint64_t duration = t1 - t0; + if (duration > gc_num.max_time_to_safepoint) + gc_num.max_time_to_safepoint = duration; + gc_num.time_to_safepoint = duration; + gc_num.total_time_to_safepoint += duration; + + if (!jl_atomic_load_acquire(&jl_gc_disable_counter)) { + JL_LOCK_NOGC(&finalizers_lock); // all the other threads are stopped, so this does not make sense, right? otherwise, failing that, this seems like plausibly a deadlock +#ifndef __clang_gcanalyzer__ + mmtk_block_thread_for_gc(); +#endif + JL_UNLOCK_NOGC(&finalizers_lock); + } + + gc_n_threads = 0; + gc_all_tls_states = NULL; + jl_safepoint_end_gc(); + jl_gc_state_set(ptls, old_state, JL_GC_STATE_WAITING); + JL_PROBE_GC_END(); + jl_safepoint_wait_thread_resume(ct); // block in thread-suspend now if requested, after clearing the gc_state + + // Only disable finalizers on current thread + // Doing this on all threads is racy (it's impossible to check + // or wait for finalizers on other threads without dead lock). + if (!ptls->finalizers_inhibited && ptls->locks.len == 0) { + JL_TIMING(GC, GC_Finalizers); + run_finalizers(ct, 0); + } + JL_PROBE_GC_FINALIZER(); + +#ifdef _OS_WINDOWS_ + SetLastError(last_error); +#endif + errno = last_errno; +} + +// ========================================================================= // +// GC Statistics +// ========================================================================= // + +JL_DLLEXPORT const char* jl_gc_active_impl(void) { + const char* mmtk_version = get_mmtk_version(); + return mmtk_version; +} + +int64_t last_gc_total_bytes = 0; +int64_t last_live_bytes = 0; // live_bytes at last collection +int64_t live_bytes = 0; + +// FIXME: The functions combine_thread_gc_counts and reset_thread_gc_counts +// are currently nearly identical for mmtk and for stock. However, the stats +// are likely different (e.g., MMTk doesn't track the bytes allocated in the fastpath, +// but only when the slowpath is called). We might need to adapt these later so that +// the statistics are the same or as close as possible for each GC. +static void combine_thread_gc_counts(jl_gc_num_t *dest, int update_heap) JL_NOTSAFEPOINT +{ + int gc_n_threads; + jl_ptls_t* gc_all_tls_states; + gc_n_threads = jl_atomic_load_acquire(&jl_n_threads); + gc_all_tls_states = jl_atomic_load_relaxed(&jl_all_tls_states); + for (int i = 0; i < gc_n_threads; i++) { + jl_ptls_t ptls = gc_all_tls_states[i]; + if (ptls) { + dest->allocd += (jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + gc_num.interval); + dest->malloc += jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.malloc); + dest->realloc += jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.realloc); + dest->poolalloc += jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.poolalloc); + dest->bigalloc += jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.bigalloc); + dest->freed += jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.free_acc); + if (update_heap) { + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.alloc_acc, 0); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.free_acc, 0); + } + } + } +} + +void reset_thread_gc_counts(void) JL_NOTSAFEPOINT +{ + int gc_n_threads; + jl_ptls_t* gc_all_tls_states; + gc_n_threads = jl_atomic_load_acquire(&jl_n_threads); + gc_all_tls_states = jl_atomic_load_relaxed(&jl_all_tls_states); + for (int i = 0; i < gc_n_threads; i++) { + jl_ptls_t ptls = gc_all_tls_states[i]; + if (ptls != NULL) { + // don't reset `pool_live_bytes` here + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, -(int64_t)gc_num.interval); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.malloc, 0); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.realloc, 0); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.poolalloc, 0); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.bigalloc, 0); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.alloc_acc, 0); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.free_acc, 0); + } + } +} + +// Retrieves Julia's `GC_Num` (structure that stores GC statistics). +JL_DLLEXPORT jl_gc_num_t jl_gc_num(void) { + jl_gc_num_t num = gc_num; + combine_thread_gc_counts(&num, 0); + return num; +} + +JL_DLLEXPORT int64_t jl_gc_diff_total_bytes(void) JL_NOTSAFEPOINT { + int64_t oldtb = last_gc_total_bytes; + int64_t newtb; + jl_gc_get_total_bytes(&newtb); + last_gc_total_bytes = newtb; + return newtb - oldtb; +} + +JL_DLLEXPORT int64_t jl_gc_sync_total_bytes(int64_t offset) JL_NOTSAFEPOINT +{ + int64_t oldtb = last_gc_total_bytes; + int64_t newtb; + jl_gc_get_total_bytes(&newtb); + last_gc_total_bytes = newtb - offset; + return newtb - oldtb; +} + +JL_DLLEXPORT int64_t jl_gc_pool_live_bytes(void) { + return 0; +} + +void jl_gc_count_allocd(size_t sz) JL_NOTSAFEPOINT +{ + jl_ptls_t ptls = jl_current_task->ptls; + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, + jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + sz); +} + +void jl_gc_count_freed(size_t sz) JL_NOTSAFEPOINT +{ +} + +int64_t inc_live_bytes(int64_t inc) JL_NOTSAFEPOINT +{ + jl_timing_counter_inc(JL_TIMING_COUNTER_HeapSize, inc); + return live_bytes += inc; +} + +void jl_gc_reset_alloc_count(void) JL_NOTSAFEPOINT +{ + combine_thread_gc_counts(&gc_num, 0); + inc_live_bytes(gc_num.deferred_alloc + gc_num.allocd); + gc_num.allocd = 0; + gc_num.deferred_alloc = 0; + reset_thread_gc_counts(); +} + +JL_DLLEXPORT int64_t jl_gc_live_bytes(void) { + return last_live_bytes; +} + +JL_DLLEXPORT void jl_gc_get_total_bytes(int64_t *bytes) JL_NOTSAFEPOINT +{ + jl_gc_num_t num = gc_num; + combine_thread_gc_counts(&num, 0); + // Sync this logic with `base/util.jl:GC_Diff` + *bytes = (num.total_allocd + num.deferred_alloc + num.allocd); +} + +JL_DLLEXPORT uint64_t jl_gc_get_max_memory(void) +{ + // FIXME: should probably return MMTk's heap size + return max_total_memory; +} + +// These are needed to collect MMTk statistics from a Julia program using ccall +JL_DLLEXPORT void (jl_mmtk_harness_begin)(void) +{ + jl_ptls_t ptls = jl_current_task->ptls; + mmtk_harness_begin(ptls); +} + +JL_DLLEXPORT void (jl_mmtk_harness_end)(void) +{ + mmtk_harness_end(); +} + +// ========================================================================= // +// Root Processing, Object Scanning and Julia-specific sweeping +// ========================================================================= // + +static void add_node_to_roots_buffer(RootsWorkClosure* closure, RootsWorkBuffer* buf, size_t* buf_len, void* root) { + if (root == NULL) + return; + + buf->ptr[*buf_len] = root; + *buf_len += 1; + if (*buf_len >= buf->cap) { + RootsWorkBuffer new_buf = (closure->report_nodes_func)(buf->ptr, *buf_len, buf->cap, closure->data, true); + *buf = new_buf; + *buf_len = 0; + } +} + +static void add_node_to_tpinned_roots_buffer(RootsWorkClosure* closure, RootsWorkBuffer* buf, size_t* buf_len, void* root) { + if (root == NULL) + return; + + buf->ptr[*buf_len] = root; + *buf_len += 1; + if (*buf_len >= buf->cap) { + RootsWorkBuffer new_buf = (closure->report_tpinned_nodes_func)(buf->ptr, *buf_len, buf->cap, closure->data, true); + *buf = new_buf; + *buf_len = 0; + } +} + +JL_DLLEXPORT void jl_gc_scan_vm_specific_roots(RootsWorkClosure* closure) +{ + // Create a new buf + RootsWorkBuffer buf = (closure->report_nodes_func)((void**)0, 0, 0, closure->data, true); + size_t len = 0; + + // add module + add_node_to_roots_buffer(closure, &buf, &len, jl_main_module); + + // buildin values + add_node_to_roots_buffer(closure, &buf, &len, jl_an_empty_vec_any); + add_node_to_roots_buffer(closure, &buf, &len, jl_module_init_order); + for (size_t i = 0; i < jl_current_modules.size; i += 2) { + if (jl_current_modules.table[i + 1] != HT_NOTFOUND) { + add_node_to_roots_buffer(closure, &buf, &len, jl_current_modules.table[i]); + } + } + add_node_to_roots_buffer(closure, &buf, &len, jl_anytuple_type_type); + for (size_t i = 0; i < N_CALL_CACHE; i++) { + jl_typemap_entry_t *v = jl_atomic_load_relaxed(&call_cache[i]); + add_node_to_roots_buffer(closure, &buf, &len, v); + } + add_node_to_roots_buffer(closure, &buf, &len, _jl_debug_method_invalidation); + + // constants + add_node_to_roots_buffer(closure, &buf, &len, jl_emptytuple_type); + add_node_to_roots_buffer(closure, &buf, &len, cmpswap_names); + + // jl_global_roots_table must be transitively pinned + RootsWorkBuffer tpinned_buf = (closure->report_tpinned_nodes_func)((void**)0, 0, 0, closure->data, true); + size_t tpinned_len = 0; + add_node_to_tpinned_roots_buffer(closure, &tpinned_buf, &tpinned_len, jl_global_roots_list); + add_node_to_tpinned_roots_buffer(closure, &tpinned_buf, &tpinned_len, jl_global_roots_keyset); + + // Push the result of the work. + (closure->report_nodes_func)(buf.ptr, len, buf.cap, closure->data, false); + (closure->report_tpinned_nodes_func)(tpinned_buf.ptr, tpinned_len, tpinned_buf.cap, closure->data, false); +} + +JL_DLLEXPORT void jl_gc_scan_julia_exc_obj(void* obj_raw, void* closure, ProcessSlotFn process_slot) { + jl_task_t *ta = (jl_task_t*)obj_raw; + + if (ta->excstack) { // inlining label `excstack` from mark_loop + + // the excstack should always be a heap object + assert(mmtk_object_is_managed_by_mmtk(ta->excstack)); + + process_slot(closure, &ta->excstack); + jl_excstack_t *excstack = ta->excstack; + size_t itr = ta->excstack->top; + size_t bt_index = 0; + size_t jlval_index = 0; + while (itr > 0) { + size_t bt_size = jl_excstack_bt_size(excstack, itr); + jl_bt_element_t *bt_data = jl_excstack_bt_data(excstack, itr); + for (; bt_index < bt_size; bt_index += jl_bt_entry_size(bt_data + bt_index)) { + jl_bt_element_t *bt_entry = bt_data + bt_index; + if (jl_bt_is_native(bt_entry)) + continue; + // Found an extended backtrace entry: iterate over any + // GC-managed values inside. + size_t njlvals = jl_bt_num_jlvals(bt_entry); + while (jlval_index < njlvals) { + jl_value_t** new_obj_slot = &bt_entry[2 + jlval_index].jlvalue; + jlval_index += 1; + process_slot(closure, new_obj_slot); + } + jlval_index = 0; + } + + jl_bt_element_t *stack_raw = (jl_bt_element_t *)(excstack+1); + jl_value_t** stack_obj_slot = &stack_raw[itr-1].jlvalue; + + itr = jl_excstack_next(excstack, itr); + bt_index = 0; + jlval_index = 0; + process_slot(closure, stack_obj_slot); + } + } +} + +// This is used in mmtk_sweep_malloced_memory and it is slightly different +// from jl_gc_free_memory from gc-stock.c as the stock GC updates the +// information in the global variable gc_heap_stats (which is specific to the stock GC) +static void jl_gc_free_memory(jl_genericmemory_t *m, int isaligned) JL_NOTSAFEPOINT +{ + assert(jl_is_genericmemory(m)); + assert(jl_genericmemory_how(m) == 1 || jl_genericmemory_how(m) == 2); + char *d = (char*)m->ptr; + size_t freed_bytes = memory_block_usable_size(d, isaligned); + assert(freed_bytes != 0); + if (isaligned) + jl_free_aligned(d); + else + free(d); + gc_num.freed += freed_bytes; + gc_num.freecall++; +} + +JL_DLLEXPORT void jl_gc_mmtk_sweep_malloced_memory(void) JL_NOTSAFEPOINT +{ + void* iter = mmtk_new_mutator_iterator(); + jl_ptls_t ptls2 = (jl_ptls_t)mmtk_get_next_mutator_tls(iter); + while(ptls2 != NULL) { + size_t n = 0; + size_t l = ptls2->gc_tls_common.heap.mallocarrays.len; + void **lst = ptls2->gc_tls_common.heap.mallocarrays.items; + // filter without preserving order + while (n < l) { + jl_genericmemory_t *m = (jl_genericmemory_t*)((uintptr_t)lst[n] & ~1); + if (mmtk_is_live_object(m)) { + n++; + } + else { + int isaligned = (uintptr_t)lst[n] & 1; + jl_gc_free_memory(m, isaligned); + l--; + lst[n] = lst[l]; + } + } + ptls2->gc_tls_common.heap.mallocarrays.len = l; + ptls2 = (jl_ptls_t)mmtk_get_next_mutator_tls(iter); + } + mmtk_close_mutator_iterator(iter); +} + +#define jl_genericmemory_elsize(a) (((jl_datatype_t*)jl_typetagof(a))->layout->size) + +// if data is inlined inside the genericmemory object --- to->ptr needs to be updated when copying the array +JL_DLLEXPORT void jl_gc_update_inlined_array(void* from, void* to) { + jl_value_t* jl_from = (jl_value_t*) from; + jl_value_t* jl_to = (jl_value_t*) to; + + uintptr_t tag_to = (uintptr_t)jl_typeof(jl_to); + jl_datatype_t *vt = (jl_datatype_t*)tag_to; + + if(vt->name == jl_genericmemory_typename) { + jl_genericmemory_t *a = (jl_genericmemory_t*)jl_from; + jl_genericmemory_t *b = (jl_genericmemory_t*)jl_to; + int how = jl_genericmemory_how(a); + + if (how == 0 && mmtk_object_is_managed_by_mmtk(a->ptr)) { // a is inlined (a->ptr points into the mmtk object) + size_t offset_of_data = ((size_t)a->ptr - (size_t)a); + if (offset_of_data > 0) { + b->ptr = (void*)((size_t) b + offset_of_data); + } + } + } +} + +// modified sweep_stack_pools from gc-stacks.c +JL_DLLEXPORT void jl_gc_mmtk_sweep_stack_pools(void) +{ + // Stack sweeping algorithm: + // // deallocate stacks if we have too many sitting around unused + // for (stk in halfof(free_stacks)) + // free_stack(stk, pool_sz); + // // then sweep the task stacks + // for (t in live_tasks) + // if (!gc-marked(t)) + // stkbuf = t->stkbuf + // bufsz = t->bufsz + // if (stkbuf) + // push(free_stacks[sz], stkbuf) + assert(gc_n_threads); + for (int i = 0; i < jl_n_threads; i++) { + jl_ptls_t ptls2 = gc_all_tls_states[i]; + if (ptls2 == NULL) + continue; + + // free half of stacks that remain unused since last sweep + for (int p = 0; p < JL_N_STACK_POOLS; p++) { + small_arraylist_t *al = &ptls2->gc_tls_common.heap.free_stacks[p]; + size_t n_to_free; + if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { + n_to_free = al->len; // not alive yet or dead, so it does not need these anymore + } + else if (al->len > MIN_STACK_MAPPINGS_PER_POOL) { + n_to_free = al->len / 2; + if (n_to_free > (al->len - MIN_STACK_MAPPINGS_PER_POOL)) + n_to_free = al->len - MIN_STACK_MAPPINGS_PER_POOL; + } + else { + n_to_free = 0; + } + for (int n = 0; n < n_to_free; n++) { + void *stk = small_arraylist_pop(al); + free_stack(stk, pool_sizes[p]); + } + if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { + small_arraylist_free(al); + } + } + if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { + small_arraylist_free(ptls2->gc_tls_common.heap.free_stacks); + } + + small_arraylist_t *live_tasks = &ptls2->gc_tls_common.heap.live_tasks; + size_t n = 0; + size_t ndel = 0; + size_t l = live_tasks->len; + void **lst = live_tasks->items; + if (l == 0) + continue; + while (1) { + jl_task_t *t = (jl_task_t*)lst[n]; + if (mmtk_is_live_object(t)) { + jl_task_t *maybe_forwarded = (jl_task_t*)mmtk_get_possibly_forwarded(t); + live_tasks->items[n] = maybe_forwarded; + t = maybe_forwarded; + assert(jl_is_task(t)); + if (t->ctx.stkbuf == NULL) + ndel++; // jl_release_task_stack called + else + n++; + } else { + ndel++; + void *stkbuf = t->ctx.stkbuf; + size_t bufsz = t->ctx.bufsz; + if (stkbuf) { + t->ctx.stkbuf = NULL; + _jl_free_stack(ptls2, stkbuf, bufsz); + } +#ifdef _COMPILER_TSAN_ENABLED_ + if (t->ctx.tsan_state) { + __tsan_destroy_fiber(t->ctx.tsan_state); + t->ctx.tsan_state = NULL; + } +#endif + } + if (n >= l - ndel) + break; + void *tmp = lst[n]; + lst[n] = lst[n + ndel]; + lst[n + ndel] = tmp; + } + live_tasks->len -= ndel; + } +} + +JL_DLLEXPORT void jl_gc_sweep_stack_pools_and_mtarraylist_buffers(jl_ptls_t ptls) JL_NOTSAFEPOINT +{ + jl_gc_mmtk_sweep_stack_pools(); + sweep_mtarraylist_buffers(); +} + +JL_DLLEXPORT void* jl_gc_get_stackbase(int16_t tid) { + assert(tid >= 0); + jl_ptls_t ptls2 = jl_all_tls_states[tid]; + return ptls2->stackbase; +} + +JL_DLLEXPORT void jl_gc_update_stats(uint64_t inc, size_t mmtk_live_bytes, bool is_nursery_gc) { + gc_num.total_time += inc; + gc_num.pause += 1; + gc_num.full_sweep += !(is_nursery_gc); + gc_num.total_allocd += gc_num.allocd; + gc_num.allocd = 0; + live_bytes = mmtk_live_bytes; +} + +#define jl_genericmemory_data_owner_field_addr(a) ((jl_value_t**)((jl_genericmemory_t*)(a) + 1)) + +JL_DLLEXPORT void* jl_gc_get_owner_address_to_mmtk(void* m) { + return (void*)jl_genericmemory_data_owner_field_addr(m); +} + +// same as jl_genericmemory_how but with JL_DLLEXPORT +// we should probably inline this in Rust +JL_DLLEXPORT size_t jl_gc_genericmemory_how(void *arg) JL_NOTSAFEPOINT +{ + jl_genericmemory_t* m = (jl_genericmemory_t*)arg; + if (m->ptr == (void*)((char*)m + 16)) // JL_SMALL_BYTE_ALIGNMENT (from julia_internal.h) + return 0; + jl_value_t *owner = jl_genericmemory_data_owner_field(m); + if (owner == (jl_value_t*)m) + return 1; + if (owner == NULL) + return 2; + return 3; +} + +// ========================================================================= // +// Weak References and Finalizers +// ========================================================================= // + +JL_DLLEXPORT jl_weakref_t *jl_gc_new_weakref_th(jl_ptls_t ptls, jl_value_t *value) +{ + jl_weakref_t *wr = (jl_weakref_t*)jl_gc_alloc(ptls, sizeof(void*), jl_weakref_type); + wr->value = value; // NOTE: wb not needed here + mmtk_add_weak_candidate(wr); + return wr; +} + +JL_DLLEXPORT void* jl_gc_get_thread_finalizer_list(void* ptls_raw) { + jl_ptls_t ptls = (jl_ptls_t) ptls_raw; + return (void*)&ptls->finalizers; +} + +JL_DLLEXPORT void* jl_gc_get_to_finalize_list(void) { + return (void*)&to_finalize; +} + +JL_DLLEXPORT void* jl_gc_get_marked_finalizers_list(void) { + return (void*)&finalizer_list_marked; +} + +JL_DLLEXPORT int* jl_gc_get_have_pending_finalizers(void) { + return (int*)&jl_gc_have_pending_finalizers; +} + +// ========================================================================= // +// Allocation +// ========================================================================= // + +#define MMTK_DEFAULT_IMMIX_ALLOCATOR (0) +#define MMTK_IMMORTAL_BUMP_ALLOCATOR (0) + +int jl_gc_classify_pools(size_t sz, int *osize) +{ + if (sz > GC_MAX_SZCLASS) + return -1; // call big alloc function + size_t allocsz = sz + sizeof(jl_taggedvalue_t); + *osize = LLT_ALIGN(allocsz, 16); + return 0; // use MMTk's fastpath logic +} + +#define MMTK_MIN_ALIGNMENT 4 +// MMTk assumes allocation size is aligned to min alignment. +STATIC_INLINE size_t mmtk_align_alloc_sz(size_t sz) JL_NOTSAFEPOINT +{ + return (sz + MMTK_MIN_ALIGNMENT - 1) & ~(MMTK_MIN_ALIGNMENT - 1); +} + +STATIC_INLINE void* bump_alloc_fast(MMTkMutatorContext* mutator, uintptr_t* cursor, uintptr_t limit, size_t size, size_t align, size_t offset, int allocator) { + intptr_t delta = (-offset - *cursor) & (align - 1); + uintptr_t result = *cursor + (uintptr_t)delta; + + if (__unlikely(result + size > limit)) { + return (void*) mmtk_alloc(mutator, size, align, offset, allocator); + } else{ + *cursor = result + size; + return (void*)result; + } +} + +STATIC_INLINE void* mmtk_immix_alloc_fast(MMTkMutatorContext* mutator, size_t size, size_t align, size_t offset) { + ImmixAllocator* allocator = &mutator->allocators.immix[MMTK_DEFAULT_IMMIX_ALLOCATOR]; + return bump_alloc_fast(mutator, (uintptr_t*)&allocator->cursor, (intptr_t)allocator->limit, size, align, offset, 0); +} + +inline void mmtk_immix_post_alloc_slow(MMTkMutatorContext* mutator, void* obj, size_t size) { + mmtk_post_alloc(mutator, obj, size, 0); +} + +STATIC_INLINE void mmtk_immix_post_alloc_fast(MMTkMutatorContext* mutator, void* obj, size_t size) { + // FIXME: for now, we do nothing + // but when supporting moving, this is where we set the valid object (VO) bit +} + +STATIC_INLINE void* mmtk_immortal_alloc_fast(MMTkMutatorContext* mutator, size_t size, size_t align, size_t offset) { + BumpAllocator* allocator = &mutator->allocators.bump_pointer[MMTK_IMMORTAL_BUMP_ALLOCATOR]; + return bump_alloc_fast(mutator, (uintptr_t*)&allocator->cursor, (uintptr_t)allocator->limit, size, align, offset, 1); +} + +STATIC_INLINE void mmtk_immortal_post_alloc_fast(MMTkMutatorContext* mutator, void* obj, size_t size) { + // FIXME: Similarly, for now, we do nothing + // but when supporting moving, this is where we set the valid object (VO) bit + // and log (old gen) bit +} + +JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_default(jl_ptls_t ptls, int osize, size_t align, void *ty) +{ + // safepoint + jl_gc_safepoint_(ptls); + + jl_value_t *v; + if ((uintptr_t)ty != jl_buff_tag) { + // v needs to be 16 byte aligned, therefore v_tagged needs to be offset accordingly to consider the size of header + jl_taggedvalue_t *v_tagged = (jl_taggedvalue_t *)mmtk_immix_alloc_fast(&ptls->gc_tls.mmtk_mutator, LLT_ALIGN(osize, align), align, sizeof(jl_taggedvalue_t)); + v = jl_valueof(v_tagged); + mmtk_immix_post_alloc_fast(&ptls->gc_tls.mmtk_mutator, v, LLT_ALIGN(osize, align)); + } else { + // allocating an extra word to store the size of buffer objects + jl_taggedvalue_t *v_tagged = (jl_taggedvalue_t *)mmtk_immix_alloc_fast(&ptls->gc_tls.mmtk_mutator, LLT_ALIGN(osize+sizeof(jl_taggedvalue_t), align), align, 0); + jl_value_t* v_tagged_aligned = ((jl_value_t*)((char*)(v_tagged) + sizeof(jl_taggedvalue_t))); + v = jl_valueof(v_tagged_aligned); + mmtk_store_obj_size_c(v, LLT_ALIGN(osize+sizeof(jl_taggedvalue_t), align)); + mmtk_immix_post_alloc_fast(&ptls->gc_tls.mmtk_mutator, v, LLT_ALIGN(osize+sizeof(jl_taggedvalue_t), align)); + } + + ptls->gc_tls_common.gc_num.allocd += osize; + ptls->gc_tls_common.gc_num.poolalloc++; + + return v; +} + +JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_big(jl_ptls_t ptls, size_t sz) +{ + // safepoint + jl_gc_safepoint_(ptls); + + size_t offs = offsetof(bigval_t, header); + assert(sz >= sizeof(jl_taggedvalue_t) && "sz must include tag"); + static_assert(offsetof(bigval_t, header) >= sizeof(void*), "Empty bigval header?"); + static_assert(sizeof(bigval_t) % JL_HEAP_ALIGNMENT == 0, ""); + size_t allocsz = LLT_ALIGN(sz + offs, JL_CACHE_BYTE_ALIGNMENT); + if (allocsz < sz) { // overflow in adding offs, size was "negative" + assert(0 && "Error when allocating big object"); + jl_throw(jl_memory_exception); + } + + bigval_t *v = (bigval_t*)mmtk_alloc_large(&ptls->gc_tls.mmtk_mutator, allocsz, JL_CACHE_BYTE_ALIGNMENT, 0, 2); + + if (v == NULL) { + assert(0 && "Allocation failed"); + jl_throw(jl_memory_exception); + } + v->sz = allocsz; + + ptls->gc_tls_common.gc_num.allocd += allocsz; + ptls->gc_tls_common.gc_num.bigalloc++; + + jl_value_t *result = jl_valueof(&v->header); + mmtk_post_alloc(&ptls->gc_tls.mmtk_mutator, result, allocsz, 2); + + return result; +} + +// Instrumented version of jl_gc_small_alloc_inner, called into by LLVM-generated code. +JL_DLLEXPORT jl_value_t *jl_gc_small_alloc(jl_ptls_t ptls, int offset, int osize, jl_value_t* type) +{ + assert(jl_atomic_load_relaxed(&ptls->gc_state) == 0); + + jl_value_t *val = jl_mmtk_gc_alloc_default(ptls, osize, 16, NULL); + maybe_record_alloc_to_profile(val, osize, (jl_datatype_t*)type); + return val; +} + +// Instrumented version of jl_gc_big_alloc_inner, called into by LLVM-generated code. +JL_DLLEXPORT jl_value_t *jl_gc_big_alloc(jl_ptls_t ptls, size_t sz, jl_value_t *type) +{ + // TODO: assertion needed here? + assert(jl_atomic_load_relaxed(&ptls->gc_state) == 0); + + jl_value_t *val = jl_mmtk_gc_alloc_big(ptls, sz); + maybe_record_alloc_to_profile(val, sz, (jl_datatype_t*)type); + return val; +} + +inline jl_value_t *jl_gc_alloc_(jl_ptls_t ptls, size_t sz, void *ty) +{ + jl_value_t *v; + const size_t allocsz = sz + sizeof(jl_taggedvalue_t); + if (sz <= GC_MAX_SZCLASS) { + v = jl_mmtk_gc_alloc_default(ptls, allocsz, 16, ty); + } + else { + if (allocsz < sz) // overflow in adding offs, size was "negative" + jl_throw(jl_memory_exception); + v = jl_mmtk_gc_alloc_big(ptls, allocsz); + } + jl_set_typeof(v, ty); + maybe_record_alloc_to_profile(v, sz, (jl_datatype_t*)ty); + return v; +} + +// allocation wrappers that track allocation and let collection run +JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz) +{ + jl_gcframe_t **pgcstack = jl_get_pgcstack(); + jl_task_t *ct = jl_current_task; + void *data = malloc(sz); + if (data != NULL && pgcstack != NULL && ct->world_age) { + jl_ptls_t ptls = ct->ptls; + malloc_maybe_collect(ptls, sz); + jl_atomic_fetch_add_relaxed(&JULIA_MALLOC_BYTES, sz); + } + return data; +} + +JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz) +{ + jl_gcframe_t **pgcstack = jl_get_pgcstack(); + jl_task_t *ct = jl_current_task; + void *data = calloc(nm, sz); + if (data != NULL && pgcstack != NULL && ct->world_age) { + jl_ptls_t ptls = ct->ptls; + malloc_maybe_collect(ptls, nm * sz); + jl_atomic_fetch_add_relaxed(&JULIA_MALLOC_BYTES, nm * sz); + } + return data; +} + +JL_DLLEXPORT void jl_gc_counted_free_with_size(void *p, size_t sz) +{ + jl_gcframe_t **pgcstack = jl_get_pgcstack(); + jl_task_t *ct = jl_current_task; + free(p); + if (pgcstack != NULL && ct->world_age) { + jl_atomic_fetch_add_relaxed(&JULIA_MALLOC_BYTES, -sz); + } +} + +JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size_t sz) +{ + jl_gcframe_t **pgcstack = jl_get_pgcstack(); + jl_task_t *ct = jl_current_task; + if (pgcstack && ct->world_age) { + jl_ptls_t ptls = ct->ptls; + malloc_maybe_collect(ptls, sz); + if (sz < old) + jl_atomic_fetch_add_relaxed(&JULIA_MALLOC_BYTES, old - sz); + else + jl_atomic_fetch_add_relaxed(&JULIA_MALLOC_BYTES, sz - old); + } + return realloc(p, sz); +} + +void *jl_gc_perm_alloc_nolock(size_t sz, int zero, unsigned align, unsigned offset) +{ + jl_ptls_t ptls = jl_current_task->ptls; + size_t allocsz = mmtk_align_alloc_sz(sz); + void* addr = mmtk_immortal_alloc_fast(&ptls->gc_tls.mmtk_mutator, allocsz, align, offset); + return addr; +} + +void *jl_gc_perm_alloc(size_t sz, int zero, unsigned align, unsigned offset) +{ + return jl_gc_perm_alloc_nolock(sz, zero, align, offset); +} + +jl_value_t *jl_gc_permobj(size_t sz, void *ty) JL_NOTSAFEPOINT +{ + const size_t allocsz = sz + sizeof(jl_taggedvalue_t); + unsigned align = (sz == 0 ? sizeof(void*) : (allocsz <= sizeof(void*) * 2 ? + sizeof(void*) * 2 : 16)); + jl_taggedvalue_t *o = (jl_taggedvalue_t*)jl_gc_perm_alloc(allocsz, 0, align, + sizeof(void*) % align); + + jl_ptls_t ptls = jl_current_task->ptls; + mmtk_immortal_post_alloc_fast(&ptls->gc_tls.mmtk_mutator, jl_valueof(o), allocsz); + o->header = (uintptr_t)ty; + return jl_valueof(o); +} + +JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz) +{ + jl_ptls_t ptls = jl_current_task->ptls; + maybe_collect(ptls); + size_t allocsz = LLT_ALIGN(sz, JL_CACHE_BYTE_ALIGNMENT); + if (allocsz < sz) // overflow in adding offs, size was "negative" + jl_throw(jl_memory_exception); + + int last_errno = errno; +#ifdef _OS_WINDOWS_ + DWORD last_error = GetLastError(); +#endif + void *b = malloc_cache_align(allocsz); + if (b == NULL) + jl_throw(jl_memory_exception); + + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, + jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + allocsz); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.malloc, + jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.malloc) + 1); + // FIXME: Should these be part of mmtk's heap? + // malloc_maybe_collect(ptls, sz); + // jl_atomic_fetch_add_relaxed(&JULIA_MALLOC_BYTES, allocsz); +#ifdef _OS_WINDOWS_ + SetLastError(last_error); +#endif + errno = last_errno; + // jl_gc_managed_malloc is currently always used for allocating array buffers. + maybe_record_alloc_to_profile((jl_value_t*)b, sz, (jl_datatype_t*)jl_buff_tag); + return b; +} + +void jl_gc_notify_image_load(const char* img_data, size_t len) +{ + mmtk_set_vm_space((void*)img_data, len); +} + +// ========================================================================= // +// Code specific to stock that is not supported by MMTk +// ========================================================================= // + +// mutex for page profile +uv_mutex_t page_profile_lock; + +JL_DLLEXPORT void jl_gc_take_page_profile(ios_t *stream) +{ + uv_mutex_lock(&page_profile_lock); + const char *str = "Page profiler in unsupported in MMTk."; + ios_write(stream, str, strlen(str)); + uv_mutex_unlock(&page_profile_lock); +} + +// this seems to be needed by the gc tests +#define JL_GC_N_MAX_POOLS 51 +JL_DLLEXPORT double jl_gc_page_utilization_stats[JL_GC_N_MAX_POOLS]; + +STATIC_INLINE void gc_dump_page_utilization_data(void) JL_NOTSAFEPOINT +{ + // FIXME: MMTk would have to provide its own stats +} + +#define MMTK_GC_PAGE_SZ (1 << 12) // MMTk's page size is defined in mmtk-core constants + +JL_DLLEXPORT uint64_t jl_get_pg_size(void) +{ + return MMTK_GC_PAGE_SZ; +} + +// Not used by mmtk +// Number of GC threads that may run parallel marking +int jl_n_markthreads; +// Number of GC threads that may run concurrent sweeping (0 or 1) +int jl_n_sweepthreads; +// `tid` of first GC thread +int gc_first_tid; +// Number of threads sweeping stacks +_Atomic(int) gc_n_threads_sweeping_stacks; +// counter for sharing work when sweeping stacks +_Atomic(int) gc_ptls_sweep_idx; +// counter for round robin of giving back stack pages to the OS +_Atomic(int) gc_stack_free_idx = 0; + +JL_DLLEXPORT void jl_gc_queue_root(const struct _jl_value_t *ptr) JL_NOTSAFEPOINT +{ + mmtk_unreachable(); +} + +JL_DLLEXPORT void jl_gc_queue_multiroot(const struct _jl_value_t *root, const void *stored, + struct _jl_datatype_t *dt) JL_NOTSAFEPOINT +{ + mmtk_unreachable(); +} + +JL_DLLEXPORT int jl_gc_mark_queue_obj(jl_ptls_t ptls, jl_value_t *obj) +{ + mmtk_unreachable(); + return 0; +} + +JL_DLLEXPORT void jl_gc_mark_queue_objarray(jl_ptls_t ptls, jl_value_t *parent, + jl_value_t **objs, size_t nobjs) +{ + mmtk_unreachable(); +} + +JL_DLLEXPORT size_t jl_gc_max_internal_obj_size(void) +{ + // TODO: meaningful for MMTk? + return GC_MAX_SZCLASS; +} + +JL_DLLEXPORT void jl_gc_schedule_foreign_sweepfunc(jl_ptls_t ptls, jl_value_t *obj) +{ + // FIXME: do we need to implement this? +} + +// gc-debug functions +JL_DLLEXPORT jl_taggedvalue_t *jl_gc_find_taggedvalue_pool(char *p, size_t *osize_p) +{ + return NULL; +} + +void jl_gc_debug_critical_error(void) JL_NOTSAFEPOINT +{ +} + +int gc_is_collector_thread(int tid) JL_NOTSAFEPOINT +{ + return 0; +} + +void jl_gc_debug_print_status(void) JL_NOTSAFEPOINT +{ + // May not be accurate but should be helpful enough + uint64_t pool_count = gc_num.poolalloc; + uint64_t big_count = gc_num.bigalloc; + jl_safe_printf("Allocations: %" PRIu64 " " + "(Pool: %" PRIu64 "; Big: %" PRIu64 "); GC: %d\n", + pool_count + big_count, pool_count, big_count, gc_num.pause); +} + +JL_DLLEXPORT size_t jl_gc_external_obj_hdr_size(void) +{ + return sizeof(bigval_t); +} + +void jl_print_gc_stats(JL_STREAM *s) +{ +} + +JL_DLLEXPORT int jl_gc_enable_conservative_gc_support(void) +{ + return 0; +} + +JL_DLLEXPORT int jl_gc_conservative_gc_support_enabled(void) +{ + return 0; +} + +// TODO: if this is needed, it can be added in MMTk +JL_DLLEXPORT jl_value_t *jl_gc_internal_obj_base_ptr(void *p) +{ + return NULL; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/gc-stacks.c b/src/gc-stacks.c index a0ca2561c5cf9..9387c7fb065ec 100644 --- a/src/gc-stacks.c +++ b/src/gc-stacks.c @@ -1,7 +1,6 @@ // This file is a part of Julia. License is MIT: https://julialang.org/license #include "gc-common.h" -#include "gc-stock.h" #include "threading.h" #ifndef _OS_WINDOWS_ # include @@ -21,9 +20,6 @@ # endif #endif -// number of stacks to always keep available per pool -#define MIN_STACK_MAPPINGS_PER_POOL 5 - const size_t jl_guard_size = (4096 * 8); static _Atomic(uint32_t) num_stack_mappings = 0; @@ -203,99 +199,6 @@ JL_DLLEXPORT void *jl_malloc_stack(size_t *bufsz, jl_task_t *owner) JL_NOTSAFEPO return stk; } -void sweep_stack_pool_loop(void) JL_NOTSAFEPOINT -{ - // Stack sweeping algorithm: - // // deallocate stacks if we have too many sitting around unused - // for (stk in halfof(free_stacks)) - // free_stack(stk, pool_sz); - // // then sweep the task stacks - // for (t in live_tasks) - // if (!gc-marked(t)) - // stkbuf = t->stkbuf - // bufsz = t->bufsz - // if (stkbuf) - // push(free_stacks[sz], stkbuf) - jl_atomic_fetch_add(&gc_n_threads_sweeping_stacks, 1); - while (1) { - int i = jl_atomic_fetch_add_relaxed(&gc_ptls_sweep_idx, -1); - if (i < 0) - break; - jl_ptls_t ptls2 = gc_all_tls_states[i]; - if (ptls2 == NULL) - continue; - assert(gc_n_threads); - // free half of stacks that remain unused since last sweep - if (i == jl_atomic_load_relaxed(&gc_stack_free_idx)) { - for (int p = 0; p < JL_N_STACK_POOLS; p++) { - small_arraylist_t *al = &ptls2->gc_tls_common.heap.free_stacks[p]; - size_t n_to_free; - if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { - n_to_free = al->len; // not alive yet or dead, so it does not need these anymore - } - else if (al->len > MIN_STACK_MAPPINGS_PER_POOL) { - n_to_free = al->len / 2; - if (n_to_free > (al->len - MIN_STACK_MAPPINGS_PER_POOL)) - n_to_free = al->len - MIN_STACK_MAPPINGS_PER_POOL; - } - else { - n_to_free = 0; - } - for (int n = 0; n < n_to_free; n++) { - void *stk = small_arraylist_pop(al); - free_stack(stk, pool_sizes[p]); - } - if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { - small_arraylist_free(al); - } - } - } - if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { - small_arraylist_free(ptls2->gc_tls_common.heap.free_stacks); - } - - small_arraylist_t *live_tasks = &ptls2->gc_tls_common.heap.live_tasks; - size_t n = 0; - size_t ndel = 0; - size_t l = live_tasks->len; - void **lst = live_tasks->items; - if (l == 0) - continue; - while (1) { - jl_task_t *t = (jl_task_t*)lst[n]; - assert(jl_is_task(t)); - if (gc_marked(jl_astaggedvalue(t)->bits.gc)) { - if (t->ctx.stkbuf == NULL) - ndel++; // jl_release_task_stack called - else - n++; - } - else { - ndel++; - void *stkbuf = t->ctx.stkbuf; - size_t bufsz = t->ctx.bufsz; - if (stkbuf) { - t->ctx.stkbuf = NULL; - _jl_free_stack(ptls2, stkbuf, bufsz); - } -#ifdef _COMPILER_TSAN_ENABLED_ - if (t->ctx.tsan_state) { - __tsan_destroy_fiber(t->ctx.tsan_state); - t->ctx.tsan_state = NULL; - } -#endif - } - if (n >= l - ndel) - break; - void *tmp = lst[n]; - lst[n] = lst[n + ndel]; - lst[n + ndel] = tmp; - } - live_tasks->len -= ndel; - } - jl_atomic_fetch_add(&gc_n_threads_sweeping_stacks, -1); -} - // Builds a list of the live tasks. Racy: `live_tasks` can expand at any time. arraylist_t *jl_get_all_tasks_arraylist(void) JL_NOTSAFEPOINT { diff --git a/src/gc-stock.c b/src/gc-stock.c index 1f6b58d71da3a..d2d9104ad8d22 100644 --- a/src/gc-stock.c +++ b/src/gc-stock.c @@ -1013,22 +1013,102 @@ void gc_sweep_wait_for_all_stacks(void) JL_NOTSAFEPOINT } } -void sweep_mtarraylist_buffers(void) JL_NOTSAFEPOINT -{ - for (int i = 0; i < gc_n_threads; i++) { - jl_ptls_t ptls = gc_all_tls_states[i]; - if (ptls == NULL) { +extern const unsigned pool_sizes[]; + +void sweep_stack_pool_loop(void) JL_NOTSAFEPOINT +{ + // Stack sweeping algorithm: + // // deallocate stacks if we have too many sitting around unused + // for (stk in halfof(free_stacks)) + // free_stack(stk, pool_sz); + // // then sweep the task stacks + // for (t in live_tasks) + // if (!gc-marked(t)) + // stkbuf = t->stkbuf + // bufsz = t->bufsz + // if (stkbuf) + // push(free_stacks[sz], stkbuf) + jl_atomic_fetch_add(&gc_n_threads_sweeping_stacks, 1); + while (1) { + int i = jl_atomic_fetch_add_relaxed(&gc_ptls_sweep_idx, -1); + if (i < 0) + break; + jl_ptls_t ptls2 = gc_all_tls_states[i]; + if (ptls2 == NULL) continue; + assert(gc_n_threads); + // free half of stacks that remain unused since last sweep + if (i == jl_atomic_load_relaxed(&gc_stack_free_idx)) { + for (int p = 0; p < JL_N_STACK_POOLS; p++) { + small_arraylist_t *al = &ptls2->gc_tls_common.heap.free_stacks[p]; + size_t n_to_free; + if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { + n_to_free = al->len; // not alive yet or dead, so it does not need these anymore + } + else if (al->len > MIN_STACK_MAPPINGS_PER_POOL) { + n_to_free = al->len / 2; + if (n_to_free > (al->len - MIN_STACK_MAPPINGS_PER_POOL)) + n_to_free = al->len - MIN_STACK_MAPPINGS_PER_POOL; + } + else { + n_to_free = 0; + } + for (int n = 0; n < n_to_free; n++) { + void *stk = small_arraylist_pop(al); + free_stack(stk, pool_sizes[p]); + } + if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { + small_arraylist_free(al); + } + } } - small_arraylist_t *buffers = &ptls->lazily_freed_mtarraylist_buffers; - void *buf; - while ((buf = small_arraylist_pop(buffers)) != NULL) { - free(buf); + if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { + small_arraylist_free(ptls2->gc_tls_common.heap.free_stacks); } + + small_arraylist_t *live_tasks = &ptls2->gc_tls_common.heap.live_tasks; + size_t n = 0; + size_t ndel = 0; + size_t l = live_tasks->len; + void **lst = live_tasks->items; + if (l == 0) + continue; + while (1) { + jl_task_t *t = (jl_task_t*)lst[n]; + assert(jl_is_task(t)); + if (gc_marked(jl_astaggedvalue(t)->bits.gc)) { + if (t->ctx.stkbuf == NULL) + ndel++; // jl_release_task_stack called + else + n++; + } + else { + ndel++; + void *stkbuf = t->ctx.stkbuf; + size_t bufsz = t->ctx.bufsz; + if (stkbuf) { + t->ctx.stkbuf = NULL; + _jl_free_stack(ptls2, stkbuf, bufsz); + } +#ifdef _COMPILER_TSAN_ENABLED_ + if (t->ctx.tsan_state) { + __tsan_destroy_fiber(t->ctx.tsan_state); + t->ctx.tsan_state = NULL; + } +#endif + } + if (n >= l - ndel) + break; + void *tmp = lst[n]; + lst[n] = lst[n + ndel]; + lst[n + ndel] = tmp; + } + live_tasks->len -= ndel; } + jl_atomic_fetch_add(&gc_n_threads_sweeping_stacks, -1); } -void sweep_stack_pools_and_mtarraylist_buffers(jl_ptls_t ptls) JL_NOTSAFEPOINT +JL_DLLEXPORT void jl_gc_sweep_stack_pools_and_mtarraylist_buffers(jl_ptls_t ptls) JL_NOTSAFEPOINT { // initialize ptls index for parallel sweeping of stack pools assert(gc_n_threads); @@ -3090,7 +3170,7 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection) current_sweep_full = sweep_full; sweep_weak_refs(); uint64_t stack_pool_time = jl_hrtime(); - sweep_stack_pools_and_mtarraylist_buffers(ptls); + jl_gc_sweep_stack_pools_and_mtarraylist_buffers(ptls); stack_pool_time = jl_hrtime() - stack_pool_time; gc_num.total_stack_pool_sweep_time += stack_pool_time; gc_num.stack_pool_sweep_time = stack_pool_time; @@ -3648,61 +3728,6 @@ JL_DLLEXPORT uint64_t jl_gc_get_max_memory(void) // allocation wrappers that add to gc pressure -JL_DLLEXPORT void *jl_malloc(size_t sz) -{ - return jl_gc_counted_malloc(sz); -} - -//_unchecked_calloc does not check for potential overflow of nm*sz -STATIC_INLINE void *_unchecked_calloc(size_t nm, size_t sz) { - size_t nmsz = nm*sz; - return jl_gc_counted_calloc(nmsz, 1); -} - -JL_DLLEXPORT void *jl_calloc(size_t nm, size_t sz) -{ - if (nm > SSIZE_MAX/sz) - return NULL; - return _unchecked_calloc(nm, sz); -} - -JL_DLLEXPORT void jl_free(void *p) -{ - if (p != NULL) { - size_t sz = memory_block_usable_size(p, 0); - free(p); - jl_task_t *ct = jl_get_current_task(); - if (ct != NULL) - jl_batch_accum_free_size(ct->ptls, sz); - } -} - -JL_DLLEXPORT void *jl_realloc(void *p, size_t sz) -{ - size_t old = p ? memory_block_usable_size(p, 0) : 0; - void *data = realloc(p, sz); - jl_task_t *ct = jl_get_current_task(); - if (data != NULL && ct != NULL) { - sz = memory_block_usable_size(data, 0); - jl_ptls_t ptls = ct->ptls; - maybe_collect(ptls); - if (!(sz < old)) - jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, - jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + (sz - old)); - jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.realloc, - jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.realloc) + 1); - - int64_t diff = sz - old; - if (diff < 0) { - jl_batch_accum_free_size(ptls, -diff); - } - else { - jl_batch_accum_heap_size(ptls, diff); - } - } - return data; -} - JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz) { void *data = malloc(sz); @@ -3739,12 +3764,34 @@ JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz) JL_DLLEXPORT void jl_gc_counted_free_with_size(void *p, size_t sz) { - return jl_free(p); + free(p); + jl_task_t *ct = jl_get_current_task(); + if (ct != NULL) + jl_batch_accum_free_size(ct->ptls, sz); } JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size_t sz) { - return jl_realloc(p, sz); + void *data = realloc(p, sz); + jl_task_t *ct = jl_get_current_task(); + if (data != NULL && ct != NULL) { + sz = memory_block_usable_size(data, 0); + jl_ptls_t ptls = ct->ptls; + maybe_collect(ptls); + if (!(sz < old)) + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, + jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + (sz - old)); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.realloc, + jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.realloc) + 1); + int64_t diff = sz - old; + if (diff < 0) { + jl_batch_accum_free_size(ptls, -diff); + } + else { + jl_batch_accum_heap_size(ptls, diff); + } + } + return data; } // allocating blocks for Arrays and Strings @@ -4008,12 +4055,20 @@ JL_DLLEXPORT size_t jl_gc_external_obj_hdr_size(void) return sizeof(bigval_t); } - JL_DLLEXPORT void jl_gc_schedule_foreign_sweepfunc(jl_ptls_t ptls, jl_value_t *obj) { arraylist_push(&ptls->gc_tls.sweep_objs, obj); } +void jl_gc_notify_image_load(const char* img_data, size_t len) +{ + // Do nothing +} + +JL_DLLEXPORT const char* jl_gc_active_impl(void) { + return "Built with stock GC"; +} + #ifdef __cplusplus } #endif diff --git a/src/gc-stock.h b/src/gc-stock.h index b9a2e720f120a..d478ee1366da0 100644 --- a/src/gc-stock.h +++ b/src/gc-stock.h @@ -5,7 +5,6 @@ . non-moving, precise mark and sweep collector . pool-allocates small objects, keeps big objects on a simple list */ - #ifndef JL_GC_H #define JL_GC_H @@ -20,6 +19,7 @@ #include "julia_internal.h" #include "julia_assert.h" #include "threading.h" +#include "gc-common.h" #ifdef __cplusplus extern "C" { @@ -85,27 +85,6 @@ typedef struct _jl_gc_chunk_t { extern uintptr_t gc_bigval_sentinel_tag; -JL_EXTENSION typedef struct _bigval_t { - struct _bigval_t *next; - struct _bigval_t *prev; - size_t sz; -#ifdef _P64 // Add padding so that the value is 64-byte aligned - // (8 pointers of 8 bytes each) - (4 other pointers in struct) - void *_padding[8 - 4]; -#else - // (16 pointers of 4 bytes each) - (4 other pointers in struct) - void *_padding[16 - 4]; -#endif - //struct jl_taggedvalue_t <>; - union { - uintptr_t header; - struct { - uintptr_t gc:2; - } bits; - }; - // must be 64-byte aligned here, in 32 & 64 bit modes -} bigval_t; - // pool page metadata typedef struct _jl_gc_pagemeta_t { // next metadata structure in per-thread list @@ -519,9 +498,6 @@ extern uv_cond_t gc_threads_cond; extern uv_sem_t gc_sweep_assists_needed; extern _Atomic(int) gc_n_threads_marking; extern _Atomic(int) gc_n_threads_sweeping_pools; -extern _Atomic(int) gc_n_threads_sweeping_stacks; -extern _Atomic(int) gc_ptls_sweep_idx; -extern _Atomic(int) gc_stack_free_idx; extern _Atomic(int) n_threads_running; extern uv_barrier_t thread_init_done; void gc_mark_queue_all_roots(jl_ptls_t ptls, jl_gc_markqueue_t *mq); diff --git a/src/gc-tls-mmtk.h b/src/gc-tls-mmtk.h new file mode 100644 index 0000000000000..5b69aef5d55fb --- /dev/null +++ b/src/gc-tls-mmtk.h @@ -0,0 +1,23 @@ +// This file is a part of Julia. License is MIT: https://julialang.org/license + +#ifndef JL_GC_TLS_H +#define JL_GC_TLS_H + +#include +#include "mmtkMutator.h" +#include "julia_atomics.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + MMTkMutatorContext mmtk_mutator; + _Atomic(size_t) malloc_sz_since_last_poll; +} jl_gc_tls_states_t; + +#ifdef __cplusplus +} +#endif + +#endif // JL_GC_TLS_H diff --git a/src/gc-tls.h b/src/gc-tls-stock.h similarity index 100% rename from src/gc-tls.h rename to src/gc-tls-stock.h diff --git a/src/julia_internal.h b/src/julia_internal.h index 446e313fbe03d..86043b9f07df7 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -226,7 +226,7 @@ extern volatile int profile_all_tasks; // Ensures that we can safely read the `live_tasks`field of every TLS when profiling. // We want to avoid the case that a GC gets interleaved with `jl_profile_task` and shrinks // the `live_tasks` array while we are reading it or frees tasks that are being profiled. -// Because of that, this lock must be held in `jl_profile_task` and `sweep_stack_pools_and_mtarraylist_buffers`. +// Because of that, this lock must be held in `jl_profile_task` and `jl_gc_sweep_stack_pools_and_mtarraylist_buffers`. extern uv_mutex_t live_tasks_lock; // Ensures that we can safely write to `profile_bt_data_prof` and `profile_bt_size_cur`. // We want to avoid the case that: diff --git a/src/julia_locks.h b/src/julia_locks.h index 35bcf7dd97322..92d67b34b1692 100644 --- a/src/julia_locks.h +++ b/src/julia_locks.h @@ -116,7 +116,7 @@ class jl_unique_gcsafe_lock { { jl_task_t *ct = jl_current_task; gc_state = jl_gc_safe_enter(ct->ptls); // contains jl_gc_safepoint after enter - this->native = std::unique_lock(native); + this->native = std::unique_lock(native); ct->ptls->engine_nqueued++; // disables finalizers until inference is finished on this method graph } jl_unique_gcsafe_lock(jl_unique_gcsafe_lock &&native) = delete; diff --git a/src/julia_threads.h b/src/julia_threads.h index faa8ab9e0aaf4..b6ef65dc7fe52 100644 --- a/src/julia_threads.h +++ b/src/julia_threads.h @@ -4,7 +4,11 @@ #ifndef JL_THREADS_H #define JL_THREADS_H -#include "gc-tls.h" +#ifndef MMTK_GC +#include "gc-tls-stock.h" +#else +#include "gc-tls-mmtk.h" +#endif #include "gc-tls-common.h" #include "julia_atomics.h" #ifndef _OS_WINDOWS_ diff --git a/src/llvm-gc-interface-passes.h b/src/llvm-gc-interface-passes.h index 278987858eab7..7b2a4bb033203 100644 --- a/src/llvm-gc-interface-passes.h +++ b/src/llvm-gc-interface-passes.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -328,6 +329,7 @@ struct LateLowerGCFrame: private JuliaPassContext { private: CallInst *pgcstack; + Function *smallAllocFunc; void MaybeNoteDef(State &S, BBState &BBS, Value *Def, const ArrayRef &SafepointsSoFar, SmallVector &&RefinedPtr = SmallVector()); @@ -366,6 +368,7 @@ struct LateLowerGCFrame: private JuliaPassContext { void RefineLiveSet(LargeSparseBitVector &LS, State &S, ArrayRef CalleeRoots); Value *EmitTagPtr(IRBuilder<> &builder, Type *T, Type *T_size, Value *V); Value *EmitLoadTag(IRBuilder<> &builder, Type *T_size, Value *V); + Value* lowerGCAllocBytesLate(CallInst *target, Function &F); }; // The final GC lowering pass. This pass lowers platform-agnostic GC diff --git a/src/llvm-late-gc-lowering-mmtk.cpp b/src/llvm-late-gc-lowering-mmtk.cpp new file mode 100644 index 0000000000000..5539c8dbcf153 --- /dev/null +++ b/src/llvm-late-gc-lowering-mmtk.cpp @@ -0,0 +1,96 @@ +// This file is a part of Julia. License is MIT: https://julialang.org/license + +#include "llvm-gc-interface-passes.h" + +Value* LateLowerGCFrame::lowerGCAllocBytesLate(CallInst *target, Function &F) +{ + assert(target->arg_size() == 3); + + IRBuilder<> builder(target); + auto ptls = target->getArgOperand(0); + auto type = target->getArgOperand(2); + if (auto CI = dyn_cast(target->getArgOperand(1))) { + size_t sz = (size_t)CI->getZExtValue(); + // This is strongly architecture and OS dependent + int osize; + int offset = jl_gc_classify_pools(sz, &osize); + if (offset >= 0) { + // In this case instead of lowering julia.gc_alloc_bytes to jl_gc_small_alloc + // We do a slowpath/fastpath check and lower it only on the slowpath, returning + // the cursor and updating it in the fastpath. + auto pool_osize_i32 = ConstantInt::get(Type::getInt32Ty(F.getContext()), osize); + auto pool_osize = ConstantInt::get(Type::getInt64Ty(F.getContext()), osize); + + // Should we generate fastpath allocation sequence here? We should always generate fastpath here for MMTk. + // Setting this to false will increase allocation overhead a lot, and should only be used for debugging. + const bool INLINE_FASTPATH_ALLOCATION = true; + + if (INLINE_FASTPATH_ALLOCATION) { + // Assuming we use the first immix allocator. + // FIXME: We should get the allocator index and type from MMTk. + auto allocator_offset = offsetof(jl_tls_states_t, gc_tls) + offsetof(jl_gc_tls_states_t, mmtk_mutator) + offsetof(MMTkMutatorContext, allocators) + offsetof(Allocators, immix); + + auto cursor_pos = ConstantInt::get(Type::getInt64Ty(target->getContext()), allocator_offset + offsetof(ImmixAllocator, cursor)); + auto limit_pos = ConstantInt::get(Type::getInt64Ty(target->getContext()), allocator_offset + offsetof(ImmixAllocator, limit)); + + auto cursor_ptr = builder.CreateInBoundsGEP(Type::getInt8Ty(target->getContext()), ptls, cursor_pos); + auto cursor = builder.CreateAlignedLoad(Type::getInt64Ty(target->getContext()), cursor_ptr, Align(sizeof(void *)), "cursor"); + + // offset = 8 + auto delta_offset = builder.CreateNSWSub(ConstantInt::get(Type::getInt64Ty(target->getContext()), 0), ConstantInt::get(Type::getInt64Ty(target->getContext()), 8)); + auto delta_cursor = builder.CreateNSWSub(ConstantInt::get(Type::getInt64Ty(target->getContext()), 0), cursor); + auto delta_op = builder.CreateNSWAdd(delta_offset, delta_cursor); + // alignment 16 (15 = 16 - 1) + auto delta = builder.CreateAnd(delta_op, ConstantInt::get(Type::getInt64Ty(target->getContext()), 15), "delta"); + auto result = builder.CreateNSWAdd(cursor, delta, "result"); + + auto new_cursor = builder.CreateNSWAdd(result, pool_osize); + + auto limit_ptr = builder.CreateInBoundsGEP(Type::getInt8Ty(target->getContext()), ptls, limit_pos); + auto limit = builder.CreateAlignedLoad(Type::getInt64Ty(target->getContext()), limit_ptr, Align(sizeof(void *)), "limit"); + + auto gt_limit = builder.CreateICmpSGT(new_cursor, limit); + + auto slowpath = BasicBlock::Create(target->getContext(), "slowpath", target->getFunction()); + auto fastpath = BasicBlock::Create(target->getContext(), "fastpath", target->getFunction()); + + auto next_instr = target->getNextNode(); + SmallVector Weights{1, 9}; + + MDBuilder MDB(F.getContext()); + SplitBlockAndInsertIfThenElse(gt_limit, next_instr, &slowpath, &fastpath, false, false, MDB.createBranchWeights(Weights)); + + builder.SetInsertPoint(next_instr); + auto phiNode = builder.CreatePHI(target->getCalledFunction()->getReturnType(), 2, "phi_fast_slow"); + + // slowpath + builder.SetInsertPoint(slowpath); + auto pool_offs = ConstantInt::get(Type::getInt32Ty(F.getContext()), 1); + auto new_call = builder.CreateCall(smallAllocFunc, { ptls, pool_offs, pool_osize_i32, type }); + new_call->setAttributes(new_call->getCalledFunction()->getAttributes()); + builder.CreateBr(next_instr->getParent()); + + // fastpath + builder.SetInsertPoint(fastpath); + builder.CreateStore(new_cursor, cursor_ptr); + + // ptls->gc_tls.gc_num.allocd += osize; + auto pool_alloc_pos = ConstantInt::get(Type::getInt64Ty(target->getContext()), offsetof(jl_tls_states_t, gc_tls_common) + offsetof(jl_gc_tls_states_common_t, gc_num)); + auto pool_alloc_tls = builder.CreateInBoundsGEP(Type::getInt8Ty(target->getContext()), ptls, pool_alloc_pos); + auto pool_allocd = builder.CreateAlignedLoad(Type::getInt64Ty(target->getContext()), pool_alloc_tls, Align(sizeof(void *))); + auto pool_allocd_total = builder.CreateAdd(pool_allocd, pool_osize); + builder.CreateStore(pool_allocd_total, pool_alloc_tls); + + auto v_raw = builder.CreateNSWAdd(result, ConstantInt::get(Type::getInt64Ty(target->getContext()), sizeof(jl_taggedvalue_t))); + auto v_as_ptr = builder.CreateIntToPtr(v_raw, smallAllocFunc->getReturnType()); + builder.CreateBr(next_instr->getParent()); + + phiNode->addIncoming(new_call, slowpath); + phiNode->addIncoming(v_as_ptr, fastpath); + phiNode->takeName(target); + return phiNode; + } + } + } + return target; +} diff --git a/src/llvm-late-gc-lowering-stock.cpp b/src/llvm-late-gc-lowering-stock.cpp new file mode 100644 index 0000000000000..2a11487773396 --- /dev/null +++ b/src/llvm-late-gc-lowering-stock.cpp @@ -0,0 +1,9 @@ +// This file is a part of Julia. License is MIT: https://julialang.org/license + +#include "llvm-gc-interface-passes.h" + +Value* LateLowerGCFrame::lowerGCAllocBytesLate(CallInst *target, Function &F) +{ + // Do nothing for the stock GC + return target; +} diff --git a/src/llvm-late-gc-lowering.cpp b/src/llvm-late-gc-lowering.cpp index ff2cac6e49406..7d6fba65a79e7 100644 --- a/src/llvm-late-gc-lowering.cpp +++ b/src/llvm-late-gc-lowering.cpp @@ -2446,6 +2446,7 @@ void LateLowerGCFrame::PlaceRootsAndUpdateCalls(ArrayRef Colors, int PreAss bool LateLowerGCFrame::runOnFunction(Function &F, bool *CFGModified) { initAll(*F.getParent()); + smallAllocFunc = getOrDeclare(jl_well_known::GCSmallAlloc); LLVM_DEBUG(dbgs() << "GC ROOT PLACEMENT: Processing function " << F.getName() << "\n"); if (!pgcstack_getter && !adoptthread_func) return CleanupIR(F, nullptr, CFGModified); @@ -2460,6 +2461,31 @@ bool LateLowerGCFrame::runOnFunction(Function &F, bool *CFGModified) { std::map> CallFrames; // = OptimizeCallFrames(S, Ordering); PlaceRootsAndUpdateCalls(Colors.first, Colors.second, S, CallFrames); CleanupIR(F, &S, CFGModified); + + + // We lower the julia.gc_alloc_bytes intrinsic in this pass to insert slowpath/fastpath blocks for MMTk + // For now, we do nothing for the Stock GC + auto GCAllocBytes = getOrNull(jl_intrinsics::GCAllocBytes); + + if (GCAllocBytes) { + for (auto it = GCAllocBytes->user_begin(); it != GCAllocBytes->user_end(); ) { + if (auto *CI = dyn_cast(*it)) { + *CFGModified = true; + + assert(CI->getCalledOperand() == GCAllocBytes); + + auto newI = lowerGCAllocBytesLate(CI, F); + if (newI != CI) { + ++it; + CI->replaceAllUsesWith(newI); + CI->eraseFromParent(); + continue; + } + } + ++it; + } + } + return true; } diff --git a/src/staticdata.c b/src/staticdata.c index ca335bd0fefee..95d7ee94e15dc 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -659,6 +659,7 @@ static void jl_load_sysimg_so(void) plen = (size_t *)&jl_system_image_size; else jl_dlsym(jl_sysimg_handle, "jl_system_image_size", (void **)&plen, 1); + jl_gc_notify_image_load(sysimg_data, *plen); jl_restore_system_image_data(sysimg_data, *plen); } @@ -4227,6 +4228,7 @@ JL_DLLEXPORT jl_value_t *jl_restore_package_image_from_file(const char *fname, j jl_dlsym(pkgimg_handle, "jl_system_image_data", (void **)&pkgimg_data, 1); size_t *plen; jl_dlsym(pkgimg_handle, "jl_system_image_size", (void **)&plen, 1); + jl_gc_notify_image_load(pkgimg_data, *plen); jl_image_t pkgimage = jl_init_processor_pkgimg(pkgimg_handle); diff --git a/src/threading.c b/src/threading.c index ac9cc276d613a..77956786af3f4 100644 --- a/src/threading.c +++ b/src/threading.c @@ -773,6 +773,10 @@ void jl_init_threading(void) } int16_t ngcthreads = jl_n_markthreads + jl_n_sweepthreads; + if (strstr(jl_gc_active_impl(), "MMTk")) { + ngcthreads = 0; + } + jl_all_tls_states_size = nthreads + nthreadsi + ngcthreads; jl_n_threads_per_pool = (int*)malloc_s(2 * sizeof(int)); jl_n_threads_per_pool[0] = nthreadsi; diff --git a/stdlib/InteractiveUtils/src/InteractiveUtils.jl b/stdlib/InteractiveUtils/src/InteractiveUtils.jl index aa13fa3cdd31d..4a320282610cd 100644 --- a/stdlib/InteractiveUtils/src/InteractiveUtils.jl +++ b/stdlib/InteractiveUtils/src/InteractiveUtils.jl @@ -166,6 +166,7 @@ function versioninfo(io::IO=stdout; verbose::Bool=false) end println(io, " WORD_SIZE: ", Sys.WORD_SIZE) println(io, " LLVM: libLLVM-",Base.libllvm_version," (", Sys.JIT, ", ", Sys.CPU_NAME, ")") + println(io, " GC: ", unsafe_string(ccall(:jl_gc_active_impl, Ptr{UInt8}, ()))) println(io, """Threads: $(Threads.nthreads(:default)) default, $(Threads.nthreads(:interactive)) interactive, \ $(Threads.ngcthreads()) GC (on $(Sys.CPU_THREADS) virtual cores)""") From ec2b509aa08196f1bd375ccbaf9a0367e1f2ed1c Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Tue, 7 Jan 2025 18:15:29 +0100 Subject: [PATCH 139/198] Give undefined constants their own binding kind (#56968) As noted in https://github.com/JuliaLang/julia/pull/56649#discussion_r1855089367, there needs to be a separate kind for undefined constants, so we know whether or not it is safe to call `partition_restriction`. --- base/runtime_internals.jl | 6 ++++-- base/show.jl | 6 ++++-- src/julia.h | 8 ++++++-- src/julia_internal.h | 19 ++++++++++++++++--- src/module.c | 5 ++++- src/toplevel.c | 7 +++---- 6 files changed, 37 insertions(+), 14 deletions(-) diff --git a/base/runtime_internals.jl b/base/runtime_internals.jl index 13c467667c51e..67694e533ac47 100644 --- a/base/runtime_internals.jl +++ b/base/runtime_internals.jl @@ -228,10 +228,12 @@ const BINDING_KIND_IMPORTED = 0x5 const BINDING_KIND_FAILED = 0x6 const BINDING_KIND_DECLARED = 0x7 const BINDING_KIND_GUARD = 0x8 +const BINDING_KIND_UNDEF_CONST = 0x9 -is_some_const_binding(kind::UInt8) = (kind == BINDING_KIND_CONST || kind == BINDING_KIND_CONST_IMPORT) +is_defined_const_binding(kind::UInt8) = (kind == BINDING_KIND_CONST || kind == BINDING_KIND_CONST_IMPORT) +is_some_const_binding(kind::UInt8) = (is_defined_const_binding(kind) || kind == BINDING_KIND_UNDEF_CONST) is_some_imported(kind::UInt8) = (kind == BINDING_KIND_IMPLICIT || kind == BINDING_KIND_EXPLICIT || kind == BINDING_KIND_IMPORTED) -is_some_guard(kind::UInt8) = (kind == BINDING_KIND_GUARD || kind == BINDING_KIND_DECLARED || kind == BINDING_KIND_FAILED) +is_some_guard(kind::UInt8) = (kind == BINDING_KIND_GUARD || kind == BINDING_KIND_DECLARED || kind == BINDING_KIND_FAILED || kind == BINDING_KIND_UNDEF_CONST) function lookup_binding_partition(world::UInt, b::Core.Binding) ccall(:jl_get_binding_partition, Ref{Core.BindingPartition}, (Any, UInt), b, world) diff --git a/base/show.jl b/base/show.jl index 381c0e7d1480a..de45ca07e3131 100644 --- a/base/show.jl +++ b/base/show.jl @@ -1045,7 +1045,7 @@ function check_world_bounded(tn::Core.TypeName) isdefined(bnd, :partitions) || return nothing partition = @atomic bnd.partitions while true - if is_some_const_binding(binding_kind(partition)) && partition_restriction(partition) <: tn.wrapper + if is_defined_const_binding(binding_kind(partition)) && partition_restriction(partition) <: tn.wrapper max_world = @atomic partition.max_world max_world == typemax(UInt) && return nothing return Int(partition.min_world):Int(max_world) @@ -3364,9 +3364,11 @@ function print_partition(io::IO, partition::Core.BindingPartition) end print(io, " - ") kind = binding_kind(partition) - if is_some_const_binding(kind) + if is_defined_const_binding(kind) print(io, "constant binding to ") print(io, partition_restriction(partition)) + elseif kind == BINDING_KIND_UNDEF_CONST + print(io, "undefined const binding") elseif kind == BINDING_KIND_GUARD print(io, "undefined binding - guard entry") elseif kind == BINDING_KIND_FAILED diff --git a/src/julia.h b/src/julia.h index 5cafc9bfa5232..bfa9d0857c73c 100644 --- a/src/julia.h +++ b/src/julia.h @@ -623,7 +623,7 @@ typedef struct _jl_weakref_t { // N.B: Needs to be synced with runtime_internals.jl enum jl_partition_kind { - // Constant: This binding partition is a constant declared using `const` + // Constant: This binding partition is a constant declared using `const _ = ...` // ->restriction holds the constant value BINDING_KIND_CONST = 0x0, // Import Constant: This binding partition is a constant declared using `import A` @@ -649,7 +649,11 @@ enum jl_partition_kind { BINDING_KIND_DECLARED = 0x7, // Guard: The binding was looked at, but no global or import was resolved at the time // ->restriction is NULL. - BINDING_KIND_GUARD = 0x8 + BINDING_KIND_GUARD = 0x8, + // Undef Constant: This binding partition is a constant declared using `const`, but + // without a value. + // ->restriction is NULL + BINDING_KIND_UNDEF_CONST = 0x9 }; #ifdef _P64 diff --git a/src/julia_internal.h b/src/julia_internal.h index 86043b9f07df7..b1c32f6e2de6e 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -924,8 +924,13 @@ EXTERN_INLINE_DECLARE enum jl_partition_kind decode_restriction_kind(jl_ptr_kind uint8_t bits = (pku & 0x7); jl_value_t *val = (jl_value_t*)(pku & ~0x7); - if (val == NULL && bits == BINDING_KIND_IMPLICIT) { - return BINDING_KIND_GUARD; + if (val == NULL) { + if (bits == BINDING_KIND_IMPLICIT) { + return BINDING_KIND_GUARD; + } + if (bits == BINDING_KIND_CONST) { + return BINDING_KIND_UNDEF_CONST; + } } return (enum jl_partition_kind)bits; @@ -947,10 +952,14 @@ STATIC_INLINE jl_value_t *decode_restriction_value(jl_ptr_kind_union_t JL_PROPAG STATIC_INLINE jl_ptr_kind_union_t encode_restriction(jl_value_t *val, enum jl_partition_kind kind) JL_NOTSAFEPOINT { #ifdef _P64 - if (kind == BINDING_KIND_GUARD || kind == BINDING_KIND_DECLARED || kind == BINDING_KIND_FAILED) + if (kind == BINDING_KIND_GUARD || kind == BINDING_KIND_DECLARED || kind == BINDING_KIND_FAILED || kind == BINDING_KIND_UNDEF_CONST) assert(val == NULL); + else if (kind == BINDING_KIND_IMPLICIT || kind == BINDING_KIND_CONST) + assert(val != NULL); if (kind == BINDING_KIND_GUARD) kind = BINDING_KIND_IMPLICIT; + else if (kind == BINDING_KIND_UNDEF_CONST) + kind = BINDING_KIND_CONST; assert((((uintptr_t)val) & 0x7) == 0); return ((jl_ptr_kind_union_t)val) | kind; #else @@ -964,6 +973,10 @@ STATIC_INLINE int jl_bkind_is_some_import(enum jl_partition_kind kind) JL_NOTSAF } STATIC_INLINE int jl_bkind_is_some_constant(enum jl_partition_kind kind) JL_NOTSAFEPOINT { + return kind == BINDING_KIND_CONST || kind == BINDING_KIND_CONST_IMPORT || kind == BINDING_KIND_UNDEF_CONST; +} + +STATIC_INLINE int jl_bkind_is_defined_constant(enum jl_partition_kind kind) JL_NOTSAFEPOINT { return kind == BINDING_KIND_CONST || kind == BINDING_KIND_CONST_IMPORT; } diff --git a/src/module.c b/src/module.c index df90180901f2c..1b4c5bd78f667 100644 --- a/src/module.c +++ b/src/module.c @@ -400,7 +400,10 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_resolved(jl_binding_t *b) JL_DLLEXPORT jl_value_t *jl_bpart_get_restriction_value(jl_binding_partition_t *bpart) { jl_ptr_kind_union_t pku = jl_atomic_load_relaxed(&bpart->restriction); - return decode_restriction_value(pku); + jl_value_t *v = decode_restriction_value(pku); + if (!v) + jl_throw(jl_undefref_exception); + return v; } typedef struct _modstack_t { diff --git a/src/toplevel.c b/src/toplevel.c index 11e1f9ad521a1..0f8fae8939faf 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -157,7 +157,7 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex else { jl_binding_t *b = jl_get_module_binding(parent_module, name, 1); jl_binding_partition_t *bpart = jl_get_binding_partition(b, ct->world_age); - jl_ptr_kind_union_t pku = encode_restriction(NULL, BINDING_KIND_CONST); + jl_ptr_kind_union_t pku = encode_restriction(NULL, BINDING_KIND_UNDEF_CONST); jl_ptr_kind_union_t new_pku = encode_restriction((jl_value_t*)newm, BINDING_KIND_CONST); if (!jl_atomic_cmpswap(&bpart->restriction, &pku, new_pku)) { if (decode_restriction_kind(pku) != BINDING_KIND_CONST) { @@ -749,8 +749,7 @@ JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val2(jl_binding_t *b, j while (1) { if (jl_bkind_is_some_constant(decode_restriction_kind(pku))) { if (!val) { - JL_GC_POP(); - return bpart; + break; } jl_value_t *old = decode_restriction_value(pku); JL_GC_PROMISE_ROOTED(old); @@ -787,7 +786,7 @@ JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val2(jl_binding_t *b, j JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val(jl_binding_t *b, jl_module_t *mod, jl_sym_t *var, jl_value_t *val) { - return jl_declare_constant_val2(b, mod, var, val, BINDING_KIND_CONST); + return jl_declare_constant_val2(b, mod, var, val, val ? BINDING_KIND_CONST : BINDING_KIND_UNDEF_CONST); } JL_DLLEXPORT void jl_eval_const_decl(jl_module_t *m, jl_value_t *arg, jl_value_t *val) From 70aef64661235feb4a8ed38b41b806026f7922cd Mon Sep 17 00:00:00 2001 From: Christian Guinard <28689358+christiangnrd@users.noreply.github.com> Date: Tue, 7 Jan 2025 18:25:11 -0400 Subject: [PATCH 140/198] Properly mark `Meta.parse` as public (#56931) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is to remove the warning that the symbol is internal when checking the docstring for `Meta.parse` since it’s in the documentation. --- base/meta.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/base/meta.jl b/base/meta.jl index 0078e15bcd98b..85b54e8225d4e 100644 --- a/base/meta.jl +++ b/base/meta.jl @@ -16,6 +16,8 @@ export quot, show_sexpr, @dump +public parse + using Base: isidentifier, isoperator, isunaryoperator, isbinaryoperator, ispostfixoperator import Base: isexpr From d54f246b9c18d9730b1a7a47c815db5cd5b49f1c Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Tue, 7 Jan 2025 19:27:14 -0500 Subject: [PATCH 141/198] remove debug print call in `process_sysimg_args!` (#56983) I assume leaving this in was not intentional? --- base/Base_compiler.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/base/Base_compiler.jl b/base/Base_compiler.jl index 6582fe87e2045..91f327980389d 100644 --- a/base/Base_compiler.jl +++ b/base/Base_compiler.jl @@ -276,7 +276,6 @@ baremodule BuildSettings end function process_sysimg_args!() let i = 2 # skip file name while i <= length(Core.ARGS) - Core.println(Core.ARGS[i]) if Core.ARGS[i] == "--buildsettings" include(BuildSettings, ARGS[i+1]) elseif Core.ARGS[i] == "--buildroot" From fe1ed74032f8769e65ac9326190a38c70c2fff06 Mon Sep 17 00:00:00 2001 From: FX Coudert Date: Wed, 8 Jan 2025 02:35:53 +0100 Subject: [PATCH 142/198] Update suitesparse to 7.8.3 (#56959) New version: https://github.com/DrTimothyAldenDavis/SuiteSparse/releases/tag/v7.8.3 --- deps/checksums/suitesparse | 76 +++++++++++++++-------------- deps/libsuitesparse.version | 4 +- stdlib/Manifest.toml | 2 +- stdlib/SuiteSparse_jll/Project.toml | 2 +- 4 files changed, 44 insertions(+), 40 deletions(-) diff --git a/deps/checksums/suitesparse b/deps/checksums/suitesparse index bac143325196f..f4e47961d8cc3 100644 --- a/deps/checksums/suitesparse +++ b/deps/checksums/suitesparse @@ -1,36 +1,40 @@ -SuiteSparse-7.8.0.tar.gz/md5/ad42a80d28bb56a1fce15f6e7332e04e -SuiteSparse-7.8.0.tar.gz/sha512/91aff0aee26e938ba88a8f92db15b0db0ecc6ada3b60153bb299f53a45ccda131db4bc66f890c220034c900180d0bb3a5fb3e2686fec7d6174f5900a3ee64424 -SuiteSparse.v7.8.0+1.aarch64-apple-darwin.tar.gz/md5/38379e14a53663a9c23f32ed56801676 -SuiteSparse.v7.8.0+1.aarch64-apple-darwin.tar.gz/sha512/3f2a7aa7778a22d150bad9ecb8d03edfa75707a07545e65660c8ccc4b0a9fb058ccab29e21e4728741d40d390d28922d521d3841e16258cf8e26acacadfc1fbd -SuiteSparse.v7.8.0+1.aarch64-linux-gnu.tar.gz/md5/bc52c7df0a442c0fb9aafb83d60878f4 -SuiteSparse.v7.8.0+1.aarch64-linux-gnu.tar.gz/sha512/436e79ea0774d6ffb571b513e385ef48d9cc70b72010cffdc23d606ad6c8984c8b49e2422ce8881def0722f3f608e4ecb87e6752dd80cf7988addd330c5ded13 -SuiteSparse.v7.8.0+1.aarch64-linux-musl.tar.gz/md5/87e4c2588efc39723621ac5010ddf2e5 -SuiteSparse.v7.8.0+1.aarch64-linux-musl.tar.gz/sha512/17115826716bb48f16e4593941be275d47012d112e54d8826c75fde119ffc9f66accd02353b309365b59779d7af3ac220f31ab7cf7eea165b209a93ecdc4102f -SuiteSparse.v7.8.0+1.aarch64-unknown-freebsd.tar.gz/md5/108a78ec5d21c910b1f0d3cd58b2b18e -SuiteSparse.v7.8.0+1.aarch64-unknown-freebsd.tar.gz/sha512/730f93e317305073acda619044296eb1844bc1380719a9c2f2f255bebd7c0c827317ff99ce06a081521f9441c3ca7fbcb2362a310ef3c5d289f485b2628c3d80 -SuiteSparse.v7.8.0+1.armv6l-linux-gnueabihf.tar.gz/md5/b1490603aa129942d8e4c9581853cd0a -SuiteSparse.v7.8.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/e23c3532784e295ae72b811d285c3729c3f8ac1b5ee1621e831b6b2824a5b357e4bfa49e09174de7763fc3ebcab6b84ef16536bc1cf6f4bc0543b1b229209178 -SuiteSparse.v7.8.0+1.armv6l-linux-musleabihf.tar.gz/md5/f8199358882f76dd30bcce741b837de1 -SuiteSparse.v7.8.0+1.armv6l-linux-musleabihf.tar.gz/sha512/2c8d4ec21bfe253d3d32a5f5f09601b9b2864149f63f53067b157f5f7315fb04236bf5b19a1e5b4569e2c73127dcbb1703d56c7d06fc3ab9ae155902b7a1c2a9 -SuiteSparse.v7.8.0+1.armv7l-linux-gnueabihf.tar.gz/md5/cc3aa1a013cc91e7076dddf20fba9f60 -SuiteSparse.v7.8.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/a6b8cfbc345a089f12e55d8d44061dcce30f94c2d79fc520d6c5dfe433ac2e362d049fac72278cb59d4b3760ca08d5e350b7e2658fa5e8c77ce8608f67c2c4c4 -SuiteSparse.v7.8.0+1.armv7l-linux-musleabihf.tar.gz/md5/0d7797d31c30c53bf219cdc0a48e64dc -SuiteSparse.v7.8.0+1.armv7l-linux-musleabihf.tar.gz/sha512/a7df8938ee6a04f62169bedd29c8408951cf33a43e0f529fb4d1e360bdad6462a50b2af297adb5f51fd726e1ced1fc8fcda7feeeafbeb44000bfe02a8e29c29e -SuiteSparse.v7.8.0+1.i686-linux-gnu.tar.gz/md5/e48fa3d2e00f210e964c21e4ff27efae -SuiteSparse.v7.8.0+1.i686-linux-gnu.tar.gz/sha512/3088c2af476285eb8549cf6aa56381156d49513a274348f86fbf01aa9ce0712961471f83fa50b261f3f365a302b88eb20ef0bb35b58c07a2cfb5dc337fdb72c1 -SuiteSparse.v7.8.0+1.i686-linux-musl.tar.gz/md5/e55202dbeca107a0c25a4f09d5d68915 -SuiteSparse.v7.8.0+1.i686-linux-musl.tar.gz/sha512/0f4de2e62016914b4d1bcb9b13bd8cb2bebefc5f0a532e103948b9aae79a20462ac7b74a3e968d4f99076c37dbbafb747699cd151e831ff89d297f78478fb84f -SuiteSparse.v7.8.0+1.i686-w64-mingw32.tar.gz/md5/e8f4de53ec4ae74554e76bd52702d7a4 -SuiteSparse.v7.8.0+1.i686-w64-mingw32.tar.gz/sha512/f944f14e62408f04a9966cd927cbbbe26b00a4beccc85ab8923dc4028875b0395c6b5e56efba1fd2f29fb954543ca83e800685ffafcdfdd97351a7d4926349a8 -SuiteSparse.v7.8.0+1.powerpc64le-linux-gnu.tar.gz/md5/12058f122b548a37070770d1847f3ce9 -SuiteSparse.v7.8.0+1.powerpc64le-linux-gnu.tar.gz/sha512/f375feeb8448ea90ce8d9f31c7e1230f6868316f06094ba0155069dded4f8da2e1b54d462ef9cfc77abd76147740d4066236dcf1fcea91f8a7141819962ad0ae -SuiteSparse.v7.8.0+1.x86_64-apple-darwin.tar.gz/md5/1bd473f2a25f1ebcea8acc858e2594b4 -SuiteSparse.v7.8.0+1.x86_64-apple-darwin.tar.gz/sha512/034af137deee5bf0ebf3746745d09ad50ce135cd4768a2049bb9811478ff90e6ed8e2c990e277b4c3b38a3a5e9eaa856938eb86239ca445fa64b6dab6af7e996 -SuiteSparse.v7.8.0+1.x86_64-linux-gnu.tar.gz/md5/c58a86d9f25e6705941105d9e41f084c -SuiteSparse.v7.8.0+1.x86_64-linux-gnu.tar.gz/sha512/56447062802f01815ffb014624423c6fd3ab6e16b642b2fe37972a151b02865965c95ca3d1a455c6d51cd31633aea8a732b235b55d68e6779c17b293c488fa43 -SuiteSparse.v7.8.0+1.x86_64-linux-musl.tar.gz/md5/ba6e10ba61c209df94f18ab51fe2dd90 -SuiteSparse.v7.8.0+1.x86_64-linux-musl.tar.gz/sha512/3b8fc504cfb4a3b628d5b955a482bad08c85e09e529f833855a84b847721247aaa469f96adef6b218a1ba5896cde91664cc819ba33115e3cc309e72140841ca3 -SuiteSparse.v7.8.0+1.x86_64-unknown-freebsd.tar.gz/md5/a50c69142a42c14edac4ce94b86b138a -SuiteSparse.v7.8.0+1.x86_64-unknown-freebsd.tar.gz/sha512/963be0dccd1a594df08fe5135ef4ac13e1d707841c3e97d31ba5477d0d6ec26bad9be1c52d9fd78f199740a53950353adbdd767469f3bf01ea1e3ee843eb6c1a -SuiteSparse.v7.8.0+1.x86_64-w64-mingw32.tar.gz/md5/7ca11ba89bd09183cc5a9320d6e8a4a7 -SuiteSparse.v7.8.0+1.x86_64-w64-mingw32.tar.gz/sha512/e1d5def1103bbf0bb29c08cdd3bf21ba60456353694985c66f8e55a31d54a32c5b891e56e1ffe30f9e1223c49283d267e483e2f1b999f566099c239b3eed1d78 +SuiteSparse-7.8.3.tar.gz/md5/242e38ecfc8a3e3aa6b7d8d44849c5cf +SuiteSparse-7.8.3.tar.gz/sha512/fc0fd0aaf55a6712a3b8ca23bf7536a31d52033e090370ebbf291f05d0e073c7dcfd991a80b037f54663f524804582b87af86522c2e4435091527f0d3c189244 +SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/md5/46541001073d1c3c85e18d910f8308f3 +SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/sha512/f7470a447b934ca9315e216a07b97e363f11bc93186f9aa057b20b2d05092c58ae4f1b733de362de4a0730861c00be4ca5588d0b3ba65f018c1798b9122b9672 +SuiteSparse.v7.8.3+2.aarch64-apple-darwin.tar.gz/md5/e97424dc7b9e44cb18ca50b99d71a0a8 +SuiteSparse.v7.8.3+2.aarch64-apple-darwin.tar.gz/sha512/2d077c785fe1109ad83e001516394c027f0ba1d77186e73df3d89ee03aea7817f09e15c0b1302711aebd168e06675cc865e2936c4c654c9f65932434f974e9c6 +SuiteSparse.v7.8.3+2.aarch64-linux-gnu.tar.gz/md5/7b14b0fe44156b117ebee60811f666e6 +SuiteSparse.v7.8.3+2.aarch64-linux-gnu.tar.gz/sha512/dc726895c6f4c3e7a8d87507946cc0fd15e8d6c6d6d22698976df8c53aeec0532abb0c34bcb98767a6ee3b3146f60189a575a8e523be75b951d33535b6de5359 +SuiteSparse.v7.8.3+2.aarch64-linux-musl.tar.gz/md5/5a4e485cb6a7025196548e8bab4228c6 +SuiteSparse.v7.8.3+2.aarch64-linux-musl.tar.gz/sha512/9c091cd13b61a4d291751c294a080b95c9068b13bd805089c962e06fafdb12da08087709759d5310ceb2c115255b14c1a99c4ed45f660f8680dcc30f55ac6f49 +SuiteSparse.v7.8.3+2.aarch64-unknown-freebsd.tar.gz/md5/895f1b9b79455c3c26a9e3c64c335dc5 +SuiteSparse.v7.8.3+2.aarch64-unknown-freebsd.tar.gz/sha512/9876a711d79314dcf68bacf0460267f69474c736346bf9f098ed56c3430fca67d9b73d7d30fa6d3c5ac1cacb017f57be2d83b2310f695d51b73e3ce98234a10e +SuiteSparse.v7.8.3+2.armv6l-linux-gnueabihf.tar.gz/md5/9784404d2ff45a94a9ce9e671badcdf0 +SuiteSparse.v7.8.3+2.armv6l-linux-gnueabihf.tar.gz/sha512/8f49fc05c80f6b869810e5f128c04a5816ebc2ae24313ba699723be9550407a634486d0c95089325350381cd534d3e991cc07a80f509a612f6da27da32b1d6d0 +SuiteSparse.v7.8.3+2.armv6l-linux-musleabihf.tar.gz/md5/b26cdada5bd08e3284dd74e7bb14a770 +SuiteSparse.v7.8.3+2.armv6l-linux-musleabihf.tar.gz/sha512/78695ebab8c73bed06723e3052c471888e84e90681561e32469bac49784b8973af355a19db5ad3663373fde97b92ade112e48a0ece4209b9933c05faa9a7b83d +SuiteSparse.v7.8.3+2.armv7l-linux-gnueabihf.tar.gz/md5/4ae051735ae0c34ab2d5e1f0bec3f26c +SuiteSparse.v7.8.3+2.armv7l-linux-gnueabihf.tar.gz/sha512/efdd084c9bfac1cd9a4128aa7d6a4f0d682cd6c791dbcf1ed2f53b77f6e9c4ab9ed13f54ff6dc54603b5426bc09f7833defaca3d135cd1995d92a177d1d97eb0 +SuiteSparse.v7.8.3+2.armv7l-linux-musleabihf.tar.gz/md5/2e55d69017c5ec6fca694aabf1470dc1 +SuiteSparse.v7.8.3+2.armv7l-linux-musleabihf.tar.gz/sha512/1c75fa1536f5db13e1d613d61959dc1004570a5df45f75820f9554c7395f7492ad5edd5865d5b5c3f6aee65ffa33aa68dab1616547aeb7614da6bf708a748dc1 +SuiteSparse.v7.8.3+2.i686-linux-gnu.tar.gz/md5/817e2479c223e9c023ec431aea4b2361 +SuiteSparse.v7.8.3+2.i686-linux-gnu.tar.gz/sha512/c0e4482570bed4366f68df9635a6229289008c0754c3d636d26a44004e5c80ae04c6ab434b0dbf57baa05e4afc847716d9e059904faf9d10be7abdade2890803 +SuiteSparse.v7.8.3+2.i686-linux-musl.tar.gz/md5/e7a6c8f58a81e0ac511d44e878b9128d +SuiteSparse.v7.8.3+2.i686-linux-musl.tar.gz/sha512/54c00ba5bd8bb514e8cc29ce0ed596c642678ea1fe27571cbbb3210b9ad8940ecac2100e05b29d5db51804daab714c48d18dbf65650924b90c076078681990a3 +SuiteSparse.v7.8.3+2.i686-w64-mingw32.tar.gz/md5/3db74decc8363735a0a9f71f2558c2c9 +SuiteSparse.v7.8.3+2.i686-w64-mingw32.tar.gz/sha512/d5dc5e263a9705d2510f541ffe9c5a543a4a0ba7c104ad03142ef04de5a25cdb7da59eed3218cdf540b7b2167235206d438db283da682ba31568d99076fccece +SuiteSparse.v7.8.3+2.powerpc64le-linux-gnu.tar.gz/md5/78f008e14dfb2580da95ac58466d9d16 +SuiteSparse.v7.8.3+2.powerpc64le-linux-gnu.tar.gz/sha512/ea7370f5071c1e5bb2980f76f16ec88eded7fab6d7773c99fff9087adee446b5f4cefd16ff483aa92197fabea35cb3e486742a58fefa6fee0997a358ada14c8a +SuiteSparse.v7.8.3+2.riscv64-linux-gnu.tar.gz/md5/966c2093ab4d0652084652f54e58c5f7 +SuiteSparse.v7.8.3+2.riscv64-linux-gnu.tar.gz/sha512/febff4241ff15471a7a3bcb544a7e34ab71da1c516b3fcff89cd726d392c2fcea0bb970c8a2ee7a4461c341c7be02f47fcdc47f4a7f88307cceeb3f75327c625 +SuiteSparse.v7.8.3+2.x86_64-apple-darwin.tar.gz/md5/7a8b5ab88a83081545a411202caf5a1f +SuiteSparse.v7.8.3+2.x86_64-apple-darwin.tar.gz/sha512/186f5fb8a7117d8cf77b311ea0c137b270eca895aecd31dc616b86425c62ae3d0218938cf1cf54d5009b7ff8247f40ae21b6c452fdd339fead5622e710c03418 +SuiteSparse.v7.8.3+2.x86_64-linux-gnu.tar.gz/md5/001cb5ce58344f1186a51d6018a9c337 +SuiteSparse.v7.8.3+2.x86_64-linux-gnu.tar.gz/sha512/8cd407ff3e857cb49d26adde68746c0a73742c4556ab624b34eb5caa95a7c438d1aa6a7fb3b9d54341f0469ae7b19f78e09f2a2642f15f4795d9583162cf12e1 +SuiteSparse.v7.8.3+2.x86_64-linux-musl.tar.gz/md5/305e268c36927a94037419153d37fe91 +SuiteSparse.v7.8.3+2.x86_64-linux-musl.tar.gz/sha512/aebd921b721f8f71bbdc94aa60ae2f2c3bc5de21acbda0ae1e96e19dbc86c13cbe1921cd5938bbb4f9f83c84a2a6b4f980e743684e8236e7a979ead0042e9dec +SuiteSparse.v7.8.3+2.x86_64-unknown-freebsd.tar.gz/md5/81f85e3374a9b7bbe0a25b8cb88d3438 +SuiteSparse.v7.8.3+2.x86_64-unknown-freebsd.tar.gz/sha512/fb0b1c219d1ce35f79d945fccb5c5a2e1e8d9f32a2401dc3071781740c6c16e729746ffb02c76680e681f8978d19948b28612c97136f1396d030e69c3eb336d9 +SuiteSparse.v7.8.3+2.x86_64-w64-mingw32.tar.gz/md5/a3a68bafb213ea68006cdfdbb15e1457 +SuiteSparse.v7.8.3+2.x86_64-w64-mingw32.tar.gz/sha512/6db131bb8b0efbcbaf4ee9f2688dc1083a570da5fc9ddb044ffc9308fd5d6949241cd780e5246484ae6417b261bfd61683b6122c7dba7d1598d5e89be6d73acc diff --git a/deps/libsuitesparse.version b/deps/libsuitesparse.version index 6f841190cebc7..cc294f68c2d5a 100644 --- a/deps/libsuitesparse.version +++ b/deps/libsuitesparse.version @@ -4,5 +4,5 @@ LIBSUITESPARSE_JLL_NAME := SuiteSparse ## source build -LIBSUITESPARSE_VER := 7.8.0 -LIBSUITESPARSE_SHA1=58e6558408f6a51c08e35a5557d5e68cae32147e +LIBSUITESPARSE_VER := 7.8.3 +LIBSUITESPARSE_SHA1=d3c4926d2c47fd6ae558e898bfc072ade210a2a1 diff --git a/stdlib/Manifest.toml b/stdlib/Manifest.toml index 6743d357fb8b3..160ccac5ffa39 100644 --- a/stdlib/Manifest.toml +++ b/stdlib/Manifest.toml @@ -243,7 +243,7 @@ version = "1.11.0" [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.8.0+1" +version = "7.8.3+2" [[deps.TOML]] deps = ["Dates"] diff --git a/stdlib/SuiteSparse_jll/Project.toml b/stdlib/SuiteSparse_jll/Project.toml index c91ef6743d653..3a1dc50a103fb 100644 --- a/stdlib/SuiteSparse_jll/Project.toml +++ b/stdlib/SuiteSparse_jll/Project.toml @@ -1,6 +1,6 @@ name = "SuiteSparse_jll" uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.8.0+1" +version = "7.8.3+2" [deps] libblastrampoline_jll = "8e850b90-86db-534c-a0d3-1478176c7d93" From 3c7bc45f14c8a2b70ccf1d92d4418cfaaa112b56 Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Tue, 7 Jan 2025 21:37:32 -0800 Subject: [PATCH 143/198] Update OpenLibm to 0.8.5 (#56984) This fixes building on FreeBSD AArch64, as there was a regression in OpenLibm 0.8.4; see https://github.com/JuliaMath/openlibm/pull/314. --- deps/checksums/openlibm | 76 ++++++++++++++++---------------- deps/openlibm.version | 6 +-- stdlib/Manifest.toml | 2 +- stdlib/OpenLibm_jll/Project.toml | 2 +- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/deps/checksums/openlibm b/deps/checksums/openlibm index 172d8ed3fb413..cad61fd42cf94 100644 --- a/deps/checksums/openlibm +++ b/deps/checksums/openlibm @@ -1,38 +1,38 @@ -OpenLibm.v0.8.4+1.aarch64-apple-darwin.tar.gz/md5/5fcbd746e90712e396e76dc4e76724d0 -OpenLibm.v0.8.4+1.aarch64-apple-darwin.tar.gz/sha512/f4ac2bc38bdc723384b67119daa2974fb43da34b2e45cea2029ea48f92c84c4cad6dfb43521b09a1e89ddf8c5b8cc22a38fa4b78ba39ac7524fd6bd1ba897aa9 -OpenLibm.v0.8.4+1.aarch64-linux-gnu.tar.gz/md5/e24c967d04812058b69b8c561f0d9f2a -OpenLibm.v0.8.4+1.aarch64-linux-gnu.tar.gz/sha512/8100dd7cfd9e02c9cfeade7627eb6105e86e8f5eb99026462a9a5370f8dd99ad981024a8904d2d7c341b113730f1b2312909d9c9c2c9b48dce74d3e80b266947 -OpenLibm.v0.8.4+1.aarch64-linux-musl.tar.gz/md5/6f9454c31b548f9fd47fb6318aab9b12 -OpenLibm.v0.8.4+1.aarch64-linux-musl.tar.gz/sha512/1769348f3e2227f307923b8c5656ab4c797daa8bd8bed61fbdf4c72d84ba9b7ae097392cdafd5e0cee0004f846e2c2ddbf9b5e7edb2406606b37c5ed665cc693 -OpenLibm.v0.8.4+1.aarch64-unknown-freebsd.tar.gz/md5/acce062e568325b675a6ed6a7a8fabbd -OpenLibm.v0.8.4+1.aarch64-unknown-freebsd.tar.gz/sha512/8ade1ae5ded62622a5159a0e60a8f6ad8345debda0da3eff764ea1e8a9937e686055e253612d83c4ee0035aa3dd2d6267d2dbd687cfcffbaffc17a7d7879e05f -OpenLibm.v0.8.4+1.armv6l-linux-gnueabihf.tar.gz/md5/8fe0900a318393a290907f016bc654c3 -OpenLibm.v0.8.4+1.armv6l-linux-gnueabihf.tar.gz/sha512/167100a2d46e68462ef9a66915ced881d6358f05337bd38f2f77176f41cfd5be37e3c5226dd5d7d59147bd3e1aa7fb0893c1c81e9516134d3ab663b5752c4969 -OpenLibm.v0.8.4+1.armv6l-linux-musleabihf.tar.gz/md5/e8566719387984604f19dc5f9354a783 -OpenLibm.v0.8.4+1.armv6l-linux-musleabihf.tar.gz/sha512/532dd2b764fa15f7a838fb14cccafd2d4fe8fa4a132ea8394479a719c7aee11442f1b8a18e5d4a26ca820fa696d9d2afc7f5ec63dd96fa3b6763cea72b7026c3 -OpenLibm.v0.8.4+1.armv7l-linux-gnueabihf.tar.gz/md5/8fe0900a318393a290907f016bc654c3 -OpenLibm.v0.8.4+1.armv7l-linux-gnueabihf.tar.gz/sha512/167100a2d46e68462ef9a66915ced881d6358f05337bd38f2f77176f41cfd5be37e3c5226dd5d7d59147bd3e1aa7fb0893c1c81e9516134d3ab663b5752c4969 -OpenLibm.v0.8.4+1.armv7l-linux-musleabihf.tar.gz/md5/e8566719387984604f19dc5f9354a783 -OpenLibm.v0.8.4+1.armv7l-linux-musleabihf.tar.gz/sha512/532dd2b764fa15f7a838fb14cccafd2d4fe8fa4a132ea8394479a719c7aee11442f1b8a18e5d4a26ca820fa696d9d2afc7f5ec63dd96fa3b6763cea72b7026c3 -OpenLibm.v0.8.4+1.i686-linux-gnu.tar.gz/md5/9580d34e69d6067427b9c33db631cfd3 -OpenLibm.v0.8.4+1.i686-linux-gnu.tar.gz/sha512/46934f82791f69ac5f5da0dab7dcc6e3e9a4577c3bb529e9c0519c38f140c7b54517c55ff3579cd4ed4df68f0863e006aa98e51873f1dab452ce9f853996429a -OpenLibm.v0.8.4+1.i686-linux-musl.tar.gz/md5/66bfc9611d04c5d609e7824cb076d24b -OpenLibm.v0.8.4+1.i686-linux-musl.tar.gz/sha512/1bda2395d44c22aba3d1aab2b08ae06f763d3755037d454aa73f8e8134289a1ab5d65862bbc5a17a7a6b9f2918eb87e926b21527ddc4471e2ea20d605ba14e2d -OpenLibm.v0.8.4+1.i686-w64-mingw32.tar.gz/md5/0e97311b2f08b57d79085635f01ccced -OpenLibm.v0.8.4+1.i686-w64-mingw32.tar.gz/sha512/ae061ea406c06969332af58ed6fdfce2825326d771d30274d90775a1709b0361b7ca1dc7e6b0b76b93e4dd7a81d1842510a2c835251ee0a0978d6c839d96070e -OpenLibm.v0.8.4+1.powerpc64le-linux-gnu.tar.gz/md5/8ecfff7db76eee29591a654871e88855 -OpenLibm.v0.8.4+1.powerpc64le-linux-gnu.tar.gz/sha512/af03993b162316dd581f6ba5d1c23bca4c26cb22356ab229f326c42e111acbdf7ef45c9ad05894fe2d68794a63670cf89888653f788192a38b9255ce4bc72e28 -OpenLibm.v0.8.4+1.riscv64-linux-gnu.tar.gz/md5/2d6ae40b640f7d39c20ec7d151d6972d -OpenLibm.v0.8.4+1.riscv64-linux-gnu.tar.gz/sha512/3a9b69601e7e1013f236c0d9f7326f371d65d9c1231d5848995ebd822fd1eff0bd5f6b771fe2c21191076902e6a7c4febb4822f78cc0d15bb7f59396d9728236 -OpenLibm.v0.8.4+1.x86_64-apple-darwin.tar.gz/md5/bd671ab9fe01835cab3e42e7cfa790fb -OpenLibm.v0.8.4+1.x86_64-apple-darwin.tar.gz/sha512/8bf2e66df17effc1e8778453904ffc20127f785bf096873289e8fdd8b17069ca844faffbd9f7621b87a7cb0a0051037eb9402360f2a03cf8794fbac8f7719777 -OpenLibm.v0.8.4+1.x86_64-linux-gnu.tar.gz/md5/df7fab134fbce3b625e9a82376f23e79 -OpenLibm.v0.8.4+1.x86_64-linux-gnu.tar.gz/sha512/64d07434e0db79833f84a2225838456eb9532617d377a776b3a534a908b1673bc4f890903f95350e4045e05c29539d993a18ecadeb879761e279ec3947f74390 -OpenLibm.v0.8.4+1.x86_64-linux-musl.tar.gz/md5/ebef6bb7651d116b397e035f39adfb1b -OpenLibm.v0.8.4+1.x86_64-linux-musl.tar.gz/sha512/de9036073e5dba2721b4119ecbbd21a0c9f75b65aff9392b7e88e464da35b97135d62404477441d0dadd3a2f8d49f1082291b35bf4b626fb1096d36d401980bf -OpenLibm.v0.8.4+1.x86_64-unknown-freebsd.tar.gz/md5/bc09186ae191700d6cf9162796bb23ba -OpenLibm.v0.8.4+1.x86_64-unknown-freebsd.tar.gz/sha512/6b7198cd68418e370348c7011a5f9ccf910b62c9482334601dea0749b683724ddb7414bde3d8da7a5123c0fadc3f93d02274538070330db6428dabca5d007835 -OpenLibm.v0.8.4+1.x86_64-w64-mingw32.tar.gz/md5/b6b5335f4c83f7ebf0f74cf753358f00 -OpenLibm.v0.8.4+1.x86_64-w64-mingw32.tar.gz/sha512/e8351ddda305b757f337bb7ea26c441968843b23861676f0bdd7bcf83bb3969af790d4112307d3204eb87fac044dda9be305f349700ebe9ba2bfe3d6df24fde8 -openlibm-c4667caea25ae3487adf6760b4a1dcf32477a4b8.tar.gz/md5/287cf81f6c6b67177b322f7cb5cc8279 -openlibm-c4667caea25ae3487adf6760b4a1dcf32477a4b8.tar.gz/sha512/3c3efa8cb344719c2b6df45fbfe178efac6239cac12fc32dcc92074431d2e1a3039a60649cf3525424e0990081b6d40acb12176316c4ccb2940add0bb3a41e85 +OpenLibm.v0.8.5+0.aarch64-apple-darwin.tar.gz/md5/5fcbd746e90712e396e76dc4e76724d0 +OpenLibm.v0.8.5+0.aarch64-apple-darwin.tar.gz/sha512/f4ac2bc38bdc723384b67119daa2974fb43da34b2e45cea2029ea48f92c84c4cad6dfb43521b09a1e89ddf8c5b8cc22a38fa4b78ba39ac7524fd6bd1ba897aa9 +OpenLibm.v0.8.5+0.aarch64-linux-gnu.tar.gz/md5/4d1b4cd566805b5179c5ecdd060da473 +OpenLibm.v0.8.5+0.aarch64-linux-gnu.tar.gz/sha512/a9fe1a3d2e3898c017eb8615b2f3dbb514995ff041ac964c931c99c60d8cfe4eab7563a9cd65058f42f83c812f33d998573a7c5cc56a2e3960a4657e459ed321 +OpenLibm.v0.8.5+0.aarch64-linux-musl.tar.gz/md5/413be59af62b3ce0ebafeca093e3179e +OpenLibm.v0.8.5+0.aarch64-linux-musl.tar.gz/sha512/7bd76373e047ba854066af61f1c56b2e3a4d28c266228d7b30f596eadbaec52b070548ae60d41840c425ad5d0829c6c0cdaf326f2f160ed7508877ab5ec1a4b1 +OpenLibm.v0.8.5+0.aarch64-unknown-freebsd.tar.gz/md5/80736f9022c695eb1198e0b591a8fa63 +OpenLibm.v0.8.5+0.aarch64-unknown-freebsd.tar.gz/sha512/c633644578265e7ccc259ceb0442457b8c09290b4861b66c86dd6be7b30c4e394e70728142798097d6fe3afcfb4d9d1bd7ef58513fe8eed5684a4fba51bf185a +OpenLibm.v0.8.5+0.armv6l-linux-gnueabihf.tar.gz/md5/8fe0900a318393a290907f016bc654c3 +OpenLibm.v0.8.5+0.armv6l-linux-gnueabihf.tar.gz/sha512/167100a2d46e68462ef9a66915ced881d6358f05337bd38f2f77176f41cfd5be37e3c5226dd5d7d59147bd3e1aa7fb0893c1c81e9516134d3ab663b5752c4969 +OpenLibm.v0.8.5+0.armv6l-linux-musleabihf.tar.gz/md5/e8566719387984604f19dc5f9354a783 +OpenLibm.v0.8.5+0.armv6l-linux-musleabihf.tar.gz/sha512/532dd2b764fa15f7a838fb14cccafd2d4fe8fa4a132ea8394479a719c7aee11442f1b8a18e5d4a26ca820fa696d9d2afc7f5ec63dd96fa3b6763cea72b7026c3 +OpenLibm.v0.8.5+0.armv7l-linux-gnueabihf.tar.gz/md5/8fe0900a318393a290907f016bc654c3 +OpenLibm.v0.8.5+0.armv7l-linux-gnueabihf.tar.gz/sha512/167100a2d46e68462ef9a66915ced881d6358f05337bd38f2f77176f41cfd5be37e3c5226dd5d7d59147bd3e1aa7fb0893c1c81e9516134d3ab663b5752c4969 +OpenLibm.v0.8.5+0.armv7l-linux-musleabihf.tar.gz/md5/e8566719387984604f19dc5f9354a783 +OpenLibm.v0.8.5+0.armv7l-linux-musleabihf.tar.gz/sha512/532dd2b764fa15f7a838fb14cccafd2d4fe8fa4a132ea8394479a719c7aee11442f1b8a18e5d4a26ca820fa696d9d2afc7f5ec63dd96fa3b6763cea72b7026c3 +OpenLibm.v0.8.5+0.i686-linux-gnu.tar.gz/md5/9580d34e69d6067427b9c33db631cfd3 +OpenLibm.v0.8.5+0.i686-linux-gnu.tar.gz/sha512/46934f82791f69ac5f5da0dab7dcc6e3e9a4577c3bb529e9c0519c38f140c7b54517c55ff3579cd4ed4df68f0863e006aa98e51873f1dab452ce9f853996429a +OpenLibm.v0.8.5+0.i686-linux-musl.tar.gz/md5/66bfc9611d04c5d609e7824cb076d24b +OpenLibm.v0.8.5+0.i686-linux-musl.tar.gz/sha512/1bda2395d44c22aba3d1aab2b08ae06f763d3755037d454aa73f8e8134289a1ab5d65862bbc5a17a7a6b9f2918eb87e926b21527ddc4471e2ea20d605ba14e2d +OpenLibm.v0.8.5+0.i686-w64-mingw32.tar.gz/md5/0e97311b2f08b57d79085635f01ccced +OpenLibm.v0.8.5+0.i686-w64-mingw32.tar.gz/sha512/ae061ea406c06969332af58ed6fdfce2825326d771d30274d90775a1709b0361b7ca1dc7e6b0b76b93e4dd7a81d1842510a2c835251ee0a0978d6c839d96070e +OpenLibm.v0.8.5+0.powerpc64le-linux-gnu.tar.gz/md5/8ecfff7db76eee29591a654871e88855 +OpenLibm.v0.8.5+0.powerpc64le-linux-gnu.tar.gz/sha512/af03993b162316dd581f6ba5d1c23bca4c26cb22356ab229f326c42e111acbdf7ef45c9ad05894fe2d68794a63670cf89888653f788192a38b9255ce4bc72e28 +OpenLibm.v0.8.5+0.riscv64-linux-gnu.tar.gz/md5/69e06de135940666791c984941e9c4ad +OpenLibm.v0.8.5+0.riscv64-linux-gnu.tar.gz/sha512/2ac84deb7eb80a6a6237eff6fe861fd2907b3c95d1a76366dea062f3f35228dbc67aa40bd982e646508b4ff7cb6ef029111e2c0325039e60679800d6c6886be5 +OpenLibm.v0.8.5+0.x86_64-apple-darwin.tar.gz/md5/bd671ab9fe01835cab3e42e7cfa790fb +OpenLibm.v0.8.5+0.x86_64-apple-darwin.tar.gz/sha512/8bf2e66df17effc1e8778453904ffc20127f785bf096873289e8fdd8b17069ca844faffbd9f7621b87a7cb0a0051037eb9402360f2a03cf8794fbac8f7719777 +OpenLibm.v0.8.5+0.x86_64-linux-gnu.tar.gz/md5/df7fab134fbce3b625e9a82376f23e79 +OpenLibm.v0.8.5+0.x86_64-linux-gnu.tar.gz/sha512/64d07434e0db79833f84a2225838456eb9532617d377a776b3a534a908b1673bc4f890903f95350e4045e05c29539d993a18ecadeb879761e279ec3947f74390 +OpenLibm.v0.8.5+0.x86_64-linux-musl.tar.gz/md5/ebef6bb7651d116b397e035f39adfb1b +OpenLibm.v0.8.5+0.x86_64-linux-musl.tar.gz/sha512/de9036073e5dba2721b4119ecbbd21a0c9f75b65aff9392b7e88e464da35b97135d62404477441d0dadd3a2f8d49f1082291b35bf4b626fb1096d36d401980bf +OpenLibm.v0.8.5+0.x86_64-unknown-freebsd.tar.gz/md5/1115497539f00a37af18aa6516d52268 +OpenLibm.v0.8.5+0.x86_64-unknown-freebsd.tar.gz/sha512/71a2c06d141b3671fd220f2d88d72e845848b6d2b08a7b3a6c4bb1d5cc27cc450e1e681647bb583e7ed6375d5a70748401e95e61dc95d7808f33a9aa06755337 +OpenLibm.v0.8.5+0.x86_64-w64-mingw32.tar.gz/md5/b6b5335f4c83f7ebf0f74cf753358f00 +OpenLibm.v0.8.5+0.x86_64-w64-mingw32.tar.gz/sha512/e8351ddda305b757f337bb7ea26c441968843b23861676f0bdd7bcf83bb3969af790d4112307d3204eb87fac044dda9be305f349700ebe9ba2bfe3d6df24fde8 +openlibm-db24332879c320606c37f77fea165e6ecb49153c.tar.gz/md5/2375dd448e77e59152442a4b33abda01 +openlibm-db24332879c320606c37f77fea165e6ecb49153c.tar.gz/sha512/36054e7051990d04913f054a0542e2e104273f61308e9a442c2dab3dd392d40c03f264fbeca93c4296218eed85dad71028989a225088254013d752f4407d57ef diff --git a/deps/openlibm.version b/deps/openlibm.version index 13129a0c0a860..788701a66301b 100644 --- a/deps/openlibm.version +++ b/deps/openlibm.version @@ -4,6 +4,6 @@ OPENLIBM_JLL_NAME := OpenLibm ## source build -OPENLIBM_VER := 0.8.4 -OPENLIBM_BRANCH=v0.8.4 -OPENLIBM_SHA1=c4667caea25ae3487adf6760b4a1dcf32477a4b8 +OPENLIBM_VER := 0.8.5 +OPENLIBM_BRANCH=v0.8.5 +OPENLIBM_SHA1=db24332879c320606c37f77fea165e6ecb49153c diff --git a/stdlib/Manifest.toml b/stdlib/Manifest.toml index 160ccac5ffa39..f029a210320cc 100644 --- a/stdlib/Manifest.toml +++ b/stdlib/Manifest.toml @@ -163,7 +163,7 @@ version = "0.3.28+3" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.4+1" +version = "0.8.5+0" [[deps.OpenSSL_jll]] deps = ["Artifacts", "Libdl"] diff --git a/stdlib/OpenLibm_jll/Project.toml b/stdlib/OpenLibm_jll/Project.toml index 1d52749032fa4..431528ee3f400 100644 --- a/stdlib/OpenLibm_jll/Project.toml +++ b/stdlib/OpenLibm_jll/Project.toml @@ -1,6 +1,6 @@ name = "OpenLibm_jll" uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.4+1" +version = "0.8.5+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" From b8ab9f37469d9c19eeac1f9b5d40a499d3a176e8 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 8 Jan 2025 08:14:34 -0500 Subject: [PATCH 144/198] Revert "add fenv cache to task struct (#51288)" (#56982) This reverts commit 12aa9dea03a8a6bbe2891d3ca6ce34a21ec84734. un-fixes #51277 Alternatively, we could add a flag for whether the state is non-default so we know whether `fesetenv` is necessary, if this behavior is considered desireable. --- src/julia.h | 4 ---- src/task.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/julia.h b/src/julia.h index bfa9d0857c73c..4084b340d91e5 100644 --- a/src/julia.h +++ b/src/julia.h @@ -20,7 +20,6 @@ #include "libsupport.h" #include #include -#include #include "htable.h" #include "arraylist.h" @@ -2314,9 +2313,6 @@ typedef struct _jl_task_t { _Atomic(uint64_t) finished_at; // hidden state: - // cached floating point environment - // only updated at task switch - fenv_t fenv; // id of owning thread - does not need to be defined until the task runs _Atomic(int16_t) tid; diff --git a/src/task.c b/src/task.c index 1a50d6fcbcf65..d56d60eb58cb5 100644 --- a/src/task.c +++ b/src/task.c @@ -541,7 +541,6 @@ JL_NO_ASAN static void ctx_switch(jl_task_t *lastt) jl_set_pgcstack(&t->gcstack); jl_signal_fence(); lastt->ptls = NULL; - fegetenv(&lastt->fenv); #ifdef MIGRATE_TASKS ptls->previous_task = lastt; #endif @@ -734,7 +733,6 @@ JL_DLLEXPORT void jl_switch(void) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER 0 == ptls->finalizers_inhibited); ptls->finalizers_inhibited = finalizers_inhibited; jl_timing_block_task_enter(ct, ptls, blk); (void)blk; - fesetenv(&ct->fenv); sig_atomic_t other_defer_signal = ptls->defer_signal; ptls->defer_signal = defer_signal; @@ -1147,7 +1145,6 @@ JL_DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, jl_value_t *completion t->excstack = NULL; t->ctx.started = 0; t->priority = 0; - fegetenv(&t->fenv); jl_atomic_store_relaxed(&t->tid, -1); t->threadpoolid = ct->threadpoolid; t->ptls = NULL; @@ -1254,7 +1251,6 @@ CFI_NORETURN if (!pt->sticky && !pt->ctx.copy_stack) jl_atomic_store_release(&pt->tid, -1); #endif - fesetenv(&ct->fenv); ct->ctx.started = 1; if (ct->metrics_enabled) { From 98dc249622fa23e073419caeaa1213c69e1a0295 Mon Sep 17 00:00:00 2001 From: rileysheridan Date: Wed, 8 Jan 2025 08:26:02 -0500 Subject: [PATCH 145/198] Add tests for Base.cwstring (#56123) Co-authored-by: Sukera <11753998+Seelengrab@users.noreply.github.com> Co-authored-by: Lilith Orion Hafner --- test/strings/basic.jl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/strings/basic.jl b/test/strings/basic.jl index 3fc611a660975..f90ce8c697ed8 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -1423,3 +1423,20 @@ end @test transcode(String, transcode(UInt8, transcode(UInt16, str))) == str end end + +if Sys.iswindows() + @testset "cwstring" begin + # empty string + str_0 = "" + # string with embedded NUL character + str_1 = "Au\000B" + # string with terminating NUL character + str_2 = "Wordu\000" + # "Regular" string with UTF-8 characters of differing byte counts + str_3 = "aܣ𒀀" + @test Base.cwstring(str_0) == UInt16[0x0000] + @test_throws ArgumentError Base.cwstring(str_1) + @test_throws ArgumentError Base.cwstring(str_2) + @test Base.cwstring(str_3) == UInt16[0x0061, 0x0723, 0xd808, 0xdc00, 0x0000] + end +end From 38b41b5f6cbef96643f1495e1c6ea2470b6e7250 Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Wed, 8 Jan 2025 08:29:43 -0500 Subject: [PATCH 146/198] Allow `map!(f, array)` (#40632) ...there's really no sensible interpretation of `map!(f, array)` other than `map!(f, array, array)`. --------- Co-authored-by: Lilith Orion Hafner --- NEWS.md | 1 + base/abstractarray.jl | 25 +++++++++++++++++++++++-- test/abstractarray.jl | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 1708866609427..6c378c8186007 100644 --- a/NEWS.md +++ b/NEWS.md @@ -117,6 +117,7 @@ New library features * `invoke` now supports passing a CodeInstance instead of a type, which can enable certain compiler plugin workflows ([#56660]). * `sort` now supports `NTuple`s ([#54494]) +* `map!(f, A)` now stores the results in `A`, like `map!(f, A, A)`. or `A .= f.(A)` ([#40632]). Standard library changes ------------------------ diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 6d222e7e26281..a370b79976ab0 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -3503,11 +3503,32 @@ julia> map!(+, zeros(Int, 5), 100:999, 1:3) ``` """ function map!(f::F, dest::AbstractArray, As::AbstractArray...) where {F} - isempty(As) && throw(ArgumentError( - """map! requires at least one "source" argument""")) + @assert !isempty(As) # should dispatch to map!(f, A) map_n!(f, dest, As) end +""" + map!(function, array) + +Like [`map`](@ref), but stores the result in the same array. +!!! compat "Julia 1.12" + This method requires Julia 1.12 or later. To support previous versions too, + use the equivalent `map!(function, array, array)`. + +# Examples +```jldoctest +julia> a = [1 2 3; 4 5 6]; + +julia> map!(x -> x^3, a); + +julia> a +2×3 Matrix{$Int}: + 1 8 27 + 64 125 216 +``` +""" +map!(f::F, inout::AbstractArray) where F = map!(f, inout, inout) + """ map(f, A::AbstractArray...) -> N-array diff --git a/test/abstractarray.jl b/test/abstractarray.jl index c7ec61704c1bc..d1f30eacafacc 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -908,7 +908,7 @@ test_ind2sub(TestAbstractArray) include("generic_map_tests.jl") generic_map_tests(map, map!) -@test_throws ArgumentError map!(-, [1]) +@test map!(-, [1]) == [-1] test_UInt_indexing(TestAbstractArray) test_13315(TestAbstractArray) From b58dcc5f3f10a20fab7317586155c9b6f07c38fc Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Wed, 8 Jan 2025 07:34:03 -0600 Subject: [PATCH 147/198] Fix and test lcm([1//2, 1//2]) == 1//1 (#56423) --- base/intfuncs.jl | 11 ++++++++++- test/intfuncs.jl | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/base/intfuncs.jl b/base/intfuncs.jl index db3b1fdeeb521..13a5007e4c74b 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -150,7 +150,16 @@ gcd(a::T, b::T) where T<:Real = throw(MethodError(gcd, (a,b))) lcm(a::T, b::T) where T<:Real = throw(MethodError(lcm, (a,b))) gcd(abc::AbstractArray{<:Real}) = reduce(gcd, abc; init=zero(eltype(abc))) -lcm(abc::AbstractArray{<:Real}) = reduce(lcm, abc; init=one(eltype(abc))) +function lcm(abc::AbstractArray{<:Real}) + # Using reduce with init=one(eltype(abc)) is buggy for Rationals. + l = length(abc) + if l == 0 + eltype(abc) <: Integer && return one(eltype(abc)) + throw(ArgumentError("lcm has no identity for $(eltype(abc))")) + end + l == 1 && return abs(only(abc)) + return reduce(lcm, abc) +end function gcd(abc::AbstractArray{<:Integer}) a = zero(eltype(abc)) diff --git a/test/intfuncs.jl b/test/intfuncs.jl index 6f1bde69dddfe..38f29344d2f30 100644 --- a/test/intfuncs.jl +++ b/test/intfuncs.jl @@ -191,6 +191,13 @@ end @test lcm(T[2, 4, 6]) ⟷ T(12) end + + # Issue #55379 + @test lcm([1//2; 1//2]) === lcm([1//2, 1//2]) === lcm(1//2, 1//2) === 1//2 + @test gcd(Int[]) === 0 + @test lcm(Int[]) === 1 + @test gcd(Rational{Int}[]) === 0//1 + @test_throws ArgumentError("lcm has no identity for Rational{$Int}") lcm(Rational{Int}[]) end ⟷(a::Tuple{T, T, T}, b::Tuple{T, T, T}) where T <: Union{Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128} = a === b From 75cdffeb0f37b438950534712755a4f7cebbdd8c Mon Sep 17 00:00:00 2001 From: FX Coudert Date: Wed, 8 Jan 2025 16:34:38 +0100 Subject: [PATCH 148/198] Install correct libgcc_s on darwin (#56965) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/JuliaLang/julia/issues/48056 We could simplify the logic a lot if we assume that modern Julia is always built against GCC ≥ 12. Would that be a fair assumption. --- deps/csl.mk | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/deps/csl.mk b/deps/csl.mk index fefe71a5e871c..a50a08fab8506 100644 --- a/deps/csl.mk +++ b/deps/csl.mk @@ -75,12 +75,24 @@ else $(eval $(call copy_csl,$(call versioned_libname,libgcc_s_seh,1))) endif else -ifeq ($(APPLE_ARCH),arm64) +ifeq ($(OS),Darwin) +# On macOS, libgcc_s has soversion 1.1 always on aarch64 and only for GCC 12+ +# (-> libgfortran 5) on x86_64 +ifeq ($(ARCH),aarch64) +$(eval $(call copy_csl,$(call versioned_libname,libgcc_s,1.1))) +else +ifeq ($(LIBGFORTRAN_VERSION),5) $(eval $(call copy_csl,$(call versioned_libname,libgcc_s,1.1))) else $(eval $(call copy_csl,$(call versioned_libname,libgcc_s,1))) endif endif +else +# Other targets just use libgcc_s.1 +$(eval $(call copy_csl,$(call versioned_libname,libgcc_s,1))) +endif +endif + # winpthread is only Windows, pthread is only others ifeq ($(OS),WINNT) $(eval $(call copy_csl,$(call versioned_libname,libwinpthread,1))) From 64d4c6b13185cf460fa2be9e6b561ebf8721e25e Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Wed, 8 Jan 2025 12:37:57 -0600 Subject: [PATCH 149/198] Clarify mathematical definition of `lcm` (#56992) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some folks define `lcm(x::T,y::T)` as any `z::T` such that there exists `a::T, b::T` with `a*x==z` and `b*y==z` and for all `zʹ::T` such that there exist `a::T, b::T` with `a*x==zʹ` and `b*y==zʹ`, there also exists `c::T` with `z*c==zʹ`. This is a reasonable definition, but not what we use. Notably, it makes `lcm(x::Rational, y::Rational) = z::Rational` true for all finite, nonzero `x`, `y`, and `z`. The definition we use requires `a`, `b`, and `c` to all be _integers_, not rationals in the case of `lcm(x::Rational, y::Rational)`. This clarifies what we mean when we define `lcm(x::Rational, y::Rational)` and also how the generic function should be extended. See [this thread](https://github.com/JuliaLang/julia/pull/56423#discussion_r1826999933) for more discussion --- base/intfuncs.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/base/intfuncs.jl b/base/intfuncs.jl index 13a5007e4c74b..dc81f2bd3e489 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -97,6 +97,9 @@ end Least common (positive) multiple (or zero if any argument is zero). The arguments may be integer and rational numbers. +``a`` is a multiple of ``b`` if there exists an integer ``m`` such +that ``a=mb``. + !!! compat "Julia 1.4" Rational arguments require Julia 1.4 or later. From 8bf280277db13a10c50f218d6940b8766c58a39a Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 8 Jan 2025 13:47:27 -0500 Subject: [PATCH 150/198] CodeInstance: remove relocatability field (#56975) This field lost its meaning awhile back and is better tracked only as part of the compressed CodeInfo instead of trying to accurately copy and update this field. --- Compiler/src/typeinfer.jl | 21 +++++---------------- Compiler/test/abioverride.jl | 2 +- base/boot.jl | 6 +++--- src/gf.c | 17 +++++++---------- src/jltypes.c | 13 ++++++------- src/julia.h | 1 - src/julia_internal.h | 2 +- src/method.c | 4 ---- src/opaque_closure.c | 2 +- src/staticdata.c | 23 ++++++++++++----------- src/staticdata_utils.c | 16 +--------------- src/toplevel.c | 2 +- test/precompile.jl | 7 +++---- 13 files changed, 41 insertions(+), 75 deletions(-) diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index e2821f79cca0c..49cc711dc72df 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -120,7 +120,6 @@ function finish!(interp::AbstractInterpreter, caller::InferenceState) end inferred_result = nothing uncompressed = inferred_result - relocatability = 0x1 const_flag = is_result_constabi_eligible(result) discard_src = caller.cache_mode === CACHE_MODE_NULL || const_flag if !discard_src @@ -139,22 +138,14 @@ function finish!(interp::AbstractInterpreter, caller::InferenceState) elseif ci.owner === nothing # The global cache can only handle objects that codegen understands inferred_result = nothing - else - relocatability = 0x0 - end - if isa(inferred_result, String) - t = @_gc_preserve_begin inferred_result - relocatability = unsafe_load(unsafe_convert(Ptr{UInt8}, inferred_result), Core.sizeof(inferred_result)) - @_gc_preserve_end t end end - # n.b. relocatability = !isa(inferred_result, String) || inferred_result[end] if !@isdefined di di = DebugInfo(result.linfo) end - ccall(:jl_update_codeinst, Cvoid, (Any, Any, Int32, UInt, UInt, UInt32, Any, UInt8, Any, Any), + ccall(:jl_update_codeinst, Cvoid, (Any, Any, Int32, UInt, UInt, UInt32, Any, Any, Any), ci, inferred_result, const_flag, first(result.valid_worlds), last(result.valid_worlds), encode_effects(result.ipo_effects), - result.analysis_results, relocatability, di, edges) + result.analysis_results, di, edges) engine_reject(interp, ci) if !discard_src && isdefined(interp, :codegen) && uncompressed isa CodeInfo # record that the caller could use this result to generate code when required, if desired, to avoid repeating n^2 work @@ -176,7 +167,6 @@ end function finish!(interp::AbstractInterpreter, mi::MethodInstance, ci::CodeInstance, src::CodeInfo) user_edges = src.edges edges = user_edges isa SimpleVector ? user_edges : user_edges === nothing ? Core.svec() : Core.svec(user_edges...) - relocatability = 0x1 const_flag = false di = src.debuginfo rettype = Any @@ -196,8 +186,8 @@ function finish!(interp::AbstractInterpreter, mi::MethodInstance, ci::CodeInstan end ccall(:jl_fill_codeinst, Cvoid, (Any, Any, Any, Any, Int32, UInt, UInt, UInt32, Any, Any, Any), ci, rettype, exctype, nothing, const_flags, min_world, max_world, ipo_effects, nothing, di, edges) - ccall(:jl_update_codeinst, Cvoid, (Any, Any, Int32, UInt, UInt, UInt32, Any, UInt8, Any, Any), - ci, nothing, const_flag, min_world, max_world, ipo_effects, nothing, relocatability, di, edges) + ccall(:jl_update_codeinst, Cvoid, (Any, Any, Int32, UInt, UInt, UInt32, Any, Any, Any), + ci, nothing, const_flag, min_world, max_world, ipo_effects, nothing, di, edges) code_cache(interp)[mi] = ci if isdefined(interp, :codegen) interp.codegen[ci] = src @@ -523,7 +513,6 @@ function finishinfer!(me::InferenceState, interp::AbstractInterpreter) rettype_const = nothing const_flags = 0x0 end - relocatability = 0x1 di = nothing edges = empty_edges # `edges` will be updated within `finish!` ci = result.ci @@ -827,7 +816,7 @@ function codeinst_as_edge(interp::AbstractInterpreter, sv::InferenceState, @nosp end end ci = CodeInstance(mi, cache_owner(interp), Any, Any, nothing, nothing, zero(Int32), - min_world, max_world, zero(UInt32), nothing, zero(UInt8), nothing, edges) + min_world, max_world, zero(UInt32), nothing, nothing, edges) if max_world == typemax(UInt) # if we can record all of the backedges in the global reverse-cache, # we can now widen our applicability in the global cache too diff --git a/Compiler/test/abioverride.jl b/Compiler/test/abioverride.jl index e257074852099..da9b1f92786e5 100644 --- a/Compiler/test/abioverride.jl +++ b/Compiler/test/abioverride.jl @@ -46,7 +46,7 @@ let world = Base.tls_world_age() #=owner=#SecondArgConstOverride(1), new_source.rettype, Any#=new_source.exctype is missing=#, #=inferred_const=#nothing, #=code=#nothing, #=const_flags=#Int32(0), new_source.min_world, new_source.max_world, #=new_source.ipo_purity_bits is missing=#UInt32(0), - #=analysis_results=#nothing, #=not relocatable?=#UInt8(0), new_source.debuginfo, new_source.edges) + #=analysis_results=#nothing, new_source.debuginfo, new_source.edges) # Poke the CI into the global cache # This isn't necessary, but does conveniently give it the mandatory permanent GC-root before calling `invoke` diff --git a/base/boot.jl b/base/boot.jl index 4652524530703..05788844fde66 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -561,11 +561,11 @@ function CodeInstance( mi::Union{MethodInstance, ABIOverride}, owner, @nospecialize(rettype), @nospecialize(exctype), @nospecialize(inferred_const), @nospecialize(inferred), const_flags::Int32, min_world::UInt, max_world::UInt, effects::UInt32, @nospecialize(analysis_results), - relocatability::UInt8, di::Union{DebugInfo,Nothing}, edges::SimpleVector) + di::Union{DebugInfo,Nothing}, edges::SimpleVector) return ccall(:jl_new_codeinst, Ref{CodeInstance}, - (Any, Any, Any, Any, Any, Any, Int32, UInt, UInt, UInt32, Any, UInt8, Any, Any), + (Any, Any, Any, Any, Any, Any, Int32, UInt, UInt, UInt32, Any, Any, Any), mi, owner, rettype, exctype, inferred_const, inferred, const_flags, min_world, max_world, - effects, analysis_results, relocatability, di, edges) + effects, analysis_results, di, edges) end GlobalRef(m::Module, s::Symbol) = ccall(:jl_module_globalref, Ref{GlobalRef}, (Any, Any), m, s) Module(name::Symbol=:anonymous, std_imports::Bool=true, default_names::Bool=true) = ccall(:jl_f_new_module, Ref{Module}, (Any, Bool, Bool), name, std_imports, default_names) diff --git a/src/gf.c b/src/gf.c index d5fbcfc7dcd6a..080d1ebd52ba8 100644 --- a/src/gf.c +++ b/src/gf.c @@ -323,7 +323,7 @@ jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_a jl_code_instance_t *codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, jl_nothing, jl_nothing, - 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, NULL, NULL); jl_mi_cache_insert(mi, codeinst); jl_atomic_store_relaxed(&codeinst->specptr.fptr1, fptr); jl_atomic_store_relaxed(&codeinst->invoke, jl_fptr_args); @@ -564,7 +564,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred( } codeinst = jl_new_codeinst( mi, owner, rettype, (jl_value_t*)jl_any_type, NULL, NULL, - 0, min_world, max_world, 0, jl_nothing, 0, di, edges); + 0, min_world, max_world, 0, jl_nothing, di, edges); jl_mi_cache_insert(mi, codeinst); return codeinst; } @@ -614,7 +614,6 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_value_t *inferred_const, jl_value_t *inferred, int32_t const_flags, size_t min_world, size_t max_world, uint32_t effects, jl_value_t *analysis_results, - uint8_t relocatability, jl_debuginfo_t *di, jl_svec_t *edges /*, int absolute_max*/) { assert(min_world <= max_world && "attempting to set invalid world constraints"); @@ -645,7 +644,6 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_atomic_store_relaxed(&codeinst->next, NULL); jl_atomic_store_relaxed(&codeinst->ipo_purity_bits, effects); codeinst->analysis_results = analysis_results; - codeinst->relocatability = relocatability; return codeinst; } @@ -653,11 +651,10 @@ JL_DLLEXPORT void jl_update_codeinst( jl_code_instance_t *codeinst, jl_value_t *inferred, int32_t const_flags, size_t min_world, size_t max_world, uint32_t effects, jl_value_t *analysis_results, - uint8_t relocatability, jl_debuginfo_t *di, jl_svec_t *edges /* , int absolute_max*/) + jl_debuginfo_t *di, jl_svec_t *edges /* , int absolute_max*/) { assert(min_world <= max_world && "attempting to set invalid world constraints"); //assert((!jl_is_method(codeinst->def->def.value) || max_world != ~(size_t)0 || min_world <= 1 || jl_svec_len(edges) != 0) && "missing edges"); - codeinst->relocatability = relocatability; codeinst->analysis_results = analysis_results; jl_gc_wb(codeinst, analysis_results); jl_atomic_store_relaxed(&codeinst->ipo_purity_bits, effects); @@ -715,7 +712,7 @@ JL_DLLEXPORT void jl_fill_codeinst( JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst_uninit(jl_method_instance_t *mi, jl_value_t *owner) { - jl_code_instance_t *codeinst = jl_new_codeinst(mi, owner, NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL); + jl_code_instance_t *codeinst = jl_new_codeinst(mi, owner, NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL); jl_atomic_store_relaxed(&codeinst->min_world, 1); // make temporarily invalid before returning, so that jl_fill_codeinst is valid later return codeinst; } @@ -2908,7 +2905,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t jl_read_codeinst_invoke(unspec, &specsigflags, &invoke, &fptr, 1); jl_code_instance_t *codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, NULL, NULL, - 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, NULL, NULL); codeinst->rettype_const = unspec->rettype_const; jl_atomic_store_relaxed(&codeinst->specptr.fptr, fptr); jl_atomic_store_relaxed(&codeinst->invoke, invoke); @@ -2929,7 +2926,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t if (!jl_code_requires_compiler(src, 0)) { jl_code_instance_t *codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, NULL, NULL, - 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, NULL, NULL); jl_atomic_store_release(&codeinst->invoke, jl_fptr_interpret_call); jl_mi_cache_insert(mi, codeinst); record_precompile_statement(mi, 0, 0); @@ -3019,7 +3016,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t jl_read_codeinst_invoke(ucache, &specsigflags, &invoke, &fptr, 1); codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, NULL, NULL, - 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, NULL, NULL); codeinst->rettype_const = ucache->rettype_const; // unspec is always not specsig, but might use specptr jl_atomic_store_relaxed(&codeinst->specptr.fptr, fptr); diff --git a/src/jltypes.c b/src/jltypes.c index fbdfe497ea312..b478ce7ea98fd 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -3638,7 +3638,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_code_instance_type = jl_new_datatype(jl_symbol("CodeInstance"), core, jl_any_type, jl_emptysvec, - jl_perm_symsvec(18, + jl_perm_symsvec(17, "def", "owner", "next", @@ -3653,9 +3653,9 @@ void jl_init_types(void) JL_GC_DISABLED //"absolute_max", "ipo_purity_bits", "analysis_results", - "specsigflags", "precompile", "relocatability", + "specsigflags", "precompile", "invoke", "specptr"), // function object decls - jl_svec(18, + jl_svec(17, jl_any_type, jl_any_type, jl_any_type, @@ -3672,13 +3672,12 @@ void jl_init_types(void) JL_GC_DISABLED jl_any_type, jl_bool_type, jl_bool_type, - jl_uint8_type, jl_any_type, jl_any_type), // fptrs jl_emptysvec, 0, 1, 1); jl_svecset(jl_code_instance_type->types, 2, jl_code_instance_type); - const static uint32_t code_instance_constfields[1] = { 0b000001000011100011 }; // Set fields 1, 2, 6-8, 13 as const - const static uint32_t code_instance_atomicfields[1] = { 0b110110111100011100 }; // Set fields 3-5, 9-12, 14-15, 17-18 as atomic + const static uint32_t code_instance_constfields[1] = { 0b00001000011100011 }; // Set fields 1, 2, 6-8, 13 as const + const static uint32_t code_instance_atomicfields[1] = { 0b11110111100011100 }; // Set fields 3-5, 9-12, 14-17 as atomic // Fields 4-5 are only operated on by construction and deserialization, so are effectively const at runtime // Fields ipo_purity_bits and analysis_results are not currently threadsafe or reliable, as they get mutated after optimization, but are not declared atomic // and there is no way to tell (during inference) if their value is finalized yet (to wait for them to be narrowed if applicable) @@ -3854,8 +3853,8 @@ void jl_init_types(void) JL_GC_DISABLED jl_svecset(jl_method_type->types, 13, jl_method_instance_type); //jl_svecset(jl_debuginfo_type->types, 0, jl_method_instance_type); // union(jl_method_instance_type, jl_method_type, jl_symbol_type) jl_svecset(jl_method_instance_type->types, 4, jl_code_instance_type); + jl_svecset(jl_code_instance_type->types, 15, jl_voidpointer_type); jl_svecset(jl_code_instance_type->types, 16, jl_voidpointer_type); - jl_svecset(jl_code_instance_type->types, 17, jl_voidpointer_type); jl_svecset(jl_binding_type->types, 0, jl_globalref_type); jl_svecset(jl_binding_partition_type->types, 3, jl_binding_partition_type); diff --git a/src/julia.h b/src/julia.h index 4084b340d91e5..b5416568b7ae9 100644 --- a/src/julia.h +++ b/src/julia.h @@ -467,7 +467,6 @@ typedef struct _jl_code_instance_t { // & 0b010 == invokeptr matches specptr // & 0b100 == From image _Atomic(uint8_t) precompile; // if set, this will be added to the output system image - uint8_t relocatability; // nonzero if all roots are built into sysimg or tagged by module key _Atomic(jl_callptr_t) invoke; // jlcall entry point usually, but if this codeinst belongs to an OC Method, then this is an jl_fptr_args_t fptr1 instead, unless it is not, because it is a special token object instead union _jl_generic_specptr_t { _Atomic(void*) fptr; diff --git a/src/julia_internal.h b/src/julia_internal.h index b1c32f6e2de6e..f8dd49eab65a3 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -691,7 +691,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_value_t *inferred_const, jl_value_t *inferred, int32_t const_flags, size_t min_world, size_t max_world, uint32_t effects, jl_value_t *analysis_results, - uint8_t relocatability, jl_debuginfo_t *di, jl_svec_t *edges /* , int absolute_max*/); + jl_debuginfo_t *di, jl_svec_t *edges /* , int absolute_max*/); JL_DLLEXPORT jl_code_instance_t *jl_get_ci_equiv(jl_code_instance_t *ci JL_PROPAGATES_ROOT, int compiled) JL_NOTSAFEPOINT; STATIC_INLINE jl_method_instance_t *jl_get_ci_mi(jl_code_instance_t *ci JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT diff --git a/src/method.c b/src/method.c index 8e3bb7d0060b7..0d173d960c90f 100644 --- a/src/method.c +++ b/src/method.c @@ -1384,10 +1384,6 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata, // at the time of writing the system image (such occur first in the list of // roots). These are the cases with `key = 0` that do not prevent // serialization. -// - CodeInstances have a `relocatability` field which when 1 indicates that -// every root is "safe," meaning it was either added at sysimg creation or is -// tagged with a non-zero `key`. Even a single unsafe root will cause this to -// have value 0. // Get the key of the current (final) block of roots static uint64_t current_root_id(jl_array_t *root_blocks) diff --git a/src/opaque_closure.c b/src/opaque_closure.c index 2d11d763be662..a10b5c617753c 100644 --- a/src/opaque_closure.c +++ b/src/opaque_closure.c @@ -169,7 +169,7 @@ JL_DLLEXPORT jl_opaque_closure_t *jl_new_opaque_closure_from_code_info(jl_tuplet if (!jl_is_svec(edges)) edges = jl_emptysvec; // OC doesn't really have edges, so just drop them for now inst = jl_new_codeinst(mi, jl_nothing, rt_ub, (jl_value_t*)jl_any_type, NULL, (jl_value_t*)ci, - 0, world, world, 0, jl_nothing, 0, ci->debuginfo, edges); + 0, world, world, 0, jl_nothing, ci->debuginfo, edges); jl_mi_cache_insert(mi, inst); } diff --git a/src/staticdata.c b/src/staticdata.c index 95d7ee94e15dc..bdeecb911e3eb 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -499,7 +499,6 @@ void *native_functions; // opaque jl_native_code_desc_t blob used for fetching // table of struct field addresses to rewrite during saving static htable_t field_replace; static htable_t bits_replace; -static htable_t relocatable_ext_cis; // array of definitions for the predefined function pointers // (reverse of fptr_to_id) @@ -924,11 +923,17 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_ } jl_value_t *inferred = jl_atomic_load_relaxed(&ci->inferred); if (inferred && inferred != jl_nothing) { // disregard if there is nothing here to delete (e.g. builtins, unspecialized) - if (!is_relocatable_ci(&relocatable_ext_cis, ci)) - record_field_change((jl_value_t**)&ci->inferred, jl_nothing); - else if (jl_is_method(mi->def.method) && // don't delete toplevel code - mi->def.method->source) { // don't delete code from optimized opaque closures that can't be reconstructed (and builtins) - if (jl_atomic_load_relaxed(&ci->max_world) != ~(size_t)0 || // delete all code that cannot run + jl_method_t *def = mi->def.method; + if (jl_is_method(def)) { // don't delete toplevel code + int is_relocatable = jl_is_code_info(inferred) || + (jl_is_string(inferred) && jl_string_len(inferred) > 0 && jl_string_data(inferred)[jl_string_len(inferred) - 1]); + if (!is_relocatable) { + record_field_change((jl_value_t**)&ci->inferred, jl_nothing); + } + else if (def->source == NULL) { + // don't delete code from optimized opaque closures that can't be reconstructed (and builtins) + } + else if (jl_atomic_load_relaxed(&ci->max_world) != ~(size_t)0 || // delete all code that cannot run jl_atomic_load_relaxed(&ci->invoke) == jl_fptr_const_return) { // delete all code that just returns a constant record_field_change((jl_value_t**)&ci->inferred, jl_nothing); } @@ -1801,7 +1806,6 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED jl_atomic_store_release(&newci->min_world, 1); jl_atomic_store_release(&newci->max_world, 0); } - newci->relocatability = 0; } jl_atomic_store_relaxed(&newci->invoke, NULL); jl_atomic_store_relaxed(&newci->specsigflags, 0); @@ -2865,7 +2869,7 @@ static void jl_prepare_serialization_data(jl_array_t *mod_array, jl_array_t *new // Extract `new_ext_cis` and `edges` now (from info prepared by jl_collect_methcache_from_mod) *method_roots_list = jl_alloc_vec_any(0); // Collect the new method roots for external specializations - jl_collect_new_roots(&relocatable_ext_cis, *method_roots_list, *new_ext_cis, worklist_key); + jl_collect_new_roots(*method_roots_list, *new_ext_cis, worklist_key); *edges = jl_alloc_vec_any(0); jl_collect_internal_cis(*edges, world); } @@ -3368,7 +3372,6 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli assert((ct->reentrant_timing & 0b1110) == 0); ct->reentrant_timing |= 0b1000; if (worklist) { - htable_new(&relocatable_ext_cis, 0); jl_prepare_serialization_data(mod_array, newly_inferred, jl_worklist_key(worklist), &extext_methods, &new_ext_cis, &method_roots_list, &edges); if (!emit_split) { @@ -3385,8 +3388,6 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli jl_save_system_image_to_stream(ff, mod_array, worklist, extext_methods, new_ext_cis, method_roots_list, edges); if (_native_data != NULL) native_functions = NULL; - if (worklist) - htable_free(&relocatable_ext_cis); // make sure we don't run any Julia code concurrently before this point // Re-enable running julia code for postoutput hooks, atexit, etc. jl_gc_enable_finalizers(ct, 1); diff --git a/src/staticdata_utils.c b/src/staticdata_utils.c index 5ff7a7b1b1fc0..5de85a8d6ec77 100644 --- a/src/staticdata_utils.c +++ b/src/staticdata_utils.c @@ -215,17 +215,6 @@ static int has_backedge_to_worklist(jl_method_instance_t *mi, htable_t *visited, return found; } -static int is_relocatable_ci(htable_t *relocatable_ext_cis, jl_code_instance_t *ci) -{ - if (!ci->relocatability) - return 0; - jl_method_instance_t *mi = jl_get_ci_mi(ci); - jl_method_t *m = mi->def.method; - if (!ptrhash_has(relocatable_ext_cis, ci) && jl_object_in_image((jl_value_t*)m) && (!jl_is_method(m) || jl_object_in_image((jl_value_t*)m->module))) - return 0; - return 1; -} - // Given the list of CodeInstances that were inferred during the build, select // those that are (1) external, (2) still valid, (3) are inferred to be called // from the worklist or explicitly added by a `precompile` statement, and @@ -247,8 +236,6 @@ static jl_array_t *queue_external_cis(jl_array_t *list) for (i = n0; i-- > 0; ) { jl_code_instance_t *ci = (jl_code_instance_t*)jl_array_ptr_ref(list, i); assert(jl_is_code_instance(ci)); - if (!ci->relocatability) - continue; jl_method_instance_t *mi = jl_get_ci_mi(ci); jl_method_t *m = mi->def.method; if (ci->owner == jl_nothing && jl_atomic_load_relaxed(&ci->inferred) && jl_is_method(m) && jl_object_in_image((jl_value_t*)m->module)) { @@ -275,7 +262,7 @@ static jl_array_t *queue_external_cis(jl_array_t *list) } // New roots for external methods -static void jl_collect_new_roots(htable_t *relocatable_ext_cis, jl_array_t *roots, jl_array_t *new_ext_cis, uint64_t key) +static void jl_collect_new_roots(jl_array_t *roots, jl_array_t *new_ext_cis, uint64_t key) { htable_t mset; htable_new(&mset, 0); @@ -286,7 +273,6 @@ static void jl_collect_new_roots(htable_t *relocatable_ext_cis, jl_array_t *root jl_method_t *m = jl_get_ci_mi(ci)->def.method; assert(jl_is_method(m)); ptrhash_put(&mset, (void*)m, (void*)m); - ptrhash_put(relocatable_ext_cis, (void*)ci, (void*)ci); } int nwithkey; void *const *table = mset.table; diff --git a/src/toplevel.c b/src/toplevel.c index 0f8fae8939faf..95a053f6135f6 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -640,7 +640,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst_for_uninferred(jl_method_instan jl_code_instance_t *ci = jl_new_codeinst(mi, (jl_value_t*)jl_uninferred_sym, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, jl_nothing, (jl_value_t*)src, 0, src->min_world, src->max_world, - 0, NULL, 1, NULL, NULL); + 0, NULL, NULL, NULL); return ci; } diff --git a/test/precompile.jl b/test/precompile.jl index 2d4a4d310b4e0..3b193e1facd7c 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -801,7 +801,7 @@ precompile_test_harness("code caching") do dir mi = minternal.specializations::Core.MethodInstance @test mi.specTypes == Tuple{typeof(M.getelsize),Vector{Int32}} ci = mi.cache - @test ci.relocatability == 0 + @test (codeunits(ci.inferred::String)[end]) === 0x01 @test ci.inferred !== nothing # ...and that we can add "untracked" roots & non-relocatable CodeInstances to them too Base.invokelatest() do @@ -812,7 +812,7 @@ precompile_test_harness("code caching") do dir mi = mispecs[2]::Core.MethodInstance mi.specTypes == Tuple{typeof(M.getelsize),Vector{M.X2}} ci = mi.cache - @test ci.relocatability == 0 + @test (codeunits(ci.inferred::String)[end]) == 0x00 # PkgA loads PkgB, and both add roots to the same `push!` method (both before and after loading B) Cache_module2 = :Cachea1544c83560f0c99 write(joinpath(dir, "$Cache_module2.jl"), @@ -1721,8 +1721,7 @@ precompile_test_harness("issue #46296") do load_path mi = first(Base.specializations(first(methods(identity)))) ci = Core.CodeInstance(mi, nothing, Any, Any, nothing, nothing, zero(Int32), typemin(UInt), - typemax(UInt), zero(UInt32), nothing, 0x00, - Core.DebugInfo(mi), Core.svec()) + typemax(UInt), zero(UInt32), nothing, Core.DebugInfo(mi), Core.svec()) __init__() = @assert ci isa Core.CodeInstance From 0868becb74faeea7a88b3050d3e960f2ca9962ba Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 8 Jan 2025 17:47:00 -0500 Subject: [PATCH 151/198] cfunction: fix segfault when jl_type_infer doesn't run (#56998) [Multivectors](https://s3.amazonaws.com/julialang-reports/nanosoldier/pkgeval/by_date/2025-01/05/Multivectors.primary.log) tried to recurse here too much though a generated function generator ending up back in inference, leading to a segfault here. --- src/codegen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 4b5676cc8216e..4b0f4ebd765fa 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7483,7 +7483,8 @@ static Function *gen_cfun_wrapper( if (lam) { // TODO: this isn't ideal to be unconditionally calling type inference from here codeinst = jl_type_infer(lam, world, SOURCE_MODE_NOT_REQUIRED); - astrt = codeinst->rettype; + if (codeinst) + astrt = codeinst->rettype; if (astrt != (jl_value_t*)jl_bottom_type && jl_type_intersection(astrt, declrt) == jl_bottom_type) { // Do not warn if the function never returns since it is From 11ce1714308460d08bd4d2acbf4a743816f898ad Mon Sep 17 00:00:00 2001 From: Diogo Netto <61364108+d-netto@users.noreply.github.com> Date: Wed, 8 Jan 2025 19:52:02 -0300 Subject: [PATCH 152/198] GC: report times spent in each step of sweeping (#56993) We've been using this patch for a while (e.g., https://github.com/RelationalAI/julia/pull/176), and it has proven valuable for identifying the most expensive part of sweeping in a customer workload. Specifically, it highlighted that the madvise stage was the bottleneck. These metrics allowed us to effectively determine whether concurrent page sweeping would be beneficial. --- base/timing.jl | 3 ++ src/gc-interface.h | 3 ++ src/gc-stock.c | 97 ++++++++++++++++++++++++++-------------------- 3 files changed, 60 insertions(+), 43 deletions(-) diff --git a/base/timing.jl b/base/timing.jl index 0088f8bb77eca..65c2a643d6a52 100644 --- a/base/timing.jl +++ b/base/timing.jl @@ -24,6 +24,9 @@ struct GC_Num mark_time ::Int64 stack_pool_sweep_time ::Int64 total_sweep_time ::Int64 + total_sweep_page_walk_time ::Int64 + total_sweep_madvise_time ::Int64 + total_sweep_free_mallocd_memory_time ::Int64 total_mark_time ::Int64 total_stack_pool_sweep_time::Int64 last_full_sweep ::Int64 diff --git a/src/gc-interface.h b/src/gc-interface.h index e4a27782f7520..826e91355b17a 100644 --- a/src/gc-interface.h +++ b/src/gc-interface.h @@ -46,6 +46,9 @@ typedef struct { uint64_t mark_time; uint64_t stack_pool_sweep_time; uint64_t total_sweep_time; + uint64_t total_sweep_page_walk_time; + uint64_t total_sweep_madvise_time; + uint64_t total_sweep_free_mallocd_memory_time; uint64_t total_mark_time; uint64_t total_stack_pool_sweep_time; uint64_t last_full_sweep; diff --git a/src/gc-stock.c b/src/gc-stock.c index d2d9104ad8d22..8118b3c5629ae 100644 --- a/src/gc-stock.c +++ b/src/gc-stock.c @@ -984,9 +984,12 @@ STATIC_INLINE void gc_sweep_pool_page(gc_page_profiler_serializer_t *s, jl_gc_pa // sweep over all memory that is being used and not in a pool static void gc_sweep_other(jl_ptls_t ptls, int sweep_full) JL_NOTSAFEPOINT { + uint64_t t_free_mallocd_memory_start = jl_hrtime(); gc_sweep_foreign_objs(); sweep_malloced_memory(); sweep_big(ptls); + uint64_t t_free_mallocd_memory_end = jl_hrtime(); + gc_num.total_sweep_free_mallocd_memory_time += t_free_mallocd_memory_end - t_free_mallocd_memory_start; jl_engine_sweep(gc_all_tls_states); } @@ -1380,58 +1383,63 @@ static void gc_sweep_pool(void) } } - // the actual sweeping - jl_gc_padded_page_stack_t *new_gc_allocd_scratch = (jl_gc_padded_page_stack_t *) calloc_s(n_threads * sizeof(jl_gc_padded_page_stack_t)); - jl_ptls_t ptls = jl_current_task->ptls; - gc_sweep_wake_all_pages(ptls, new_gc_allocd_scratch); - gc_sweep_pool_parallel(ptls); - gc_sweep_wait_for_all_pages(); - - // reset half-pages pointers - for (int t_i = 0; t_i < n_threads; t_i++) { - jl_ptls_t ptls2 = gc_all_tls_states[t_i]; - if (ptls2 != NULL) { - ptls2->gc_tls.page_metadata_allocd = new_gc_allocd_scratch[t_i].stack; - for (int i = 0; i < JL_GC_N_POOLS; i++) { - jl_gc_pool_t *p = &ptls2->gc_tls.heap.norm_pools[i]; - p->newpages = NULL; + uint64_t t_page_walk_start = jl_hrtime(); + { + // the actual sweeping + jl_gc_padded_page_stack_t *new_gc_allocd_scratch = (jl_gc_padded_page_stack_t *) calloc_s(n_threads * sizeof(jl_gc_padded_page_stack_t)); + jl_ptls_t ptls = jl_current_task->ptls; + gc_sweep_wake_all_pages(ptls, new_gc_allocd_scratch); + gc_sweep_pool_parallel(ptls); + gc_sweep_wait_for_all_pages(); + + // reset half-pages pointers + for (int t_i = 0; t_i < n_threads; t_i++) { + jl_ptls_t ptls2 = gc_all_tls_states[t_i]; + if (ptls2 != NULL) { + ptls2->gc_tls.page_metadata_allocd = new_gc_allocd_scratch[t_i].stack; + for (int i = 0; i < JL_GC_N_POOLS; i++) { + jl_gc_pool_t *p = &ptls2->gc_tls.heap.norm_pools[i]; + p->newpages = NULL; + } } } - } - // merge free lists - for (int t_i = 0; t_i < n_threads; t_i++) { - jl_ptls_t ptls2 = gc_all_tls_states[t_i]; - if (ptls2 == NULL) { - continue; - } - jl_gc_pagemeta_t *pg = jl_atomic_load_relaxed(&ptls2->gc_tls.page_metadata_allocd.bottom); - while (pg != NULL) { - jl_gc_pagemeta_t *pg2 = pg->next; - if (pg->fl_begin_offset != UINT16_MAX) { - char *cur_pg = pg->data; - jl_taggedvalue_t *fl_beg = (jl_taggedvalue_t*)(cur_pg + pg->fl_begin_offset); - jl_taggedvalue_t *fl_end = (jl_taggedvalue_t*)(cur_pg + pg->fl_end_offset); - *pfl[t_i * JL_GC_N_POOLS + pg->pool_n] = fl_beg; - pfl[t_i * JL_GC_N_POOLS + pg->pool_n] = &fl_end->next; + // merge free lists + for (int t_i = 0; t_i < n_threads; t_i++) { + jl_ptls_t ptls2 = gc_all_tls_states[t_i]; + if (ptls2 == NULL) { + continue; + } + jl_gc_pagemeta_t *pg = jl_atomic_load_relaxed(&ptls2->gc_tls.page_metadata_allocd.bottom); + while (pg != NULL) { + jl_gc_pagemeta_t *pg2 = pg->next; + if (pg->fl_begin_offset != UINT16_MAX) { + char *cur_pg = pg->data; + jl_taggedvalue_t *fl_beg = (jl_taggedvalue_t*)(cur_pg + pg->fl_begin_offset); + jl_taggedvalue_t *fl_end = (jl_taggedvalue_t*)(cur_pg + pg->fl_end_offset); + *pfl[t_i * JL_GC_N_POOLS + pg->pool_n] = fl_beg; + pfl[t_i * JL_GC_N_POOLS + pg->pool_n] = &fl_end->next; + } + pg = pg2; } - pg = pg2; } - } - // null out terminal pointers of free lists - for (int t_i = 0; t_i < n_threads; t_i++) { - jl_ptls_t ptls2 = gc_all_tls_states[t_i]; - if (ptls2 != NULL) { - for (int i = 0; i < JL_GC_N_POOLS; i++) { - *pfl[t_i * JL_GC_N_POOLS + i] = NULL; + // null out terminal pointers of free lists + for (int t_i = 0; t_i < n_threads; t_i++) { + jl_ptls_t ptls2 = gc_all_tls_states[t_i]; + if (ptls2 != NULL) { + for (int i = 0; i < JL_GC_N_POOLS; i++) { + *pfl[t_i * JL_GC_N_POOLS + i] = NULL; + } } } - } - // cleanup - free(pfl); - free(new_gc_allocd_scratch); + // cleanup + free(pfl); + free(new_gc_allocd_scratch); + } + uint64_t t_page_walk_end = jl_hrtime(); + gc_num.total_sweep_page_walk_time += t_page_walk_end - t_page_walk_start; #ifdef _P64 // only enable concurrent sweeping on 64bit // wake thread up to sweep concurrently @@ -1439,7 +1447,10 @@ static void gc_sweep_pool(void) uv_sem_post(&gc_sweep_assists_needed); } else { + uint64_t t_madvise_start = jl_hrtime(); gc_free_pages(); + uint64_t t_madvise_end = jl_hrtime(); + gc_num.total_sweep_madvise_time += t_madvise_end - t_madvise_start; } #else gc_free_pages(); From 4250be80f52531fda3c72542c3e351c5ad67b4a5 Mon Sep 17 00:00:00 2001 From: Simeon David Schaub Date: Thu, 9 Jan 2025 11:37:29 +0100 Subject: [PATCH 153/198] add detection for zen 5 (#56967) ref https://github.com/llvm/llvm-project/commit/149a150b50c112e26fc5acbdd58250c44ccd777f --------- Co-authored-by: gbaraldi --- src/features_x86.h | 28 +++++++++++++++++++++++++++- src/processor_x86.cpp | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/features_x86.h b/src/features_x86.h index 2ecc8fee32a38..b6e2b23985b4f 100644 --- a/src/features_x86.h +++ b/src/features_x86.h @@ -5,6 +5,13 @@ #else #define JL_X86_64ONLY_VER(x) x #endif +// The code is similar to what is here so the bits can be used as reference +// https://github.com/llvm/llvm-project/blob/3f7905733820851bc4f65cb4af693c3101cbf20d/llvm/lib/TargetParser/Host.cpp#L1257 + +// The way the bits here work is an index into the features array. This is a bit array +// The index works as follows: +// 32*i + j where i is the index into the array and j is the bit in the array. +// There is a reference to what each index corresponds to in _get_host_cpu // X86 features definition // EAX=1: ECX @@ -79,6 +86,7 @@ JL_FEATURE_DEF(avx512vp2intersect, 32 * 4 + 8, 0) JL_FEATURE_DEF(serialize, 32 * 4 + 14, 110000) JL_FEATURE_DEF(tsxldtrk, 32 * 4 + 16, 110000) JL_FEATURE_DEF(pconfig, 32 * 4 + 18, 0) +// JL_FEATURE_DEF(ibt, 32 * 4 + 20, 0) JL_FEATURE_DEF_NAME(amx_bf16, 32 * 4 + 22, 110000, "amx-bf16") JL_FEATURE_DEF(avx512fp16, 32 * 4 + 23, 140000) JL_FEATURE_DEF_NAME(amx_tile, 32 * 4 + 24, 110000, "amx-tile") @@ -110,10 +118,28 @@ JL_FEATURE_DEF(clzero, 32 * 8 + 0, 0) JL_FEATURE_DEF(wbnoinvd, 32 * 8 + 9, 0) // EAX=7,ECX=1: EAX +JL_FEATURE_DEF(sha512, 32 * 9 + 0, 170000) +JL_FEATURE_DEF(sm3, 32 * 9 + 1, 170000) +JL_FEATURE_DEF(sm4, 32 * 9 + 2, 170000) +JL_FEATURE_DEF(raoint, 32 * 9 + 3, 170000) JL_FEATURE_DEF(avxvnni, 32 * 9 + 4, 120000) JL_FEATURE_DEF(avx512bf16, 32 * 9 + 5, 0) +JL_FEATURE_DEF(cmpccxadd, 32 * 9 + 7, 160000) +JL_FEATURE_DEF_NAME(amx_fp16, 32 * 9 + 21, 160000, "amx-fp16") +JL_FEATURE_DEF(hreset, 32 * 9 + 22, 160000) +JL_FEATURE_DEF(avxifma, 32 * 9 + 23, 160000) + +// EAX=7,ECX=1: EBX +JL_FEATURE_DEF(avxvnniint8, 32 * 10 + 4, 160000) +JL_FEATURE_DEF(avxneconvert, 32 * 10 + 5, 160000) +JL_FEATURE_DEF_NAME(amx_complex, 32 * 10 + 8, 170000, "amx-complex") +JL_FEATURE_DEF(avxvnniint16, 32 * 10 + 10, 170000) +JL_FEATURE_DEF(prefetchi, 32 * 10 + 14, 160000) +JL_FEATURE_DEF(usermsr, 32 * 10 + 15, 170000) +// JL_FEATURE_DEF(avx10, 32 * 10 + 19, 170000) // TODO: What to do about avx10 and it's mess? +// JL_FEATURE_DEF(apxf, 32 * 10 + 21, 190000) // EAX=0x14,ECX=0: EBX -JL_FEATURE_DEF(ptwrite, 32 * 10 + 4, 0) +JL_FEATURE_DEF(ptwrite, 32 * 11 + 4, 0) #undef JL_X86_64ONLY_VER diff --git a/src/processor_x86.cpp b/src/processor_x86.cpp index f1dff063de1d9..bf765be160ed2 100644 --- a/src/processor_x86.cpp +++ b/src/processor_x86.cpp @@ -96,9 +96,10 @@ enum class CPU : uint32_t { amd_znver2, amd_znver3, amd_znver4, + amd_znver5, }; -static constexpr size_t feature_sz = 11; +static constexpr size_t feature_sz = 12; static constexpr FeatureName feature_names[] = { #define JL_FEATURE_DEF(name, bit, llvmver) {#name, bit, llvmver}, #define JL_FEATURE_DEF_NAME(name, bit, llvmver, str) {str, bit, llvmver}, @@ -141,6 +142,10 @@ static constexpr FeatureDep deps[] = { {vpclmulqdq, avx}, {vpclmulqdq, pclmul}, {avxvnni, avx2}, + {avxvnniint8, avx2}, + {avxvnniint16, avx2}, + {avxifma, avx2}, + {avxneconvert, avx2}, {avx512f, avx2}, {avx512dq, avx512f}, {avx512ifma, avx512f}, @@ -159,6 +164,8 @@ static constexpr FeatureDep deps[] = { {avx512fp16, avx512vl}, {amx_int8, amx_tile}, {amx_bf16, amx_tile}, + {amx_fp16, amx_tile}, + {amx_complex, amx_tile}, {sse4a, sse3}, {xop, fma4}, {fma4, avx}, @@ -166,6 +173,9 @@ static constexpr FeatureDep deps[] = { {xsaveopt, xsave}, {xsavec, xsave}, {xsaves, xsave}, + {sha512, avx2}, + {sm3, avx}, + {sm4, avx2}, }; // We require cx16 on 64bit by default. This can be overwritten with `-cx16` @@ -236,6 +246,7 @@ constexpr auto znver2 = znver1 | get_feature_masks(clwb, rdpid, wbnoinvd); constexpr auto znver3 = znver2 | get_feature_masks(shstk, pku, vaes, vpclmulqdq); constexpr auto znver4 = znver3 | get_feature_masks(avx512f, avx512cd, avx512dq, avx512bw, avx512vl, avx512ifma, avx512vbmi, avx512vbmi2, avx512vnni, avx512bitalg, avx512vpopcntdq, avx512bf16, gfni, shstk, xsaves); +constexpr auto znver5 = znver4 | get_feature_masks(avxvnni, movdiri, movdir64b, avx512vp2intersect, prefetchi, avxvnni); } @@ -298,6 +309,7 @@ static constexpr CPUSpec cpus[] = { {"znver2", CPU::amd_znver2, CPU::generic, 0, Feature::znver2}, {"znver3", CPU::amd_znver3, CPU::amd_znver2, 120000, Feature::znver3}, {"znver4", CPU::amd_znver4, CPU::amd_znver3, 160000, Feature::znver4}, + {"znver5", CPU::amd_znver5, CPU::amd_znver4, 190000, Feature::znver5}, }; static constexpr size_t ncpu_names = sizeof(cpus) / sizeof(cpus[0]); @@ -575,6 +587,9 @@ static CPU get_amd_processor_name(uint32_t family, uint32_t model, const uint32_ return CPU::amd_znver4; } return CPU::amd_znver3; // fallback + case 26: + // if (model <= 0x77) + return CPU::amd_znver5; } } @@ -660,11 +675,12 @@ static NOINLINE std::pair> _get_host_cpu(void) int32_t info7[4]; jl_cpuidex(info7, 7, 1); features[9] = info7[0]; + features[10] = info7[1]; } if (maxleaf >= 0x14) { int32_t info14[4]; jl_cpuidex(info14, 0x14, 0); - features[10] = info14[1]; + features[11] = info14[1]; } // Fix up AVX bits to account for OS support and match LLVM model @@ -705,7 +721,20 @@ static NOINLINE std::pair> _get_host_cpu(void) else { cpu = uint32_t(CPU::generic); } - + /* Feature bits to register map + feature[0] = ecx + feature[1] = edx + feature[2] = leaf 7 ebx + feature[3] = leaf 7 ecx + feature[4] = leaf 7 edx + feature[5] = leaf 0x80000001 ecx + feature[6] = leaf 0x80000001 edx + feature[7] = leaf 0xd subleaf 1 eax + feature[8] = leaf 0x80000008 ebx + feature[9] = leaf 7 ebx subleaf 1 eax + feature[10] = leaf 7 ebx subleaf 1 ebx + feature[11] = leaf 0x14 ebx + */ return std::make_pair(cpu, features); } From 1ebacacc5a82e16930bd5ae70b641a3cbd6ee883 Mon Sep 17 00:00:00 2001 From: Will Tebbutt Date: Thu, 9 Jan 2025 11:30:55 +0000 Subject: [PATCH 154/198] fix deepcopy for non-trivial circular references (#56990) Resolves #56775 . Credit for this fix rests entirely with bbrehm . --------- Co-authored-by: Lilith Orion Hafner Co-authored-by: Neven Sajko <4944410+nsajko@users.noreply.github.com> --- base/deepcopy.jl | 7 +++++-- test/copy.jl | 9 +++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/base/deepcopy.jl b/base/deepcopy.jl index c4f9ae1a6cb10..f60ce2043dd5a 100644 --- a/base/deepcopy.jl +++ b/base/deepcopy.jl @@ -120,11 +120,14 @@ function _deepcopy_memory_t(@nospecialize(x::Memory), T, stackdict::IdDict) end return dest end -@eval function deepcopy_internal(x::Array{T, N}, stackdict::IdDict) where {T, N} +function deepcopy_internal(x::Array{T, N}, stackdict::IdDict) where {T, N} if haskey(stackdict, x) return stackdict[x]::typeof(x) end - stackdict[x] = $(Expr(:new, :(Array{T, N}), :(deepcopy_internal(x.ref, stackdict)), :(x.size))) + y = stackdict[x] = Array{T, N}(undef, ntuple(Returns(0), Val{N}())) + setfield!(y, :ref, deepcopy_internal(x.ref, stackdict)) + setfield!(y, :size, x.size) + y end function deepcopy_internal(x::GenericMemoryRef, stackdict::IdDict) if haskey(stackdict, x) diff --git a/test/copy.jl b/test/copy.jl index 559bf5d3e757a..f5cc57c86feaa 100644 --- a/test/copy.jl +++ b/test/copy.jl @@ -253,6 +253,15 @@ end @test copyto!(s, String[]) == [1, 2] # No error end +@testset "circular reference arrays" begin + # issue 56775 + p = Any[nothing] + p[1] = p + p2 = deepcopy(p) + @test p2 === p2[1] + @test p2 !== p +end + @testset "deepcopy_internal arrays" begin @test (@inferred Base.deepcopy_internal(zeros(), IdDict())) == zeros() end From cfd3922cabfdfca0b417651ee4cea5a649cbebe5 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Thu, 9 Jan 2025 17:28:11 +0100 Subject: [PATCH 155/198] Add basic code for binding partition revalidation (#56649) This adds the binding partition revalidation code from #54654. This is the last piece of that PR that hasn't been merged yet - however the TODO in that PR still stands for future work. This PR itself adds a callback that gets triggered by deleting a binding. It will then walk all code in the system and invalidate code instances of Methods whose lowered source referenced the given global. This walk is quite slow. Future work will add backedges and optimizations to make this faster, but the basic functionality should be in place with this PR. --- base/Base_compiler.jl | 1 + base/invalidation.jl | 111 ++++++++++++++++++++++++++++++++++++++++++ src/gf.c | 5 ++ src/module.c | 26 +++++++++- test/rebinding.jl | 7 +++ 5 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 base/invalidation.jl diff --git a/base/Base_compiler.jl b/base/Base_compiler.jl index 91f327980389d..db3ebb0232e38 100644 --- a/base/Base_compiler.jl +++ b/base/Base_compiler.jl @@ -255,6 +255,7 @@ include("ordering.jl") using .Order include("coreir.jl") +include("invalidation.jl") # For OS specific stuff # We need to strcat things here, before strings are really defined diff --git a/base/invalidation.jl b/base/invalidation.jl new file mode 100644 index 0000000000000..40a010ab7361c --- /dev/null +++ b/base/invalidation.jl @@ -0,0 +1,111 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +struct GlobalRefIterator + mod::Module +end +IteratorSize(::Type{GlobalRefIterator}) = SizeUnknown() +globalrefs(mod::Module) = GlobalRefIterator(mod) + +function iterate(gri::GlobalRefIterator, i = 1) + m = gri.mod + table = ccall(:jl_module_get_bindings, Ref{SimpleVector}, (Any,), m) + i == length(table) && return nothing + b = table[i] + b === nothing && return iterate(gri, i+1) + return ((b::Core.Binding).globalref, i+1) +end + +const TYPE_TYPE_MT = Type.body.name.mt +const NONFUNCTION_MT = Core.MethodTable.name.mt +function foreach_module_mtable(visit, m::Module, world::UInt) + for gb in globalrefs(m) + binding = gb.binding + bpart = lookup_binding_partition(world, binding) + if is_defined_const_binding(binding_kind(bpart)) + v = partition_restriction(bpart) + uw = unwrap_unionall(v) + name = gb.name + if isa(uw, DataType) + tn = uw.name + if tn.module === m && tn.name === name && tn.wrapper === v && isdefined(tn, :mt) + # this is the original/primary binding for the type (name/wrapper) + mt = tn.mt + if mt !== nothing && mt !== TYPE_TYPE_MT && mt !== NONFUNCTION_MT + @assert mt.module === m + visit(mt) || return false + end + end + elseif isa(v, Module) && v !== m && parentmodule(v) === m && _nameof(v) === name + # this is the original/primary binding for the submodule + foreach_module_mtable(visit, v, world) || return false + elseif isa(v, Core.MethodTable) && v.module === m && v.name === name + # this is probably an external method table here, so let's + # assume so as there is no way to precisely distinguish them + visit(v) || return false + end + end + end + return true +end + +function foreach_reachable_mtable(visit, world::UInt) + visit(TYPE_TYPE_MT) || return + visit(NONFUNCTION_MT) || return + for mod in loaded_modules_array() + foreach_module_mtable(visit, mod, world) + end +end + +function should_invalidate_code_for_globalref(gr::GlobalRef, src::CodeInfo) + found_any = false + labelchangemap = nothing + stmts = src.code + isgr(g::GlobalRef) = gr.mod == g.mod && gr.name === g.name + isgr(g) = false + for i = 1:length(stmts) + stmt = stmts[i] + if isgr(stmt) + found_any = true + continue + end + for ur in Compiler.userefs(stmt) + arg = ur[] + # If any of the GlobalRefs in this stmt match the one that + # we are about, we need to move out all GlobalRefs to preserve + # effect order, in case we later invalidate a different GR + if isa(arg, GlobalRef) + if isgr(arg) + @assert !isa(stmt, PhiNode) + found_any = true + break + end + end + end + end + return found_any +end + +function invalidate_code_for_globalref!(gr::GlobalRef, new_max_world::UInt) + valid_in_valuepos = false + foreach_reachable_mtable(new_max_world) do mt::Core.MethodTable + for method in MethodList(mt) + if isdefined(method, :source) + src = _uncompressed_ir(method) + old_stmts = src.code + if should_invalidate_code_for_globalref(gr, src) + for mi in specializations(method) + ci = mi.cache + while true + if ci.max_world > new_max_world + ccall(:jl_invalidate_code_instance, Cvoid, (Any, UInt), ci, new_max_world) + end + isdefined(ci, :next) || break + ci = ci.next + end + end + end + end + end + return true + end +end diff --git a/src/gf.c b/src/gf.c index 080d1ebd52ba8..ba28edfbeeff7 100644 --- a/src/gf.c +++ b/src/gf.c @@ -1867,6 +1867,11 @@ static void invalidate_code_instance(jl_code_instance_t *replaced, size_t max_wo JL_UNLOCK(&replaced_mi->def.method->writelock); } +JL_DLLEXPORT void jl_invalidate_code_instance(jl_code_instance_t *replaced, size_t max_world) +{ + invalidate_code_instance(replaced, max_world, 1); +} + static void _invalidate_backedges(jl_method_instance_t *replaced_mi, size_t max_world, int depth) { jl_array_t *backedges = replaced_mi->backedges; if (backedges) { diff --git a/src/module.c b/src/module.c index 1b4c5bd78f667..004371b9144b2 100644 --- a/src/module.c +++ b/src/module.c @@ -1032,6 +1032,21 @@ JL_DLLEXPORT void jl_set_const(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var jl_gc_wb(bpart, val); } +void jl_invalidate_binding_refs(jl_globalref_t *ref, size_t new_world) +{ + static jl_value_t *invalidate_code_for_globalref = NULL; + if (invalidate_code_for_globalref == NULL && jl_base_module != NULL) + invalidate_code_for_globalref = jl_get_global(jl_base_module, jl_symbol("invalidate_code_for_globalref!")); + if (!invalidate_code_for_globalref) + jl_error("Binding invalidation is not permitted during bootstrap."); + if (jl_generating_output()) + jl_error("Binding invalidation is not permitted during image generation."); + jl_value_t *boxed_world = jl_box_ulong(new_world); + JL_GC_PUSH1(&boxed_world); + jl_call2((jl_function_t*)invalidate_code_for_globalref, (jl_value_t*)ref, boxed_world); + JL_GC_POP(); +} + extern jl_mutex_t world_counter_lock; JL_DLLEXPORT void jl_disable_binding(jl_globalref_t *gr) { @@ -1046,9 +1061,11 @@ JL_DLLEXPORT void jl_disable_binding(jl_globalref_t *gr) JL_LOCK(&world_counter_lock); jl_task_t *ct = jl_current_task; + size_t last_world = ct->world_age; size_t new_max_world = jl_atomic_load_acquire(&jl_world_counter); - // TODO: Trigger invalidation here - (void)ct; + ct->world_age = jl_typeinf_world; + jl_invalidate_binding_refs(gr, new_max_world); + ct->world_age = last_world; jl_atomic_store_release(&bpart->max_world, new_max_world); jl_atomic_store_release(&jl_world_counter, new_max_world + 1); JL_UNLOCK(&world_counter_lock); @@ -1334,6 +1351,11 @@ JL_DLLEXPORT void jl_add_to_module_init_list(jl_value_t *mod) jl_array_ptr_1d_push(jl_module_init_order, mod); } +JL_DLLEXPORT jl_svec_t *jl_module_get_bindings(jl_module_t *m) +{ + return jl_atomic_load_relaxed(&m->bindings); +} + JL_DLLEXPORT void jl_init_restored_module(jl_value_t *mod) { if (!jl_generating_output() || jl_options.incremental) { diff --git a/test/rebinding.jl b/test/rebinding.jl index c93c34be7a75c..ad0ad1fc1643d 100644 --- a/test/rebinding.jl +++ b/test/rebinding.jl @@ -33,4 +33,11 @@ module Rebinding @test Base.@world(Foo, defined_world_age) == typeof(x) @test Base.@world(Rebinding.Foo, defined_world_age) == typeof(x) @test Base.@world((@__MODULE__).Foo, defined_world_age) == typeof(x) + + # Test invalidation (const -> undefined) + const delete_me = 1 + f_return_delete_me() = delete_me + @test f_return_delete_me() == 1 + Base.delete_binding(@__MODULE__, :delete_me) + @test_throws UndefVarError f_return_delete_me() end From 3d85309e800fcc8368a8291cc76bc28a10067b10 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Thu, 9 Jan 2025 17:29:39 +0100 Subject: [PATCH 156/198] Consolidate various isdefined functionality into a new builtin (#56985) In #54999 I extended `:isdefined` with the ability to specify whether or not to consider imported bindings defined. As a result, we now have two mechanisms for querying `isdefined` on globals (the other being `Core.isdefined`) with incompatible feature sets (`Core.isdefined` supports an atomic ordering argument, but not `allow_import`). Additionally, only one of them had proper codegen support. I also don't like to have IR forms for things that could be perfectly well handled by builtin calls (along the lines of #56713). So this tries to clean that all up by: 1. Adding a new builtin `isdefinedglobal` that has the full feature set 2. Dropping `:isdefined` on globals as an IR form (the frontend form gets lowered to the intrinsic if called on globals) 3. Wiring up codegen and correcting inference for that new builtin An additional motivation is that `isdefined` on globals needs support for partition edges (like other builtins), and having to have a special case for :isdefined was marginally annoying. Just using an intrinsic for this is much cleaner. Lastly, the reason for a new intrinsic over extending the existing `isdefined`, is that over time we've moved away from conflating fields and globals for Module (e.g. introducing `getglobal`/`setglobal!`), so this is a natural extension of that. Of course, the existing behavior is retained for ordinary `isdefined`. --- Compiler/src/Compiler.jl | 4 +- Compiler/src/abstractinterpretation.jl | 105 +++++++++++++++++++------ Compiler/src/ssair/verify.jl | 4 +- base/boot.jl | 2 +- base/docs/basedocs.jl | 34 ++++++++ doc/src/base/base.md | 1 + doc/src/devdocs/ast.md | 7 +- src/builtin_proto.h | 1 + src/builtins.c | 28 +++++++ src/codegen.cpp | 98 +++++++++++++++-------- src/interpreter.c | 13 +-- src/julia-syntax.scm | 10 ++- src/staticdata.c | 5 +- test/meta.jl | 2 +- test/syntax.jl | 34 ++++---- 15 files changed, 245 insertions(+), 103 deletions(-) diff --git a/Compiler/src/Compiler.jl b/Compiler/src/Compiler.jl index a9ab27a682ad7..ea939f86422c5 100644 --- a/Compiler/src/Compiler.jl +++ b/Compiler/src/Compiler.jl @@ -49,7 +49,7 @@ using Core: ABIOverride, Builtin, CodeInstance, IntrinsicFunction, MethodInstanc using Base using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospecializeinfer, - BINDING_KIND_GLOBAL, Base, BitVector, Bottom, Callable, DataTypeFieldDesc, + BINDING_KIND_GLOBAL, BINDING_KIND_UNDEF_CONST, Base, BitVector, Bottom, Callable, DataTypeFieldDesc, EffectsOverride, Filter, Generator, IteratorSize, JLOptions, NUM_EFFECTS_OVERRIDES, OneTo, Ordering, RefValue, SizeUnknown, _NAMEDTUPLE_NAME, _array_for, _bits_findnext, _methods_by_ftype, _uniontypes, all, allocatedinline, any, @@ -58,7 +58,7 @@ using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospeciali datatype_pointerfree, decode_effects_override, diff_names, fieldindex, generating_output, get_nospecializeinfer_sig, get_world_counter, has_free_typevars, hasgenerator, hasintersect, indexed_iterate, isType, is_file_tracked, is_function_def, - is_meta_expr, is_meta_expr_head, is_nospecialized, is_nospecializeinfer, + is_meta_expr, is_meta_expr_head, is_nospecialized, is_nospecializeinfer, is_defined_const_binding, is_some_const_binding, is_some_guard, is_some_imported, is_valid_intrinsic_elptr, isbitsunion, isconcretedispatch, isdispatchelem, isexpr, isfieldatomic, isidentityfree, iskindtype, ismutabletypename, ismutationfree, issingletontype, isvarargtype, isvatuple, diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index f2d4461a9874a..0c340a89d9878 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -2637,21 +2637,14 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), elseif f === Core.getfield && argtypes_are_actually_getglobal(argtypes) return Future(abstract_eval_getglobal(interp, sv, si.saw_latestworld, argtypes)) elseif f === Core.isdefined && argtypes_are_actually_getglobal(argtypes) - exct = Bottom - if length(argtypes) == 4 - order = argtypes[4] - exct = global_order_exct(order, #=loading=#true, #=storing=#false) - if !(isa(order, Const) && get_atomic_order(order.val, #=loading=#true, #=storing=#false).x >= MEMORY_ORDER_UNORDERED.x) - exct = Union{exct, ConcurrencyViolationError} - end - end - return Future(merge_exct(CallMeta(abstract_eval_isdefined( - interp, - GlobalRef((argtypes[2]::Const).val::Module, - (argtypes[3]::Const).val::Symbol), - si.saw_latestworld, - sv), - NoCallInfo()), exct)) + return Future(abstract_eval_isdefinedglobal(interp, argtypes[2], argtypes[3], Const(true), + length(argtypes) == 4 ? argtypes[4] : Const(:unordered), + si.saw_latestworld, sv)) + elseif f === Core.isdefinedglobal && 3 <= length(argtypes) <= 5 + return Future(abstract_eval_isdefinedglobal(interp, argtypes[2], argtypes[3], + length(argtypes) >= 4 ? argtypes[4] : Const(true), + length(argtypes) >= 5 ? argtypes[5] : Const(:unordered), + si.saw_latestworld, sv)) elseif f === Core.get_binding_type return Future(abstract_eval_get_binding_type(interp, sv, argtypes)) end @@ -3203,21 +3196,73 @@ function abstract_eval_isdefined_expr(interp::AbstractInterpreter, e::Expr, ssta return abstract_eval_isdefined(interp, sym, sstate.saw_latestworld, sv) end -function abstract_eval_isdefined(interp::AbstractInterpreter, @nospecialize(sym), saw_latestworld::Bool, sv::AbsIntState) +const generic_isdefinedglobal_effects = Effects(EFFECTS_TOTAL, consistent=ALWAYS_FALSE, nothrow=false) +function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, mod::Module, sym::Symbol, allow_import::Union{Bool, Nothing}, saw_latestworld::Bool, sv::AbsIntState) rt = Bool + if saw_latestworld + return RTEffects(rt, Union{}, Effects(generic_isdefinedglobal_effects, nothrow=true)) + end + effects = EFFECTS_TOTAL - exct = Union{} - isa(sym, Symbol) && (sym = GlobalRef(frame_module(sv), sym)) - if isa(sym, GlobalRef) - rte = abstract_eval_globalref(interp, sym, saw_latestworld, sv) + partition = lookup_binding_partition!(interp, GlobalRef(mod, sym), sv) + if allow_import !== true && is_some_imported(binding_kind(partition)) + if allow_import === false + rt = Const(false) + else + effects = Effects(generic_isdefinedglobal_effects, nothrow=true) + end + else + partition = walk_binding_partition!(interp, partition, sv) + rte = abstract_eval_partition_load(interp, partition) if rte.exct == Union{} rt = Const(true) elseif rte.rt === Union{} && rte.exct === UndefVarError rt = Const(false) else - effects = Effects(EFFECTS_TOTAL; consistent=ALWAYS_FALSE) + effects = Effects(generic_isdefinedglobal_effects, nothrow=true) + end + end + return RTEffects(rt, Union{}, effects) +end + +function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, @nospecialize(M), @nospecialize(s), @nospecialize(allow_import_arg), @nospecialize(order_arg), saw_latestworld::Bool, sv::AbsIntState) + exct = Bottom + allow_import = true + if allow_import_arg !== nothing + if !isa(allow_import_arg, Const) + allow_import = nothing + if widenconst(allow_import_arg) != Bool + exct = Union{exct, TypeError} + end + else + allow_import = allow_import_arg.val + end + end + if order_arg !== nothing + exct = global_order_exct(order_arg, #=loading=#true, #=storing=#false) + if !(isa(order_arg, Const) && get_atomic_order(order_arg.val, #=loading=#true, #=storing=#false).x >= MEMORY_ORDER_UNORDERED.x) + exct = Union{exct, ConcurrencyViolationError} + end + end + if M isa Const && s isa Const + M, s = M.val, s.val + if M isa Module && s isa Symbol + return merge_exct(CallMeta(abstract_eval_isdefinedglobal(interp, M, s, allow_import, saw_latestworld, sv), NoCallInfo()), exct) end - elseif isexpr(sym, :static_parameter) + return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo()) + elseif !hasintersect(widenconst(M), Module) || !hasintersect(widenconst(s), Symbol) + return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo()) + elseif M ⊑ Module && s ⊑ Symbol + return CallMeta(Bool, Union{exct, UndefVarError}, generic_isdefinedglobal_effects, NoCallInfo()) + end + return CallMeta(Bool, Union{exct, TypeError, UndefVarError}, generic_isdefinedglobal_effects, NoCallInfo()) +end + +function abstract_eval_isdefined(interp::AbstractInterpreter, @nospecialize(sym), saw_latestworld::Bool, sv::AbsIntState) + rt = Bool + effects = EFFECTS_TOTAL + exct = Union{} + if isexpr(sym, :static_parameter) n = sym.args[1]::Int if 1 <= n <= length(sv.sptypes) sp = sv.sptypes[n] @@ -3443,22 +3488,31 @@ function abstract_eval_globalref_type(g::GlobalRef, src::Union{CodeInfo, IRCode, return partition_restriction(partition) end -function abstract_eval_binding_partition!(interp::AbstractInterpreter, g::GlobalRef, sv::AbsIntState) +function lookup_binding_partition!(interp::AbstractInterpreter, g::GlobalRef, sv::AbsIntState) force_binding_resolution!(g) partition = lookup_binding_partition(get_inference_world(interp), g) update_valid_age!(sv, WorldRange(partition.min_world, partition.max_world)) + partition +end +function walk_binding_partition!(interp::AbstractInterpreter, partition::Core.BindingPartition, sv::AbsIntState) while is_some_imported(binding_kind(partition)) imported_binding = partition_restriction(partition)::Core.Binding partition = lookup_binding_partition(get_inference_world(interp), imported_binding) update_valid_age!(sv, WorldRange(partition.min_world, partition.max_world)) end + return partition +end +function abstract_eval_binding_partition!(interp::AbstractInterpreter, g::GlobalRef, sv::AbsIntState) + partition = lookup_binding_partition!(interp, g, sv) + partition = walk_binding_partition!(interp, partition, sv) return partition end function abstract_eval_partition_load(interp::AbstractInterpreter, partition::Core.BindingPartition) - if is_some_guard(binding_kind(partition)) + kind = binding_kind(partition) + if is_some_guard(kind) || kind == BINDING_KIND_UNDEF_CONST if InferenceParams(interp).assume_bindings_static return RTEffects(Union{}, UndefVarError, EFFECTS_THROWS) else @@ -3468,13 +3522,12 @@ function abstract_eval_partition_load(interp::AbstractInterpreter, partition::Co end end - if is_some_const_binding(binding_kind(partition)) + if is_defined_const_binding(kind) rt = Const(partition_restriction(partition)) return RTEffects(rt, Union{}, Effects(EFFECTS_TOTAL, inaccessiblememonly=is_mutation_free_argtype(rt) ? ALWAYS_TRUE : ALWAYS_FALSE)) end rt = partition_restriction(partition) - return RTEffects(rt, UndefVarError, generic_getglobal_effects) end diff --git a/Compiler/src/ssair/verify.jl b/Compiler/src/ssair/verify.jl index 072a564a31f78..12eb09be693f3 100644 --- a/Compiler/src/ssair/verify.jl +++ b/Compiler/src/ssair/verify.jl @@ -366,7 +366,7 @@ function verify_ir(ir::IRCode, print::Bool=true, @verify_error "Assignment should have been removed during SSA conversion" raise_error() elseif stmt.head === :isdefined - if length(stmt.args) > 2 || (length(stmt.args) == 2 && !isa(stmt.args[2], Bool)) + if length(stmt.args) > 2 @verify_error "malformed isdefined" raise_error() end @@ -382,7 +382,7 @@ function verify_ir(ir::IRCode, print::Bool=true, elseif stmt.head === :foreigncall isforeigncall = true elseif stmt.head === :isdefined && length(stmt.args) == 1 && - (stmt.args[1] isa GlobalRef || isexpr(stmt.args[1], :static_parameter)) + isexpr(stmt.args[1], :static_parameter) # a GlobalRef or static_parameter isdefined check does not evaluate its argument continue elseif stmt.head === :call diff --git a/base/boot.jl b/base/boot.jl index 05788844fde66..53e439d83ebe2 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -231,7 +231,7 @@ export fieldtype, getfield, setfield!, swapfield!, modifyfield!, replacefield!, setfieldonce!, nfields, throw, tuple, ===, isdefined, eval, # access to globals - getglobal, setglobal!, swapglobal!, modifyglobal!, replaceglobal!, setglobalonce!, + getglobal, setglobal!, swapglobal!, modifyglobal!, replaceglobal!, setglobalonce!, isdefinedglobal, # ifelse, sizeof # not exported, to avoid conflicting with Base # type reflection <:, typeof, isa, typeassert, diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index 16175010a20fa..88ed34de02b64 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -2754,6 +2754,9 @@ compatible with the stores to that location. Otherwise, if not declared as To test whether an array element is defined, use [`isassigned`](@ref) instead. +The global variable variant is supported for compatibility with older julia +releases. For new code, prefer [`isdefinedglobal`](@ref). + See also [`@isdefined`](@ref). # Examples @@ -2781,6 +2784,37 @@ false """ isdefined + +""" + isdefinedglobal(m::Module, s::Symbol, [allow_import::Bool=true, [order::Symbol=:unordered]]) + +Tests whether a global variable `s` is defined in module `m` (in the current world age). +A variable is considered defined if and only if a value may be read from this global variable +and an access will not throw. This includes both constants and global variables that have +a value set. + +If `allow_import` is `false`, the global variable must be defined inside `m` +and may not be imported from another module. + +See also [`@isdefined`](@ref). + +# Examples +```jldoctest +julia> isdefinedglobal(Base, :sum) +true + +julia> isdefinedglobal(Base, :NonExistentMethod) +false + +julia> isdefinedglobal(Base, :sum, false) +true + +julia> isdefinedglobal(Main, :sum, false) +false +``` +""" +isdefinedglobal + """ Memory{T}(undef, n) diff --git a/doc/src/base/base.md b/doc/src/base/base.md index 7181965d9aa81..e6c8ff554d494 100644 --- a/doc/src/base/base.md +++ b/doc/src/base/base.md @@ -166,6 +166,7 @@ Core.replacefield! Core.swapfield! Core.setfieldonce! Core.isdefined +Core.isdefinedglobal Base.@isdefined Base.convert Base.promote diff --git a/doc/src/devdocs/ast.md b/doc/src/devdocs/ast.md index d8db3ca677082..fe63dfe35edac 100644 --- a/doc/src/devdocs/ast.md +++ b/doc/src/devdocs/ast.md @@ -426,11 +426,8 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. * `isdefined` - `Expr(:isdefined, :x [, allow_import])` returns a Bool indicating whether `x` has - already been defined in the current scope. The optional second argument is a boolean - that specifies whether `x` should be considered defined by an import or if only constants - or globals in the current module count as being defined. If `x` is not a global, the argument - is ignored. + `Expr(:isdefined, :x)` returns a Bool indicating whether `x` has + already been defined in the current scope. * `the_exception` diff --git a/src/builtin_proto.h b/src/builtin_proto.h index 70ad67040991d..77463ae4884cb 100644 --- a/src/builtin_proto.h +++ b/src/builtin_proto.h @@ -45,6 +45,7 @@ DECLARE_BUILTIN(invoke); DECLARE_BUILTIN(is); DECLARE_BUILTIN(isa); DECLARE_BUILTIN(isdefined); +DECLARE_BUILTIN(isdefinedglobal); DECLARE_BUILTIN(issubtype); DECLARE_BUILTIN(memorynew); DECLARE_BUILTIN(memoryref); diff --git a/src/builtins.c b/src/builtins.c index c326e53ea968d..90d8a0d453e20 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1352,6 +1352,33 @@ JL_CALLABLE(jl_f_getglobal) return v; } +JL_CALLABLE(jl_f_isdefinedglobal) +{ + jl_module_t *m = NULL; + jl_sym_t *s = NULL; + JL_NARGS(isdefined, 2, 3); + int allow_import = 1; + enum jl_memory_order order = jl_memory_order_unspecified; + JL_TYPECHK(isdefined, module, args[0]); + JL_TYPECHK(isdefined, symbol, args[1]); + if (nargs == 3) { + JL_TYPECHK(isdefined, bool, args[2]); + allow_import = jl_unbox_bool(args[2]); + } + if (nargs == 4) { + JL_TYPECHK(isdefined, symbol, args[3]); + order = jl_get_atomic_order_checked((jl_sym_t*)args[2], 1, 0); + } + m = (jl_module_t*)args[0]; + s = (jl_sym_t*)args[1]; + if (order == jl_memory_order_unspecified) + order = jl_memory_order_unordered; + if (order < jl_memory_order_unordered) + jl_atomic_error("isdefined: module binding cannot be accessed non-atomically"); + int bound = jl_boundp(m, s, allow_import); // seq_cst always + return bound ? jl_true : jl_false; +} + JL_CALLABLE(jl_f_setglobal) { enum jl_memory_order order = jl_memory_order_release; @@ -2451,6 +2478,7 @@ void jl_init_primitives(void) JL_GC_DISABLED // module bindings jl_builtin_getglobal = add_builtin_func("getglobal", jl_f_getglobal); jl_builtin_setglobal = add_builtin_func("setglobal!", jl_f_setglobal); + jl_builtin_isdefinedglobal = add_builtin_func("isdefinedglobal", jl_f_isdefinedglobal); add_builtin_func("get_binding_type", jl_f_get_binding_type); jl_builtin_swapglobal = add_builtin_func("swapglobal!", jl_f_swapglobal); jl_builtin_replaceglobal = add_builtin_func("replaceglobal!", jl_f_replaceglobal); diff --git a/src/codegen.cpp b/src/codegen.cpp index 4b0f4ebd765fa..7bc14d2d0347f 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4173,6 +4173,34 @@ static bool emit_f_opfield(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return false; } +static jl_cgval_t emit_isdefinedglobal(jl_codectx_t &ctx, jl_module_t *modu, jl_sym_t *name, int allow_import, enum jl_memory_order order) +{ + Value *isnull = NULL; + jl_binding_t *bnd = allow_import ? jl_get_binding(modu, name) : jl_get_module_binding(modu, name, 0); + jl_binding_partition_t *bpart = jl_get_binding_partition_all(bnd, ctx.min_world, ctx.max_world); + jl_ptr_kind_union_t pku = bpart ? jl_atomic_load_relaxed(&bpart->restriction) : encode_restriction(NULL, BINDING_KIND_GUARD); + if (decode_restriction_kind(pku) == BINDING_KIND_GLOBAL || jl_bkind_is_some_constant(decode_restriction_kind(pku))) { + if (jl_get_binding_value_if_const(bnd)) + return mark_julia_const(ctx, jl_true); + Value *bp = julia_binding_gv(ctx, bnd); + bp = julia_binding_pvalue(ctx, bp); + LoadInst *v = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*))); + jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_binding); + ai.decorateInst(v); + v->setOrdering(get_llvm_atomic_order(order)); + isnull = ctx.builder.CreateICmpNE(v, Constant::getNullValue(ctx.types().T_prjlvalue)); + } + else { + Value *v = ctx.builder.CreateCall(prepare_call(jlboundp_func), { + literal_pointer_val(ctx, (jl_value_t*)modu), + literal_pointer_val(ctx, (jl_value_t*)name), + ConstantInt::get(getInt32Ty(ctx.builder.getContext()), allow_import) + }); + isnull = ctx.builder.CreateICmpNE(v, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0)); + } + return mark_julia_type(ctx, isnull, false, jl_bool_type); +} + static bool emit_f_opmemory(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, ArrayRef argv, size_t nargs, const jl_cgval_t *modifyop) { @@ -5074,6 +5102,42 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } } + else if (f == jl_builtin_isdefinedglobal && (nargs == 2 || nargs == 3 || nargs == 4)) { + const jl_cgval_t &mod = argv[1]; + const jl_cgval_t &sym = argv[2]; + bool allow_import = true; + enum jl_memory_order order = jl_memory_order_unspecified; + + if (nargs >= 3) { + const jl_cgval_t &arg3 = argv[3]; + if (arg3.constant && jl_is_bool(arg3.constant)) + allow_import = jl_unbox_bool(arg3.constant); + else + return false; + } + + if (nargs == 4) { + const jl_cgval_t &arg4 = argv[4]; + if (arg4.constant && jl_is_symbol(arg4.constant)) + order = jl_get_atomic_order((jl_sym_t*)arg4.constant, true, false); + else + return false; + } + else + order = jl_memory_order_unordered; + + if (order < jl_memory_order_unordered) { + return false; + } + + if (!mod.constant || !sym.constant || !jl_is_symbol(sym.constant) || !jl_is_module(mod.constant)) { + return false; + } + + *ret = emit_isdefinedglobal(ctx, (jl_module_t*)mod.constant, (jl_sym_t*)sym.constant, allow_import, order); + return true; + } + else if (f == jl_builtin_isdefined && (nargs == 2 || nargs == 3)) { const jl_cgval_t &obj = argv[1]; const jl_cgval_t &fld = argv[2]; @@ -6074,39 +6138,7 @@ static jl_cgval_t emit_isdefined(jl_codectx_t &ctx, jl_value_t *sym, int allow_i isnull = ctx.builder.CreateICmpNE(emit_typeof(ctx, sp, false, true), emit_tagfrom(ctx, jl_tvar_type)); } else { - jl_module_t *modu; - jl_sym_t *name; - if (jl_is_globalref(sym)) { - modu = jl_globalref_mod(sym); - name = jl_globalref_name(sym); - } - else { - assert(jl_is_symbol(sym) && "malformed isdefined expression"); - modu = ctx.module; - name = (jl_sym_t*)sym; - } - jl_binding_t *bnd = allow_import ? jl_get_binding(modu, name) : jl_get_module_binding(modu, name, 0); - jl_binding_partition_t *bpart = jl_get_binding_partition_all(bnd, ctx.min_world, ctx.max_world); - jl_ptr_kind_union_t pku = bpart ? jl_atomic_load_relaxed(&bpart->restriction) : encode_restriction(NULL, BINDING_KIND_GUARD); - if (decode_restriction_kind(pku) == BINDING_KIND_GLOBAL || jl_bkind_is_some_constant(decode_restriction_kind(pku))) { - if (jl_get_binding_value_if_const(bnd)) - return mark_julia_const(ctx, jl_true); - Value *bp = julia_binding_gv(ctx, bnd); - bp = julia_binding_pvalue(ctx, bp); - LoadInst *v = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*))); - jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_binding); - ai.decorateInst(v); - v->setOrdering(AtomicOrdering::Unordered); - isnull = ctx.builder.CreateICmpNE(v, Constant::getNullValue(ctx.types().T_prjlvalue)); - } - else { - Value *v = ctx.builder.CreateCall(prepare_call(jlboundp_func), { - literal_pointer_val(ctx, (jl_value_t*)modu), - literal_pointer_val(ctx, (jl_value_t*)name), - ConstantInt::get(getInt32Ty(ctx.builder.getContext()), allow_import) - }); - isnull = ctx.builder.CreateICmpNE(v, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0)); - } + assert(false && "malformed expression"); } return mark_julia_type(ctx, isnull, false, jl_bool_type); } diff --git a/src/interpreter.c b/src/interpreter.c index b9bd1997caa17..338853b56f692 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -251,22 +251,15 @@ static jl_value_t *eval_value(jl_value_t *e, interpreter_state *s) else if (head == jl_isdefined_sym) { jl_value_t *sym = args[0]; int defined = 0; - int allow_import = 1; - if (nargs == 2) { - assert(jl_is_bool(args[1]) && "malformed IR"); - allow_import = args[1] == jl_true; - } + assert(nargs == 1 && "malformed IR"); if (jl_is_slotnumber(sym) || jl_is_argument(sym)) { ssize_t n = jl_slot_number(sym); if (src == NULL || n > jl_source_nslots(src) || n < 1 || s->locals == NULL) jl_error("access to invalid slot number"); defined = s->locals[n - 1] != NULL; } - else if (jl_is_globalref(sym)) { - defined = jl_boundp(jl_globalref_mod(sym), jl_globalref_name(sym), allow_import); - } - else if (jl_is_symbol(sym)) { - defined = jl_boundp(s->module, (jl_sym_t*)sym, allow_import); + else if (jl_is_globalref(sym) || jl_is_symbol(sym)) { + jl_error("[Internal Error]: :isdefined on globalref should use `isdefinedglobal`"); } else if (jl_is_expr(sym) && ((jl_expr_t*)sym)->head == jl_static_parameter_sym) { ssize_t n = jl_unbox_long(jl_exprarg(sym, 0)); diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index c522a565f462a..007c3ce820820 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -1022,7 +1022,7 @@ (call (core svec) ,@attrs) ,mut ,min-initialized)) (call (core _setsuper!) ,name ,super) - (if (isdefined (globalref (thismodule) ,name) (false)) + (if (call (core isdefinedglobal) (thismodule) (inert ,name) (false)) (block (= ,prev (globalref (thismodule) ,name)) (if (call (core _equiv_typedef) ,prev ,name) @@ -1084,7 +1084,7 @@ (= ,name (call (core _abstracttype) (thismodule) (inert ,name) (call (core svec) ,@params))) (call (core _setsuper!) ,name ,super) (call (core _typebody!) ,name) - (if (&& (isdefined (globalref (thismodule) ,name) (false)) + (if (&& (call (core isdefinedglobal) (thismodule) (inert ,name) (false)) (call (core _equiv_typedef) (globalref (thismodule) ,name) ,name)) (null) (const (globalref (thismodule) ,name) ,name)) @@ -1105,7 +1105,7 @@ (= ,name (call (core _primitivetype) (thismodule) (inert ,name) (call (core svec) ,@params) ,n)) (call (core _setsuper!) ,name ,super) (call (core _typebody!) ,name) - (if (&& (isdefined (globalref (thismodule) ,name) (false)) + (if (&& (call (core isdefinedglobal) (thismodule) (inert ,name) (false)) (call (core _equiv_typedef) (globalref (thismodule) ,name) ,name)) (null) (const (globalref (thismodule) ,name) ,name)) @@ -4064,7 +4064,9 @@ f(x) = yt(x) (if (and (vinfo:asgn vi) (vinfo:capt vi)) `(call (core isdefined) ,sym (inert contents)) e)) - (else e)))) + (else (if (globalref? sym) + `(call (core isdefinedglobal) ,(cadr sym) (inert ,(caddr sym))) + e))))) ((_opaque_closure) (let* ((isva (car (cddddr e))) (nargs (cadr (cddddr e))) diff --git a/src/staticdata.c b/src/staticdata.c index bdeecb911e3eb..4124d3b481bb3 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -101,7 +101,7 @@ extern "C" { // TODO: put WeakRefs on the weak_refs list during deserialization // TODO: handle finalizers -#define NUM_TAGS 195 +#define NUM_TAGS 196 // An array of references that need to be restored from the sysimg // This is a manually constructed dual of the gvars array, which would be produced by codegen for Julia code, for C. @@ -311,6 +311,7 @@ jl_value_t **const*const get_tags(void) { INSERT_TAG(jl_builtin_compilerbarrier); INSERT_TAG(jl_builtin_getglobal); INSERT_TAG(jl_builtin_setglobal); + INSERT_TAG(jl_builtin_isdefinedglobal); INSERT_TAG(jl_builtin_swapglobal); INSERT_TAG(jl_builtin_modifyglobal); INSERT_TAG(jl_builtin_replaceglobal); @@ -506,7 +507,7 @@ static htable_t bits_replace; static const jl_fptr_args_t id_to_fptrs[] = { &jl_f_throw, &jl_f_throw_methoderror, &jl_f_is, &jl_f_typeof, &jl_f_issubtype, &jl_f_isa, &jl_f_typeassert, &jl_f__apply_iterate, &jl_f__apply_pure, - &jl_f__call_latest, &jl_f__call_in_world, &jl_f__call_in_world_total, &jl_f_isdefined, + &jl_f__call_latest, &jl_f__call_in_world, &jl_f__call_in_world_total, &jl_f_isdefined, &jl_f_isdefinedglobal, &jl_f_tuple, &jl_f_svec, &jl_f_intrinsic_call, &jl_f_getfield, &jl_f_setfield, &jl_f_swapfield, &jl_f_modifyfield, &jl_f_setfieldonce, &jl_f_replacefield, &jl_f_fieldtype, &jl_f_nfields, &jl_f_apply_type, &jl_f_memorynew, diff --git a/test/meta.jl b/test/meta.jl index 2b235d3cc1b0d..e9e344bba2e22 100644 --- a/test/meta.jl +++ b/test/meta.jl @@ -274,7 +274,7 @@ ci = code_lowered(g, Tuple{Val{true}})[1] @eval isdefined_globalref(x) = $(Expr(:isdefined, GlobalRef(Base, :foo))) ci = code_lowered(isdefined_globalref, Tuple{Int})[1] @test Meta.partially_inline!(copy(ci.code), Any[isdefined_globalref, 1], Tuple{typeof(isdefined_globalref), Int}, - [], 0, 0, :propagate)[1] == Expr(:isdefined, GlobalRef(Base, :foo)) + [], 0, 0, :propagate)[1] == Expr(:call, GlobalRef(Core, :isdefinedglobal), Base, QuoteNode(:foo)) withunreachable(s::String) = sin(s) ci = code_lowered(withunreachable, Tuple{String})[1] diff --git a/test/syntax.jl b/test/syntax.jl index fca8b9e8ccdf5..9fd0204821eab 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -3919,28 +3919,28 @@ module ExtendedIsDefined import .Import.x4 @test x2 == 2 # Resolve the binding @eval begin - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x1))) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x2))) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x3))) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x4))) + @test Core.isdefinedglobal(@__MODULE__, :x1) + @test Core.isdefinedglobal(@__MODULE__, :x2) + @test Core.isdefinedglobal(@__MODULE__, :x3) + @test Core.isdefinedglobal(@__MODULE__, :x4) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x1), false)) - @test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x2), false)) - @test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x3), false)) - @test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x4), false)) + @test Core.isdefinedglobal(@__MODULE__, :x1, false) + @test !Core.isdefinedglobal(@__MODULE__, :x2, false) + @test !Core.isdefinedglobal(@__MODULE__, :x3, false) + @test !Core.isdefinedglobal(@__MODULE__, :x4, false) end @eval begin @Base.Experimental.force_compile - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x1))) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x2))) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x3))) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x4))) - - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x1), false)) - @test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x2), false)) - @test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x3), false)) - @test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x4), false)) + @test Core.isdefinedglobal(@__MODULE__, :x1) + @test Core.isdefinedglobal(@__MODULE__, :x2) + @test Core.isdefinedglobal(@__MODULE__, :x3) + @test Core.isdefinedglobal(@__MODULE__, :x4) + + @test Core.isdefinedglobal(@__MODULE__, :x1, false) + @test !Core.isdefinedglobal(@__MODULE__, :x2, false) + @test !Core.isdefinedglobal(@__MODULE__, :x3, false) + @test !Core.isdefinedglobal(@__MODULE__, :x4, false) end end From b80dd58346a9644d18c52d1cf0e949c62d9e281b Mon Sep 17 00:00:00 2001 From: Michael Persico Date: Thu, 9 Jan 2025 21:24:04 -0500 Subject: [PATCH 157/198] Fix devcontainer definition (#57006) --- .devcontainer/Dockerfile | 3 --- .devcontainer/devcontainer.json | 16 ++++++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) delete mode 100644 .devcontainer/Dockerfile diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index a688be130711c..0000000000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM julia:latest - -RUN apt-get update && apt-get install -y build-essential libatomic1 python gfortran perl wget m4 cmake pkg-config git diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a3747ca019694..455f8bea3e952 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,8 +1,12 @@ { - "extensions": [ - "julialang.language-julia", - "ms-vscode.cpptools" - ], - - "dockerFile": "Dockerfile" + "image": "docker.io/library/julia:latest", + "customizations": { + "vscode": { + "extensions": [ + "julialang.language-julia", + "ms-vscode.cpptools" + ] + } + }, + "onCreateCommand": "apt-get update && apt-get install -y build-essential libatomic1 python3 gfortran perl wget m4 cmake pkg-config git" } From 6ac351a9890272db959396a77254c8b4b807d69f Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Thu, 9 Jan 2025 23:24:49 -0300 Subject: [PATCH 158/198] Make write(IO, Char) actually return the amount of printed bytes instead of the attempted written bytes. (#56980) --- base/io.jl | 5 ++--- test/iobuffer.jl | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/base/io.jl b/base/io.jl index 83a215d6359fc..46aec6ca393b7 100644 --- a/base/io.jl +++ b/base/io.jl @@ -864,11 +864,10 @@ end function write(io::IO, c::Char) u = bswap(reinterpret(UInt32, c)) - n = 1 + n = 0 while true - write(io, u % UInt8) + n += write(io, u % UInt8) (u >>= 8) == 0 && return n - n += 1 end end # write(io, ::AbstractChar) is not defined: implementations diff --git a/test/iobuffer.jl b/test/iobuffer.jl index 933662f7e41d1..a9d58f4b7871e 100644 --- a/test/iobuffer.jl +++ b/test/iobuffer.jl @@ -399,3 +399,9 @@ end io = IOBuffer(data) @test read(io) == data end + +@testset "Writing Char to full buffer" begin + io = IOBuffer(;maxsize=1) + write(io, 'a') + @test write(io, 'a') == 0 +end From d3964b600a5e596bd47cf04b3da4a1e78d4aecaf Mon Sep 17 00:00:00 2001 From: Neven Sajko <4944410+nsajko@users.noreply.github.com> Date: Fri, 10 Jan 2025 10:00:22 +0100 Subject: [PATCH 159/198] broadcast: align `ndims` implementation with intent behind code (#56999) The `N<:Integer` constraint was nonsensical, given that `(N === Any) || (N isa Int)`. N5N3 noticed this back in 2022: https://github.com/JuliaLang/julia/pull/44061#discussion_r883261337 Follow up on #44061. Also xref #45477. --- base/broadcast.jl | 9 +++++++-- test/broadcast.jl | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/base/broadcast.jl b/base/broadcast.jl index 7f278fc1ca66f..512b397352040 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -280,9 +280,14 @@ Base.@propagate_inbounds function Base.iterate(bc::Broadcasted, s) end Base.IteratorSize(::Type{T}) where {T<:Broadcasted} = Base.HasShape{ndims(T)}() -Base.ndims(BC::Type{<:Broadcasted{<:Any,Nothing}}) = _maxndims(fieldtype(BC, :args)) -Base.ndims(::Type{<:Broadcasted{<:AbstractArrayStyle{N},Nothing}}) where {N<:Integer} = N +Base.ndims(BC::Type{<:Broadcasted{<:Any,Nothing}}) = _maxndims_broadcasted(BC) +# the `AbstractArrayStyle` type parameter is required to be either equal to `Any` or be an `Int` value +Base.ndims(BC::Type{<:Broadcasted{<:AbstractArrayStyle{Any},Nothing}}) = _maxndims_broadcasted(BC) +Base.ndims(::Type{<:Broadcasted{<:AbstractArrayStyle{N},Nothing}}) where {N} = N::Int +function _maxndims_broadcasted(BC::Type{<:Broadcasted}) + _maxndims(fieldtype(BC, :args)) +end _maxndims(::Type{T}) where {T<:Tuple} = reduce(max, ntuple(n -> (F = fieldtype(T, n); F <: Tuple ? 1 : ndims(F)), Base._counttuple(T))) _maxndims(::Type{<:Tuple{T}}) where {T} = T <: Tuple ? 1 : ndims(T) function _maxndims(::Type{<:Tuple{T, S}}) where {T, S} diff --git a/test/broadcast.jl b/test/broadcast.jl index 57441de67c0ce..0f5bdf7a40bb1 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -930,6 +930,8 @@ let @test @inferred(Base.IteratorSize(Broadcast.broadcasted(+, (1,2,3), a1, zeros(3,3,3)))) === Base.HasShape{3}() + @test @inferred(Base.IteratorSize(Base.broadcasted(randn))) === Base.HasShape{0}() + # inference on nested bc = Base.broadcasted(+, AD1(randn(3)), AD1(randn(3))) bc_nest = Base.broadcasted(+, bc , bc) From 9211a932bb5e73adfa9c494d068bf0ad10e5f552 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 10 Jan 2025 18:44:21 +0100 Subject: [PATCH 160/198] Add edge kind for access to non-explicit partitioned bindings (#57009) Our binding partion invalidation code scans the original source for any GlobalRefs that need to be invalidated. However, this is not the only source of access to binding partitions. Various intrinsics (in particular the `*global` ones) also operate on bindings. Since these are not manifest in the source, we instead use the existing `edges` mechanism to give them forward edges. This PR only includes the basic info type, and validation in the replacement case. There's a bit more work to do there, but I'm waiting on #56499 for that part, precompilation in particular. --- Compiler/src/abstractinterpretation.jl | 86 ++++++++++++-------------- Compiler/src/stmtinfo.jl | 14 +++++ Compiler/src/typeinfer.jl | 3 + base/invalidation.jl | 41 ++++++++---- src/module.c | 8 +-- src/staticdata_utils.c | 8 +++ stdlib/REPL/src/REPLCompletions.jl | 6 +- sysimage.mk | 1 + test/rebinding.jl | 9 ++- 9 files changed, 110 insertions(+), 66 deletions(-) diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 0c340a89d9878..3766907905aef 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -2395,7 +2395,8 @@ function abstract_eval_getglobal(interp::AbstractInterpreter, sv::AbsIntState, s if M isa Const && s isa Const M, s = M.val, s.val if M isa Module && s isa Symbol - return CallMeta(abstract_eval_globalref(interp, GlobalRef(M, s), saw_latestworld, sv), NoCallInfo()) + (ret, bpart) = abstract_eval_globalref(interp, GlobalRef(M, s), saw_latestworld, sv) + return CallMeta(ret, bpart === nothing ? NoCallInfo() : GlobalAccessInfo(bpart)) end return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo()) elseif !hasintersect(widenconst(M), Module) || !hasintersect(widenconst(s), Symbol) @@ -2473,8 +2474,8 @@ function abstract_eval_setglobal!(interp::AbstractInterpreter, sv::AbsIntState, if isa(M, Const) && isa(s, Const) M, s = M.val, s.val if M isa Module && s isa Symbol - rt, exct = global_assignment_rt_exct(interp, sv, saw_latestworld, GlobalRef(M, s), v) - return CallMeta(rt, exct, Effects(setglobal!_effects, nothrow=exct===Bottom), NoCallInfo()) + (rt, exct), partition = global_assignment_rt_exct(interp, sv, saw_latestworld, GlobalRef(M, s), v) + return CallMeta(rt, exct, Effects(setglobal!_effects, nothrow=exct===Bottom), GlobalAccessInfo(partition)) end return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo()) end @@ -2512,7 +2513,7 @@ function abstract_eval_swapglobal!(interp::AbstractInterpreter, sv::AbsIntState, scm = abstract_eval_setglobal!(interp, sv, saw_latestworld, M, s, v) scm.rt === Bottom && return scm gcm = abstract_eval_getglobal(interp, sv, saw_latestworld, M, s) - return CallMeta(gcm.rt, Union{scm.exct,gcm.exct}, merge_effects(scm.effects, gcm.effects), NoCallInfo()) + return CallMeta(gcm.rt, Union{scm.exct,gcm.exct}, merge_effects(scm.effects, gcm.effects), scm.info) end function abstract_eval_swapglobal!(interp::AbstractInterpreter, sv::AbsIntState, saw_latestworld::Bool, @@ -2520,7 +2521,7 @@ function abstract_eval_swapglobal!(interp::AbstractInterpreter, sv::AbsIntState, scm = abstract_eval_setglobal!(interp, sv, saw_latestworld, M, s, v, order) scm.rt === Bottom && return scm gcm = abstract_eval_getglobal(interp, sv, saw_latestworld, M, s, order) - return CallMeta(gcm.rt, Union{scm.exct,gcm.exct}, merge_effects(scm.effects, gcm.effects), NoCallInfo()) + return CallMeta(gcm.rt, Union{scm.exct,gcm.exct}, merge_effects(scm.effects, gcm.effects), scm.info) end function abstract_eval_swapglobal!(interp::AbstractInterpreter, sv::AbsIntState, saw_latestworld::Bool, argtypes::Vector{Any}) @@ -2569,7 +2570,7 @@ function abstract_eval_replaceglobal!(interp::AbstractInterpreter, sv::AbsIntSta end exct = Union{rte.exct, global_assignment_binding_rt_exct(interp, partition, v)[2]} effects = merge_effects(rte.effects, Effects(setglobal!_effects, nothrow=exct===Bottom)) - sg = CallMeta(Any, exct, effects, NoCallInfo()) + sg = CallMeta(Any, exct, effects, GlobalAccessInfo(partition)) else sg = abstract_eval_setglobal!(interp, sv, saw_latestworld, M, s, v) end @@ -2937,7 +2938,8 @@ function abstract_eval_special_value(interp::AbstractInterpreter, @nospecialize( return RTEffects(sv.ir.argtypes[e.n], Union{}, EFFECTS_TOTAL) # TODO frame_argtypes(sv)[e.n] and remove the assertion end elseif isa(e, GlobalRef) - return abstract_eval_globalref(interp, e, sstate.saw_latestworld, sv) + # No need for an edge since an explicit GlobalRef will be picked up by the source scan + return abstract_eval_globalref(interp, e, sstate.saw_latestworld, sv)[1] end if isa(e, QuoteNode) e = e.value @@ -3193,14 +3195,31 @@ function abstract_eval_isdefined_expr(interp::AbstractInterpreter, e::Expr, ssta end return RTEffects(rt, Union{}, EFFECTS_TOTAL) end - return abstract_eval_isdefined(interp, sym, sstate.saw_latestworld, sv) + rt = Bool + effects = EFFECTS_TOTAL + exct = Union{} + if isexpr(sym, :static_parameter) + n = sym.args[1]::Int + if 1 <= n <= length(sv.sptypes) + sp = sv.sptypes[n] + if !sp.undef + rt = Const(true) + elseif sp.typ === Bottom + rt = Const(false) + end + end + else + effects = EFFECTS_UNKNOWN + exct = Any + end + return RTEffects(rt, exct, effects) end const generic_isdefinedglobal_effects = Effects(EFFECTS_TOTAL, consistent=ALWAYS_FALSE, nothrow=false) function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, mod::Module, sym::Symbol, allow_import::Union{Bool, Nothing}, saw_latestworld::Bool, sv::AbsIntState) rt = Bool if saw_latestworld - return RTEffects(rt, Union{}, Effects(generic_isdefinedglobal_effects, nothrow=true)) + return CallMeta(RTEffects(rt, Union{}, Effects(generic_isdefinedglobal_effects, nothrow=true)), NoCallInfo()) end effects = EFFECTS_TOTAL @@ -3222,7 +3241,7 @@ function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, mod::Module, effects = Effects(generic_isdefinedglobal_effects, nothrow=true) end end - return RTEffects(rt, Union{}, effects) + return CallMeta(RTEffects(rt, Union{}, effects), GlobalAccessInfo(partition)) end function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, @nospecialize(M), @nospecialize(s), @nospecialize(allow_import_arg), @nospecialize(order_arg), saw_latestworld::Bool, sv::AbsIntState) @@ -3247,7 +3266,7 @@ function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, @nospecializ if M isa Const && s isa Const M, s = M.val, s.val if M isa Module && s isa Symbol - return merge_exct(CallMeta(abstract_eval_isdefinedglobal(interp, M, s, allow_import, saw_latestworld, sv), NoCallInfo()), exct) + return merge_exct(abstract_eval_isdefinedglobal(interp, M, s, allow_import, saw_latestworld, sv), exct) end return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo()) elseif !hasintersect(widenconst(M), Module) || !hasintersect(widenconst(s), Symbol) @@ -3258,26 +3277,6 @@ function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, @nospecializ return CallMeta(Bool, Union{exct, TypeError, UndefVarError}, generic_isdefinedglobal_effects, NoCallInfo()) end -function abstract_eval_isdefined(interp::AbstractInterpreter, @nospecialize(sym), saw_latestworld::Bool, sv::AbsIntState) - rt = Bool - effects = EFFECTS_TOTAL - exct = Union{} - if isexpr(sym, :static_parameter) - n = sym.args[1]::Int - if 1 <= n <= length(sv.sptypes) - sp = sv.sptypes[n] - if !sp.undef - rt = Const(true) - elseif sp.typ === Bottom - rt = Const(false) - end - end - else - effects = EFFECTS_UNKNOWN - end - return RTEffects(rt, exct, effects) -end - function abstract_eval_throw_undef_if_not(interp::AbstractInterpreter, e::Expr, sstate::StatementState, sv::AbsIntState) condt = abstract_eval_value(interp, e.args[2], sstate, sv) condval = maybe_extract_const_bool(condt) @@ -3533,26 +3532,29 @@ end function abstract_eval_globalref(interp::AbstractInterpreter, g::GlobalRef, saw_latestworld::Bool, sv::AbsIntState) if saw_latestworld - return RTEffects(Any, Any, generic_getglobal_effects) + return Pair{RTEffects, Union{Nothing, Core.BindingPartition}}(RTEffects(Any, Any, generic_getglobal_effects), nothing) end partition = abstract_eval_binding_partition!(interp, g, sv) ret = abstract_eval_partition_load(interp, partition) if ret.rt !== Union{} && ret.exct === UndefVarError && InferenceParams(interp).assume_bindings_static if isdefined(g, :binding) && isdefined(g.binding, :value) - return RTEffects(ret.rt, Union{}, Effects(generic_getglobal_effects, nothrow=true)) + ret = RTEffects(ret.rt, Union{}, Effects(generic_getglobal_effects, nothrow=true)) end # We do not assume in general that assigned global bindings remain assigned. # The existence of pkgimages allows them to revert in practice. end - return ret + return Pair{RTEffects, Union{Nothing, Core.BindingPartition}}(ret, partition) end function global_assignment_rt_exct(interp::AbstractInterpreter, sv::AbsIntState, saw_latestworld::Bool, g::GlobalRef, @nospecialize(newty)) if saw_latestworld - return Pair{Any,Any}(newty, Union{ErrorException, TypeError}) + return Pair{Pair{Any,Any}, Union{Core.BindingPartition, Nothing}}( + Pair{Any,Any}(newty, Union{ErrorException, TypeError}), nothing) end partition = abstract_eval_binding_partition!(interp, g, sv) - return global_assignment_binding_rt_exct(interp, partition, newty) + return Pair{Pair{Any,Any}, Union{Core.BindingPartition, Nothing}}( + global_assignment_binding_rt_exct(interp, partition, newty), + partition) end function global_assignment_binding_rt_exct(interp::AbstractInterpreter, partition::Core.BindingPartition, @nospecialize(newty)) @@ -3573,18 +3575,6 @@ function global_assignment_binding_rt_exct(interp::AbstractInterpreter, partitio return Pair{Any,Any}(newty, Bottom) end -function handle_global_assignment!(interp::AbstractInterpreter, frame::InferenceState, saw_latestworld::Bool, lhs::GlobalRef, @nospecialize(newty)) - effect_free = ALWAYS_FALSE - nothrow = global_assignment_rt_exct(interp, frame, saw_latestworld, lhs, ignorelimited(newty))[2] === Union{} - inaccessiblememonly = ALWAYS_FALSE - if !nothrow - sub_curr_ssaflag!(frame, IR_FLAG_NOTHROW) - end - sub_curr_ssaflag!(frame, IR_FLAG_EFFECT_FREE) - merge_effects!(interp, frame, Effects(EFFECTS_TOTAL; effect_free, nothrow, inaccessiblememonly)) - return nothing -end - abstract_eval_ssavalue(s::SSAValue, sv::InferenceState) = abstract_eval_ssavalue(s, sv.ssavaluetypes) function abstract_eval_ssavalue(s::SSAValue, ssavaluetypes::Vector{Any}) diff --git a/Compiler/src/stmtinfo.jl b/Compiler/src/stmtinfo.jl index a42a9e47b328e..e3f8e2f56c86b 100644 --- a/Compiler/src/stmtinfo.jl +++ b/Compiler/src/stmtinfo.jl @@ -481,4 +481,18 @@ end add_edges_impl(edges::Vector{Any}, info::VirtualMethodMatchInfo) = _add_edges_impl(edges, info.info, #=mi_edge=#true) +""" + info::GlobalAccessInfo <: CallInfo + +Represents access to a global through runtime reflection, rather than as a manifest +`GlobalRef` in the source code. Used for builtins (getglobal/setglobal/etc.) that +perform such accesses. +""" +struct GlobalAccessInfo <: CallInfo + bpart::Core.BindingPartition +end +GlobalAccessInfo(::Nothing) = NoCallInfo() +add_edges_impl(edges::Vector{Any}, info::GlobalAccessInfo) = + push!(edges, info.bpart) + @specialize diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index 49cc711dc72df..ec1e62817106d 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -544,6 +544,9 @@ function store_backedges(caller::CodeInstance, edges::SimpleVector) # ignore `Method`-edges (from e.g. failed `abstract_call_method`) i += 1 continue + elseif isa(item, Core.BindingPartition) + i += 1 + continue end if isa(item, CodeInstance) item = item.def diff --git a/base/invalidation.jl b/base/invalidation.jl index 40a010ab7361c..5abb0b74ad884 100644 --- a/base/invalidation.jl +++ b/base/invalidation.jl @@ -9,7 +9,7 @@ globalrefs(mod::Module) = GlobalRefIterator(mod) function iterate(gri::GlobalRefIterator, i = 1) m = gri.mod table = ccall(:jl_module_get_bindings, Ref{SimpleVector}, (Any,), m) - i == length(table) && return nothing + i > length(table) && return nothing b = table[i] b === nothing && return iterate(gri, i+1) return ((b::Core.Binding).globalref, i+1) @@ -85,18 +85,33 @@ function should_invalidate_code_for_globalref(gr::GlobalRef, src::CodeInfo) return found_any end -function invalidate_code_for_globalref!(gr::GlobalRef, new_max_world::UInt) - valid_in_valuepos = false - foreach_reachable_mtable(new_max_world) do mt::Core.MethodTable - for method in MethodList(mt) - if isdefined(method, :source) - src = _uncompressed_ir(method) - old_stmts = src.code - if should_invalidate_code_for_globalref(gr, src) +function scan_edge_list(ci::Core.CodeInstance, bpart::Core.BindingPartition) + isdefined(ci, :edges) || return false + edges = ci.edges + i = 1 + while i <= length(edges) + if isassigned(edges, i) && edges[i] === bpart + return true + end + i += 1 + end + return false +end + +function invalidate_code_for_globalref!(gr::GlobalRef, invalidated_bpart::Core.BindingPartition, new_max_world::UInt) + try + valid_in_valuepos = false + foreach_reachable_mtable(new_max_world) do mt::Core.MethodTable + for method in MethodList(mt) + if isdefined(method, :source) + src = _uncompressed_ir(method) + old_stmts = src.code + invalidate_all = should_invalidate_code_for_globalref(gr, src) for mi in specializations(method) + isdefined(mi, :cache) || continue ci = mi.cache while true - if ci.max_world > new_max_world + if ci.max_world > new_max_world && (invalidate_all || scan_edge_list(ci, invalidated_bpart)) ccall(:jl_invalidate_code_instance, Cvoid, (Any, UInt), ci, new_max_world) end isdefined(ci, :next) || break @@ -105,7 +120,11 @@ function invalidate_code_for_globalref!(gr::GlobalRef, new_max_world::UInt) end end end + return true end - return true + catch err + bt = catch_backtrace() + invokelatest(Base.println, "Internal Error during invalidation:") + invokelatest(Base.display_error, err, bt) end end diff --git a/src/module.c b/src/module.c index 004371b9144b2..66049031f8790 100644 --- a/src/module.c +++ b/src/module.c @@ -1032,7 +1032,7 @@ JL_DLLEXPORT void jl_set_const(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var jl_gc_wb(bpart, val); } -void jl_invalidate_binding_refs(jl_globalref_t *ref, size_t new_world) +void jl_invalidate_binding_refs(jl_globalref_t *ref, jl_binding_partition_t *invalidated_bpart, size_t new_world) { static jl_value_t *invalidate_code_for_globalref = NULL; if (invalidate_code_for_globalref == NULL && jl_base_module != NULL) @@ -1043,7 +1043,7 @@ void jl_invalidate_binding_refs(jl_globalref_t *ref, size_t new_world) jl_error("Binding invalidation is not permitted during image generation."); jl_value_t *boxed_world = jl_box_ulong(new_world); JL_GC_PUSH1(&boxed_world); - jl_call2((jl_function_t*)invalidate_code_for_globalref, (jl_value_t*)ref, boxed_world); + jl_call3((jl_function_t*)invalidate_code_for_globalref, (jl_value_t*)ref, (jl_value_t*)invalidated_bpart, boxed_world); JL_GC_POP(); } @@ -1063,10 +1063,10 @@ JL_DLLEXPORT void jl_disable_binding(jl_globalref_t *gr) jl_task_t *ct = jl_current_task; size_t last_world = ct->world_age; size_t new_max_world = jl_atomic_load_acquire(&jl_world_counter); + jl_atomic_store_release(&bpart->max_world, new_max_world); ct->world_age = jl_typeinf_world; - jl_invalidate_binding_refs(gr, new_max_world); + jl_invalidate_binding_refs(gr, bpart, new_max_world); ct->world_age = last_world; - jl_atomic_store_release(&bpart->max_world, new_max_world); jl_atomic_store_release(&jl_world_counter, new_max_world + 1); JL_UNLOCK(&world_counter_lock); } diff --git a/src/staticdata_utils.c b/src/staticdata_utils.c index 5de85a8d6ec77..79d2909970d99 100644 --- a/src/staticdata_utils.c +++ b/src/staticdata_utils.c @@ -878,6 +878,10 @@ static int jl_verify_method(jl_code_instance_t *codeinst, size_t *minworld, size size_t min_valid2; size_t max_valid2; assert(!jl_is_method(edge)); // `Method`-edge isn't allowed for the optimized one-edge format + if (jl_is_binding_partition(edge)) { + j += 1; + continue; + } if (jl_is_code_instance(edge)) edge = (jl_value_t*)jl_get_ci_mi((jl_code_instance_t*)edge); if (jl_is_method_instance(edge)) { @@ -1051,6 +1055,10 @@ static void jl_insert_backedges(jl_array_t *edges, jl_array_t *ext_ci_list) j += 1; continue; } + else if (jl_is_binding_partition(edge)) { + j += 1; + continue; + } if (jl_is_code_instance(edge)) edge = (jl_value_t*)((jl_code_instance_t*)edge)->def; if (jl_is_method_instance(edge)) { diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 2c03c6d563c1e..723a008b10f28 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -646,9 +646,11 @@ function CC.abstract_eval_globalref(interp::REPLInterpreter, g::GlobalRef, baile sv::CC.InferenceState) if (interp.limit_aggressive_inference ? is_repl_frame(sv) : is_call_graph_uncached(sv)) if isdefined_globalref(g) - return CC.RTEffects(Const(ccall(:jl_get_globalref_value, Any, (Any,), g)), Union{}, CC.EFFECTS_TOTAL) + return Pair{CC.RTEffects, Union{Nothing, Core.BindingPartition}}( + CC.RTEffects(Const(ccall(:jl_get_globalref_value, Any, (Any,), g)), Union{}, CC.EFFECTS_TOTAL), nothing) end - return CC.RTEffects(Union{}, UndefVarError, CC.EFFECTS_THROWS) + return Pair{CC.RTEffects, Union{Nothing, Core.BindingPartition}}( + CC.RTEffects(Union{}, UndefVarError, CC.EFFECTS_THROWS), nothing) end return @invoke CC.abstract_eval_globalref(interp::CC.AbstractInterpreter, g::GlobalRef, bailed::Bool, sv::CC.InferenceState) diff --git a/sysimage.mk b/sysimage.mk index a74aace4dd11c..571e2da003346 100644 --- a/sysimage.mk +++ b/sysimage.mk @@ -43,6 +43,7 @@ COMPILER_SRCS := $(addprefix $(JULIAHOME)/, \ base/int.jl \ base/indices.jl \ base/iterators.jl \ + base/invalidation.jl \ base/namedtuple.jl \ base/number.jl \ base/operators.jl \ diff --git a/test/rebinding.jl b/test/rebinding.jl index ad0ad1fc1643d..10da27ce3ad8f 100644 --- a/test/rebinding.jl +++ b/test/rebinding.jl @@ -31,7 +31,7 @@ module Rebinding # Tests for @world syntax @test Base.@world(Foo, defined_world_age) == typeof(x) - @test Base.@world(Rebinding.Foo, defined_world_age) == typeof(x) + nameof(@__MODULE__) === :Rebinding && @test Base.@world(Rebinding.Foo, defined_world_age) == typeof(x) @test Base.@world((@__MODULE__).Foo, defined_world_age) == typeof(x) # Test invalidation (const -> undefined) @@ -40,4 +40,11 @@ module Rebinding @test f_return_delete_me() == 1 Base.delete_binding(@__MODULE__, :delete_me) @test_throws UndefVarError f_return_delete_me() + + ## + via indirect access + const delete_me = 2 + f_return_delete_me_indirect() = getglobal(@__MODULE__, :delete_me) + @test f_return_delete_me_indirect() == 2 + Base.delete_binding(@__MODULE__, :delete_me) + @test_throws UndefVarError f_return_delete_me_indirect() end From 64706d789f4816230d595b03f527fc0e9d934a3e Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Fri, 10 Jan 2025 14:14:07 -0500 Subject: [PATCH 161/198] remove fence that GC change made unnecessary (#56986) @gbaraldi and I think that this fence can probably be removed now that https://github.com/JuliaLang/julia/pull/55223 is merged. This should slightly expand the set of cases where the Memory is removable. --- src/cgutils.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 295dd93e869ba..98c5627578b80 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -4463,8 +4463,6 @@ static void emit_memory_zeroinit_and_stores(jl_codectx_t &ctx, jl_datatype_t *ty auto len_store = ctx.builder.CreateAlignedStore(nel, len_field, Align(sizeof(void*))); auto aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memorylen); aliasinfo.decorateInst(len_store); - //This avoids the length store from being deleted which is illegal - ctx.builder.CreateFence(AtomicOrdering::Release, SyncScope::SingleThread); // zeroinit pointers and unions if (zi) { Value *memory_ptr = ctx.builder.CreateStructGEP(ctx.types().T_jlgenericmemory, decay_alloc, 1); From db8cc484fd8e9b6120483acc6387d843de8f7fd4 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Fri, 10 Jan 2025 15:34:21 -0500 Subject: [PATCH 162/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?Pkg=20stdlib=20from=208d3cf02e5=20to=20bc9fb21b1=20(#57013)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: IanButterworth <1694067+IanButterworth@users.noreply.github.com> --- .../Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 | 1 - .../Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 | 1 - .../Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/md5 | 1 + .../Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/sha512 | 1 + stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 create mode 100644 deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/md5 create mode 100644 deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/sha512 diff --git a/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 b/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 deleted file mode 100644 index 0ec07e44a059d..0000000000000 --- a/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -30eed5409ab2f5e7791cac9f6583ccad diff --git a/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 b/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 deleted file mode 100644 index 37415fcac993c..0000000000000 --- a/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -bb995ff7bc047121e79162da8775cbf21a2874427af53ea46ccf9db2a01d5d3e864262d232e2988f41248e6b45a266a64467ada7e6a88f2306135ac4f1bb794f diff --git a/deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/md5 b/deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/md5 new file mode 100644 index 0000000000000..5180b5f916d1b --- /dev/null +++ b/deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/md5 @@ -0,0 +1 @@ +2332986e216728bc85e364994f2ed910 diff --git a/deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/sha512 b/deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/sha512 new file mode 100644 index 0000000000000..04bc79171c734 --- /dev/null +++ b/deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/sha512 @@ -0,0 +1 @@ +99bf03f921ae79767009dbd68a94a7119513b2454d5c9832b157bc1e092a35a6b90cb7a5d81346a7d927f9b0275328582098ca6b8b376b4a406ddf0b3167a280 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 568a15dae1cc0..4240c77105583 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = master -PKG_SHA1 = 8d3cf02e5e35913c89440c3b5c6678c1a806e975 +PKG_SHA1 = bc9fb21b1f2d72038491eff938673fc5fbc99445 PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From c1db3a419699a92c29ce2aff7547019eec3045a4 Mon Sep 17 00:00:00 2001 From: Cody Tapscott <84105208+topolarity@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:29:48 -0500 Subject: [PATCH 163/198] Miscellaneous `Meta.partially_inline!` fixes (#56813) This fixes up a couple of conspicuous problems I noticed when reviewing #56787 I'm unsure we should have accepted this pass in Base to begin with... It should at least be re-written to error on unexpected IR elements (instead of performing an invalid transform silently), but the real problem is that this pass is out-of-pipeline and so it doesn't run on most user code and we have much worse coverage compared to passes in the main Compiler. --- base/meta.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/base/meta.jl b/base/meta.jl index 85b54e8225d4e..36875b8e2c625 100644 --- a/base/meta.jl +++ b/base/meta.jl @@ -364,6 +364,19 @@ function _partially_inline!(@nospecialize(x), slot_replacements::Vector{Any}, x.edges .+= slot_offset return x end + if isa(x, Core.UpsilonNode) + if !isdefined(x, :val) + return x + end + return Core.UpsilonNode( + _partially_inline!(x.val, slot_replacements, type_signature, static_param_values, + slot_offset, statement_offset, boundscheck), + ) + end + if isa(x, Core.PhiCNode) + _partially_inline!(x.values, slot_replacements, type_signature, static_param_values, + slot_offset, statement_offset, boundscheck) + end if isa(x, Core.ReturnNode) # Unreachable doesn't have val defined if !isdefined(x, :val) @@ -383,6 +396,9 @@ function _partially_inline!(@nospecialize(x), slot_replacements::Vector{Any}, ) end if isa(x, Core.EnterNode) + if x.catch_dest == 0 + return x + end return Core.EnterNode(x, x.catch_dest + statement_offset) end if isa(x, Expr) From 49428e8fa2f787d8df894a4a8f538350ec0e54fe Mon Sep 17 00:00:00 2001 From: Erik Schnetter Date: Fri, 10 Jan 2025 18:19:03 -0500 Subject: [PATCH 164/198] README.md: Update current stable version (#57016) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cfa2111600f22..021322336d286 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ and then use the command prompt to change into the resulting julia directory. By Julia. However, most users should use the [most recent stable version](https://github.com/JuliaLang/julia/releases) of Julia. You can get this version by running: - git checkout v1.11.1 + git checkout v1.11.2 To build the `julia` executable, run `make` from within the julia directory. From 71bfbb3b0134c05e1af49c385738b8f5d8f06e7c Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Fri, 10 Jan 2025 19:41:51 -0800 Subject: [PATCH 165/198] Update HelloWorldC in Artifacts tests and bump LazyArtifacts for the same change (#57000) This updates the version of HelloWorldC in `stdlib/Artifacts/test/Artifacts.toml` from 1.1.2 to 1.4.0, for which there are binaries for FreeBSD AArch64 and Linux RISC-V. The same change was made to LazyArtifacts, as it contains that same `Artifacts.toml` file in its tests, and the version of LazyArtifacts used here has been updated accordingly. No other changes have been made to LazyArtifacts since the previous version used here. --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/Artifacts/test/Artifacts.toml | 113 ++++++++++-------- stdlib/Artifacts/test/runtests.jl | 12 +- stdlib/LazyArtifacts.version | 2 +- 7 files changed, 74 insertions(+), 57 deletions(-) delete mode 100644 deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/md5 delete mode 100644 deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/sha512 create mode 100644 deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/md5 create mode 100644 deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/sha512 diff --git a/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/md5 b/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/md5 deleted file mode 100644 index 363c289573765..0000000000000 --- a/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -ce3754f1d195e1533fc1f3c51e2a2d4c diff --git a/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/sha512 b/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/sha512 deleted file mode 100644 index 62227971fe7f7..0000000000000 --- a/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -1e1beb6202f089b82f06c1f1fcb129a31d2b438df8a3a49c7367d3df4587d8b9b8fbcf74d3f5ff3c25c241314c71e5dfd72014338b822f01252890e2a14831d1 diff --git a/deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/md5 b/deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/md5 new file mode 100644 index 0000000000000..48bd7a8a7fa25 --- /dev/null +++ b/deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/md5 @@ -0,0 +1 @@ +405faa2237105ff823e80e759b2df17a diff --git a/deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/sha512 b/deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/sha512 new file mode 100644 index 0000000000000..9fa6aec4d1939 --- /dev/null +++ b/deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/sha512 @@ -0,0 +1 @@ +9bd2bdd5a83df28a26ebfb0d4e59b50584962e07b1364e6fd76bc7a6a7b109f1facaa04366beaa9f340192ea9efa540decde1393ddd50dc3efa13937deeb5d7f diff --git a/stdlib/Artifacts/test/Artifacts.toml b/stdlib/Artifacts/test/Artifacts.toml index 4b715b74c128b..5faf1012dec54 100644 --- a/stdlib/Artifacts/test/Artifacts.toml +++ b/stdlib/Artifacts/test/Artifacts.toml @@ -1,146 +1,163 @@ [[HelloWorldC]] arch = "aarch64" -git-tree-sha1 = "95fce80ec703eeb5f4270fef6821b38d51387499" +git-tree-sha1 = "0835a23111b12d2aa5e1f7a852ed71e0b92e3425" os = "macos" [[HelloWorldC.download]] - sha256 = "23f45918421881de8e9d2d471c70f6b99c26edd1dacd7803d2583ba93c8bbb28" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.aarch64-apple-darwin.tar.gz" + sha256 = "4406a35689feaf532ff0347a11896449571e8a1c919e5550b01dfe10f2e64822" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.aarch64-apple-darwin.tar.gz" [[HelloWorldC]] arch = "aarch64" -git-tree-sha1 = "1ccbaad776766366943fd5a66a8cbc9877ee8df9" +git-tree-sha1 = "c82465bd6d0aa1369ff2fd961b73884d1f5de49a" libc = "glibc" os = "linux" [[HelloWorldC.download]] - sha256 = "82bca07ff25a75875936116ca977285160a2afcc4f58dd160c7b1600f55da655" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.aarch64-linux-gnu.tar.gz" + sha256 = "5bfa84332c7ee485ca8e2eee216ad9fa77b2c43d5f261baa823e301b7c789ec4" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.aarch64-linux-gnu.tar.gz" [[HelloWorldC]] arch = "aarch64" -git-tree-sha1 = "dc43ab874611cfc26641741c31b8230276d7d664" +git-tree-sha1 = "cb4b8c88778c6cd93b6df38ec5b95a2678434f5d" libc = "musl" os = "linux" [[HelloWorldC.download]] - sha256 = "36b7c554f1cb04d5282b991c66a10b2100085ac8deb2156bf52b4f7c4e406c04" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.aarch64-linux-musl.tar.gz" + sha256 = "924df1c2a386f79a2727a2f989393102649a24863214f2e88cb4a677d3d22e14" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.aarch64-linux-musl.tar.gz" +[[HelloWorldC]] +arch = "aarch64" +git-tree-sha1 = "7db155cf8485fbeb23d30a305f76ece191db9dc4" +os = "freebsd" + + [[HelloWorldC.download]] + sha256 = "d86d992f428df1264d55d7ac886ccd0a0539fda82363bf5dda872d12ea742528" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.aarch64-unknown-freebsd.tar.gz" [[HelloWorldC]] arch = "armv6l" call_abi = "eabihf" -git-tree-sha1 = "b7128521583d02d2dbe9c8de6fe156b79df781d9" +git-tree-sha1 = "20a32b71145b67e708f63fb5880a7243727aec0f" libc = "glibc" os = "linux" [[HelloWorldC.download]] - sha256 = "5e094b9c6e4c6a77ecc8dfc2b841ac1f2157f6a81f4c47f1e0d3e9a04eec7945" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.armv6l-linux-gnueabihf.tar.gz" + sha256 = "6f0997b0aad387ba6e2402530642bb4ded85b0243460d2e4b13d94f2c8340a44" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.armv6l-linux-gnueabihf.tar.gz" [[HelloWorldC]] arch = "armv6l" call_abi = "eabihf" -git-tree-sha1 = "edb3893a154519d6786234f5c83994c34e11feed" +git-tree-sha1 = "c1179604ea37fa66ee6d5d592c7bbfd1f20292c3" libc = "musl" os = "linux" [[HelloWorldC.download]] - sha256 = "0a2203f061ba2ef7ce4c452ec7874be3acc6db1efac8091f85d113c3404e6bb6" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.armv6l-linux-musleabihf.tar.gz" + sha256 = "0aca47bce6f09c38a7939277a593deb988123fe59f7992225a1ede8e174f1b06" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.armv6l-linux-musleabihf.tar.gz" [[HelloWorldC]] arch = "armv7l" call_abi = "eabihf" -git-tree-sha1 = "5a8288c8a30578c0d0f24a9cded29579517ce7a8" +git-tree-sha1 = "0a8e7b523ef6be31311aefe9983a488616e58201" libc = "glibc" os = "linux" [[HelloWorldC.download]] - sha256 = "a4392a4c8f834c97f9d8822ddfb1813d8674fa602eeaf04d6359c0a9e98478ec" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.armv7l-linux-gnueabihf.tar.gz" + sha256 = "f29f4da556d2b4ee9eaff7740aa0f9436406b75b0f1ec428e881a47ab7b7477b" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.armv7l-linux-gnueabihf.tar.gz" [[HelloWorldC]] arch = "armv7l" call_abi = "eabihf" -git-tree-sha1 = "169c261b321c4dc95894cdd2db9d0d0caa84677f" +git-tree-sha1 = "ca94b4d87f1a276066a2994733142e35046c41dd" libc = "musl" os = "linux" [[HelloWorldC.download]] - sha256 = "ed1aacbf197a6c78988725a39defad130ed31a2258f8e7846f73b459821f21d3" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.armv7l-linux-musleabihf.tar.gz" + sha256 = "5fb4019d6d797e5e3860cfec90cab12f6865fa624e87b51c20220a44bb94846a" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.armv7l-linux-musleabihf.tar.gz" [[HelloWorldC]] arch = "i686" -git-tree-sha1 = "fd35f9155dc424602d01fbf983eb76be3217a28f" +git-tree-sha1 = "91376c8b0bc90c47076cab4e55bf77e86bb59076" libc = "glibc" os = "linux" [[HelloWorldC.download]] - sha256 = "048fcff5ff47a3cc1e84a2688935fcd658ad1c7e7c52c0e81fe88ce6c3697aba" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.i686-linux-gnu.tar.gz" + sha256 = "b775c985231cd0626afd0111902a764c75c9a8a123b12e1f386a1c2af3cef799" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.i686-linux-gnu.tar.gz" [[HelloWorldC]] arch = "i686" -git-tree-sha1 = "8db14df0f1d2a3ed9c6a7b053a590ca6527eb95e" +git-tree-sha1 = "b50220be02e9c839749f91a70694ae68c2712c8e" libc = "musl" os = "linux" [[HelloWorldC.download]] - sha256 = "d521b4420392b8365de5ed0ef38a3b6c822665d7c257d3eef6f725c205bb3d78" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.i686-linux-musl.tar.gz" + sha256 = "6aecc06cf803ad16703744610deb243a21b39e19ae1951a38977610881698f9e" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.i686-linux-musl.tar.gz" [[HelloWorldC]] arch = "i686" -git-tree-sha1 = "56f82168947b8dc7bb98038f063209b9f864eaff" +git-tree-sha1 = "cc9cfa3272d4d3844d6fcf8b6b971bd68dbc792f" os = "windows" [[HelloWorldC.download]] - sha256 = "de578cf5ee2f457e9ff32089cbe17d03704a929980beddf4c41f4c0eb32f19c6" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.i686-w64-mingw32.tar.gz" + sha256 = "bbf3276bcfc8223061c3b1cf8725425bfc33ac2929214ba57eecfd170d30f096" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.i686-w64-mingw32.tar.gz" [[HelloWorldC]] arch = "powerpc64le" -git-tree-sha1 = "9c8902b62f5b1aaa7c2839c804bed7c3a0912c7b" +git-tree-sha1 = "5e9c87fc4e3372c27a77061a49d97fa5002df0e4" +libc = "glibc" +os = "linux" + + [[HelloWorldC.download]] + sha256 = "e2a728b29124fc7408d6e47cc6fc943d0336d1386e56a3775a0665b34528881b" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.powerpc64le-linux-gnu.tar.gz" +[[HelloWorldC]] +arch = "riscv64" +git-tree-sha1 = "3c9b23e46b82ab59141bbbc042158af4037d846d" libc = "glibc" os = "linux" [[HelloWorldC.download]] - sha256 = "63ddbfbb6ea0cafef544cc25415e7ebee6ee0a69db0878d0d4e1ed27c0ae0ab5" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.powerpc64le-linux-gnu.tar.gz" + sha256 = "59e2250eab04924eb7167d3232e4b0176c53097e4b21f2f3e3621f1e39f43107" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.riscv64-linux-gnu.tar.gz" [[HelloWorldC]] arch = "x86_64" -git-tree-sha1 = "f8ab5a03697f9afc82210d8a2be1d94509aea8bc" +git-tree-sha1 = "2e1742c9c0addd693b0b025f7a1e7aa4c50a0e6c" os = "macos" [[HelloWorldC.download]] - sha256 = "f5043338613672b12546c59359c7997c5381a9a60b86aeb951dee74de428d5e3" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.x86_64-apple-darwin.tar.gz" + sha256 = "c4f0c83ae4f72a039c33beb26ebb1d4c0fb739f34360102be79909a0dc17f47f" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.x86_64-apple-darwin.tar.gz" [[HelloWorldC]] arch = "x86_64" -git-tree-sha1 = "1ed3d81088f16e3a1fa4e3d4c4c509b8c117fecf" +git-tree-sha1 = "8c8251b0c21615bce0701995eded26ac7697b5cc" libc = "glibc" os = "linux" [[HelloWorldC.download]] - sha256 = "a18212e7984b08b23bec06e8bf9286a89b9fa2e8ee0dd46af3b852fe22013a4f" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.x86_64-linux-gnu.tar.gz" + sha256 = "974f7e1d1cdbebad149e51fed4f1b7c6a0b5ccfa350f7d252dfcf66c2dbf9f63" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.x86_64-linux-gnu.tar.gz" [[HelloWorldC]] arch = "x86_64" -git-tree-sha1 = "c04ef757b8bb773d17a0fd0ea396e52db1c7c385" +git-tree-sha1 = "cfaaf0517421585561e3b30dd6f53f6c14b2835f" libc = "musl" os = "linux" [[HelloWorldC.download]] - sha256 = "7a3d1b09410989508774f00e073ea6268edefcaba7617fc5085255ec8e82555b" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.x86_64-linux-musl.tar.gz" + sha256 = "25d3d6ecc753f4dbbcaab0db7b6c20b29b0a79b0c31f7a26a0cf18c365d27809" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.x86_64-linux-musl.tar.gz" [[HelloWorldC]] arch = "x86_64" -git-tree-sha1 = "5f7e7abf7d545a1aaa368f22e3e01ea0268870b1" +git-tree-sha1 = "8e8a17876a9c1147bae6a53a175344b805ee72d4" os = "freebsd" [[HelloWorldC.download]] - sha256 = "56aedffe38fe20294e93cfc2eb0a193c8e2ddda5a697b302e77ff48ac1195198" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.x86_64-unknown-freebsd.tar.gz" + sha256 = "61a3f945941adbf75c87c1c28f05e95b187959fedf29ecaa36519c5d1941bf23" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.x86_64-unknown-freebsd.tar.gz" [[HelloWorldC]] arch = "x86_64" -git-tree-sha1 = "2f1a6d4f82cd1eea785a5141b992423c09491f1b" +git-tree-sha1 = "6e1eb164b0651aa44621eac4dfa340d6e60295ef" os = "windows" [[HelloWorldC.download]] - sha256 = "aad77a16cbc9752f6ec62549a28c7e9f3f7f57919f6fa9fb924e0c669b11f8c4" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.x86_64-w64-mingw32.tar.gz" + sha256 = "1f10e46f7b073136f7f668de89096d631ae8bb8903547d588f6817f0b780b2fc" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.x86_64-w64-mingw32.tar.gz" [socrates] git-tree-sha1 = "43563e7631a7eafae1f9f8d9d332e3de44ad7239" diff --git a/stdlib/Artifacts/test/runtests.jl b/stdlib/Artifacts/test/runtests.jl index a09b3c7531996..cb81c16347abf 100644 --- a/stdlib/Artifacts/test/runtests.jl +++ b/stdlib/Artifacts/test/runtests.jl @@ -195,8 +195,8 @@ end with_artifacts_directory(artifacts_dir) do win64 = Platform("x86_64", "windows") mac64 = Platform("x86_64", "macos") - @test basename(@artifact_str("HelloWorldC", win64)) == "2f1a6d4f82cd1eea785a5141b992423c09491f1b" - @test basename(@artifact_str("HelloWorldC", mac64)) == "f8ab5a03697f9afc82210d8a2be1d94509aea8bc" + @test basename(@artifact_str("HelloWorldC", win64)) == "6e1eb164b0651aa44621eac4dfa340d6e60295ef" + @test basename(@artifact_str("HelloWorldC", mac64)) == "2e1742c9c0addd693b0b025f7a1e7aa4c50a0e6c" end end @@ -206,7 +206,7 @@ end # Check the first key in Artifacts.toml is hashed correctly @test artifact_hash("HelloWorldC", joinpath(@__DIR__, "Artifacts.toml"); platform=armv7l_linux) == - SHA1("5a8288c8a30578c0d0f24a9cded29579517ce7a8") + SHA1("0a8e7b523ef6be31311aefe9983a488616e58201") # Check the second key in Artifacts.toml is hashed correctly @test artifact_hash("socrates", joinpath(@__DIR__, "Artifacts.toml"); platform=armv7l_linux) == @@ -214,18 +214,18 @@ end # Check artifact_hash() works for any AbstractString @test artifact_hash(SubString("HelloWorldC0", 1, 11), joinpath(@__DIR__, "Artifacts.toml"); platform=armv7l_linux) == - SHA1("5a8288c8a30578c0d0f24a9cded29579517ce7a8") + SHA1("0a8e7b523ef6be31311aefe9983a488616e58201") end @testset "select_downloadable_artifacts()" begin armv7l_linux = Platform("armv7l", "linux") artifacts = select_downloadable_artifacts(joinpath(@__DIR__, "Artifacts.toml"); platform=armv7l_linux) @test length(keys(artifacts)) == 1 - @test artifacts["HelloWorldC"]["git-tree-sha1"] == "5a8288c8a30578c0d0f24a9cded29579517ce7a8" + @test artifacts["HelloWorldC"]["git-tree-sha1"] == "0a8e7b523ef6be31311aefe9983a488616e58201" artifacts = select_downloadable_artifacts(joinpath(@__DIR__, "Artifacts.toml"); platform=armv7l_linux, include_lazy=true) @test length(keys(artifacts)) == 2 - @test artifacts["HelloWorldC"]["git-tree-sha1"] == "5a8288c8a30578c0d0f24a9cded29579517ce7a8" + @test artifacts["HelloWorldC"]["git-tree-sha1"] == "0a8e7b523ef6be31311aefe9983a488616e58201" @test artifacts["socrates"]["git-tree-sha1"] == "43563e7631a7eafae1f9f8d9d332e3de44ad7239" end diff --git a/stdlib/LazyArtifacts.version b/stdlib/LazyArtifacts.version index f740516eb9953..8988e27bcb4ac 100644 --- a/stdlib/LazyArtifacts.version +++ b/stdlib/LazyArtifacts.version @@ -1,4 +1,4 @@ LAZYARTIFACTS_BRANCH = main -LAZYARTIFACTS_SHA1 = a719c0e3d68a95c6f3dc9571459428ca8761fa2c +LAZYARTIFACTS_SHA1 = e4cfc39598c238f75bdfdbdb3f82c9329a5af59c LAZYARTIFACTS_GIT_URL := https://github.com/JuliaPackaging/LazyArtifacts.jl.git LAZYARTIFACTS_TAR_URL = https://api.github.com/repos/JuliaPackaging/LazyArtifacts.jl/tarball/$1 From 056a69d1eb2a1f9525c44d89d7439714c78001ca Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Sun, 12 Jan 2025 18:03:34 +0100 Subject: [PATCH 166/198] Avoid promotion in `muladd` involving unitful `Furlong` (#56886) --- base/complex.jl | 2 +- test/testhelpers/Furlongs.jl | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/base/complex.jl b/base/complex.jl index 095c842795d38..5d9f9df6f2b78 100644 --- a/base/complex.jl +++ b/base/complex.jl @@ -342,7 +342,7 @@ end *(x::Real, z::Complex) = Complex(x * real(z), x * imag(z)) *(z::Complex, x::Real) = Complex(x * real(z), x * imag(z)) -muladd(x::Real, z::Complex, y::Number) = muladd(z, x, y) +muladd(x::Real, z::Complex, y::Union{Real,Complex}) = muladd(z, x, y) muladd(z::Complex, x::Real, y::Real) = Complex(muladd(real(z),x,y), imag(z)*x) muladd(z::Complex, x::Real, w::Complex) = Complex(muladd(real(z),x,real(w)), muladd(imag(z),x,imag(w))) diff --git a/test/testhelpers/Furlongs.jl b/test/testhelpers/Furlongs.jl index 6d52260bb20fd..3ddf42bf1a82c 100644 --- a/test/testhelpers/Furlongs.jl +++ b/test/testhelpers/Furlongs.jl @@ -100,5 +100,11 @@ for op in (:rem, :mod) end Base.sqrt(x::Furlong) = _div(sqrt(x.val), x, Val(2)) Base.muladd(x::Furlong, y::Furlong, z::Furlong) = x*y + z +Base.muladd(x::Furlong, y::Number, z::Number) = x*y + z +Base.muladd(x::Furlong, y::Furlong, z::Number) = x*y + z +Base.muladd(x::Number, y::Furlong, z::Number) = x*y + z +Base.muladd(x::Number, y::Number, z::Furlong) = x*y + z +Base.muladd(x::Number, y::Furlong, z::Furlong) = x*y + z +Base.muladd(x::Furlong, y::Number, z::Furlong) = x*y + z end From 37b8b61ee0bd4b8db1b210a5389cf794a1358ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Sun, 12 Jan 2025 18:12:35 +0000 Subject: [PATCH 167/198] [docs] Add RISC-V page to table of content (#57022) This was missed in #56105. --- doc/make.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/make.jl b/doc/make.jl index 5ef5fcf55b215..43d51e9936b58 100644 --- a/doc/make.jl +++ b/doc/make.jl @@ -248,6 +248,7 @@ DevDocs = [ "devdocs/build/windows.md", "devdocs/build/freebsd.md", "devdocs/build/arm.md", + "devdocs/build/riscv.md", "devdocs/build/distributing.md", ] ] From cac16d2e862a0b5719121b268c892f8abf38acef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Sun, 12 Jan 2025 23:52:21 +0000 Subject: [PATCH 168/198] [CompilerSupportLibraries_jll] Update to new build with GCC 14 (#57024) --- Make.inc | 2 +- deps/checksums/compilersupportlibraries | 194 +++++++++--------- deps/csl.mk | 11 +- .../CompilerSupportLibraries_jll/Project.toml | 2 +- 4 files changed, 106 insertions(+), 103 deletions(-) diff --git a/Make.inc b/Make.inc index 216fc6fd7adde..26b5ae7752555 100644 --- a/Make.inc +++ b/Make.inc @@ -1395,7 +1395,7 @@ LIBGFORTRAN_VERSION := $(subst libgfortran,,$(filter libgfortran%,$(subst -,$(SP # shipped with CSL. Although we do not depend on any of the symbols, it is entirely # possible that a user might choose to install a library which depends on symbols provided # by a newer libstdc++. Without runtime detection, those libraries would break. -CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.33|GLIBCXX_3\.5\.|GLIBCXX_4\. +CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.34|GLIBCXX_3\.5\.|GLIBCXX_4\. # This is the set of projects that BinaryBuilder dependencies are hooked up for. diff --git a/deps/checksums/compilersupportlibraries b/deps/checksums/compilersupportlibraries index a03ae8ee83f9a..08802ca1f4de3 100644 --- a/deps/checksums/compilersupportlibraries +++ b/deps/checksums/compilersupportlibraries @@ -1,96 +1,98 @@ -CompilerSupportLibraries.v1.2.0+0.aarch64-apple-darwin-libgfortran5.tar.gz/md5/20ebaad57850393b6ac9fa924e511fe4 -CompilerSupportLibraries.v1.2.0+0.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/020de4d8b0ff6bedbadaa305ff8445e6849f12053762ea4aa68412d1ec763dbd86f479587a2fbb862487f1feb04d976c38099ddf3887817a3d32b3f029cf85b1 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-gnu-libgfortran3.tar.gz/md5/d641904255ee412c45b089d92c53262b -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/ace0383fe9bd64faeed1fb05a11bbec932bd56b8460d06d2b7c3e1b5f4f6e9a9b3345937088684e5cd1ca9a85ef1a5ff56a97a1f60449cd6e35247de1e123d81 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-gnu-libgfortran4.tar.gz/md5/2a71f320d8b9242ad26aabed74cbf404 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/03e2a4482baaca2d6ce5cc207224d03bd7851486ebe8072c7317f5fcdd641395d945552d9462ab44a9f2e4b0ffaa3874a76f314d67bc0f75393a1151ab518611 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-gnu-libgfortran5.tar.gz/md5/1beec15ad689a5f572040ca2a7b6a880 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/27bbe212a8d43e841cf8f3e9964b72bc220fea03cf5e65721b02d2f3aa5193acdce41e512578ed6be935b413cd0d2224a6bcd2e9624931f39092ba3cfc5cbcc0 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-musl-libgfortran3.tar.gz/md5/9e949c2efe48a7b2a62bff7e1ffdede0 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-musl-libgfortran3.tar.gz/sha512/2947acb250f8ff4936da5ed02ddbfa492fc38bc87baa588a36bb892ba68b6636a912cda976f8fff00cc7a710c3bfb185826b4cd4a726750ef5f161d5f1aa21a2 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-musl-libgfortran4.tar.gz/md5/7202764b1a89a748b07460d9c40a9279 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-musl-libgfortran4.tar.gz/sha512/63236225a9becdd166c4395ea5081c64f57bc51af89c2edb5abeb419d6eb8224a380a633afd861bb84a12435fd19c8554cbe5ffadf8324ff2c7f17021ed53e69 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-musl-libgfortran5.tar.gz/md5/f66c30d3cec8057ae47f05df022ead51 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-musl-libgfortran5.tar.gz/sha512/5329d9469bb0f47560e52b15eb21ab70e0e2da0275bdb2f8e6ed4feb132bc9989a6b44984329455104546c95d05a05f8fb4f1cf232856219ba005100f4b16dc3 -CompilerSupportLibraries.v1.2.0+0.aarch64-unknown-freebsd-libgfortran4.tar.gz/md5/1d8ae93fe000440d00c404ba5044f169 -CompilerSupportLibraries.v1.2.0+0.aarch64-unknown-freebsd-libgfortran4.tar.gz/sha512/6733bd456c389c7c2cd83c5e44aa575552aa7ab5549a5b3efefbc745a6129aa76d78bacb1441208fc77c58b36f1b0775aa3a44bb97e6769ff730744ecf5e8abc -CompilerSupportLibraries.v1.2.0+0.aarch64-unknown-freebsd-libgfortran5.tar.gz/md5/bf1a5a3320a0a38133f04861afab33b8 -CompilerSupportLibraries.v1.2.0+0.aarch64-unknown-freebsd-libgfortran5.tar.gz/sha512/221502795c075f64196dae687a35b83aa83a9a1ecf1ec3e9f51613bd7431c526015e412132a081e00ca13a5730d733330df79baad6fccc8758c17db9877e59dd -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/05ff63780f5b7c8c6c590c3626f32ac0 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/8d3c4149531f3782f5efbb6a6fbbb7080ba005298ba962b5bc5f66250ea9fde91b34836ed909c16f306d21d2e358f985360962e9362a8e807ccd4254da3bb19b -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/3ca2b6e8101d831e546c1b6ed2ca9a42 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/21a0b9c5acde96c0a91303f4f395e55f272d5585ad18f0365105188d129a3ca94ad66d4dd99b471abdf41a7a7262a3b258fd04b887110ad15255b284cd1612b0 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/d4d560b8ecce0ff2cb4dbc88cb25942a -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/d405f61525af1b2fe85107a70ed67b8a1eb767923487fa71539e0f49d6e70358c8a24f4ef1c224256cf677af99b54a2f8243f1e207350fcb14d426a7a6bb3915 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/8c6eddaa156fd0afee28ac5a154bc3f7 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/b9fc86bb706ad98d61b63eb4cc8bfce6b2c67b58ba2cebecea7574f44790cce044bb1b4db1d20050b59538fa43b51cb352d752c77333a0f0621fde47c63a3596 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/0a54c16fea86c6dadb39eff65c465528 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/c635c636384d3af5b4b078be7398fbc665a185eae69dd223279affb4836fb5c575d6ab296ae940ccbe73777bdb5e355f4f28a2fa27606ac143ff424641c60c65 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/892dfd91703f0f77d170a5371a1c25d4 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/8ac59d00192c0e847168e61b3e93957f3909aab59ba8d05e47686a9f8b7226496f89b932151c42198ec966ccd47721cdf547a247ea4e5c61b22bfccce2ec591c -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/05ff63780f5b7c8c6c590c3626f32ac0 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/8d3c4149531f3782f5efbb6a6fbbb7080ba005298ba962b5bc5f66250ea9fde91b34836ed909c16f306d21d2e358f985360962e9362a8e807ccd4254da3bb19b -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/3ca2b6e8101d831e546c1b6ed2ca9a42 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/21a0b9c5acde96c0a91303f4f395e55f272d5585ad18f0365105188d129a3ca94ad66d4dd99b471abdf41a7a7262a3b258fd04b887110ad15255b284cd1612b0 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/d4d560b8ecce0ff2cb4dbc88cb25942a -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/d405f61525af1b2fe85107a70ed67b8a1eb767923487fa71539e0f49d6e70358c8a24f4ef1c224256cf677af99b54a2f8243f1e207350fcb14d426a7a6bb3915 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/8c6eddaa156fd0afee28ac5a154bc3f7 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/b9fc86bb706ad98d61b63eb4cc8bfce6b2c67b58ba2cebecea7574f44790cce044bb1b4db1d20050b59538fa43b51cb352d752c77333a0f0621fde47c63a3596 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/0a54c16fea86c6dadb39eff65c465528 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/c635c636384d3af5b4b078be7398fbc665a185eae69dd223279affb4836fb5c575d6ab296ae940ccbe73777bdb5e355f4f28a2fa27606ac143ff424641c60c65 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/892dfd91703f0f77d170a5371a1c25d4 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/8ac59d00192c0e847168e61b3e93957f3909aab59ba8d05e47686a9f8b7226496f89b932151c42198ec966ccd47721cdf547a247ea4e5c61b22bfccce2ec591c -CompilerSupportLibraries.v1.2.0+0.i686-linux-gnu-libgfortran3.tar.gz/md5/3094705222b6b61fd6a10422a73e1149 -CompilerSupportLibraries.v1.2.0+0.i686-linux-gnu-libgfortran3.tar.gz/sha512/27f874cde357ffa45aaa10f2e620ec0f8ab4e5a8bf4607fc023a2ec42040bcc9a724f959237c340d67451f8621402fa05133c1420086b87135f40326c30b97af -CompilerSupportLibraries.v1.2.0+0.i686-linux-gnu-libgfortran4.tar.gz/md5/ba0acaff60648efa3915348a8a353df8 -CompilerSupportLibraries.v1.2.0+0.i686-linux-gnu-libgfortran4.tar.gz/sha512/0b6aaf75363cbe6133ca3aed351ab58ef1e441f61375f5baf702d8043813c459d48e8af17630f1a07dc22772ec9b02076af33726ed94e6314ae37d5a139d6dcc -CompilerSupportLibraries.v1.2.0+0.i686-linux-gnu-libgfortran5.tar.gz/md5/95f1d57cfc43677e40bfc121bce79274 -CompilerSupportLibraries.v1.2.0+0.i686-linux-gnu-libgfortran5.tar.gz/sha512/edacd9960e9de1236c91752e103cddfc018d697e87fabb3cceadf36153b4e97842ef284bd1532290a5620007234882b4c4cd4f36525b61763d97b2f608358262 -CompilerSupportLibraries.v1.2.0+0.i686-linux-musl-libgfortran3.tar.gz/md5/f37fe1818e1634476c44afae478611c8 -CompilerSupportLibraries.v1.2.0+0.i686-linux-musl-libgfortran3.tar.gz/sha512/6e4e3eb5ac9570bfdf5280f59167eb6c4a74f3aa152afb4c5d180b9a6cdbdca557e7dd13f0b5b76943b45a65e848fe77c5b3bbc6ddb0fd846d03fbc9fbedf7ce -CompilerSupportLibraries.v1.2.0+0.i686-linux-musl-libgfortran4.tar.gz/md5/b4ffd52179aa0006c56f279b87cb7556 -CompilerSupportLibraries.v1.2.0+0.i686-linux-musl-libgfortran4.tar.gz/sha512/a047ac7db204c31802f646351af51c55fe06498e851b2df58d7f93f75d9c0067f8736f247f108991ec01ac7f86f3026ecf58b5f2f3a76d7eab00130754e7f704 -CompilerSupportLibraries.v1.2.0+0.i686-linux-musl-libgfortran5.tar.gz/md5/2d38fc835f236f89f457fdf859ccb903 -CompilerSupportLibraries.v1.2.0+0.i686-linux-musl-libgfortran5.tar.gz/sha512/51fbe41efbce33b1cf3728df6fa59fd0e85a13308b3e868fe9f70f4d67857615f83542ba69be824a73e89959503dd7a11335d1c495704bd7d6cad6656d0c5d57 -CompilerSupportLibraries.v1.2.0+0.i686-w64-mingw32-libgfortran3.tar.gz/md5/9650002f6729c0964d33afcab334d77d -CompilerSupportLibraries.v1.2.0+0.i686-w64-mingw32-libgfortran3.tar.gz/sha512/0b7907811a13d09b7b33203c7e46888308c7d6fcf5d69790babafc39f640541551f784264247f159a552f15df1ddd061c421a93b983d838d3bd7f85ba6427f70 -CompilerSupportLibraries.v1.2.0+0.i686-w64-mingw32-libgfortran4.tar.gz/md5/47e9fb99906b9647e26e4126a913074e -CompilerSupportLibraries.v1.2.0+0.i686-w64-mingw32-libgfortran4.tar.gz/sha512/d7285691fbe1318e48e061d678e54890762cc16996652a34b190924cc1462d24ab0b08729945eb25f4bef60e60d50f3e78db57d4cda0302b8ba579db8a1311e1 -CompilerSupportLibraries.v1.2.0+0.i686-w64-mingw32-libgfortran5.tar.gz/md5/b588b2710f2b83d2c70c6104e585a3bd -CompilerSupportLibraries.v1.2.0+0.i686-w64-mingw32-libgfortran5.tar.gz/sha512/b62a63b0c8750f85fc265db88456307b794e912352a68997c7cce06444391307c03edbe5b901833f53c5bd55f5a1e61a586538b08487cc139a2d71fccdce1d31 -CompilerSupportLibraries.v1.2.0+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/7cce4f3dc057ebebaa677bf6f0d51e9e -CompilerSupportLibraries.v1.2.0+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/a0dd93905f0ede4da5e2fbacf2579154db8ac8e9963c77fb62284489686f2aa372925b3341742d86430a839267421af55f6e1e413473d17f13a1a199e6a904a0 -CompilerSupportLibraries.v1.2.0+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/06ee6aaeca78b3e9005f53f1fa32731f -CompilerSupportLibraries.v1.2.0+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/ff0e33ce9f93b3a867cf409b95e763efbc8f4dde65ed19107eb14d29460d084f253e03ebd6375f1da996182b3d96e1fda4abff06507258da9a89ece36663db84 -CompilerSupportLibraries.v1.2.0+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/483251d28076ee959dff131d13d7e53b -CompilerSupportLibraries.v1.2.0+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/a7c9053a8c1b784cb6459762f26e0c2106a9758cbe2aefe8975a14aaaf61b8a08e51c465e733e44d01537beb59d467c57e536ebd8b27b7b68f46945174c469c7 -CompilerSupportLibraries.v1.2.0+0.x86_64-apple-darwin-libgfortran3.tar.gz/md5/a147bf3a6d6550c177b8a784b9b02e21 -CompilerSupportLibraries.v1.2.0+0.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/c6f7a13f0195eae8f7ad980a4b24de9b155be69c4437522723411f9866a4aee3c5b350ee2f0c95f41f19aba43acaca78309881157e8498df0664c902d0c05a5d -CompilerSupportLibraries.v1.2.0+0.x86_64-apple-darwin-libgfortran4.tar.gz/md5/3f19c9d0e723a8d5591357ac3a9452a0 -CompilerSupportLibraries.v1.2.0+0.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/5752bac310d80ed2dc1fc3d6580300d185787b9b933e31c8e0f572099abd0727d9483da8f9af858f706e96a183d2b10702c44381a080438cbb17d6459321ccfb -CompilerSupportLibraries.v1.2.0+0.x86_64-apple-darwin-libgfortran5.tar.gz/md5/ad0f0e2fe3e7d147a0a27271a2aba0fc -CompilerSupportLibraries.v1.2.0+0.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/f42231adea3d0b6133c3b5bc5fbf765bc6a7ba8ef0f407fa1b8def36dd8a71d20ef39fb6e57b43208489c2795a96562cdbf15f3d20b3f3a09edb29b99d19a33a -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-gnu-libgfortran3.tar.gz/md5/4c78d56dbbbff682c0a78d11fb9d1e70 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/0e9d6dcc4b8fddaaa94a26a46e915d33fb474f8a8ee14edd4d1c7e774846c44c5c5d852649a4f70409c99ac0e1d458077b7f0eb7dc0b0326ee8b625644d7074d -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-gnu-libgfortran4.tar.gz/md5/039d37f813b183c75feebadd21011eb6 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/05e7291de1fd2520247402f0db9d348fdd7a02d8dd9133ac65701f88d237110a3cc6c6e2c5717364ab786b6e6063038ec10c9605e77bc4dbe1064a0e77617f5d -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-gnu-libgfortran5.tar.gz/md5/a985f13a85eb14d1b6339ba4983dc372 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/27468ccd5642e6e11bd5972684518a0fb883bf4835ac18f5279c3fce97b1779131c7d9e39d8de26a15c293c832946334e964919f51d7679cd0569ce82b938579 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-musl-libgfortran3.tar.gz/md5/9d86ce2fe481ea97a1fd098bd47d524c -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-musl-libgfortran3.tar.gz/sha512/a865a4127bacaedd81b6c81279f6a44bc3497ab29a0401f66da1abfc0738ea459be9f158d06969c161a65925739665084bec5f8650a8cd1e8f0d08f1f44d729f -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-musl-libgfortran4.tar.gz/md5/86d9db869a7af6c96dea39f5d9d90505 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-musl-libgfortran4.tar.gz/sha512/01e0c69b04138989200ded92eddae6ff1873d3a440d17273d08bee40d53b2929e35bfd14be051074fe78671cac34ac2dd7360c1571790ee52f94a5921de42a65 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-musl-libgfortran5.tar.gz/md5/e72d28df4bcb60ab2f3389046e7c83a8 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-musl-libgfortran5.tar.gz/sha512/cac193a26328ddeff5f7bcc3d7207101c574f9bdb1bff5c2b925315c5c2404a2fdb6591d1968f30931373fbfcae9bda784c72e65580ad3acc398448cd193f65d -CompilerSupportLibraries.v1.2.0+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/35642304a9a2f435cf5214b2715198fe -CompilerSupportLibraries.v1.2.0+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/a67f41ba31c99a064f504f508711537f9e90089ca5352bfc2698c3fcd3e499ca716f07ffeac4fb1b88c2c934f7f380f262af8c863d3b16ac7e805d5c805ab358 -CompilerSupportLibraries.v1.2.0+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/01df0fbb265e5ff1a480a7a5e23b0835 -CompilerSupportLibraries.v1.2.0+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/57a79f2b8e846c1514dcb18420f26ae2889962040f410b746836cab4395749155fa9cd9d00d4c25954c0ffa72f9f3823b1b50688a20ddf675301f64e0d4b5c7e -CompilerSupportLibraries.v1.2.0+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/1f1f6380ce8815cc9cedcea0b40860e7 -CompilerSupportLibraries.v1.2.0+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/a88ea8af8c8df792861812bfdf7f1bcaae31582ab78ce78b47a0dc6fd57b93441c0471f529ce23877131ac9701c6eed72ce89241746e18271f3686fbd718138c -CompilerSupportLibraries.v1.2.0+0.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/38fc8c445a1a610db40a7609155e22d6 -CompilerSupportLibraries.v1.2.0+0.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/085652c7ca583c3623611ca9262b70765c9936c9feb5f9034b2c6b6d6677a7a1d7d201b83d82d0d268f3190bd1a62eab0124e8fae3625407dee7f1df89d4106c -CompilerSupportLibraries.v1.2.0+0.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/f3f89eb3c2e441fde6e6b9c1c1a61183 -CompilerSupportLibraries.v1.2.0+0.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/c53f79e20ad043ab099873f38ece98c6bed22950610ba88b9c178a4bd943039cc426473828d509deb8c65c93309da1de87bdf36fb3954b8f8047277c418fe2e0 -CompilerSupportLibraries.v1.2.0+0.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/024f7133425db23e215dc55589bb9171 -CompilerSupportLibraries.v1.2.0+0.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/819945496ea48dd44d8c0f12a11a358b7d1ebf198d60fbad576d74ddee68cdea98070cdd11ca96567d0c772ec007c03cbc83ff5c7d2ad737cbd486fe0c9afcd5 +CompilerSupportLibraries.v1.3.0+1.aarch64-apple-darwin-libgfortran5.tar.gz/md5/20ebaad57850393b6ac9fa924e511fe4 +CompilerSupportLibraries.v1.3.0+1.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/020de4d8b0ff6bedbadaa305ff8445e6849f12053762ea4aa68412d1ec763dbd86f479587a2fbb862487f1feb04d976c38099ddf3887817a3d32b3f029cf85b1 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-gnu-libgfortran3.tar.gz/md5/c679907ddce62f21bc30667cc40d8d52 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/284b17b6634087f0b969d3e99b2e4152667ab5eb9e6b5813f9739bd14ae1c25dba01f15488e901ca5fcfd780b02bc02b6bff670fefed7d965dcb585e81b03782 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-gnu-libgfortran4.tar.gz/md5/1b4f6efeb83f5f3e27c42eddeafe993a +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/b1d5aa122b2bd25bcd1ce47e000f71785d617d77f44acda56f9f5ad77101a0c54f6c6a4c5560a7c12ffb8c89ae325d4f056bd92f893d219385c3d5c85aa457e9 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-gnu-libgfortran5.tar.gz/md5/834adb105f78ac1bb223ef309dbf7cdc +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/dd0440805145f1a8e8521633a955317567606bf2e3725a5a7eb90515128b077f2163832ab608022fab152526f2a55991f50256ab92104d5d62bbb8a740e25009 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-musl-libgfortran3.tar.gz/md5/d613881e48181bb8ac0bf34a456c9736 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-musl-libgfortran3.tar.gz/sha512/34214bca9f7c66e3c508b2f9d88cb296695721cfba0c001660e2edb0387a2efbb2fecb0360f8eb2b1d0ec502480fe63e802f350367498a342c455c0f58aadd82 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-musl-libgfortran4.tar.gz/md5/97e4ea4394df1d784ce4de3f75aed580 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-musl-libgfortran4.tar.gz/sha512/a072ceece6600b704dae5a7491f1ead9b4e11da3d4438b7056f2c71e59b0a37d3023fb812cbae205a4f1fcaf18a4b223a5ba2cea32131c5eda0d55b1f0649c23 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-musl-libgfortran5.tar.gz/md5/df09c5b33b2e307e0d9c2b39b450c0eb +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-musl-libgfortran5.tar.gz/sha512/d0a8dc03ea1667d90bd58c2376b575a1090a54a4412bc53b311a3ea910c76dc698be5ca1078e6ca8341244f1fd6b84201ba10c10baba194c1d6c3ffb7e69563c +CompilerSupportLibraries.v1.3.0+1.aarch64-unknown-freebsd-libgfortran4.tar.gz/md5/4f9b257eabaf0a817755495cfbf75088 +CompilerSupportLibraries.v1.3.0+1.aarch64-unknown-freebsd-libgfortran4.tar.gz/sha512/876036a8b599008512ab7010f4bc5f11fbf963bb9b9f77499adcca21fcad89f94180f653dce3121e5c1206f4fd4ace717ef8f3b40d8009a71039a84ae7272588 +CompilerSupportLibraries.v1.3.0+1.aarch64-unknown-freebsd-libgfortran5.tar.gz/md5/0d296a080921b54d959a2a60884b7938 +CompilerSupportLibraries.v1.3.0+1.aarch64-unknown-freebsd-libgfortran5.tar.gz/sha512/d8232dd9131c2890ea2f5c90f62c646ea1dc93a0a6de4af0a98c7e69928c5ca5698e79ff9d23bdcf47de1f5670467c9e8fed5f01e82e009696641896f0658030 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/3e0727a3813c699b6daa041e336d6e13 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/00cc2c34af7c4a5df06deaff27dff5b94b231ede4afe7a47b7b783a8d2e62158c0ba1b2062d40df949fdc0a21ac703f8c9011f998ab032bac265aef153cea012 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/b7cb328b5e5fae5b5e456d058f5c18b7 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ff191595bdf4dfb2cdd77d42e591adc0b27ca0e1055efa7fb25fc06784f26add83e6c5c7594405bdfd715f9c8e6ae3f2171a50ae218b4b691099da754fe9bedd +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/46a3fc18a65e223ba59d984f99d42979 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/cb470147f6695b101d497bf2d84caeb1f97d967bf23d1844ad70be47505588d981df096378136a98c35cda5aec090255d60cf7c1c8def9801233c72ca002b563 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/28e1bc0fb0ac1512a8598f26ee3f376a +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/7ec17859790cd08942929281906918e4c69d7f306a8302dcd591a4a67b3d95f7f72f7afbeea3a86a0d94ca5b608b3bda00ce43b594e9f173edb0228c0f79ba49 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/f9bff1a49d95fc0f3ad3d4a90b259c87 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/8ad503a213b949f569c5b9eac28e33ed51cc55298bb66b147375dc12cb9ed90e60165aa2dca8e3d28f1a2c153894a9e4672bdb2ae3cfb3a67b1e06b345cb454f +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/d550a4dac1b20606681a56acc00c01ad +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/14ca10ad8809dfd2434e300ad5280915f21cc1ba159a9f4aed7aa2164ae624687a2a7a9e6dd99abcfe95f40cb037c72292c992f4483fa1affcf8a9b5cf29c9bf +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/3e0727a3813c699b6daa041e336d6e13 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/00cc2c34af7c4a5df06deaff27dff5b94b231ede4afe7a47b7b783a8d2e62158c0ba1b2062d40df949fdc0a21ac703f8c9011f998ab032bac265aef153cea012 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/b7cb328b5e5fae5b5e456d058f5c18b7 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ff191595bdf4dfb2cdd77d42e591adc0b27ca0e1055efa7fb25fc06784f26add83e6c5c7594405bdfd715f9c8e6ae3f2171a50ae218b4b691099da754fe9bedd +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/46a3fc18a65e223ba59d984f99d42979 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/cb470147f6695b101d497bf2d84caeb1f97d967bf23d1844ad70be47505588d981df096378136a98c35cda5aec090255d60cf7c1c8def9801233c72ca002b563 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/28e1bc0fb0ac1512a8598f26ee3f376a +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/7ec17859790cd08942929281906918e4c69d7f306a8302dcd591a4a67b3d95f7f72f7afbeea3a86a0d94ca5b608b3bda00ce43b594e9f173edb0228c0f79ba49 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/f9bff1a49d95fc0f3ad3d4a90b259c87 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/8ad503a213b949f569c5b9eac28e33ed51cc55298bb66b147375dc12cb9ed90e60165aa2dca8e3d28f1a2c153894a9e4672bdb2ae3cfb3a67b1e06b345cb454f +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/d550a4dac1b20606681a56acc00c01ad +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/14ca10ad8809dfd2434e300ad5280915f21cc1ba159a9f4aed7aa2164ae624687a2a7a9e6dd99abcfe95f40cb037c72292c992f4483fa1affcf8a9b5cf29c9bf +CompilerSupportLibraries.v1.3.0+1.i686-linux-gnu-libgfortran3.tar.gz/md5/73e14b94dc74d17aca38a51ad402f836 +CompilerSupportLibraries.v1.3.0+1.i686-linux-gnu-libgfortran3.tar.gz/sha512/d37263a216fb3e9b94dd032642ed6bf5be154a5c66de3e4bd74e5e2059d9740958a673796eb652ca9ebea8ec09a7eec837d8906a50775913325899aa190808db +CompilerSupportLibraries.v1.3.0+1.i686-linux-gnu-libgfortran4.tar.gz/md5/23996e5c6690b35e7c36bff245f6f4d1 +CompilerSupportLibraries.v1.3.0+1.i686-linux-gnu-libgfortran4.tar.gz/sha512/660dc4866a13f9a1ae98424b605723b250218a034e02151d4160d58ca07bba4fa1390e99e7fe2f31eccdd518d1ac4c5f5454968ce52525e3a2d21918b6b5bba8 +CompilerSupportLibraries.v1.3.0+1.i686-linux-gnu-libgfortran5.tar.gz/md5/af836562cfaf76f0728be0d875d29ae1 +CompilerSupportLibraries.v1.3.0+1.i686-linux-gnu-libgfortran5.tar.gz/sha512/a2b10c2f72d1e84c7b496b7ad6d38629342c93cd6a7f691e5bbe96ce28ef40fd38509d382d22208e40cc4953e7b93d1c211bf59529db0ad1a77b684ba75bc68a +CompilerSupportLibraries.v1.3.0+1.i686-linux-musl-libgfortran3.tar.gz/md5/502f089e5ee03b3a290ee6e18577a22f +CompilerSupportLibraries.v1.3.0+1.i686-linux-musl-libgfortran3.tar.gz/sha512/13a97c2386f37aba2416ec35fe67b99a1eccb880b0254ff0a70f2ba01a01a15c80251606ec7eb0503d59a7723542b6b9778d6c9d9e4ba66ae5cce51e46a9cb40 +CompilerSupportLibraries.v1.3.0+1.i686-linux-musl-libgfortran4.tar.gz/md5/221aa40c278faee74ab6af46686d68d6 +CompilerSupportLibraries.v1.3.0+1.i686-linux-musl-libgfortran4.tar.gz/sha512/9e4e598c8acdecebc812555de9631f022f6158d679c329537e37f83c76c818f31476a5827924b5ac12978515d64a7e913f220ca75314f41d3227573e9a2ac9af +CompilerSupportLibraries.v1.3.0+1.i686-linux-musl-libgfortran5.tar.gz/md5/c364ec196e66dd5eadc3932b208a0385 +CompilerSupportLibraries.v1.3.0+1.i686-linux-musl-libgfortran5.tar.gz/sha512/3f7b80fb35a967d9354c2f4c40bb6d62751a0d791aeec09817cdc278393cacef089214f61d8338c0981f7a4ed3144d37bc9267cf0e7ce6c4cf651bc67c431b70 +CompilerSupportLibraries.v1.3.0+1.i686-w64-mingw32-libgfortran3.tar.gz/md5/4177f1ede00d81472bb69888f5b3e26f +CompilerSupportLibraries.v1.3.0+1.i686-w64-mingw32-libgfortran3.tar.gz/sha512/09ab710599d237ee35fca6a39b4d67b36bbadb7d127797724743026eae72319faa161755b03f4cb67c83f801aa4132968b561245487b2c2c0836d0ff867c0e83 +CompilerSupportLibraries.v1.3.0+1.i686-w64-mingw32-libgfortran4.tar.gz/md5/9402d280886784bc245096bdc838fbc6 +CompilerSupportLibraries.v1.3.0+1.i686-w64-mingw32-libgfortran4.tar.gz/sha512/60e72336efdd307b88b1e6db5234388ac1892504ac858b412d18f072a33ca1aeaf1b8621ccf43027508b7a4653150f0849a89c57164beb1e7f24ef32f7fb7f11 +CompilerSupportLibraries.v1.3.0+1.i686-w64-mingw32-libgfortran5.tar.gz/md5/310b163628e7defdfa6a293360b203db +CompilerSupportLibraries.v1.3.0+1.i686-w64-mingw32-libgfortran5.tar.gz/sha512/02e9a797246feb9c4b09b0c67c773dac5c3bb61568bdd48be147adeb2dc08fd2bd7151f2293e2756685d011e463e39dc5ca0f79593dda7501cacbc15adfc74e0 +CompilerSupportLibraries.v1.3.0+1.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/c139a9d54f39701e805d2af185a6f17c +CompilerSupportLibraries.v1.3.0+1.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/0d1f29cb04b42b276edd7998a02f6166295f6b7a2a8ffdf6b2986145476385b19c2f93b012974835363ef57f2018bdb80814adef3b72b9378f0d2c6a8805c43e +CompilerSupportLibraries.v1.3.0+1.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/3ab360133835e1d0a6a24bb2de1dde02 +CompilerSupportLibraries.v1.3.0+1.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/9c2f765b58a73b3705f787f68c995d8f2cbd211978c0ec8ac2adbfec6685f4b3a02aa63bf75b9dbf0a2a5c048e35536929d04b89c120671174d76132cbd2c7ed +CompilerSupportLibraries.v1.3.0+1.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/6ce9e27ab33b35900d8f81c2ad05eec2 +CompilerSupportLibraries.v1.3.0+1.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/1d8af2664e68d18ef4f68b9fed28979af0acf3dd09c8064c4b25b3268808bc6901ce727b5b3ec3c27e37914a7c1f8c92e5ce35de093d66cb6a2e98ad59c2252b +CompilerSupportLibraries.v1.3.0+1.riscv64-linux-gnu-libgfortran5.tar.gz/md5/6c292cf98c6b4cbf10aeb4f0af383222 +CompilerSupportLibraries.v1.3.0+1.riscv64-linux-gnu-libgfortran5.tar.gz/sha512/1497789d918d633f319f89a04241678602d3b0f441ca6f8f6d756f6d1fba59d5eca54fd24183e39e9b956cd3c053afd747dc03a9a1e2d4819d26de3539c5eb07 +CompilerSupportLibraries.v1.3.0+1.x86_64-apple-darwin-libgfortran3.tar.gz/md5/0aae7ac19dade024e0228bb1a3565edf +CompilerSupportLibraries.v1.3.0+1.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/b779badad7e6021875b5df04793445b4056d84cc217f389f9496d8ca61af71d98a667ec29b912131c83319be4d6e82c59e7c3f409f302cc3691899f0e77edd46 +CompilerSupportLibraries.v1.3.0+1.x86_64-apple-darwin-libgfortran4.tar.gz/md5/6fcb9749463a96504f1e23cd97695f60 +CompilerSupportLibraries.v1.3.0+1.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/66d4cb8237859234f8fd49461b5976a7f155e02fb93c765208701c43c041dc8693f3f8b868ba74bd28614586c0f5109a5b5aa0d0d69ac38732ad6d84d2635e04 +CompilerSupportLibraries.v1.3.0+1.x86_64-apple-darwin-libgfortran5.tar.gz/md5/af01aefc789a0388df504abae68fc01f +CompilerSupportLibraries.v1.3.0+1.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/444d1d54fb6ef95f2093894c685a4065e9708504b820bd9325bdf32619eac8b2972b1601e788ff8f1ee2759117b726c04c8bb395820359bdc737bdfdc3c4026b +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-gnu-libgfortran3.tar.gz/md5/df1c55a47f9faebf09ea093d5d1ee344 +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/03477fdf14d8dfce204999e6825d9ad94c2c78686d59b251f39d1bb357b3c9d9a74339c4d5f5e97420870d44f7bc2fceca637fbf7b862d0d1cf04a19a2a0b036 +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-gnu-libgfortran4.tar.gz/md5/8812418d84c2ac289d64a597d4968704 +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/4da50ea541c13a98ae05c6ff67b8021496b871a205f994605f0230a67eb6c58ede55aa3a471df8bbdd5618177d34914186cfae106664b80a7fef795e5fe97e8f +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-gnu-libgfortran5.tar.gz/md5/55bd8dacbc4afff6196494542ea13eec +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/2bb63e68f56818c0a3bb988f395ebcbe99af2740f806e324c385c1dcd7a5dbb058afd286fb6d85a1621ca668aba962a8701bef96a4547b0d22f92d9e4f4b51cc +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-musl-libgfortran3.tar.gz/md5/1e06592e53de4448b0712a79e61b9a51 +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-musl-libgfortran3.tar.gz/sha512/cf92bbc217a51b9a18e07c5b5248ac5f59f92a7924c5fc566a1bd5b87a1acd36ec9c1d64871b273f80670596c05c1795cec91294f32f8dc1490633ea6d543037 +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-musl-libgfortran4.tar.gz/md5/fa81135fc7e697eb8409baf3fcafdcb6 +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-musl-libgfortran4.tar.gz/sha512/32ab98be0521f2451ce9b71c5ce7dfc70094583df80ed8db3990a2041594839f065abcf6c847fe6b8293eac3b3395da16ab3d24cf5e15c962aa320b28a6cd4be +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-musl-libgfortran5.tar.gz/md5/d6f0a90da74eaf2f9bf4f7b884231a2a +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-musl-libgfortran5.tar.gz/sha512/cbbbd0284799f78cf20a41f1b2d110651ee0460f0191d519d522a5034a31edaaf62ef130e7ef42c28882e224a4f997f0bead5b569254cdda7100b1f41e286b78 +CompilerSupportLibraries.v1.3.0+1.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/c525e70e726f0fc1c49deedd08ab6026 +CompilerSupportLibraries.v1.3.0+1.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/eb50d1443e1d13b892c141ac579b2e807f346d98a75e2ce9a0a23494c754b7149d1900046f5c39e324b48bfeedc6bee590a7e2c182e6f0e3c07b9f816fcb9d6d +CompilerSupportLibraries.v1.3.0+1.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/9777c3216792efd8e8625f5f72442be6 +CompilerSupportLibraries.v1.3.0+1.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/215398a9c893a5298101d98a3cf3df1e59e6dd4b0d66b3cdcd9decd8725541ae33c30d1e391fb51d7aaaa33dc5911511257f7ee7e3ea6350a8942ae70fcb3ada +CompilerSupportLibraries.v1.3.0+1.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/c7571567040d646935234b51c121745b +CompilerSupportLibraries.v1.3.0+1.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/159900879d46eb2a2e45f0bfbf6eb7b03c1e28705d576ad712f67a3ae242e7e4642c08f3be181b9fbac659e1c76de6ca278ad3662fd15e8371adc7bf19e9e9b3 +CompilerSupportLibraries.v1.3.0+1.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/63187354746bbcfd43c11b8047595d21 +CompilerSupportLibraries.v1.3.0+1.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/7c004e5ee255a9cc410b2f8f8836d0dffae8f4e35552c57a74a9c2eb8dadd6f0966ffceb296fd61c5c0ad7a0ea25c80ee2d7bd80ed3ccf1305f236b64e2dad5a +CompilerSupportLibraries.v1.3.0+1.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/64f5d316b2d694dbdb2c96e557482de8 +CompilerSupportLibraries.v1.3.0+1.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/e1b3be2e6e9d4ccae55ec131f6cd51a7c4391639365057f7c8ecde539c9f5fa4d73942cbc2d06c62f43c2e1bca0469862a9ac6dc064536400ec09f37a20e2b1d +CompilerSupportLibraries.v1.3.0+1.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/d10bb5d9facb9428c22f920798876f9b +CompilerSupportLibraries.v1.3.0+1.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/7671d0a7e1d965d0dfd56e3f037dbb47a2748cbff2656be26741e1b15687b3ba48bb44e7d43e005cd610257c94ffa8e71eb3e3ade772ee5c6f6aeee4535f04ce diff --git a/deps/csl.mk b/deps/csl.mk index a50a08fab8506..fef950aa41621 100644 --- a/deps/csl.mk +++ b/deps/csl.mk @@ -117,13 +117,14 @@ distclean-csl: clean-csl else $(eval $(call bb-install,csl,CSL,true)) ifeq ($(OS),WINNT) +GCC_VERSION = 14 install-csl: mkdir -p $(build_private_libdir)/ - cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libgcc_s.a $(build_private_libdir)/ - cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libgcc.a $(build_private_libdir)/ - cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libmsvcrt.a $(build_private_libdir)/ - cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libssp.dll.a $(build_private_libdir)/ - cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libssp.dll.a $(build_libdir)/ + cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/$(GCC_VERSION)/libgcc_s.a $(build_private_libdir)/ + cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/$(GCC_VERSION)/libgcc.a $(build_private_libdir)/ + cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/$(GCC_VERSION)/libmsvcrt.a $(build_private_libdir)/ + cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/$(GCC_VERSION)/libssp.dll.a $(build_private_libdir)/ + cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/$(GCC_VERSION)/libssp.dll.a $(build_libdir)/ endif endif ifeq ($(OS),WINNT) diff --git a/stdlib/CompilerSupportLibraries_jll/Project.toml b/stdlib/CompilerSupportLibraries_jll/Project.toml index 12806e4bc427a..2f8143a77d740 100644 --- a/stdlib/CompilerSupportLibraries_jll/Project.toml +++ b/stdlib/CompilerSupportLibraries_jll/Project.toml @@ -4,7 +4,7 @@ uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" # NOTE: When updating this, also make sure to update the value # `CSL_NEXT_GLIBCXX_VERSION` in `Make.inc`, to properly disable # automatic usage of BB-built CSLs on extremely up-to-date systems! -version = "1.2.0+0" +version = "1.3.0+1" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" From b671c9dcdd715ea8c2ff7123b2905a0259873739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:30:14 +0000 Subject: [PATCH 169/198] [OpenBLAS_jll] Upgrade to v0.3.29 (#57025) [OpenBLAS v0.3.29](https://github.com/OpenMathLib/OpenBLAS/releases) was released just 6 hours ago. Note that OpenBLAS 0.3.29 [doesn't support building for PowerPC with GCC before v11](https://github.com/OpenMathLib/OpenBLAS/issues/5068#issuecomment-2585836284), which means we can't support libgfortran3 and 4 anymore. --- deps/checksums/openblas | 194 +++++++++--------- deps/openblas.mk | 7 +- deps/openblas.version | 6 +- ...enblas-memory-buffer-multi-threading.patch | 49 ----- stdlib/OpenBLAS_jll/Project.toml | 2 +- 5 files changed, 101 insertions(+), 157 deletions(-) delete mode 100644 deps/patches/openblas-memory-buffer-multi-threading.patch diff --git a/deps/checksums/openblas b/deps/checksums/openblas index 74cdaa26c30b2..f1bcf3f322d8c 100644 --- a/deps/checksums/openblas +++ b/deps/checksums/openblas @@ -1,98 +1,96 @@ -OpenBLAS.v0.3.28+3.aarch64-apple-darwin-libgfortran5.tar.gz/md5/312aa603d089d680205dad7d5da58195 -OpenBLAS.v0.3.28+3.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/ffb0069561f52f8ac2f8affe937a00592e0c5d75c6d64bb0d5c93d1c925c93a46b763638031c88818b9dcef4a7b149ee3f15792a812e87f57a8ad086604164c4 -OpenBLAS.v0.3.28+3.aarch64-linux-gnu-libgfortran3.tar.gz/md5/7c43d9e9ac07820130a3d5faefdef882 -OpenBLAS.v0.3.28+3.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/3ade0f098796148c37b118f9c052bad4e40431b4792f001043f040f8b1e4b7c3bae512f56ea21e6c0111246b2200e7720fe720a56a19dd11d1fba789344f29e3 -OpenBLAS.v0.3.28+3.aarch64-linux-gnu-libgfortran4.tar.gz/md5/cd2fe87dac703c8bfa25406aa732b88a -OpenBLAS.v0.3.28+3.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/2aea68bd8f1db2ac920951c8d9a47ce8c071f3736ee8aad8d185a09be25234a0ffd11b9f9640015b82770ba3b3fad9aa511cc43501c1bb5a3a44f1fb7ccd5692 -OpenBLAS.v0.3.28+3.aarch64-linux-gnu-libgfortran5.tar.gz/md5/e3db2bf2f1f38aeee8530c78f3ec049a -OpenBLAS.v0.3.28+3.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/a0ccb92e818650ac3cbc292d5af1a000ee9b123953cc3eb16e2479e926af3f2be0ed9858e3c0c1075b1b9dd70ec1e51b9dce2c9d45b999d296aa050d257a3cb1 -OpenBLAS.v0.3.28+3.aarch64-linux-musl-libgfortran3.tar.gz/md5/5bb605738930037259e773ebdb4a7041 -OpenBLAS.v0.3.28+3.aarch64-linux-musl-libgfortran3.tar.gz/sha512/967e0f33be7b743d9617627a947a802286962a46c7c3b2418aaa1504cffc5f311b01e1702b35ded18ae3686b1914c6085213b03fa8a51e0a7ca16dc4cfee8504 -OpenBLAS.v0.3.28+3.aarch64-linux-musl-libgfortran4.tar.gz/md5/ce175e82b9c6597c546552e79a43f934 -OpenBLAS.v0.3.28+3.aarch64-linux-musl-libgfortran4.tar.gz/sha512/8ff5dff293d9786fc4f541b209b35afcbe325c13ddd0f9c8f9bfca8ba5c318c7890152260a5441b9e9088751ce03b1ff8f0f5d6fd4f142fae34bdb7390d1952c -OpenBLAS.v0.3.28+3.aarch64-linux-musl-libgfortran5.tar.gz/md5/cae6aabbdccf31fb78b234785b52d48a -OpenBLAS.v0.3.28+3.aarch64-linux-musl-libgfortran5.tar.gz/sha512/ac842023e5db243fcfada22adca051bd2ffa04fca496454539931eede159e5d0490d444c338684c2d178c3367b23b8f3d76c544e30f1897bbed181f56237619f -OpenBLAS.v0.3.28+3.aarch64-unknown-freebsd-libgfortran4.tar.gz/md5/875223f1a3867d1d77ca911da1f12e7d -OpenBLAS.v0.3.28+3.aarch64-unknown-freebsd-libgfortran4.tar.gz/sha512/a53eced30cd5d85bf13f17959f0d43127a1d967dfa3fc18fd931b8a0670d8f4fa7fa4e5360937ec301a195e8c4757d2454c8d1d189e6429b97fe3b322559c970 -OpenBLAS.v0.3.28+3.aarch64-unknown-freebsd-libgfortran5.tar.gz/md5/efc5b9b88bbb515b88b4cd84d280d6f2 -OpenBLAS.v0.3.28+3.aarch64-unknown-freebsd-libgfortran5.tar.gz/sha512/16581e2b61500c939f3be0d1e1aab3c103c2cdf56b9e5880368ff87bd2ecec89e6ee6ed00f2db90208ca26132c0b92f318084b0b2644ed93e72ca3c9706f951c -OpenBLAS.v0.3.28+3.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/5d1f45f53dd1730051095fb8e027b14f -OpenBLAS.v0.3.28+3.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/0b1f91e86b5078b7cd6b64bc429a0e63bb5adf28df1baa336e67819fbd2c09f59b643c39e580f63e3bbccdc631c5d5e14c7d8afa6af94250453ce5286958f90f -OpenBLAS.v0.3.28+3.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/8b3e3ea928975c575798d47466aafb82 -OpenBLAS.v0.3.28+3.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ebac0f7047dd8b97d85e4251953a23824701af02754afd6808f13eb276326b30eb292c85fa717fbd2f21b929e6a9816a012b8ea378a0fa27e671f81435f5d3b9 -OpenBLAS.v0.3.28+3.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/5aacfce96d5673b4d8341cb097d22c4a -OpenBLAS.v0.3.28+3.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/b84dc2b8cbe5453555182c3fcd8624d7a2b28fe3826d54fde3b77ad2c33e60309317d150f07554dd85e168b0ac1f91537a5c2c17fff9c02dd9216f01161e4965 -OpenBLAS.v0.3.28+3.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/dfeac22ee204868cf254dab5ae79382b -OpenBLAS.v0.3.28+3.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/710117eb7400a0aacf69d6053730eb3b3ff4767f8d38defb2aaad94aebf1646a794489e78a8f46b469901159cdca73dd2b9460fff11e95daa4a2642cab721a25 -OpenBLAS.v0.3.28+3.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/13ff2a40bc55839bdef76b796db1eb76 -OpenBLAS.v0.3.28+3.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/eb61fe6c0221e8f9d7a626b8d088ae1497155341dafb69835e7d53af76689ae212e1e4621e0729df5d896888c0b2d7354a24f7b57fe1d68f0b35c26bcf096699 -OpenBLAS.v0.3.28+3.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/aa7349724ba1d47256705777e755289a -OpenBLAS.v0.3.28+3.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/25ab56c44b7d0d5de17344f39071e6894e878e89b5e35412a3c9fe345abd2eef76d7816cabb6407c7c521c3bf67a4741b37ad7e580962ead9275273e431f1fb3 -OpenBLAS.v0.3.28+3.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/5d1f45f53dd1730051095fb8e027b14f -OpenBLAS.v0.3.28+3.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/0b1f91e86b5078b7cd6b64bc429a0e63bb5adf28df1baa336e67819fbd2c09f59b643c39e580f63e3bbccdc631c5d5e14c7d8afa6af94250453ce5286958f90f -OpenBLAS.v0.3.28+3.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/8b3e3ea928975c575798d47466aafb82 -OpenBLAS.v0.3.28+3.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ebac0f7047dd8b97d85e4251953a23824701af02754afd6808f13eb276326b30eb292c85fa717fbd2f21b929e6a9816a012b8ea378a0fa27e671f81435f5d3b9 -OpenBLAS.v0.3.28+3.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/5aacfce96d5673b4d8341cb097d22c4a -OpenBLAS.v0.3.28+3.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/b84dc2b8cbe5453555182c3fcd8624d7a2b28fe3826d54fde3b77ad2c33e60309317d150f07554dd85e168b0ac1f91537a5c2c17fff9c02dd9216f01161e4965 -OpenBLAS.v0.3.28+3.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/dfeac22ee204868cf254dab5ae79382b -OpenBLAS.v0.3.28+3.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/710117eb7400a0aacf69d6053730eb3b3ff4767f8d38defb2aaad94aebf1646a794489e78a8f46b469901159cdca73dd2b9460fff11e95daa4a2642cab721a25 -OpenBLAS.v0.3.28+3.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/13ff2a40bc55839bdef76b796db1eb76 -OpenBLAS.v0.3.28+3.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/eb61fe6c0221e8f9d7a626b8d088ae1497155341dafb69835e7d53af76689ae212e1e4621e0729df5d896888c0b2d7354a24f7b57fe1d68f0b35c26bcf096699 -OpenBLAS.v0.3.28+3.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/aa7349724ba1d47256705777e755289a -OpenBLAS.v0.3.28+3.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/25ab56c44b7d0d5de17344f39071e6894e878e89b5e35412a3c9fe345abd2eef76d7816cabb6407c7c521c3bf67a4741b37ad7e580962ead9275273e431f1fb3 -OpenBLAS.v0.3.28+3.i686-linux-gnu-libgfortran3.tar.gz/md5/53087cc770708c57d2654fd0095b64df -OpenBLAS.v0.3.28+3.i686-linux-gnu-libgfortran3.tar.gz/sha512/90961448ae40b0445bf881d0815aec54d2096ad235dc8e3db8d698a72961ef9a97e7fcd08f79c83cd1f7c5a341464f52a90351d927d5f1c3e9c8ee32b17970db -OpenBLAS.v0.3.28+3.i686-linux-gnu-libgfortran4.tar.gz/md5/ee910e19faa961bde11fdf90c211df9d -OpenBLAS.v0.3.28+3.i686-linux-gnu-libgfortran4.tar.gz/sha512/f5cfecfe965991cfd7843eff71efa71d6842058565bb63657e909b2942e58a8c7506aa66335308961e59f392da16e1177d79542ae509795566a14122f67a1782 -OpenBLAS.v0.3.28+3.i686-linux-gnu-libgfortran5.tar.gz/md5/fe52ba7ca8e16f37aa04b79248e0471d -OpenBLAS.v0.3.28+3.i686-linux-gnu-libgfortran5.tar.gz/sha512/79b5108886d60f12424709a841e359dc1cf23cef21bb0ee6d1a48043ac48a35dac1637e43c8ebf3f2e10dd34721993a7a12c5776f2975dd5bd7b6e29e1a9adc3 -OpenBLAS.v0.3.28+3.i686-linux-musl-libgfortran3.tar.gz/md5/88d8ff421d29456f1d7670ceaf8867ca -OpenBLAS.v0.3.28+3.i686-linux-musl-libgfortran3.tar.gz/sha512/91c1bd8142845d11fecba87a719315a14218e3863955ddd2ed82cecd4a2c177a48c660b6aac374ee9a11008245c0ced1bae70eaf5a1a6e3114db02e09a96396f -OpenBLAS.v0.3.28+3.i686-linux-musl-libgfortran4.tar.gz/md5/3035066a53032b551e49f56b323e941d -OpenBLAS.v0.3.28+3.i686-linux-musl-libgfortran4.tar.gz/sha512/f218e152a1c92bd374599814612add8010aedc78113cbe06465e8a1ee7f66892bb654cad687aa55555e74f3a65d74608692d41c9f0ce6c0bc63475ef62ab55b7 -OpenBLAS.v0.3.28+3.i686-linux-musl-libgfortran5.tar.gz/md5/f7cf36ac9a0cbb535952ec73f2e6c9ea -OpenBLAS.v0.3.28+3.i686-linux-musl-libgfortran5.tar.gz/sha512/00ab052d9fa4a72a640545782019f24ed6017b36aa89c5e659ce73b1e821817f560c09f71b26c027c0a05bd13567c71a6d7f5995d1c39ab233bec56cd3a7fd9e -OpenBLAS.v0.3.28+3.i686-w64-mingw32-libgfortran3.tar.gz/md5/b19d09297372e071805ba033afb55def -OpenBLAS.v0.3.28+3.i686-w64-mingw32-libgfortran3.tar.gz/sha512/eb1138578033167ececfe428db17fe28fad70631da3c25532edb4204fe733821156d6c619b6541fd47d53d335d6ab11b3d1ac1effb56031a2f782a5e8d863a89 -OpenBLAS.v0.3.28+3.i686-w64-mingw32-libgfortran4.tar.gz/md5/98ed2a8f2d3249438b913d5f35715a53 -OpenBLAS.v0.3.28+3.i686-w64-mingw32-libgfortran4.tar.gz/sha512/fbc32d81a4189ac170b18a029419bc98bb0655ee4d485f4bd165a394d223b80ba77f848d94a9ad96d926291de3db4a7602abd81c44fec55e4591dfe0aa91e29e -OpenBLAS.v0.3.28+3.i686-w64-mingw32-libgfortran5.tar.gz/md5/cb99d7d4944c5283a1a0142683e1d377 -OpenBLAS.v0.3.28+3.i686-w64-mingw32-libgfortran5.tar.gz/sha512/b77d3225e60f49506917bfff78c187df7157dbc834eccda2fa03d03eef8214b225682888a411a8b6e4b29a8d7e2b0ca625ea8c56b84ecc39e1f4f1012523c096 -OpenBLAS.v0.3.28+3.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/c6e5d4867a068e08b3f56f474e498b81 -OpenBLAS.v0.3.28+3.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/de6249439758a501bfd27d3ef04ec04cc06edf64de73f0709a6a40a2eaf40bd3d5d77dfd54b7b19e2f6bf6c104b4416d3e225faa0cff4cb631785c08d90b8614 -OpenBLAS.v0.3.28+3.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/32e70466cfa3cfec65ab4cad3abc5f03 -OpenBLAS.v0.3.28+3.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/2642385a5e9fc8e9c3839a5a44f9753b21b5078725f7d0c3e1ebe96b76129a3b8e2627d92629dee4f6fd7e8e51e86a7fbedc80cbe4d1a6812cea363559950da0 -OpenBLAS.v0.3.28+3.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/e2332831bd88d57132241697952819e7 -OpenBLAS.v0.3.28+3.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/ad03edf9ac56bf6311f0ca70a1bc359242accfe82cba9e42f39f6cb1c3006226179ff9be8218847889cae10fac13bc33f60837e1e3249e309172da7fbc25400f -OpenBLAS.v0.3.28+3.x86_64-apple-darwin-libgfortran3.tar.gz/md5/27c24775af446a44a72a28ffd197696d -OpenBLAS.v0.3.28+3.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/2af8caa33bee88efff84653f3932b04e8fd4aabb1bf16d49fa73657b0ec13c9457fde7ab3f953fc9b01da5c2841c3c9b588e3b0f559b89df0e6268468d1f7cc8 -OpenBLAS.v0.3.28+3.x86_64-apple-darwin-libgfortran4.tar.gz/md5/414e701d918d5fba08a12de6979db4b5 -OpenBLAS.v0.3.28+3.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/949886d388b80e19b944d102852f2bb58ffa03c42e624986dd9dc076797c996634d4a8fc0f04544451d6848c2079969816979e1f68a999b2747e9dd5472be7a6 -OpenBLAS.v0.3.28+3.x86_64-apple-darwin-libgfortran5.tar.gz/md5/29fcf62c0280cc10f91d22189a2e8de8 -OpenBLAS.v0.3.28+3.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/02e75d4ecf9cd922157a72c0ca2e713cf336b125df3982cd5f7cc4f2a04367ad4c2b1190ca2a0a9df8b639c7ebcfc9783066e99dd0b13acde7b02038391e8567 -OpenBLAS.v0.3.28+3.x86_64-linux-gnu-libgfortran3.tar.gz/md5/147d5e8eb2ec78fc8a31bdb091fab001 -OpenBLAS.v0.3.28+3.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/2319eda568800c0b1f2d96a8a36c59b1bbd792c06de1d740aea3f1e49798242426ea8d10c100c42c3c281702e2b4f5b673b6ab5252b276d48542e875bcaa3094 -OpenBLAS.v0.3.28+3.x86_64-linux-gnu-libgfortran4.tar.gz/md5/448857d9c4b2e95afc12a14c75b24055 -OpenBLAS.v0.3.28+3.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/3e7c8cd55e0b15a30992b1e0b48a6e2ae36fd9babf689fa5595c7de94aec401de1d7821d45a22bf14cd5c45c708bc8fa3511d34d732dadd4daaca3f49e200bdb -OpenBLAS.v0.3.28+3.x86_64-linux-gnu-libgfortran5.tar.gz/md5/3aaf417685b44e0e505208f7b31b981a -OpenBLAS.v0.3.28+3.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/f7b1d123e48ede93fe624a79d9535a8915bfa3441d7a6f9c6643467027414c9f2538e299858ea98bbb49d4e6d385a6a491063cb1878ac3b0b3d6a8f7ff0a48df -OpenBLAS.v0.3.28+3.x86_64-linux-musl-libgfortran3.tar.gz/md5/5723136deaaf4b2e5960fb0774943288 -OpenBLAS.v0.3.28+3.x86_64-linux-musl-libgfortran3.tar.gz/sha512/127ea8b2b0d8d4586a23a2b8ecbf148d512efe68626e89b0688c3c9e29ed9420b45ae86755c1467313c565f9f3835762051d7086a815b813dbe6e9eb05fb4be1 -OpenBLAS.v0.3.28+3.x86_64-linux-musl-libgfortran4.tar.gz/md5/80b1b9cf5346916edda653174a987aa2 -OpenBLAS.v0.3.28+3.x86_64-linux-musl-libgfortran4.tar.gz/sha512/77e1387ec969bbed4945d2a598a1cd04d258265c4b2d5c43af92118eb32e0c69e40619a20ea1835f277febcfea068b241343d44932afef832bdcfd2e9f618f0a -OpenBLAS.v0.3.28+3.x86_64-linux-musl-libgfortran5.tar.gz/md5/44dcedf01c938d1a1c67dd3bc90ab61d -OpenBLAS.v0.3.28+3.x86_64-linux-musl-libgfortran5.tar.gz/sha512/e490d49b8d41d73ab3e71aca8c691ca58704f0fc6930cbfcc203f97b8db8d83144bad597a2c53ff0c0c4f7c40316d975a1b589a3603873d508f6beeb75970c5b -OpenBLAS.v0.3.28+3.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/0e8a7e88b54cb836292c289d1c456fa9 -OpenBLAS.v0.3.28+3.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/0e9b3af6839b9c41c950bb4d8b739f0243a890af7092ef9f3a00e4931f2acc3820afb78e40c7bfef716dcd3230c1d0acc7b0b37f30eb47441b476bd7540745e6 -OpenBLAS.v0.3.28+3.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/5fc47ad55780c99ef9cab7ef1b26d9c0 -OpenBLAS.v0.3.28+3.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/c531201e4abddd652efeb5801658f5c1e4891578f181e99d6e41fc0d3bc6347b82e5e928ff8a717ee1e75bb0a6a765260bf7c99fce44aa24c21f1c5a5e3c1e3b -OpenBLAS.v0.3.28+3.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/dc127f3ab984b5d47b325d5701ab73cd -OpenBLAS.v0.3.28+3.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/50850911703320894a2e1e996c5de4613b5f9e3012f5cbf591f3677799599c45d9cc4c42cf310bdc6ba91ef550e52f6424bbbabdf47f96748d4669d94e6b46a4 -OpenBLAS.v0.3.28+3.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/937847e2ad00539f3422d1ecb9d26d55 -OpenBLAS.v0.3.28+3.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/751d889661ddd46cd5718b49e34f826a4fb34b1b992251a5a975bc0af15b74a75d8a56f403e8fae570223477b2b8927d9cb36764e4b9e466045d5f317b8e7196 -OpenBLAS.v0.3.28+3.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/180c54c50362d05696589b270693ee8f -OpenBLAS.v0.3.28+3.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/2e3b76be5b7c4a7dc45f07e17493abd7ef9185e92429d8fa4d38766e0da96dd0777b619a9e420d2e1142bdab2ae1f755f9bc9ad97ee9a7927741778f89b9135f -OpenBLAS.v0.3.28+3.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/2f0fac7c96af66ea63fce26e409f4db6 -OpenBLAS.v0.3.28+3.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/141522971447c38b4908342f3ad09ffb18142d2e79b44f66fd80047b44c09216c9b94c39f776e3093f9ceb6bc4d6270cbbfb4209b2fc0debfe93e7145cb4dbff -openblas-5ef8b1964658f9cb6a6324a06f6a1a022609b0c5.tar.gz/md5/f7a1fe86cefbf7d4f2608843c7833ca7 -openblas-5ef8b1964658f9cb6a6324a06f6a1a022609b0c5.tar.gz/sha512/5f6020e958967a12a3c5b18bde13331f9c0602bd073563f35cd7cec848c92b45f30ca362819b12cd16989c0e4641ee3e63db8322d1092f61b31ba2e4068dd7a7 +OpenBLAS.v0.3.29+0.aarch64-apple-darwin-libgfortran5.tar.gz/md5/227fc95ef10e30698aade797ebd8b685 +OpenBLAS.v0.3.29+0.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/49a932f0c1c2d1087d20a3de2940733ed6a944284e1cf2a384a7401c5ca6bd90a35e9679b4f19bac176923aa170427e7514a47fc16261413ee03a59bbb301bd0 +OpenBLAS.v0.3.29+0.aarch64-linux-gnu-libgfortran3.tar.gz/md5/77acdfde5dc6f05629f3fb68a95b78f8 +OpenBLAS.v0.3.29+0.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/f28187213eac2d481bc12263fe13fcb35f4771084bacaa42b0b149ac15cf89d033910519ecc5cada77915a48c95a2de3ea4a476c0c6bc3f154e7f2ceb4bf3ffd +OpenBLAS.v0.3.29+0.aarch64-linux-gnu-libgfortran4.tar.gz/md5/4fb2bd80d3e4ad8ce04fa33c9a2aaa19 +OpenBLAS.v0.3.29+0.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/8cc2aee3b351cc5c78e494efededdf98f65ce8942453bb3a55c90e0822ddcc07bc7716d0746bbc16701eca458b7a7aa933e9363f71bd56788c9fab36bd9bcf6d +OpenBLAS.v0.3.29+0.aarch64-linux-gnu-libgfortran5.tar.gz/md5/3a3ef97dc80dec3d0debade503ca2232 +OpenBLAS.v0.3.29+0.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/53d707f9bf57c1a19279f0146e767d779280f922ef621b5f372cedc018efb2798adabbd762324819f342d0fd98ec17c68badc50da7b6e9aa3e57c3a3c045dab2 +OpenBLAS.v0.3.29+0.aarch64-linux-musl-libgfortran3.tar.gz/md5/463cb6b46091f4b4b4f2535b9f38f11d +OpenBLAS.v0.3.29+0.aarch64-linux-musl-libgfortran3.tar.gz/sha512/5a5a7d5a7ca5e619d5af9bcbab7cfffcb4b7954005cb4a2d03f4cd0ef29c95707e830ad0b0303d694cace557cb1e9973c0244ae1f635249a313fb9f9cdfaacd9 +OpenBLAS.v0.3.29+0.aarch64-linux-musl-libgfortran4.tar.gz/md5/699ca0247ec7cccec0d9d2801b5a35a7 +OpenBLAS.v0.3.29+0.aarch64-linux-musl-libgfortran4.tar.gz/sha512/3bb2926d2d2a43c280bb947063dd74b65194118edbd99df820bef56a546648ed903245e0947ebc31765ff43784b11349bf86cd592c78d143c0627d692162b344 +OpenBLAS.v0.3.29+0.aarch64-linux-musl-libgfortran5.tar.gz/md5/2ab069e5abd5014495b849bfbaabbd3a +OpenBLAS.v0.3.29+0.aarch64-linux-musl-libgfortran5.tar.gz/sha512/fd10e4ce326c524d97e69e50342ab63b8298c796faab8f4512772fbb9c4ae1ddc85d54643c868f3b2dc8084af974430e1f8751576bedfdc88af2ba0d2affba1a +OpenBLAS.v0.3.29+0.aarch64-unknown-freebsd-libgfortran4.tar.gz/md5/ce5d04e041e9447529ad8e043e45895c +OpenBLAS.v0.3.29+0.aarch64-unknown-freebsd-libgfortran4.tar.gz/sha512/eaf521d3957713e9d22b2c0b991f5eb846096891dc15bc42ad0817c32e6a1343617d28afe739dce0e39c185d022d3cdd44db2610635691990003b1b0a29f4657 +OpenBLAS.v0.3.29+0.aarch64-unknown-freebsd-libgfortran5.tar.gz/md5/00b3a4433f93a56fa8b0f17acc254865 +OpenBLAS.v0.3.29+0.aarch64-unknown-freebsd-libgfortran5.tar.gz/sha512/a9845380778ec15642d74a46dfa65f8a325929f8ec8d61915941f6e228bb1ed29310f86f20ec559fdc2d5dac98a780f71a1b3116676a34e18ee7c0cb86cb7124 +OpenBLAS.v0.3.29+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/1be6fa7ef684733faab744fdec6c8dbd +OpenBLAS.v0.3.29+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/7c7803a0484b8c8e343ff5049e52fe81b76e43f0aaca7a5ad0134079147d2311cb5b159738486dcdd7ec69eb42cb0eea738741401179499a53fead2fbd8dba3b +OpenBLAS.v0.3.29+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/451dad687dd26a299e4a44db37a8db2a +OpenBLAS.v0.3.29+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ea73ee91896203566dd7510303c73d77189afec913ac1de3b7c7935dc2c460f87c83a8ddd272d9542b619e419b9392479f02540ef1c8d3daa528bf05aaf5c3f1 +OpenBLAS.v0.3.29+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/07ca32f715981570f2e1a5ac6721e569 +OpenBLAS.v0.3.29+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/c6ece0dac375fd66a303ca6f503e46f78472a59dc13381e8462e3e9c29e133cbe87ee77f6144a80924ae286162620c4395f5217e4f9ba379a471409085950427 +OpenBLAS.v0.3.29+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/49ac07fcdf0d7ce221051d089b408e05 +OpenBLAS.v0.3.29+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/6c9c379473f1bb5f202ca183c6ef4d43b442c867e67712e6ec2936790c282143c1edae0a1385e366f729c952e02fca13604f6b51d778dabb28ca7be0f359281e +OpenBLAS.v0.3.29+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/87e3dea9e115fbc9a0c7f64020c41f74 +OpenBLAS.v0.3.29+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/63a37a9cc882562978460e1e0f603177921a64ece7d4050b0b7a584e05d80f58314e7f8e988ea5446945d7009620c4f746ce547fe7dcb77a0707d54fd830983e +OpenBLAS.v0.3.29+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/8c85e7ce9bd702438c548bdae54f5c32 +OpenBLAS.v0.3.29+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/3dbaa326944d79688fa167c968a7e2660bf3b94c2e052755cc8b1ede853c02364edb7fa974880c37c60ee6e6f84c75848eb4d999c5c1e8881441191dbab056e2 +OpenBLAS.v0.3.29+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/1be6fa7ef684733faab744fdec6c8dbd +OpenBLAS.v0.3.29+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/7c7803a0484b8c8e343ff5049e52fe81b76e43f0aaca7a5ad0134079147d2311cb5b159738486dcdd7ec69eb42cb0eea738741401179499a53fead2fbd8dba3b +OpenBLAS.v0.3.29+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/451dad687dd26a299e4a44db37a8db2a +OpenBLAS.v0.3.29+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ea73ee91896203566dd7510303c73d77189afec913ac1de3b7c7935dc2c460f87c83a8ddd272d9542b619e419b9392479f02540ef1c8d3daa528bf05aaf5c3f1 +OpenBLAS.v0.3.29+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/07ca32f715981570f2e1a5ac6721e569 +OpenBLAS.v0.3.29+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/c6ece0dac375fd66a303ca6f503e46f78472a59dc13381e8462e3e9c29e133cbe87ee77f6144a80924ae286162620c4395f5217e4f9ba379a471409085950427 +OpenBLAS.v0.3.29+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/49ac07fcdf0d7ce221051d089b408e05 +OpenBLAS.v0.3.29+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/6c9c379473f1bb5f202ca183c6ef4d43b442c867e67712e6ec2936790c282143c1edae0a1385e366f729c952e02fca13604f6b51d778dabb28ca7be0f359281e +OpenBLAS.v0.3.29+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/87e3dea9e115fbc9a0c7f64020c41f74 +OpenBLAS.v0.3.29+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/63a37a9cc882562978460e1e0f603177921a64ece7d4050b0b7a584e05d80f58314e7f8e988ea5446945d7009620c4f746ce547fe7dcb77a0707d54fd830983e +OpenBLAS.v0.3.29+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/8c85e7ce9bd702438c548bdae54f5c32 +OpenBLAS.v0.3.29+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/3dbaa326944d79688fa167c968a7e2660bf3b94c2e052755cc8b1ede853c02364edb7fa974880c37c60ee6e6f84c75848eb4d999c5c1e8881441191dbab056e2 +OpenBLAS.v0.3.29+0.i686-linux-gnu-libgfortran3.tar.gz/md5/86834236dee3db3affb38b8cdcf59681 +OpenBLAS.v0.3.29+0.i686-linux-gnu-libgfortran3.tar.gz/sha512/6731b4ea22a0f3d25f9d041e2baa6d66f1027dce49931a334a33711fc4c6de5da368274c9328618ed78158855c5d38524b917447d1aafb5c551934cf982505d2 +OpenBLAS.v0.3.29+0.i686-linux-gnu-libgfortran4.tar.gz/md5/c63c2fb1bda01456d99590e9aec3b45f +OpenBLAS.v0.3.29+0.i686-linux-gnu-libgfortran4.tar.gz/sha512/437c260499f4a28db9efb4bbdff31c0f675f3ccef1bd48fd2dfbb8c8897fc75608bd7247293bd3eae129b133cb05c3c8150dd19c243faa09b6506688f57c633a +OpenBLAS.v0.3.29+0.i686-linux-gnu-libgfortran5.tar.gz/md5/376567d56bf4314f8a4adcfc4d1baa66 +OpenBLAS.v0.3.29+0.i686-linux-gnu-libgfortran5.tar.gz/sha512/c4952874b19af4fd0d5541999d07094f7e7e983124964405a4756b9adf619172b7128e11557e64a80bc4eadaf76c783609a75f25ccfc44fc4f181886a0c8ca18 +OpenBLAS.v0.3.29+0.i686-linux-musl-libgfortran3.tar.gz/md5/8f7abbc6d5cefdbefb2b9499ec8874c9 +OpenBLAS.v0.3.29+0.i686-linux-musl-libgfortran3.tar.gz/sha512/b8c39674df9400efecbe4ac740f0c3ef11a04dd852f31774d63db3ca6583a21c8e0a0b80aa4e7b82be7a8fa3de38892d4fbca34244acef7fb49e8ffc0e1eed09 +OpenBLAS.v0.3.29+0.i686-linux-musl-libgfortran4.tar.gz/md5/6b0f0544fe45de9d2dea946c7f55cc40 +OpenBLAS.v0.3.29+0.i686-linux-musl-libgfortran4.tar.gz/sha512/8c21df39a8ee99614ef0880706c1497d032f68dfc332cc5ee111f69bfc818db4896115a964f16115ac49b01b31713037c905792d9586dd05471efdb21dd0be88 +OpenBLAS.v0.3.29+0.i686-linux-musl-libgfortran5.tar.gz/md5/aa343048c35c5227a4bcc37f25ddfacb +OpenBLAS.v0.3.29+0.i686-linux-musl-libgfortran5.tar.gz/sha512/af6c9d15d9d5a4901d228522d2e20da5276f1bf35d7f34648697ba7a39153a9152dc17f5f0d360593e733ef3e3317df29581cb86fdd9fe8d6e6093592a6240bb +OpenBLAS.v0.3.29+0.i686-w64-mingw32-libgfortran3.tar.gz/md5/8595dda5ee1f15b2070d8ac20077f389 +OpenBLAS.v0.3.29+0.i686-w64-mingw32-libgfortran3.tar.gz/sha512/df7d7ad68b47f8865d01f6edd6ba44587c6563ebc4a1900f92210b5117fc7c581e6145f95e10fe7a3db48eda9805330073c8cbeec7eb8a19978ec33f2528cef8 +OpenBLAS.v0.3.29+0.i686-w64-mingw32-libgfortran4.tar.gz/md5/4e67905ab599f24327e9726f70d261cf +OpenBLAS.v0.3.29+0.i686-w64-mingw32-libgfortran4.tar.gz/sha512/13ba78e98d7c2cda62a6ca9226365e90fa8a5404e4006ae5e49030b314b762a37d78977f14c72448c844e68a6b83ecd679c60362fde023c9052b9b8597d7775c +OpenBLAS.v0.3.29+0.i686-w64-mingw32-libgfortran5.tar.gz/md5/e78c5005d9ee57ab464fca86c6d6fff1 +OpenBLAS.v0.3.29+0.i686-w64-mingw32-libgfortran5.tar.gz/sha512/8ceb9527461136cd4f4d02f10c241f5e7070991f73c974389acedb1d9d7be4bade592bc021ba1001c5ac148ea580cf8355fb89c88438820bfa665bf3e72392fa +OpenBLAS.v0.3.29+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/421d93da4cfab0df79569e09dff1015b +OpenBLAS.v0.3.29+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/351174d948626ad36daf40c45672cd1ac40bbe4af25c28332fbea62a7ba89188a7d33836d327d31ce99b9a9334c6053366d33b58f588355c2818e332e46b34d0 +OpenBLAS.v0.3.29+0.riscv64-linux-gnu-libgfortran5.tar.gz/md5/34cc0b3260d9471bc8fb32005e3c5043 +OpenBLAS.v0.3.29+0.riscv64-linux-gnu-libgfortran5.tar.gz/sha512/5eec279c5eead55d099d8db4a75dd4a3f2bcbc8bb22b33884a89d678e4eebf87c6dece1aa4c24374d0162b35f376648a473c2d6d7866583e61016e37f4262820 +OpenBLAS.v0.3.29+0.x86_64-apple-darwin-libgfortran3.tar.gz/md5/f921a0ad6ebf91f444cb8d927886e573 +OpenBLAS.v0.3.29+0.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/5cc98edf9fa8ba8981ce78b2595fd27645c783561ff19d0fd25ecc927f63492437a4b9b80d5caf51ad619b7ca5d24cb43e153156921f9f03c64741014b686196 +OpenBLAS.v0.3.29+0.x86_64-apple-darwin-libgfortran4.tar.gz/md5/0126b52c134954e63ab8f9197afebd7a +OpenBLAS.v0.3.29+0.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/6d1e37009e6831a26f25bfd3e95dbcc841ee50a3f84dc4355d7fd528cd74a400138955558306345e986a732d0d1ef9294c4f5be457d05119a8e1e5851cc8ca20 +OpenBLAS.v0.3.29+0.x86_64-apple-darwin-libgfortran5.tar.gz/md5/e8c7bd786672a9caf989dbe4fcef896a +OpenBLAS.v0.3.29+0.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/2e708fddfa8e5821d2e44bbc00a86df83b09cdfc0054d7c2bbb2a8de52ed80c95973e6602048335a60b54be1baeb617121b605644daf50579b2044d0c5766063 +OpenBLAS.v0.3.29+0.x86_64-linux-gnu-libgfortran3.tar.gz/md5/b1efd957a2a63f814168bd318381812e +OpenBLAS.v0.3.29+0.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/097a750b7f381089588498e52a2b07a67202bfd4bc2e38f5abbbeb372129e392fcd53beade2fa7cb60ef0038f2baf61d57fab40b5585806d3ddb1fcdad73bbe3 +OpenBLAS.v0.3.29+0.x86_64-linux-gnu-libgfortran4.tar.gz/md5/c3560828f503962c6ae94135c4f00ac5 +OpenBLAS.v0.3.29+0.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/1ad514172e51a5d3eb6fea03182e3eb9c6db99d9d11c430e3d8542a9ce0f5d6967e623b9c0951535b683210ce0b02460358c67520b06363594f6063f8f012396 +OpenBLAS.v0.3.29+0.x86_64-linux-gnu-libgfortran5.tar.gz/md5/07a9c3050824bbc6a96efdb333fff0ea +OpenBLAS.v0.3.29+0.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/b737ab1fc8c5ffd1494804c59f8fd3e5d3d8a063a89fbbc29cbd75d43af233ddf77f63d0e514059164517f408ea340ffe95c020a7c696af8c52be3a7259922ab +OpenBLAS.v0.3.29+0.x86_64-linux-musl-libgfortran3.tar.gz/md5/9a4a828a1b58737c79eb170c94021c52 +OpenBLAS.v0.3.29+0.x86_64-linux-musl-libgfortran3.tar.gz/sha512/785443a38cda87a63ee4268cdaa51bbc2c4662de27e0695cd7e21ffe55c3bddb1fa1a399edec39c3466f2ea0bd5ce727daca2eb381213059419c2e8371b5a733 +OpenBLAS.v0.3.29+0.x86_64-linux-musl-libgfortran4.tar.gz/md5/cd4afdd6f6ba06c7541e7124316802b3 +OpenBLAS.v0.3.29+0.x86_64-linux-musl-libgfortran4.tar.gz/sha512/55796fdb52e1ac92750dfc2233d3feb37b53920b12024be605bf6c7322153c4dbeb650f16d6def4f0fac685733a04a1c4cacb1fc4e562a27a00b4f44484a4715 +OpenBLAS.v0.3.29+0.x86_64-linux-musl-libgfortran5.tar.gz/md5/8cd55ac7a7f0a7bda80b44171793718e +OpenBLAS.v0.3.29+0.x86_64-linux-musl-libgfortran5.tar.gz/sha512/728991a4c39d691abebac3ebbb2dbe093f3a4acd2d3aefb5c7c08bccf0dc1fd5aaa24de6367961d278d448b76a4ddacab36b7be15128f7ccec5049eab83828da +OpenBLAS.v0.3.29+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/c2dda93a61e02812831b6a6e33f7d2ca +OpenBLAS.v0.3.29+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/bd62e44f266b834c6dfab068841506a83eaf510eefbcf8896dfca36671321430293dc251885af108d94affc5b193919e0e29c965fef3ce6d994df37324aef013 +OpenBLAS.v0.3.29+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/8cbd64d2ce4e3944e702696839a4ad3a +OpenBLAS.v0.3.29+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/3621dfa5cf8bca62bb8f2a049acdc0ed4e02cb2b5585758e6e1173e61b3a5f0e1655a10f2feb2f0e70a098b00181d0b24dcd61e1205324d436b712f58e58df5d +OpenBLAS.v0.3.29+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/476f1ebfb93baad6fac778fa00c4f99e +OpenBLAS.v0.3.29+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/06aa18da572b0904e5d8ec0823626d0af02a29224aba98efd43d8fbf4636d2625ece9f88f9a86d2e493f016c106f2ae71422191afc16dda2b26bbc81eb09d901 +OpenBLAS.v0.3.29+0.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/8c55d04d9def74f6bc2cc0d03b764975 +OpenBLAS.v0.3.29+0.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/d6196a339a263d80c05b94596ec5acfeff6e3ce93fafee348a864f760aa1239aa59ee294cab29fd730dcf7974ac6dcb230433184be093612bad3bc3edc067649 +OpenBLAS.v0.3.29+0.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/8427f098a44457ba65b21a16439ee6c0 +OpenBLAS.v0.3.29+0.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/4855321b2a16d55e1c6e830e33d0a199286002798c0f33c7f594a55626b5a502df94c172de4fd0a38ab6ba92f384abbbc3ef06123c3115a3f290f50a9d43ae9d +OpenBLAS.v0.3.29+0.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/9d1636bb7500d9ba15ed703231f8def2 +OpenBLAS.v0.3.29+0.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/0b3530fd95e01d58b85157d7bb75e44ee7b2f0c5a912920ff0763f404e1ab28d16a624463f3f20241c7baea57e00fca3f896d6e0befb6a1c9e5ece4264b87e35 +openblas-8795fc7985635de1ecf674b87e2008a15097ffab.tar.gz/md5/095d293409140dd8eee500eb92372eb7 +openblas-8795fc7985635de1ecf674b87e2008a15097ffab.tar.gz/sha512/7b10d4c2bef68159e0a88fb6d4fd0ecca17b4c6394479e8f838f5078d9d5acef24c6bd44777d43c03859c952d4612d76b57aa0bff367b197920ea16eb3839144 diff --git a/deps/openblas.mk b/deps/openblas.mk index 8cea044ca348f..e5a988ba84df2 100644 --- a/deps/openblas.mk +++ b/deps/openblas.mk @@ -90,12 +90,7 @@ $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-winexit.patch-applied: $(BUILDDIR)/$(OP patch -p1 -f < $(SRCDIR)/patches/openblas-winexit.patch echo 1 > $@ -$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-memory-buffer-multi-threading.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-winexit.patch-applied - cd $(BUILDDIR)/$(OPENBLAS_SRC_DIR) && \ - patch -p1 -f < $(SRCDIR)/patches/openblas-memory-buffer-multi-threading.patch - echo 1 > $@ - -$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-ofast-power.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-memory-buffer-multi-threading.patch-applied +$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-ofast-power.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-winexit.patch-applied cd $(BUILDDIR)/$(OPENBLAS_SRC_DIR) && \ patch -p1 -f < $(SRCDIR)/patches/openblas-ofast-power.patch echo 1 > $@ diff --git a/deps/openblas.version b/deps/openblas.version index 09dcdc45af1ef..f9729639c67ab 100644 --- a/deps/openblas.version +++ b/deps/openblas.version @@ -3,9 +3,9 @@ OPENBLAS_JLL_NAME := OpenBLAS ## source build -OPENBLAS_VER := 0.3.28 -OPENBLAS_BRANCH=v0.3.28 -OPENBLAS_SHA1=5ef8b1964658f9cb6a6324a06f6a1a022609b0c5 +OPENBLAS_VER := 0.3.29 +OPENBLAS_BRANCH=v0.3.29 +OPENBLAS_SHA1=8795fc7985635de1ecf674b87e2008a15097ffab # LAPACK, source-only LAPACK_VER := 3.9.0 diff --git a/deps/patches/openblas-memory-buffer-multi-threading.patch b/deps/patches/openblas-memory-buffer-multi-threading.patch deleted file mode 100644 index 9693b5cf61597..0000000000000 --- a/deps/patches/openblas-memory-buffer-multi-threading.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 23b5d66a86417a071bba9a96a0573192237981b6 Mon Sep 17 00:00:00 2001 -From: Martin Kroeker -Date: Wed, 14 Aug 2024 10:35:44 +0200 -Subject: [PATCH 1/2] Ensure a memory buffer has been allocated for each thread - before invoking it - ---- - driver/others/blas_server.c | 2 ++ - 1 file changed, 2 insertions(+) - -From d24b3cf39392a99e81ed47a5f093fbd074d4b39b Mon Sep 17 00:00:00 2001 -From: Martin Kroeker -Date: Thu, 15 Aug 2024 15:32:58 +0200 -Subject: [PATCH 2/2] properly fix buffer allocation and assignment - ---- - driver/others/blas_server.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) -diff --git a/driver/others/blas_server.c b/driver/others/blas_server.c -index 765511d8c7..b9a7674c17 100644 ---- a/driver/others/blas_server.c -+++ b/driver/others/blas_server.c -@@ -1076,6 +1076,8 @@ fprintf(STDERR, "Server[%2ld] Calculation started. Mode = 0x%03x M = %3ld N=%3l - main_status[cpu] = MAIN_RUNNING1; - #endif - -+if (buffer == NULL) blas_thread_buffer[cpu] = blas_memory_alloc(2); -+ - //For target LOONGSON3R5, applying an offset to the buffer is essential - //for minimizing cache conflicts and optimizing performance. - #if defined(ARCH_LOONGARCH64) && !defined(NO_AFFINITY) - -diff --git a/driver/others/blas_server.c b/driver/others/blas_server.c -index b9a7674c17..29f8a5e646 100644 ---- a/driver/others/blas_server.c -+++ b/driver/others/blas_server.c -@@ -1076,7 +1076,11 @@ fprintf(STDERR, "Server[%2ld] Calculation started. Mode = 0x%03x M = %3ld N=%3l - main_status[cpu] = MAIN_RUNNING1; - #endif - --if (buffer == NULL) blas_thread_buffer[cpu] = blas_memory_alloc(2); -+if (buffer == NULL) { -+ blas_thread_buffer[cpu] = blas_memory_alloc(2); -+ buffer = blas_thread_buffer[cpu]; -+} -+ - - //For target LOONGSON3R5, applying an offset to the buffer is essential - //for minimizing cache conflicts and optimizing performance. diff --git a/stdlib/OpenBLAS_jll/Project.toml b/stdlib/OpenBLAS_jll/Project.toml index 01e3af1d9467c..07a81d3c1d547 100644 --- a/stdlib/OpenBLAS_jll/Project.toml +++ b/stdlib/OpenBLAS_jll/Project.toml @@ -1,6 +1,6 @@ name = "OpenBLAS_jll" uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.28+3" +version = "0.3.29+0" [deps] # See note in `src/OpenBLAS_jll.jl` about this dependency. From de1dba2c96649d0dd30403cee1ae456ae19a2ac8 Mon Sep 17 00:00:00 2001 From: Jakob Nybo Nissen Date: Mon, 13 Jan 2025 04:56:14 +0100 Subject: [PATCH 170/198] Check channel state on iterate (#52981) --- base/channels.jl | 9 +++++++++ test/channels.jl | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/base/channels.jl b/base/channels.jl index 8882171095e7a..527c22b3d45fd 100644 --- a/base/channels.jl +++ b/base/channels.jl @@ -716,6 +716,15 @@ function iterate(c::Channel, state=nothing) end end else + # If the channel was closed with an exception, it needs to be thrown + if (@atomic :acquire c.state) === :closed + e = c.excp + if isa(e, InvalidStateException) && e.state === :closed + nothing + else + throw(e) + end + end return nothing end end diff --git a/test/channels.jl b/test/channels.jl index f3e5381a62e94..4acf6c94da1b6 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -499,12 +499,35 @@ end end end +struct CustomError <: Exception end + @testset "check_channel_state" begin c = Channel(1) close(c) @test !isopen(c) c.excp === nothing # to trigger the branch @test_throws InvalidStateException Base.check_channel_state(c) + + # Issue 52974 - closed channels with exceptions + # must be thrown on iteration, if channel is empty + c = Channel(2) + put!(c, 5) + close(c, CustomError()) + @test take!(c) == 5 + @test_throws CustomError iterate(c) + + c = Channel(Inf) + put!(c, 1) + close(c) + @test take!(c) == 1 + @test_throws InvalidStateException take!(c) + @test_throws InvalidStateException put!(c, 5) + + c = Channel(3) + put!(c, 1) + close(c) + @test first(iterate(c)) == 1 + @test isnothing(iterate(c)) end # PR #36641 From cea96c9046c6f8efaa01ae10880d9a67f4527073 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:53:43 -0500 Subject: [PATCH 171/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?SparseArrays=20stdlib=20from=204fd3aad=20to=205f52721=20(#57027?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: SparseArrays URL: https://github.com/JuliaSparse/SparseArrays.jl.git Stdlib branch: main Julia branch: master Old commit: 4fd3aad New commit: 5f52721 Julia version: 1.12.0-DEV SparseArrays version: 1.12.0 Bump invoked by: @ViralBShah Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaSparse/SparseArrays.jl/compare/4fd3aad5735e3b80eefe7b068f3407d7dd0c0924...5f527215c188ee99247cdce31ba8ce9e11f35055 ``` $ git log --oneline 4fd3aad..5f52721 5f52721 Update wrappers for SuiteSparse 7.8.3 (#593) c575811 Mention vectors in more docstrings (#591) ``` Co-authored-by: ViralBShah <744411+ViralBShah@users.noreply.github.com> --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/SparseArrays.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/md5 delete mode 100644 deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/sha512 create mode 100644 deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 create mode 100644 deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 diff --git a/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/md5 b/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/md5 deleted file mode 100644 index 4c75f5c1f619a..0000000000000 --- a/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -308e26cc6171656caaa7f6ba07e83d1c diff --git a/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/sha512 b/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/sha512 deleted file mode 100644 index ad389d6e42048..0000000000000 --- a/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -62b94ad0dca0d62e5753f50aef806ebdb5c8b56b241a285957190845be21fc6b8c8f93089b6f627795f6d7f2b1b01118bcff87c21102a3f3bae6d4c408362681 diff --git a/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 b/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 new file mode 100644 index 0000000000000..946bec189c1bd --- /dev/null +++ b/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 @@ -0,0 +1 @@ +4b07db52a5a6d3cc6eeab380bd783a1e diff --git a/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 b/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 new file mode 100644 index 0000000000000..846867193d932 --- /dev/null +++ b/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 @@ -0,0 +1 @@ +4c631f1046ad0a6b972a4dce285c2092372ecbed269c83524c10b4be5124035670d703af53e1f8058d23230be20c06aa554097cc9bc7a12b3de3c039d3c545e8 diff --git a/stdlib/SparseArrays.version b/stdlib/SparseArrays.version index 0ff7a761bffa3..3f6ab5b878069 100644 --- a/stdlib/SparseArrays.version +++ b/stdlib/SparseArrays.version @@ -1,4 +1,4 @@ SPARSEARRAYS_BRANCH = main -SPARSEARRAYS_SHA1 = 4fd3aad5735e3b80eefe7b068f3407d7dd0c0924 +SPARSEARRAYS_SHA1 = 5f527215c188ee99247cdce31ba8ce9e11f35055 SPARSEARRAYS_GIT_URL := https://github.com/JuliaSparse/SparseArrays.jl.git SPARSEARRAYS_TAR_URL = https://api.github.com/repos/JuliaSparse/SparseArrays.jl/tarball/$1 From 3b629f1b95db6280cb67783ef6427cd6e71c6618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Mon, 13 Jan 2025 06:37:04 +0000 Subject: [PATCH 172/198] Update builds of MPFR_jll and OpenSSL_jll (#57026) --- deps/checksums/mpfr | 70 +++++++++++++++++---------------- deps/checksums/openssl | 70 +++++++++++++++++---------------- stdlib/MPFR_jll/Project.toml | 2 +- stdlib/OpenSSL_jll/Project.toml | 2 +- 4 files changed, 74 insertions(+), 70 deletions(-) diff --git a/deps/checksums/mpfr b/deps/checksums/mpfr index 4d029986663c9..7b3b57978bd01 100644 --- a/deps/checksums/mpfr +++ b/deps/checksums/mpfr @@ -1,36 +1,38 @@ -MPFR.v4.2.1+1.aarch64-apple-darwin.tar.gz/md5/816f9ff59070f21f1df2f310e2606c06 -MPFR.v4.2.1+1.aarch64-apple-darwin.tar.gz/sha512/dad9adba7a8867d1ce26d77efb5c33b602b920a2cdbec84ea58a054cfab3ab7df54d2bda101de72b71604e7844993f1e216b002ba092e69277d0764040216c81 -MPFR.v4.2.1+1.aarch64-linux-gnu.tar.gz/md5/c1e3c9619af6454d8adae9bcbd911dba -MPFR.v4.2.1+1.aarch64-linux-gnu.tar.gz/sha512/5d916492aa73d11e022a7ca3f31940ceb8f8667bdf878ba29d6256736a380a2f6a11ac90cd8de3f1d3454a79165db240a1b971b9794fd21692ed64502ec34b9a -MPFR.v4.2.1+1.aarch64-linux-musl.tar.gz/md5/8ada267e2d23eb0c65ab2d2df02362d5 -MPFR.v4.2.1+1.aarch64-linux-musl.tar.gz/sha512/0c7f18e6d0f3e2052541e3279dfa9a74eb34067ac4fea0b17ab805cd73010cc83f8d7cb4eda8f4a904da398268d1c0d638c35521a9f339f8c7c3b5f159f27277 -MPFR.v4.2.1+1.aarch64-unknown-freebsd.tar.gz/md5/8aa99bf9c6157b8bb2833d8987ce0806 -MPFR.v4.2.1+1.aarch64-unknown-freebsd.tar.gz/sha512/6e4f547596eb8dd8ee2e1d3aefd7c73eed744add401c1f93d9951a9187c96fa9fc39be14683723dcb43cdf6891ea0021dc3416e43a0e2ec2038b0d1cd7c8434e -MPFR.v4.2.1+1.armv6l-linux-gnueabihf.tar.gz/md5/42bdb78eee83f496d7da699ad9603913 -MPFR.v4.2.1+1.armv6l-linux-gnueabihf.tar.gz/sha512/edaa9ece1404a606d6b635406ad5e721c8d094ffa1c73ce19222afc2b4ea7b3b9e23e7c5589ae10fd9f4c4aefa265773bcfce6c510efbca57782115d43daeb13 -MPFR.v4.2.1+1.armv6l-linux-musleabihf.tar.gz/md5/2213207772b8a50de4768816fdc20e2f -MPFR.v4.2.1+1.armv6l-linux-musleabihf.tar.gz/sha512/d24debc38b8135ac5c10c4ea19de0c69126b6881940b4e182118e12cc2c7cf0aca2db065620f0cca636742da32eddec5bda3b4f449a035274f05120c977ed449 -MPFR.v4.2.1+1.armv7l-linux-gnueabihf.tar.gz/md5/a0d9fe20c9ff0027b6816ee0102b1f9a -MPFR.v4.2.1+1.armv7l-linux-gnueabihf.tar.gz/sha512/97ce02898dc0d29a616048fd7ecee3100a710f7a30a21f2276c01675749034a5241be88bd46dff3dbf9ea0adca98a4357bd16e43fa9520e7a02477494c2d072e -MPFR.v4.2.1+1.armv7l-linux-musleabihf.tar.gz/md5/7898b9047c914b290b5928af5df63030 -MPFR.v4.2.1+1.armv7l-linux-musleabihf.tar.gz/sha512/cbefa9588752c65751630832417c1c42e4819d49ff9a505f61c2567ef4271097e585542fa898efd61409a43e439d827bb79f693a0937d0a3a427b39535979588 -MPFR.v4.2.1+1.i686-linux-gnu.tar.gz/md5/ac5a9db4bef94e7062dac463b5f87346 -MPFR.v4.2.1+1.i686-linux-gnu.tar.gz/sha512/2b5f3656e25065bfd83c81ee75999e6162c6e5436fcb0e3e3a767e2d941a556b4ebd3bebab78c63e8165105f81576959d8ad6e6d9cef1052751e39849e85df73 -MPFR.v4.2.1+1.i686-linux-musl.tar.gz/md5/6dc6a00d3ea22e2c60374d49926598d6 -MPFR.v4.2.1+1.i686-linux-musl.tar.gz/sha512/4a90356091b53d7238dda59f6e9c5c420614f16460dc67310e581611ad46a2dd3324d6164cfecf1bcd660b8f2e473f0afe137aac954c608b11be3acbda648e14 -MPFR.v4.2.1+1.i686-w64-mingw32.tar.gz/md5/7f7158a28ce8f262b897b38218f57958 -MPFR.v4.2.1+1.i686-w64-mingw32.tar.gz/sha512/8fbae0f1dd36534d4b9c63192c6e5cb1e531732d8eb1ab36783a6c71182f24ef80245b31a03460fd2f412fd0acaf1c4b9c8b574725271391217a3977b9ae4c79 -MPFR.v4.2.1+1.powerpc64le-linux-gnu.tar.gz/md5/ac70f716bddd5323b4add663b473b52d -MPFR.v4.2.1+1.powerpc64le-linux-gnu.tar.gz/sha512/ebb0f5ea76c892b7a4e4636706e71f476aaea58bb88e1734a7966c44495fda8c81318e0e8629e208185f0fc8d0c73b6f3463034cd831dfb5fbbd493a0689bc06 -MPFR.v4.2.1+1.x86_64-apple-darwin.tar.gz/md5/ff13e865e3be717b0fffc16296cb2f56 -MPFR.v4.2.1+1.x86_64-apple-darwin.tar.gz/sha512/98479210910945714da0285a40803674242581894a731ba4709c70dc1341849e736a88aa4914df0ff536c15f8848c417e712ff6abeb25047d300f8b215fd131f -MPFR.v4.2.1+1.x86_64-linux-gnu.tar.gz/md5/ca582be47601b8e6edb9d39f2881f44a -MPFR.v4.2.1+1.x86_64-linux-gnu.tar.gz/sha512/44a2e6158fde9fa8eaa6fac513dd5a8cae25a4b8879e5bb752a3f6af53d750c3a8e79be669ad87925b10c559cf9518fae431a607a342c48c00a390555e7e7b1f -MPFR.v4.2.1+1.x86_64-linux-musl.tar.gz/md5/0babbb823964ccebf63b42fd07f08936 -MPFR.v4.2.1+1.x86_64-linux-musl.tar.gz/sha512/880b685d9b456fa2bf78e707273783423f9ff00791b529eba00c5e1b94ff96f4ba01e680152a4d6b45b695e3c1169d07f793db42c5a4120861813d5458dfc828 -MPFR.v4.2.1+1.x86_64-unknown-freebsd.tar.gz/md5/f11d634e5a19177fe36b2b2f6f5727ca -MPFR.v4.2.1+1.x86_64-unknown-freebsd.tar.gz/sha512/291245c06edf31b2e39b6774359ebd4f95b924f19d2a7e8581822a5bf908426d00f0452c061a027da0d7d4bb2fa1bb7ef8ab6d8e49bc848d6d7450a8d5c8a9c4 -MPFR.v4.2.1+1.x86_64-w64-mingw32.tar.gz/md5/dcfad84470f15484443734feccbf8bf6 -MPFR.v4.2.1+1.x86_64-w64-mingw32.tar.gz/sha512/ceba1814fa671c2ba3e1ffeb6c736776981052e14111112fe963b5c11fd070136f8f022c5c21895f1f4f5084a5612fa673dddbb6b9622d7cade9b62eefcc8a14 +MPFR.v4.2.1+2.aarch64-apple-darwin.tar.gz/md5/1f5bba3e8e540720e239da75e5ae79eb +MPFR.v4.2.1+2.aarch64-apple-darwin.tar.gz/sha512/7de26c625e540a5b88e280ec2cb8712d4514732d80a0c6342d2b2cabc6bc17c05f6c614b8e38800c93a4af5438c554733d3fa2002ef70072dfb44c08d3f03d26 +MPFR.v4.2.1+2.aarch64-linux-gnu.tar.gz/md5/112ddd4e5cddf36b005394f9cd81b8e5 +MPFR.v4.2.1+2.aarch64-linux-gnu.tar.gz/sha512/dc125f625e8c74ce18c052ef759ccbcfc2f3a932f2810a306bdddf70d5f37f3546200690fd08fb76742022322a7c1b9aa907b4aec6edb318060f0648ff426cbc +MPFR.v4.2.1+2.aarch64-linux-musl.tar.gz/md5/a0919ef7cc35bb663d05e27da2bcb9a7 +MPFR.v4.2.1+2.aarch64-linux-musl.tar.gz/sha512/8acbaaca766c2ce225ac8df88c103a57fc52119d1fd54e9fc7d1f9d725c4ca9f74a0090e86eea0c140482a1abaf5b6086c453824a7516e9aef3ede5058f1767c +MPFR.v4.2.1+2.aarch64-unknown-freebsd.tar.gz/md5/61e1dcc7e323b976854a4e8164316d37 +MPFR.v4.2.1+2.aarch64-unknown-freebsd.tar.gz/sha512/f3a5493f88b290d15aff9bf79b15158d19bea05af7210b2967368e0b2f98cd291f77e62f39ee0c7ad4e9d2ef6ebdba4bf2fea24c723791f71f7b9b1ef989a67d +MPFR.v4.2.1+2.armv6l-linux-gnueabihf.tar.gz/md5/629aad4ac45ba23becd8a26df188638c +MPFR.v4.2.1+2.armv6l-linux-gnueabihf.tar.gz/sha512/bb05a8bf127eb16608a82037546f48462cb6168e1adcdb2c60dc3bd08f62cff30cf603abcab87bb336305d37dbb7b0480ea8f6664191879bdcd487738a33dd99 +MPFR.v4.2.1+2.armv6l-linux-musleabihf.tar.gz/md5/0c3c026051b096d98c8d476dd44db334 +MPFR.v4.2.1+2.armv6l-linux-musleabihf.tar.gz/sha512/9e791fe9748c87068c167517883cc905fe51ea38d2db89562a7a0959cfd83b268eed2897e5eaaf90c0b0b08a4efd8039bdeece64e83b17bf1d676570d13c2b98 +MPFR.v4.2.1+2.armv7l-linux-gnueabihf.tar.gz/md5/a2433a717e49ad95c3e430a538d01134 +MPFR.v4.2.1+2.armv7l-linux-gnueabihf.tar.gz/sha512/abde21a943d4af312e0d44b1ff1d4aefa10b2f38c74ff0e04c0c2b8561750ef5d164679564ffe1b551821d83ebcafbe99467230b37fe4591c593a24dfb070c6a +MPFR.v4.2.1+2.armv7l-linux-musleabihf.tar.gz/md5/4c892b4cbf1926d5d2b6a88330015c8f +MPFR.v4.2.1+2.armv7l-linux-musleabihf.tar.gz/sha512/24825bb1268ef2ea42894ec9ff6589308abae430dd8e43a2ca0d368f1e718fd3cdf6d9bc4bc383346970ba845d2ef1721c4848ee0c783d09addc5505131db3e6 +MPFR.v4.2.1+2.i686-linux-gnu.tar.gz/md5/0b1e0268dcaeb3aa0f7f0a6451c6b841 +MPFR.v4.2.1+2.i686-linux-gnu.tar.gz/sha512/f0ef142c7b86e8f92b78a7ff0607da70bf8f3970b118fa77438cbb0acbea604dc0c7566b52ff1f85b179aac7661b31e4aee049f2c5ff799c95b385ba9cde2a25 +MPFR.v4.2.1+2.i686-linux-musl.tar.gz/md5/2fc9a938e76e7bdc0b73d7e8bfc8b8ee +MPFR.v4.2.1+2.i686-linux-musl.tar.gz/sha512/4aed3884ad569b7695b9383db9d9dbb279ffe5349f7757b867ff860fa600b47faa4c169f4a60409666ce45fc6e6f269c18cef2df6fa0585f056d7e07e55005b8 +MPFR.v4.2.1+2.i686-w64-mingw32.tar.gz/md5/d13c44bb28d721107639c8555db5e157 +MPFR.v4.2.1+2.i686-w64-mingw32.tar.gz/sha512/1b5562d2df322c28bd06bb4ba8c9039cf90ed62affcf7f2b0d7ae8925d503c76a0d3d2f9b65c8c55575f245a4df8fbc4c7c63e93e7b973188f203a7fbda4eac5 +MPFR.v4.2.1+2.powerpc64le-linux-gnu.tar.gz/md5/52b3912b2c5f59ab3dcd7c3e06ca41b5 +MPFR.v4.2.1+2.powerpc64le-linux-gnu.tar.gz/sha512/533cf1f93c4464b4bed1d56ea79946fc2d20f3a7825d6b0383ed98cec99f85713e7bca549fd8948adb69aedc14e5d14a54238b3e67ef103e1b049b0cfb6cc1c9 +MPFR.v4.2.1+2.riscv64-linux-gnu.tar.gz/md5/aef7709c8457ee2db2622c39f1da16b7 +MPFR.v4.2.1+2.riscv64-linux-gnu.tar.gz/sha512/7a9c88563e3e7ab22a3aaa45690ed89c3e7eb22333a3d45c5e04ad2660c91ad2c97f10cd6c1aa1ccfdbf97186f9fd7f92330a41ec0be026e2ff84c5ba91f2652 +MPFR.v4.2.1+2.x86_64-apple-darwin.tar.gz/md5/12afc9778e39a5b6d9ea0161e2c80a95 +MPFR.v4.2.1+2.x86_64-apple-darwin.tar.gz/sha512/a9070423a898fa865740753ae7513d3cc0b500bd9b6b5c6aa672833dcac429efd806eff48501b51afcba5db0d31e79dac243b11b2f8847a1551576c6131506f5 +MPFR.v4.2.1+2.x86_64-linux-gnu.tar.gz/md5/46c6a5f40243795bdff51bd68a89c82e +MPFR.v4.2.1+2.x86_64-linux-gnu.tar.gz/sha512/df8209d69ae55dd54491055078f113f4ac8be7bc68e1c0eb62944e6c9c04ed3e9a55c4a5f28ec68eb69f558d9f4d1b975f36de572fbd0ef7720568efc8042327 +MPFR.v4.2.1+2.x86_64-linux-musl.tar.gz/md5/045236ee0d558d2eda42df76c3397f69 +MPFR.v4.2.1+2.x86_64-linux-musl.tar.gz/sha512/52b68a673160af7cd09b191f3c28e17d5af7516b5baa86c0df9cb63a116772a15b5358f3db5f0b254b5752c652f8959454667cc1726ea4ff30946e3bbdb90ab4 +MPFR.v4.2.1+2.x86_64-unknown-freebsd.tar.gz/md5/da3da71bc7572eca5bc3d3895abf73c2 +MPFR.v4.2.1+2.x86_64-unknown-freebsd.tar.gz/sha512/4270b83ebe72d431f8fd9127b2b8d3bd75c2e52c563d390a4ca8d40c0514f5996fce57746d07b7d3bcbf93bfe78d420f815fde5eda4d84a5bcb7b7cf0e092504 +MPFR.v4.2.1+2.x86_64-w64-mingw32.tar.gz/md5/2a6f5ccb8d45591a845ad43916beb85a +MPFR.v4.2.1+2.x86_64-w64-mingw32.tar.gz/sha512/db9ecc9d8247fe4421c4cc9c6ab540e17a7445056b7a1062d4e334b353783a1c067062fd8e6f0517d8bd8782c9bb75abcce8ab8247be707ba066dc90b7fc12ff mpfr-4.2.1.tar.bz2/md5/7765afa036e4ce7fb0e02bce0fef894b mpfr-4.2.1.tar.bz2/sha512/c81842532ecc663348deb7400d911ad71933d3b525a2f9e5adcd04265c9c0fdd1f22eca229f482703ac7f222ef209fc9e339dd1fa47d72ae57f7f70b2336a76f diff --git a/deps/checksums/openssl b/deps/checksums/openssl index 4d56641b34c80..c973f592861f3 100644 --- a/deps/checksums/openssl +++ b/deps/checksums/openssl @@ -1,36 +1,38 @@ -OpenSSL.v3.0.15+1.aarch64-apple-darwin.tar.gz/md5/8495727a34f178bc474c970855b88e8d -OpenSSL.v3.0.15+1.aarch64-apple-darwin.tar.gz/sha512/2beb6003e0431d56fd4161a7739d0ea2e2238181b2a064f552d5083b59e7724904e8a991e5d0ecaeb05e21d17b56ca44f321c71ac477db4ddaa05d792cb61c9b -OpenSSL.v3.0.15+1.aarch64-linux-gnu.tar.gz/md5/652845c276f3403e8374111fd6654aa0 -OpenSSL.v3.0.15+1.aarch64-linux-gnu.tar.gz/sha512/5d7a20836fffd253eaf574eb461eb10dcbb3fcf0d4f3d763539ef02a922af944e4ff29e8f20cec210ed798a48c742684ea713d511c58c784f33793e167a98469 -OpenSSL.v3.0.15+1.aarch64-linux-musl.tar.gz/md5/52397b6264c156815cdf9de5709533ef -OpenSSL.v3.0.15+1.aarch64-linux-musl.tar.gz/sha512/f1e8c0a3a7bac3c8b78d68fce551c29e5d537f7289f51c297e75c5c7bc3678747dc19ed579387021def041f02bf08d0e7938c5498b4493438efeb4685e01a191 -OpenSSL.v3.0.15+1.aarch64-unknown-freebsd.tar.gz/md5/bbdbea23761b13821d99f9eb4ba5d198 -OpenSSL.v3.0.15+1.aarch64-unknown-freebsd.tar.gz/sha512/a1c3985658eaf38a901bc7de1e782101ab41638d4641fea3115c5020b229d3f6fba3e3709c5568b3395986f396d82feb32b804d343dfd05c2fa1e6eefe120e96 -OpenSSL.v3.0.15+1.armv6l-linux-gnueabihf.tar.gz/md5/ceeb288e5c8da5831047dc4b1c2a983e -OpenSSL.v3.0.15+1.armv6l-linux-gnueabihf.tar.gz/sha512/961c4ec351b69aaf42082b462623afd7315b6606c2a5fb98142ca1bc6ce0494c388f5020474eff5081e850fd34aed8b3ef2f881304872255236fcae0b0b641e4 -OpenSSL.v3.0.15+1.armv6l-linux-musleabihf.tar.gz/md5/e75d83ecf3876a595cfe36cf81853489 -OpenSSL.v3.0.15+1.armv6l-linux-musleabihf.tar.gz/sha512/3e113a275233f434df685b114342f2a59634282a9b68606d4c16da51e5173cbed26498512b22f84017100a18415cc1bb2d269f1ba0d44941d51b8d05c73950cc -OpenSSL.v3.0.15+1.armv7l-linux-gnueabihf.tar.gz/md5/fbe3bf8921cf9b679b60ea12e2d19458 -OpenSSL.v3.0.15+1.armv7l-linux-gnueabihf.tar.gz/sha512/294c91308eede14b8db255ff1b47fe5dba3b6441318e38e284446f276355b93d97b88e6c78d9ed6bb6623623c47be5c65ce6b2fa5ce5ea087a8bfaeb94830627 -OpenSSL.v3.0.15+1.armv7l-linux-musleabihf.tar.gz/md5/ab35b5d4f79e349d558742c69c775d34 -OpenSSL.v3.0.15+1.armv7l-linux-musleabihf.tar.gz/sha512/6a5c85e36ed609ad33d0d2466fa1732a47072af37226052456172d7b049b9d943ad48d94b444600ed1f859a4c016226fc1952fda7381f3aaa6229bcd15c72f78 -OpenSSL.v3.0.15+1.i686-linux-gnu.tar.gz/md5/99e76e6c5d50fd0a4e6218bb807f1062 -OpenSSL.v3.0.15+1.i686-linux-gnu.tar.gz/sha512/30235842672e3b854d38ffd3ba1812a9e81b1f9fcf285ed12d07622d386a5355b79f2264be3d0e84d0bec0e57a9f3e1ac6de898463c43f6d2e3290854205cb30 -OpenSSL.v3.0.15+1.i686-linux-musl.tar.gz/md5/adb2ed9a8ef34294643f7762de1c7842 -OpenSSL.v3.0.15+1.i686-linux-musl.tar.gz/sha512/56d56eb89ea0dcadafbfc92a3bd2032b6c934d217882f56ba47086783b7a5134816f43d391a569963fa978ab708bf695af5abf03cac11c709930752882c761b7 -OpenSSL.v3.0.15+1.i686-w64-mingw32.tar.gz/md5/4596a947bb22aab728ba585d2727053a -OpenSSL.v3.0.15+1.i686-w64-mingw32.tar.gz/sha512/6a1479036c7ccb170daf42ed7d6054d2c7f3a4115dbb01fe34e518efdf0a60929eb89771d5f7fdcb3d055ebf05351cbc82397606d49ea4bde44c465cdb60274e -OpenSSL.v3.0.15+1.powerpc64le-linux-gnu.tar.gz/md5/f36402387dde259a64b0bed2a0d2a3c9 -OpenSSL.v3.0.15+1.powerpc64le-linux-gnu.tar.gz/sha512/3011eec16c1abcbf3c452a2d8e4e7c5a3c280981ea57374a938e3f8843f25022e9b0beaa6a87a1e5f7547ae4abd614221cc2a0a51495869fe99a03f6b3f46d8e -OpenSSL.v3.0.15+1.x86_64-apple-darwin.tar.gz/md5/f4c82b74f80a3cda4ae409e4623b6615 -OpenSSL.v3.0.15+1.x86_64-apple-darwin.tar.gz/sha512/d4a08a914533e603f06e584b8d7e69f4fca9671635fe24e1a896a362bfd388eea2397b9b66b82aecc0ba751e72dfcfbd8b46c5a148349f5aaeb9c37bc257ed37 -OpenSSL.v3.0.15+1.x86_64-linux-gnu.tar.gz/md5/9868c286c6275581a5891167540def7d -OpenSSL.v3.0.15+1.x86_64-linux-gnu.tar.gz/sha512/5631aa288e0e174bd05d520d90a29423c743576eb2385e97a58ed45361e94e59daa3b3193e81ce649bfed21d07fd508c135a38b486b34120afc3af1b4f92451d -OpenSSL.v3.0.15+1.x86_64-linux-musl.tar.gz/md5/e118f2b842a3a1be539208aff17281ec -OpenSSL.v3.0.15+1.x86_64-linux-musl.tar.gz/sha512/1c6fa866bebf5c0c6cc5ea8a423d2a522b186e7f2590146e464813be22d66de0a9bc797449508fa5508d296309348b8dd3a881c0099e6fb77b8d28ff270fab35 -OpenSSL.v3.0.15+1.x86_64-unknown-freebsd.tar.gz/md5/03830b4a8735a7e704df444e9a4353ab -OpenSSL.v3.0.15+1.x86_64-unknown-freebsd.tar.gz/sha512/bfc9e4ca160a9e3d4232117d819ea37f3997d4c433cfc85a4055ced60e8c65e7df6009d58f6b94f6f2aa1b436a8ee9f08dcf5a21faf7106bfdb50ca9a05322c6 -OpenSSL.v3.0.15+1.x86_64-w64-mingw32.tar.gz/md5/5b2c640cb72115f417cdd7ec82a8336f -OpenSSL.v3.0.15+1.x86_64-w64-mingw32.tar.gz/sha512/d2224dd37205c7781be93f1581a08c4008f4c35cb3f457f3b4455a00805c1a20be7f7e29188a55164364c42a926ffa12527af379d1bc8d11f4351b07d8a5928b +OpenSSL.v3.0.15+2.aarch64-apple-darwin.tar.gz/md5/d11d92e6530705e3d93925bbb4dfccff +OpenSSL.v3.0.15+2.aarch64-apple-darwin.tar.gz/sha512/e30d763d956f930c3dab961ef1b382385b78cbb2324ae7f5e943420b9178bc2b086d9877c2d2b41b30a92ca109d7832a2ae50f70547fcc9788e25889d8252ffc +OpenSSL.v3.0.15+2.aarch64-linux-gnu.tar.gz/md5/d29f0d3a35d592488ba3a8bbb0dc8d0e +OpenSSL.v3.0.15+2.aarch64-linux-gnu.tar.gz/sha512/67c527c1930b903d2fbb55df1bd3fc1b8394bc4fadd15dd8fb84e776bae8c448487c117492e22b9b014f823cc7fe709695f4064639066b10427b06355540e997 +OpenSSL.v3.0.15+2.aarch64-linux-musl.tar.gz/md5/4f5313f1f18e29585951e95372a7a0fe +OpenSSL.v3.0.15+2.aarch64-linux-musl.tar.gz/sha512/48007a1f6667d6aeb87cc7287723ed00e39fe2bc9c353ff33348442516f1a28961985cc4a29a2a8f76b3a7049bd955973562d7c6c4af43af884596def636f7f8 +OpenSSL.v3.0.15+2.aarch64-unknown-freebsd.tar.gz/md5/5b6041353197bb8f75b39ed8f58cf4e9 +OpenSSL.v3.0.15+2.aarch64-unknown-freebsd.tar.gz/sha512/9be617d51fdc167085887380e720e6baf8e1e180f455b297f44d0bc0862fd490f015b5292d952d4ad095750cde796cc7dac4f901389b73135cb399b3a9d378c1 +OpenSSL.v3.0.15+2.armv6l-linux-gnueabihf.tar.gz/md5/858f548a28e289153842226473138a3e +OpenSSL.v3.0.15+2.armv6l-linux-gnueabihf.tar.gz/sha512/f9385678fca65d1fb8d96756442518b16607a57a9b6d76991414b37dfc4e30a7e1eebe5f3977b088b491216af4a34f958b64fe95062ee9ae23a9212f46c4e923 +OpenSSL.v3.0.15+2.armv6l-linux-musleabihf.tar.gz/md5/c4e52ecb4f9e24d948724424f1070071 +OpenSSL.v3.0.15+2.armv6l-linux-musleabihf.tar.gz/sha512/12f9276c68049026f2741c7d97e62d24525e5e832911546e1ea3868362034e6384304d749730122edf828b8c5573084055d59cc0bd75bda32f000ce630837c2b +OpenSSL.v3.0.15+2.armv7l-linux-gnueabihf.tar.gz/md5/767d3f3047366ccd6e2aa275f80d9f6c +OpenSSL.v3.0.15+2.armv7l-linux-gnueabihf.tar.gz/sha512/17700fd33c221070a7dd2db79d045e102591b85e16b3d4099356fb6a8635aea297b5fcef91740f75c55344a12ed356772b3b85c0cc68627856093ceb53ea8eb3 +OpenSSL.v3.0.15+2.armv7l-linux-musleabihf.tar.gz/md5/3ef2385cb1fec9e2d3af2ba9385ac733 +OpenSSL.v3.0.15+2.armv7l-linux-musleabihf.tar.gz/sha512/6156e9431fa8269b8d037149271be6cca0b119be67be01cfd958dabf59cdd468ef2a5ebf885e5835585006efdedd29afc308076283d070d4ae743146b57cd2b1 +OpenSSL.v3.0.15+2.i686-linux-gnu.tar.gz/md5/e62992d214cec6b1970f9fbd04cb8ecd +OpenSSL.v3.0.15+2.i686-linux-gnu.tar.gz/sha512/dfdb3d2d1d5fed7bf1c322899d6138c81f0653350f4b918858dd51bf7bcc86d2d04de824533925fa5f8d366a5c18ee33ade883f50a538b657717f8a428be8c60 +OpenSSL.v3.0.15+2.i686-linux-musl.tar.gz/md5/186a6bb8055ce089ac0c9897bd2cd697 +OpenSSL.v3.0.15+2.i686-linux-musl.tar.gz/sha512/f3c8d608113e9b0e91dd6af697172a46892d4a66572e35e13ad394397291dded3042667c1ec4fafe051778e71ff56a876dc3e848a2b85cef9f925ef3969ab950 +OpenSSL.v3.0.15+2.i686-w64-mingw32.tar.gz/md5/b72b8e4883337e4bc90094dce86c8b8b +OpenSSL.v3.0.15+2.i686-w64-mingw32.tar.gz/sha512/3b5ddef15ca1463ab92ef5b88df36f8418c8c44ffb123a0922e55718ab317b5fe379994aba9a5e8ca112475043d5cf99b1574702cdb30de438f458ee06ac80ea +OpenSSL.v3.0.15+2.powerpc64le-linux-gnu.tar.gz/md5/da194ce6f37f34cc19cc78d25c9af5e2 +OpenSSL.v3.0.15+2.powerpc64le-linux-gnu.tar.gz/sha512/e256a9d9a0af8764de730419281aa4d3ee9f6146692ec9105a318d8301d8fda5cca82c6ef4d0d7b70d721992361771724b237ce26ef81f92c295f6056d5a7cdd +OpenSSL.v3.0.15+2.riscv64-linux-gnu.tar.gz/md5/86825ee5f83ec0c827d5c051fe1a3d41 +OpenSSL.v3.0.15+2.riscv64-linux-gnu.tar.gz/sha512/7db4ae2f0a9491ae484da5b8b0c3698d970ada91c83f9783c9e5bd92006f52dffa1a4c7fb282b63e34760199a97c52793040dc306ad0986970cfa233e29cb195 +OpenSSL.v3.0.15+2.x86_64-apple-darwin.tar.gz/md5/271cc359f5bc4718659044ad5ac7631d +OpenSSL.v3.0.15+2.x86_64-apple-darwin.tar.gz/sha512/10e7575dc4cce6c617c96e6f94dbfe3058aad696292d3fac4bde7c92623f2a849b7d10e35b156b7582294b3cf103d61b3ea73605f958ee4c9f8ff05b647939a7 +OpenSSL.v3.0.15+2.x86_64-linux-gnu.tar.gz/md5/5d045d93d632af9914bff551f67eed9b +OpenSSL.v3.0.15+2.x86_64-linux-gnu.tar.gz/sha512/240791382d9549be029e2d404bc0e962f9876ab0597bf20cf34c87fcfafc3d75ba9f223641287895f9aee8519a5a33293910ed6d67bc1424ff3513eedaa8b699 +OpenSSL.v3.0.15+2.x86_64-linux-musl.tar.gz/md5/bb2637babf3730ed1117f89cb8aab34a +OpenSSL.v3.0.15+2.x86_64-linux-musl.tar.gz/sha512/b847539acc00870f77b242eeccfcf16f590493b7deb0089fa3654026f4016d40f9595d3bbb21ab981e9decfde4321da71f162beb1837a158fd3a884375a86fee +OpenSSL.v3.0.15+2.x86_64-unknown-freebsd.tar.gz/md5/23b69e0256e6c86e026be3ade20aed5c +OpenSSL.v3.0.15+2.x86_64-unknown-freebsd.tar.gz/sha512/1b7da1e13d325c7776b8e1a63aaa334bd633bb10604f8bed5f5f6a81955268b3d11ad221a5dd181dbdc7ad27c35d5754e6875d36226003c2fd7da6cd91854de1 +OpenSSL.v3.0.15+2.x86_64-w64-mingw32.tar.gz/md5/73cf4138ab403b7c9f91368a030590f9 +OpenSSL.v3.0.15+2.x86_64-w64-mingw32.tar.gz/sha512/052bb52837c29b4b18a97df71a80ad77486bd6ccef6e2e57dfa68a02754180976dc0302a158886393ef13fe91904f963119b17429a4ecc6f8b6c80ff878df05d openssl-3.0.15.tar.gz/md5/08f458c00fff496a52ef931c481045cd openssl-3.0.15.tar.gz/sha512/acd80f2f7924d90c1416946a5c61eff461926ad60f4821bb6b08845ea18f8452fd5e88a2c2c5bd0d7590a792cb8341a3f3be042fd0a5b6c9c1b84a497c347bbf diff --git a/stdlib/MPFR_jll/Project.toml b/stdlib/MPFR_jll/Project.toml index a9987ccfa38f6..50de38f169ff0 100644 --- a/stdlib/MPFR_jll/Project.toml +++ b/stdlib/MPFR_jll/Project.toml @@ -1,6 +1,6 @@ name = "MPFR_jll" uuid = "3a97d323-0669-5f0c-9066-3539efd106a3" -version = "4.2.1+1" +version = "4.2.1+2" [deps] GMP_jll = "781609d7-10c4-51f6-84f2-b8444358ff6d" diff --git a/stdlib/OpenSSL_jll/Project.toml b/stdlib/OpenSSL_jll/Project.toml index df00f99b205c9..0773311e11043 100644 --- a/stdlib/OpenSSL_jll/Project.toml +++ b/stdlib/OpenSSL_jll/Project.toml @@ -1,6 +1,6 @@ name = "OpenSSL_jll" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.15+1" +version = "3.0.15+2" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" From f135f3a2dc89d8aa6b885795f27ae989dadc6c3f Mon Sep 17 00:00:00 2001 From: Nicholas Bauer Date: Mon, 13 Jan 2025 14:51:46 -0500 Subject: [PATCH 173/198] More efficient hvcat of scalars and arrays of numbers (#39729) First attempt to address #39713 Original: ``` const a, b, c, d = zeros(Int, 2, 2), [3 4], [2 ; 4], 5 using BenchmarkTools @btime [a c ; b d] # 31 allocations and 1.25 kb ``` New: ``` @btime [a c ; b d] # 15 allocations and 656 bytes ``` Others unchanged, as expected. ~~Though if different types of numbers are mixed, it still takes the longer path. I tried expanding the definition but there's some weird stuff going on that increases allocations in the other situations I posted in that issue.~~ Works for any Number element type. Fixes #39713 --- base/abstractarray.jl | 59 ++++--------------------------------------- 1 file changed, 5 insertions(+), 54 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index a370b79976ab0..1ab78a55c93b5 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -2189,48 +2189,8 @@ true hvcat(rows::Tuple{Vararg{Int}}, xs::AbstractArray...) = typed_hvcat(promote_eltype(xs...), rows, xs...) hvcat(rows::Tuple{Vararg{Int}}, xs::AbstractArray{T}...) where {T} = typed_hvcat(T, rows, xs...) -function typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, as::AbstractVecOrMat...) where T - nbr = length(rows) # number of block rows - - nc = 0 - for i=1:rows[1] - nc += size(as[i],2) - end - - nr = 0 - a = 1 - for i = 1:nbr - nr += size(as[a],1) - a += rows[i] - end - - out = similar(as[1], T, nr, nc) - - a = 1 - r = 1 - for i = 1:nbr - c = 1 - szi = size(as[a],1) - for j = 1:rows[i] - Aj = as[a+j-1] - szj = size(Aj,2) - if size(Aj,1) != szi - throw(DimensionMismatch("mismatched height in block row $(i) (expected $szi, got $(size(Aj,1)))")) - end - if c-1+szj > nc - throw(DimensionMismatch("block row $(i) has mismatched number of columns (expected $nc, got $(c-1+szj))")) - end - out[r:r-1+szi, c:c-1+szj] = Aj - c += szj - end - if c != nc+1 - throw(DimensionMismatch("block row $(i) has mismatched number of columns (expected $nc, got $(c-1))")) - end - r += szi - a += rows[i] - end - out -end +rows_to_dimshape(rows::Tuple{Vararg{Int}}) = all(==(rows[1]), rows) ? (length(rows), rows[1]) : (rows, (sum(rows),)) +typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, as::AbstractVecOrMat...) where T = typed_hvncat(T, rows_to_dimshape(rows), true, as...) hvcat(rows::Tuple{Vararg{Int}}) = [] typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}) where {T} = Vector{T}() @@ -2288,16 +2248,7 @@ function typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, xs::Number...) where T hvcat_fill!(Matrix{T}(undef, nr, nc), xs) end -function typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, as...) where T - nbr = length(rows) # number of block rows - rs = Vector{Any}(undef, nbr) - a = 1 - for i = 1:nbr - rs[i] = typed_hcat(T, as[a:a-1+rows[i]]...) - a += rows[i] - end - T[rs...;] -end +typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, as...) where T = typed_hvncat(T, rows_to_dimshape(rows), true, as...) ## N-dimensional concatenation ## @@ -2645,7 +2596,7 @@ function _typed_hvncat_dims(::Type{T}, dims::NTuple{N, Int}, row_first::Bool, as throw(DimensionMismatch("mismatched number of elements; expected $(outlen), got $(elementcount)")) # copy into final array - A = cat_similar(as[1], T, outdims) + A = cat_similar(as[1], T, ntuple(i -> outdims[i], N)) # @assert all(==(0), currentdims) outdims .= 0 hvncat_fill!(A, currentdims, outdims, d1, d2, as) @@ -2739,7 +2690,7 @@ function _typed_hvncat_shape(::Type{T}, shape::NTuple{N, Tuple}, row_first, as:: # @assert all(==(0), blockcounts) # copy into final array - A = cat_similar(as[1], T, outdims) + A = cat_similar(as[1], T, ntuple(i -> outdims[i], nd)) hvncat_fill!(A, currentdims, blockcounts, d1, d2, as) return A end From 664528adac261df806f291493593f63b66ff169c Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 14 Jan 2025 05:26:23 +0900 Subject: [PATCH 174/198] make `datatype_min_ninitialized` robust against non `DataType` input (#57033) By unwrapping the input type in `datatype_min_ninitialized`, and guard against non `DataType` input by returning the most conservative value `0` in such cases. Fixes #56997 --- Compiler/src/abstractinterpretation.jl | 2 +- Compiler/src/typelimits.jl | 2 +- Compiler/src/typeutils.jl | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 3766907905aef..59510dbfbb65a 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -3708,7 +3708,7 @@ end if isa(rt, PartialStruct) fields = copy(rt.fields) anyrefine = !isvarargtype(rt.fields[end]) && - length(rt.fields) > datatype_min_ninitialized(unwrap_unionall(rt.typ)) + length(rt.fields) > datatype_min_ninitialized(rt.typ) 𝕃 = typeinf_lattice(info.interp) ⊏ = strictpartialorder(𝕃) for i in 1:length(fields) diff --git a/Compiler/src/typelimits.jl b/Compiler/src/typelimits.jl index 11245fbaee9b0..536b5fb34d1b1 100644 --- a/Compiler/src/typelimits.jl +++ b/Compiler/src/typelimits.jl @@ -601,7 +601,7 @@ end end nflds == 0 && return nothing fields = Vector{Any}(undef, nflds) - anyrefine = nflds > datatype_min_ninitialized(unwrap_unionall(aty)) + anyrefine = nflds > datatype_min_ninitialized(aty) for i = 1:nflds ai = getfield_tfunc(𝕃, typea, Const(i)) bi = getfield_tfunc(𝕃, typeb, Const(i)) diff --git a/Compiler/src/typeutils.jl b/Compiler/src/typeutils.jl index 4af8fed0e40c3..5175e00612270 100644 --- a/Compiler/src/typeutils.jl +++ b/Compiler/src/typeutils.jl @@ -64,7 +64,9 @@ end # Compute the minimum number of initialized fields for a particular datatype # (therefore also a lower bound on the number of fields) -function datatype_min_ninitialized(t::DataType) +function datatype_min_ninitialized(@nospecialize t0) + t = unwrap_unionall(t0) + t isa DataType || return 0 isabstracttype(t) && return 0 if t.name === _NAMEDTUPLE_NAME names, types = t.parameters[1], t.parameters[2] From a861a551b764062d47ab3c2a3748bcf540221bae Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Tue, 14 Jan 2025 01:14:56 -0300 Subject: [PATCH 175/198] Move all platforms to use llvm.minimum/llvm.maximum for fmin/fmax (#56371) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This used to not work but LLVM now has support for this on all platforms we care about. Maybe this should be a builtin. This allows for more vectorization opportunities since llvm understands the code better Fix #48487. --------- Co-authored-by: Mosè Giordano <765740+giordano@users.noreply.github.com> Co-authored-by: oscarddssmith --- Compiler/src/tfuncs.jl | 4 ++++ base/fastmath.jl | 10 ++++----- base/math.jl | 45 +++++----------------------------------- src/intrinsics.cpp | 32 ++++++++++++++++++++++++++++ src/intrinsics.h | 4 ++++ src/julia_internal.h | 2 ++ src/runtime_intrinsics.c | 39 +++++++++++++++++++++++++++++++++- 7 files changed, 89 insertions(+), 47 deletions(-) diff --git a/Compiler/src/tfuncs.jl b/Compiler/src/tfuncs.jl index f0c793a4ae3b7..cfb865b06e9e5 100644 --- a/Compiler/src/tfuncs.jl +++ b/Compiler/src/tfuncs.jl @@ -189,6 +189,8 @@ add_tfunc(add_float, 2, 2, math_tfunc, 2) add_tfunc(sub_float, 2, 2, math_tfunc, 2) add_tfunc(mul_float, 2, 2, math_tfunc, 8) add_tfunc(div_float, 2, 2, math_tfunc, 10) +add_tfunc(min_float, 2, 2, math_tfunc, 1) +add_tfunc(max_float, 2, 2, math_tfunc, 1) add_tfunc(fma_float, 3, 3, math_tfunc, 8) add_tfunc(muladd_float, 3, 3, math_tfunc, 8) @@ -198,6 +200,8 @@ add_tfunc(add_float_fast, 2, 2, math_tfunc, 2) add_tfunc(sub_float_fast, 2, 2, math_tfunc, 2) add_tfunc(mul_float_fast, 2, 2, math_tfunc, 8) add_tfunc(div_float_fast, 2, 2, math_tfunc, 10) +add_tfunc(min_float_fast, 2, 2, math_tfunc, 1) +add_tfunc(max_float_fast, 2, 2, math_tfunc, 1) # bitwise operators # ----------------- diff --git a/base/fastmath.jl b/base/fastmath.jl index b82d613f1fc76..f2f60519b99ac 100644 --- a/base/fastmath.jl +++ b/base/fastmath.jl @@ -28,7 +28,7 @@ module FastMath export @fastmath import Core.Intrinsics: sqrt_llvm_fast, neg_float_fast, - add_float_fast, sub_float_fast, mul_float_fast, div_float_fast, + add_float_fast, sub_float_fast, mul_float_fast, div_float_fast, min_float_fast, max_float_fast, eq_float_fast, ne_float_fast, lt_float_fast, le_float_fast import Base: afoldl @@ -168,6 +168,9 @@ add_fast(x::T, y::T) where {T<:FloatTypes} = add_float_fast(x, y) sub_fast(x::T, y::T) where {T<:FloatTypes} = sub_float_fast(x, y) mul_fast(x::T, y::T) where {T<:FloatTypes} = mul_float_fast(x, y) div_fast(x::T, y::T) where {T<:FloatTypes} = div_float_fast(x, y) +max_fast(x::T, y::T) where {T<:FloatTypes} = max_float_fast(x, y) +min_fast(x::T, y::T) where {T<:FloatTypes} = min_float_fast(x, y) +minmax_fast(x::T, y::T) where {T<:FloatTypes} = (min_fast(x, y), max_fast(x, y)) @fastmath begin cmp_fast(x::T, y::T) where {T<:FloatTypes} = ifelse(x==y, 0, ifelse(x x, y, x) - min_fast(x::T, y::T) where {T<:FloatTypes} = ifelse(y > x, x, y) - minmax_fast(x::T, y::T) where {T<:FloatTypes} = ifelse(y > x, (x,y), (y,x)) end # fall-back implementations and type promotion diff --git a/base/math.jl b/base/math.jl index 16a8a547e8de1..650fc6bc0cef0 100644 --- a/base/math.jl +++ b/base/math.jl @@ -25,7 +25,7 @@ using .Base: sign_mask, exponent_mask, exponent_one, significand_bits, exponent_bits, exponent_bias, exponent_max, exponent_raw_max, clamp, clamp! -using Core.Intrinsics: sqrt_llvm +using Core.Intrinsics: sqrt_llvm, min_float, max_float using .Base: IEEEFloat @@ -831,47 +831,12 @@ min(x::T, y::T) where {T<:AbstractFloat} = isnan(x) || ~isnan(y) && _isless(x, y max(x::T, y::T) where {T<:AbstractFloat} = isnan(x) || ~isnan(y) && _isless(y, x) ? x : y minmax(x::T, y::T) where {T<:AbstractFloat} = min(x, y), max(x, y) -_isless(x::Float16, y::Float16) = signbit(widen(x) - widen(y)) - -const has_native_fminmax = Sys.ARCH === :aarch64 -@static if has_native_fminmax - @eval begin - Base.@assume_effects :total @inline llvm_min(x::Float64, y::Float64) = ccall("llvm.minimum.f64", llvmcall, Float64, (Float64, Float64), x, y) - Base.@assume_effects :total @inline llvm_min(x::Float32, y::Float32) = ccall("llvm.minimum.f32", llvmcall, Float32, (Float32, Float32), x, y) - Base.@assume_effects :total @inline llvm_max(x::Float64, y::Float64) = ccall("llvm.maximum.f64", llvmcall, Float64, (Float64, Float64), x, y) - Base.@assume_effects :total @inline llvm_max(x::Float32, y::Float32) = ccall("llvm.maximum.f32", llvmcall, Float32, (Float32, Float32), x, y) - end -end - -function min(x::T, y::T) where {T<:Union{Float32,Float64}} - @static if has_native_fminmax - return llvm_min(x,y) - end - diff = x - y - argmin = ifelse(signbit(diff), x, y) - anynan = isnan(x)|isnan(y) - return ifelse(anynan, diff, argmin) +function min(x::T, y::T) where {T<:IEEEFloat} + return min_float(x, y) end -function max(x::T, y::T) where {T<:Union{Float32,Float64}} - @static if has_native_fminmax - return llvm_max(x,y) - end - diff = x - y - argmax = ifelse(signbit(diff), y, x) - anynan = isnan(x)|isnan(y) - return ifelse(anynan, diff, argmax) -end - -function minmax(x::T, y::T) where {T<:Union{Float32,Float64}} - @static if has_native_fminmax - return llvm_min(x, y), llvm_max(x, y) - end - diff = x - y - sdiff = signbit(diff) - min, max = ifelse(sdiff, x, y), ifelse(sdiff, y, x) - anynan = isnan(x)|isnan(y) - return ifelse(anynan, diff, min), ifelse(anynan, diff, max) +function max(x::T, y::T) where {T<:IEEEFloat} + return max_float(x, y) end """ diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index 09916297e16ff..7b5aa7c397129 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -83,10 +83,14 @@ const auto &float_func() { float_func[sub_float] = true; float_func[mul_float] = true; float_func[div_float] = true; + float_func[min_float] = true; + float_func[max_float] = true; float_func[add_float_fast] = true; float_func[sub_float_fast] = true; float_func[mul_float_fast] = true; float_func[div_float_fast] = true; + float_func[min_float_fast] = true; + float_func[max_float_fast] = true; float_func[fma_float] = true; float_func[muladd_float] = true; float_func[eq_float] = true; @@ -1490,6 +1494,34 @@ static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, ArrayRefgetType() == y->getType()); + FunctionCallee minintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::minimum, ArrayRef(t)); + return ctx.builder.CreateCall(minintr, {x, y}); + } + case max_float: { + assert(x->getType() == y->getType()); + FunctionCallee maxintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::maximum, ArrayRef(t)); + return ctx.builder.CreateCall(maxintr, {x, y}); + } + case min_float_fast: { + assert(x->getType() == y->getType()); + FunctionCallee minintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::minimum, ArrayRef(t)); + auto call = ctx.builder.CreateCall(minintr, {x, y}); + auto fmf = call->getFastMathFlags(); + fmf.setFast(); + call->copyFastMathFlags(fmf); + return call; + } + case max_float_fast: { + assert(x->getType() == y->getType()); + FunctionCallee maxintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::maximum, ArrayRef(t)); + auto call = ctx.builder.CreateCall(maxintr, {x, y}); + auto fmf = call->getFastMathFlags(); + fmf.setFast(); + call->copyFastMathFlags(fmf); + return call; + } case add_float_fast: return math_builder(ctx, true)().CreateFAdd(x, y); case sub_float_fast: return math_builder(ctx, true)().CreateFSub(x, y); case mul_float_fast: return math_builder(ctx, true)().CreateFMul(x, y); diff --git a/src/intrinsics.h b/src/intrinsics.h index 5b463e3bafe28..5765e3e671bc6 100644 --- a/src/intrinsics.h +++ b/src/intrinsics.h @@ -17,6 +17,8 @@ ADD_I(sub_float, 2) \ ADD_I(mul_float, 2) \ ADD_I(div_float, 2) \ + ADD_I(min_float, 2) \ + ADD_I(max_float, 2) \ ADD_I(fma_float, 3) \ ADD_I(muladd_float, 3) \ /* fast arithmetic */ \ @@ -25,6 +27,8 @@ ALIAS(sub_float_fast, sub_float) \ ALIAS(mul_float_fast, mul_float) \ ALIAS(div_float_fast, div_float) \ + ALIAS(min_float_fast, min_float) \ + ALIAS(max_float_fast, max_float) \ /* same-type comparisons */ \ ADD_I(eq_int, 2) \ ADD_I(ne_int, 2) \ diff --git a/src/julia_internal.h b/src/julia_internal.h index f8dd49eab65a3..81e9ebb537667 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -1595,6 +1595,8 @@ JL_DLLEXPORT jl_value_t *jl_add_float(jl_value_t *a, jl_value_t *b); JL_DLLEXPORT jl_value_t *jl_sub_float(jl_value_t *a, jl_value_t *b); JL_DLLEXPORT jl_value_t *jl_mul_float(jl_value_t *a, jl_value_t *b); JL_DLLEXPORT jl_value_t *jl_div_float(jl_value_t *a, jl_value_t *b); +JL_DLLEXPORT jl_value_t *jl_min_float(jl_value_t *a, jl_value_t *b); +JL_DLLEXPORT jl_value_t *jl_max_float(jl_value_t *a, jl_value_t *b); JL_DLLEXPORT jl_value_t *jl_fma_float(jl_value_t *a, jl_value_t *b, jl_value_t *c); JL_DLLEXPORT jl_value_t *jl_muladd_float(jl_value_t *a, jl_value_t *b, jl_value_t *c); diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index 80281b733bf44..1790b9bd8d106 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -1398,13 +1398,50 @@ bi_iintrinsic_fast(LLVMURem, rem, urem_int, u) bi_iintrinsic_fast(jl_LLVMSMod, smod, smod_int, ) #define frem(a, b) \ fp_select2(a, b, fmod) - un_fintrinsic(neg_float,neg_float) bi_fintrinsic(add,add_float) bi_fintrinsic(sub,sub_float) bi_fintrinsic(mul,mul_float) bi_fintrinsic(div,div_float) +float min_float(float x, float y) JL_NOTSAFEPOINT +{ + float diff = x - y; + float argmin = signbit(diff) ? x : y; + int is_nan = isnan(x) || isnan(y); + return is_nan ? diff : argmin; +} + +double min_double(double x, double y) JL_NOTSAFEPOINT +{ + double diff = x - y; + double argmin = signbit(diff) ? x : y; + int is_nan = isnan(x) || isnan(y); + return is_nan ? diff : argmin; +} + +#define _min(a, b) sizeof(a) == sizeof(float) ? min_float(a, b) : min_double(a, b) +bi_fintrinsic(_min, min_float) + +float max_float(float x, float y) JL_NOTSAFEPOINT +{ + float diff = x - y; + float argmin = signbit(diff) ? y : x; + int is_nan = isnan(x) || isnan(y); + return is_nan ? diff : argmin; +} + +double max_double(double x, double y) JL_NOTSAFEPOINT +{ + double diff = x - y; + double argmin = signbit(diff) ? x : y; + int is_nan = isnan(x) || isnan(y); + return is_nan ? diff : argmin; +} + +#define _max(a, b) sizeof(a) == sizeof(float) ? max_float(a, b) : max_double(a, b) +bi_fintrinsic(_max, max_float) + // ternary operators // // runtime fma is broken on windows, define julia_fma(f) ourself with fma_emulated as reference. #if defined(_OS_WINDOWS_) From 9b1ea1a880e1c47ebdc549a12fca288b5cc60013 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 14 Jan 2025 15:37:18 +0900 Subject: [PATCH 176/198] publish Compiler.jl v0.0.3 (#57032) Cthulhu.jl requires this (as the signature of `jl_update_codeinst` has been updated). --- Compiler/Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Compiler/Project.toml b/Compiler/Project.toml index 046d672c4877c..994634f5a8b78 100644 --- a/Compiler/Project.toml +++ b/Compiler/Project.toml @@ -1,6 +1,6 @@ name = "Compiler" uuid = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1" -version = "0.0.2" +version = "0.0.3" [compat] julia = "1.10" From 3ba504a5484c48720aa3f19e7ef51a5a32c3a7db Mon Sep 17 00:00:00 2001 From: Yi Lin Date: Wed, 15 Jan 2025 00:39:11 +1300 Subject: [PATCH 177/198] Fix getall failure with MMTk dependency (#57038) This PR fixes https://github.com/JuliaLang/julia/issues/57002. The current makefile checks if `MMTK_JULIA_DIR` points to `$(BUILDROOT)/usr/lib/mmtk_julia` and defines the rule `get-mmtk_julia` if the condition is met. For non-mmtk builds (e.g. `make -C deps getall`), `MMTK_JULIA_DIR` is not defined, thus `get-mmtk_julia` is not defined. This PR moves the rule `get-mmtk_julia` outside the condition so it always exists. --- deps/mmtk_julia.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deps/mmtk_julia.mk b/deps/mmtk_julia.mk index ccf638e9211bb..7ec55426821c3 100644 --- a/deps/mmtk_julia.mk +++ b/deps/mmtk_julia.mk @@ -6,9 +6,11 @@ MMTK_MOVING := 0 MMTK_VARS := MMTK_PLAN=$(MMTK_PLAN) MMTK_MOVING=$(MMTK_MOVING) +$(eval $(call git-external,mmtk_julia,MMTK_JULIA,,,$(BUILDDIR))) +get-mmtk_julia: $(MMTK_JULIA_SRC_FILE) + # Download the binding, build it from source ifeq (${MMTK_JULIA_DIR},$(BUILDROOT)/usr/lib/mmtk_julia) -$(eval $(call git-external,mmtk_julia,MMTK_JULIA,,,$(BUILDDIR))) MMTK_JULIA_DIR=$(BUILDROOT)/deps/$(BUILDDIR)/$(MMTK_JULIA_SRC_DIR) MMTK_JULIA_LIB_PATH=$(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD) @@ -24,7 +26,6 @@ $(BUILDROOT)/usr/lib/libmmtk_julia.so: $(MMTK_JULIA_LIB_PATH)/libmmtk_julia.so $(MMTK_JULIA_LIB_PATH)/libmmtk_julia.so: $(BUILDDIR)/$(MMTK_JULIA_SRC_DIR)/source-extracted @$(PROJECT_DIRS) $(MMTK_VARS) $(MAKE) -C $(MMTK_JULIA_DIR) $(MMTK_BUILD) -get-mmtk_julia: $(MMTK_JULIA_SRC_FILE) extract-mmtk_julia: $(BUILDDIR)/$(MMTK_JULIA_SRC_DIR)/source-extracted configure-mmtk_julia: extract-mmtk_julia compile-mmtk_julia: $(BUILDROOT)/usr/lib/libmmtk_julia.so From b23f557e80cabac1624fc98abacfba152156ef8f Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Tue, 14 Jan 2025 16:28:34 +0100 Subject: [PATCH 178/198] Revert "Avoid allocations in views of views (#53231)" (#57044) This reverts commit 2bd4cf8090f2c651543f562a4c469d73e4b15bd6. (#53231) The reason for this revert is that it caused exponential blowup of types in iterated views causing some packages to simply freeze when doing something that worked ok in 1.10. In my opinion, the perf gain from the PR is not outweighed by the "risk" of hitting this compilation blowup case. Fixes https://github.com/JuliaLang/julia/issues/56760. Co-authored-by: KristofferC --- base/subarray.jl | 6 +++--- test/subarray.jl | 25 ------------------------- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/base/subarray.jl b/base/subarray.jl index d6ddf7786f7ec..eacaddc068f1f 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -291,18 +291,18 @@ reindex(idxs::Tuple{Slice, Vararg{Any}}, subidxs::Tuple{Any, Vararg{Any}}) = # Re-index into parent vectors with one subindex reindex(idxs::Tuple{AbstractVector, Vararg{Any}}, subidxs::Tuple{Any, Vararg{Any}}) = - (@_propagate_inbounds_meta; (maybeview(idxs[1], subidxs[1]), reindex(tail(idxs), tail(subidxs))...)) + (@_propagate_inbounds_meta; (idxs[1][subidxs[1]], reindex(tail(idxs), tail(subidxs))...)) # Parent matrices are re-indexed with two sub-indices reindex(idxs::Tuple{AbstractMatrix, Vararg{Any}}, subidxs::Tuple{Any, Any, Vararg{Any}}) = - (@_propagate_inbounds_meta; (maybeview(idxs[1], subidxs[1], subidxs[2]), reindex(tail(idxs), tail(tail(subidxs)))...)) + (@_propagate_inbounds_meta; (idxs[1][subidxs[1], subidxs[2]], reindex(tail(idxs), tail(tail(subidxs)))...)) # In general, we index N-dimensional parent arrays with N indices @generated function reindex(idxs::Tuple{AbstractArray{T,N}, Vararg{Any}}, subidxs::Tuple{Vararg{Any}}) where {T,N} if length(subidxs.parameters) >= N subs = [:(subidxs[$d]) for d in 1:N] tail = [:(subidxs[$d]) for d in N+1:length(subidxs.parameters)] - :(@_propagate_inbounds_meta; (maybeview(idxs[1], $(subs...)), reindex(tail(idxs), ($(tail...),))...)) + :(@_propagate_inbounds_meta; (idxs[1][$(subs...)], reindex(tail(idxs), ($(tail...),))...)) else :(throw(ArgumentError("cannot re-index SubArray with fewer indices than dimensions\nThis should not occur; please submit a bug report."))) end diff --git a/test/subarray.jl b/test/subarray.jl index 818365730f079..a462224e7643a 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -1027,31 +1027,6 @@ catch err err isa ErrorException && startswith(err.msg, "syntax:") end - -@testset "avoid allocating in reindex" begin - a = reshape(1:16, 4, 4) - inds = ([2,3], [3,4]) - av = view(a, inds...) - av2 = view(av, 1, 1) - @test parentindices(av2) === (2,3) - av2 = view(av, 2:2, 2:2) - @test parentindices(av2) === (view(inds[1], 2:2), view(inds[2], 2:2)) - - inds = (reshape([eachindex(a);], size(a)),) - av = view(a, inds...) - av2 = view(av, 1, 1) - @test parentindices(av2) === (1,) - av2 = view(av, 2:2, 2:2) - @test parentindices(av2) === (view(inds[1], 2:2, 2:2),) - - inds = (reshape([eachindex(a);], size(a)..., 1),) - av = view(a, inds...) - av2 = view(av, 1, 1, 1) - @test parentindices(av2) === (1,) - av2 = view(av, 2:2, 2:2, 1:1) - @test parentindices(av2) === (view(inds[1], 2:2, 2:2, 1:1),) -end - @testset "isassigned" begin a = Vector{BigFloat}(undef, 5) a[2] = 0 From 1b0fba7ffd455d919f1c4f6bb8f31d7c4fae0cc0 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 14 Jan 2025 10:31:17 -0500 Subject: [PATCH 179/198] debuginfo: fix GC error in OC debuginfo (#57036) Also add some extra annotations that seemed to be required locally, though unrelated to the primary change. Observed on CI: https://buildkite.com/julialang/julia-master/builds/43693#01946057-7150-4741-a756-79e7d59a7717 Fixes #57042 --- src/aotcompile.cpp | 112 +++++++++++++++++++++++---------------------- src/debuginfo.cpp | 8 +++- src/jitlayers.cpp | 2 +- src/jitlayers.h | 11 +++-- 4 files changed, 72 insertions(+), 61 deletions(-) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index b839ced8336da..0235758979cd1 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -2209,65 +2209,67 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, jl_ if (src && jl_is_code_info(src)) { auto ctx = jl_ExecutionEngine->makeContext(); orc::ThreadSafeModule m = jl_create_ts_module(name_from_method_instance(mi), ctx); - uint64_t compiler_start_time = 0; - uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); - if (measure_compile_time_enabled) - compiler_start_time = jl_hrtime(); - auto target_info = m.withModuleDo([&](Module &M) { - return std::make_pair(M.getDataLayout(), Triple(M.getTargetTriple())); - }); - jl_codegen_params_t output(ctx, std::move(target_info.first), std::move(target_info.second)); - output.params = ¶ms; - output.imaging_mode = jl_options.image_codegen; - output.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0); - JL_GC_PUSH1(&output.temporary_roots); - auto decls = jl_emit_code(m, mi, src, NULL, output); - output.temporary_roots = nullptr; - JL_GC_POP(); // GC the global_targets array contents now since reflection doesn't need it - - Function *F = NULL; - if (m) { - // if compilation succeeded, prepare to return the result - // Similar to jl_link_global from jitlayers.cpp, - // so that code_llvm shows similar codegen to the jit - for (auto &global : output.global_targets) { - if (jl_options.image_codegen) { - global.second->setLinkage(GlobalValue::ExternalLinkage); + Function *F = nullptr; + { + uint64_t compiler_start_time = 0; + uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); + if (measure_compile_time_enabled) + compiler_start_time = jl_hrtime(); + auto target_info = m.withModuleDo([&](Module &M) { + return std::make_pair(M.getDataLayout(), Triple(M.getTargetTriple())); + }); + jl_codegen_params_t output(ctx, std::move(target_info.first), std::move(target_info.second)); + output.params = ¶ms; + output.imaging_mode = jl_options.image_codegen; + output.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0); + JL_GC_PUSH1(&output.temporary_roots); + auto decls = jl_emit_code(m, mi, src, NULL, output); + output.temporary_roots = nullptr; + JL_GC_POP(); // GC the global_targets array contents now since reflection doesn't need it + + if (m) { + // if compilation succeeded, prepare to return the result + // Similar to jl_link_global from jitlayers.cpp, + // so that code_llvm shows similar codegen to the jit + for (auto &global : output.global_targets) { + if (jl_options.image_codegen) { + global.second->setLinkage(GlobalValue::ExternalLinkage); + } + else { + auto p = literal_static_pointer_val(global.first, global.second->getValueType()); + Type *elty = PointerType::get(output.getContext(), 0); + // For pretty printing, when LLVM inlines the global initializer into its loads + auto alias = GlobalAlias::create(elty, 0, GlobalValue::PrivateLinkage, global.second->getName() + ".jit", p, global.second->getParent()); + global.second->setInitializer(ConstantExpr::getBitCast(alias, global.second->getValueType())); + global.second->setConstant(true); + global.second->setLinkage(GlobalValue::PrivateLinkage); + global.second->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); + global.second->setVisibility(GlobalValue::DefaultVisibility); + } } - else { - auto p = literal_static_pointer_val(global.first, global.second->getValueType()); - Type *elty = PointerType::get(output.getContext(), 0); - // For pretty printing, when LLVM inlines the global initializer into its loads - auto alias = GlobalAlias::create(elty, 0, GlobalValue::PrivateLinkage, global.second->getName() + ".jit", p, global.second->getParent()); - global.second->setInitializer(ConstantExpr::getBitCast(alias, global.second->getValueType())); - global.second->setConstant(true); - global.second->setLinkage(GlobalValue::PrivateLinkage); - global.second->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); - global.second->setVisibility(GlobalValue::DefaultVisibility); + if (!jl_options.image_codegen) { + optimizeDLSyms(*m.getModuleUnlocked()); } - } - if (!jl_options.image_codegen) { - optimizeDLSyms(*m.getModuleUnlocked()); - } - assert(!verifyLLVMIR(*m.getModuleUnlocked())); - if (optimize) { - NewPM PM{jl_ExecutionEngine->cloneTargetMachine(), getOptLevel(jl_options.opt_level)}; - //Safe b/c context lock is held by output - PM.run(*m.getModuleUnlocked()); assert(!verifyLLVMIR(*m.getModuleUnlocked())); + if (optimize) { + NewPM PM{jl_ExecutionEngine->cloneTargetMachine(), getOptLevel(jl_options.opt_level)}; + //Safe b/c context lock is held by output + PM.run(*m.getModuleUnlocked()); + assert(!verifyLLVMIR(*m.getModuleUnlocked())); + } + const std::string *fname; + if (decls.functionObject == "jl_fptr_args" || decls.functionObject == "jl_fptr_sparam") + getwrapper = false; + if (!getwrapper) + fname = &decls.specFunctionObject; + else + fname = &decls.functionObject; + F = cast(m.getModuleUnlocked()->getNamedValue(*fname)); + } + if (measure_compile_time_enabled) { + auto end = jl_hrtime(); + jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, end - compiler_start_time); } - const std::string *fname; - if (decls.functionObject == "jl_fptr_args" || decls.functionObject == "jl_fptr_sparam") - getwrapper = false; - if (!getwrapper) - fname = &decls.specFunctionObject; - else - fname = &decls.functionObject; - F = cast(m.getModuleUnlocked()->getNamedValue(*fname)); - } - if (measure_compile_time_enabled) { - auto end = jl_hrtime(); - jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, end - compiler_start_time); } if (F) { dump->TSM = wrap(new orc::ThreadSafeModule(std::move(m))); diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index c16fb559a6516..17e093cecb89a 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -162,14 +162,18 @@ static void jl_profile_atomic(T f) JL_NOTSAFEPOINT // --- storing and accessing source location metadata --- -void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const DataLayout &DL) +void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const DataLayout &DL) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER { // Non-opaque-closure MethodInstances are considered globally rooted // through their methods, but for OC, we need to create a global root // here. jl_method_instance_t *mi = jl_get_ci_mi(codeinst); - if (jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure) + if (jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure) { + jl_task_t *ct = jl_current_task; + int8_t gc_state = jl_gc_unsafe_enter(ct->ptls); jl_as_global_root((jl_value_t*)mi, 1); + jl_gc_unsafe_leave(ct->ptls, gc_state); + } getJITDebugRegistry().add_code_in_flight(name, codeinst, DL); } diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 396a42505188a..0acb7beaca9ab 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -699,7 +699,7 @@ static void jl_compile_codeinst_now(jl_code_instance_t *codeinst) } } -void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const DataLayout &DL); +void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const DataLayout &DL) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER; extern "C" JL_DLLEXPORT_CODEGEN void jl_emit_codeinst_to_jit_impl( diff --git a/src/jitlayers.h b/src/jitlayers.h index b41f2e38bc470..7198c9b2f0210 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -178,10 +178,15 @@ struct jl_locked_stream { } }; -typedef struct _jl_llvm_functions_t { +struct jl_llvm_functions_t { std::string functionObject; // jlcall llvm Function name std::string specFunctionObject; // specialized llvm Function name -} jl_llvm_functions_t; + jl_llvm_functions_t() JL_NOTSAFEPOINT = default; + jl_llvm_functions_t &operator=(const jl_llvm_functions_t&) JL_NOTSAFEPOINT = default; + jl_llvm_functions_t(const jl_llvm_functions_t &) JL_NOTSAFEPOINT = default; + jl_llvm_functions_t(jl_llvm_functions_t &&) JL_NOTSAFEPOINT = default; + ~jl_llvm_functions_t() JL_NOTSAFEPOINT = default; +}; struct jl_returninfo_t { llvm::FunctionCallee decl; @@ -642,7 +647,7 @@ Module &jl_codegen_params_t::shared_module() JL_NOTSAFEPOINT { } void fixupTM(TargetMachine &TM) JL_NOTSAFEPOINT; -void optimizeDLSyms(Module &M); +void optimizeDLSyms(Module &M) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER; // NewPM #include "passes.h" From 1f05953fab1e14e1e881a224d8719d2c7d637da3 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 14 Jan 2025 10:33:09 -0500 Subject: [PATCH 180/198] linux: workaround to avoid deadlock inside dl_iterate_phdr in glibc (#57035) Extend the fix for #43578 on Darwin to also cover the same bug in Glibc (and just assume other libc have the same bug). We cannot use the same atfork trick, since the atfork implementation of this in Glibc makes this unsafe to use this after fork, just like Darwin (though for different basic concurrency mistakes in each of their respective codes). Fix #57017 --- src/julia_internal.h | 3 +- src/signals-mach.c | 9 +-- src/signals-unix.c | 186 +++++++++++++++++++++++-------------------- src/signals-win.c | 19 +++-- src/stackwalk.c | 18 ++++- 5 files changed, 130 insertions(+), 105 deletions(-) diff --git a/src/julia_internal.h b/src/julia_internal.h index 81e9ebb537667..a464025edf856 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -208,8 +208,7 @@ JL_DLLEXPORT void jl_lock_profile(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_ENTER; JL_DLLEXPORT void jl_unlock_profile(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE; JL_DLLEXPORT void jl_lock_profile_wr(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_ENTER; JL_DLLEXPORT void jl_unlock_profile_wr(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE; -int jl_lock_stackwalk(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_ENTER; -void jl_unlock_stackwalk(int lockret) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE; +void jl_with_stackwalk_lock(void (*f)(void*) JL_NOTSAFEPOINT, void *ctx) JL_NOTSAFEPOINT; arraylist_t *jl_get_all_tasks_arraylist(void) JL_NOTSAFEPOINT; typedef struct { diff --git a/src/signals-mach.c b/src/signals-mach.c index 24508a8902d5e..1c4af2cf9d033 100644 --- a/src/signals-mach.c +++ b/src/signals-mach.c @@ -714,13 +714,10 @@ static void jl_unlock_profile_mach(int dlsymlock, int keymgr_locked) jl_unlock_profile(); } -int jl_lock_stackwalk(void) -{ - return jl_lock_profile_mach(1); -} - -void jl_unlock_stackwalk(int lockret) +void jl_with_stackwalk_lock(void (*f)(void*), void *ctx) { + int lockret = jl_lock_profile_mach(1); + f(ctx); jl_unlock_profile_mach(1, lockret); } diff --git a/src/signals-unix.c b/src/signals-unix.c index 394c4a108b647..91d3378068f84 100644 --- a/src/signals-unix.c +++ b/src/signals-unix.c @@ -308,20 +308,27 @@ int exc_reg_is_write_fault(uintptr_t esr) { #else #include #include +#include -int jl_lock_stackwalk(void) +typedef struct { + void (*f)(void*) JL_NOTSAFEPOINT; + void *ctx; +} callback_t; +static int with_dl_iterate_phdr_lock(struct dl_phdr_info *info, size_t size, void *data) { jl_lock_profile(); - return 0; + callback_t *callback = (callback_t*)data; + callback->f(callback->ctx); + jl_unlock_profile(); + return 1; // only call this once } -void jl_unlock_stackwalk(int lockret) +void jl_with_stackwalk_lock(void (*f)(void*), void *ctx) { - (void)lockret; - jl_unlock_profile(); + callback_t callback = {f, ctx}; + dl_iterate_phdr(with_dl_iterate_phdr_lock, &callback); } - #if defined(_OS_LINUX_) && (defined(_CPU_X86_64_) || defined(_CPU_X86_)) int is_write_fault(void *context) { ucontext_t *ctx = (ucontext_t*)context; @@ -435,7 +442,7 @@ JL_NO_ASAN static void segv_handler(int sig, siginfo_t *info, void *context) } pthread_mutex_t in_signal_lock; // shared with jl_delete_thread -static bt_context_t *signal_context; // protected by in_signal_lock +static bt_context_t *usr2_signal_context; // protected by in_signal_lock static int exit_signal_cond = -1; static int signal_caught_cond = -1; static int signals_inflight = 0; @@ -507,7 +514,7 @@ int jl_thread_suspend_and_get_state(int tid, int timeout, bt_context_t *ctx) request = jl_atomic_load_acquire(&ptls2->signal_request); assert(request == 0 || request == -1); (void) request; jl_atomic_store_release(&ptls2->signal_request, 4); // prepare to resume normally, but later code may change this - *ctx = *signal_context; + *ctx = *usr2_signal_context; return 1; } @@ -587,8 +594,8 @@ void usr2_handler(int sig, siginfo_t *info, void *ctx) if (!jl_atomic_cmpswap(&ptls->signal_request, &request, -1)) return; if (request == 1) { - signal_context = jl_to_bt_context(ctx); - // acknowledge that we saw the signal_request and set signal_context + usr2_signal_context = jl_to_bt_context(ctx); + // acknowledge that we saw the signal_request and set usr2_signal_context int err; eventfd_t got = 1; err = write(signal_caught_cond, &got, sizeof(eventfd_t)); @@ -602,7 +609,7 @@ void usr2_handler(int sig, siginfo_t *info, void *ctx) if (err != sizeof(eventfd_t)) abort(); assert(got == 1); request = jl_atomic_exchange(&ptls->signal_request, -1); - signal_context = NULL; + usr2_signal_context = NULL; assert(request == 2 || request == 3 || request == 4); } int err; @@ -806,7 +813,7 @@ void trigger_profile_peek(void) jl_safe_printf("\n======================================================================================\n"); jl_safe_printf("Information request received. A stacktrace will print followed by a %.1f second profile\n", profile_peek_duration); jl_safe_printf("======================================================================================\n"); - if (profile_bt_size_max == 0){ + if (profile_bt_size_max == 0) { // If the buffer hasn't been initialized, initialize with default size // Keep these values synchronized with Profile.default_init() if (jl_profile_init(10000000, 1000000) == -1) { @@ -821,59 +828,93 @@ void trigger_profile_peek(void) profile_autostop_time = jl_hrtime() + (profile_peek_duration * 1e9); } -// assumes holding `jl_lock_stackwalk` -void jl_profile_thread_unix(int tid, bt_context_t *signal_context) +#if !defined(JL_DISABLE_LIBUNWIND) + +static jl_bt_element_t signal_bt_data[JL_MAX_BT_SIZE + 1]; +static size_t signal_bt_size = 0; +static void do_critical_profile(void *ctx) { - if (jl_profile_is_buffer_full()) { - // Buffer full: Delete the timer - jl_profile_stop_timer(); - return; - } - // notify thread to stop - if (!jl_thread_suspend_and_get_state(tid, 1, signal_context)) - return; - // unwinding can fail, so keep track of the current state - // and restore from the SEGV handler if anything happens. - jl_jmp_buf *old_buf = jl_get_safe_restore(); - jl_jmp_buf buf; - - jl_set_safe_restore(&buf); - if (jl_setjmp(buf, 0)) { - jl_safe_printf("WARNING: profiler attempt to access an invalid memory location\n"); - } else { - // Get backtrace data - profile_bt_size_cur += rec_backtrace_ctx((jl_bt_element_t*)profile_bt_data_prof + profile_bt_size_cur, - profile_bt_size_max - profile_bt_size_cur - 1, signal_context, NULL); + bt_context_t signal_context; + // sample each thread, round-robin style in reverse order + // (so that thread zero gets notified last) + int nthreads = jl_atomic_load_acquire(&jl_n_threads); + for (int i = nthreads; i-- > 0; ) { + // notify thread to stop + if (!jl_thread_suspend_and_get_state(i, 1, &signal_context)) + continue; + + // do backtrace on thread contexts for critical signals + // this part must be signal-handler safe + signal_bt_size += rec_backtrace_ctx(signal_bt_data + signal_bt_size, + JL_MAX_BT_SIZE / nthreads - 1, + &signal_context, NULL); + signal_bt_data[signal_bt_size++].uintptr = 0; + jl_thread_resume(i); } - jl_set_safe_restore(old_buf); +} - jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[tid]; +static void do_profile(void *ctx) +{ + bt_context_t signal_context; + int nthreads = jl_atomic_load_acquire(&jl_n_threads); + int *randperm = profile_get_randperm(nthreads); + for (int idx = nthreads; idx-- > 0; ) { + // Stop the threads in the random order. + int tid = randperm[idx]; + // do backtrace for profiler + if (!profile_running) + return; + if (jl_profile_is_buffer_full()) { + // Buffer full: Delete the timer + jl_profile_stop_timer(); + return; + } + // notify thread to stop + if (!jl_thread_suspend_and_get_state(tid, 1, &signal_context)) + return; + // unwinding can fail, so keep track of the current state + // and restore from the SEGV handler if anything happens. + jl_jmp_buf *old_buf = jl_get_safe_restore(); + jl_jmp_buf buf; + + jl_set_safe_restore(&buf); + if (jl_setjmp(buf, 0)) { + jl_safe_printf("WARNING: profiler attempt to access an invalid memory location\n"); + } + else { + // Get backtrace data + profile_bt_size_cur += rec_backtrace_ctx((jl_bt_element_t*)profile_bt_data_prof + profile_bt_size_cur, + profile_bt_size_max - profile_bt_size_cur - 1, &signal_context, NULL); + } + jl_set_safe_restore(old_buf); - // store threadid but add 1 as 0 is preserved to indicate end of block - profile_bt_data_prof[profile_bt_size_cur++].uintptr = ptls2->tid + 1; + jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[tid]; - // store task id (never null) - profile_bt_data_prof[profile_bt_size_cur++].jlvalue = (jl_value_t*)jl_atomic_load_relaxed(&ptls2->current_task); + // store threadid but add 1 as 0 is preserved to indicate end of block + profile_bt_data_prof[profile_bt_size_cur++].uintptr = ptls2->tid + 1; - // store cpu cycle clock - profile_bt_data_prof[profile_bt_size_cur++].uintptr = cycleclock(); + // store task id (never null) + profile_bt_data_prof[profile_bt_size_cur++].jlvalue = (jl_value_t*)jl_atomic_load_relaxed(&ptls2->current_task); - // store whether thread is sleeping (don't ever encode a state as `0` since is preserved to indicate end of block) - int state = jl_atomic_load_relaxed(&ptls2->sleep_check_state) == 0 ? PROFILE_STATE_THREAD_NOT_SLEEPING : PROFILE_STATE_THREAD_SLEEPING; - profile_bt_data_prof[profile_bt_size_cur++].uintptr = state; + // store cpu cycle clock + profile_bt_data_prof[profile_bt_size_cur++].uintptr = cycleclock(); - // Mark the end of this block with two 0's - profile_bt_data_prof[profile_bt_size_cur++].uintptr = 0; - profile_bt_data_prof[profile_bt_size_cur++].uintptr = 0; + // store whether thread is sleeping (don't ever encode a state as `0` since is preserved to indicate end of block) + int state = jl_atomic_load_relaxed(&ptls2->sleep_check_state) == 0 ? PROFILE_STATE_THREAD_NOT_SLEEPING : PROFILE_STATE_THREAD_SLEEPING; + profile_bt_data_prof[profile_bt_size_cur++].uintptr = state; - // notify thread to resume - jl_thread_resume(tid); + // Mark the end of this block with two 0's + profile_bt_data_prof[profile_bt_size_cur++].uintptr = 0; + profile_bt_data_prof[profile_bt_size_cur++].uintptr = 0; + + // notify thread to resume + jl_thread_resume(tid); + } } +#endif static void *signal_listener(void *arg) { - static jl_bt_element_t bt_data[JL_MAX_BT_SIZE + 1]; - static size_t bt_size = 0; sigset_t sset; int sig, critical, profile; jl_sigsetset(&sset); @@ -1005,28 +1046,10 @@ static void *signal_listener(void *arg) } } - int nthreads = jl_atomic_load_acquire(&jl_n_threads); - bt_size = 0; + signal_bt_size = 0; #if !defined(JL_DISABLE_LIBUNWIND) - bt_context_t signal_context; if (critical) { - int lockret = jl_lock_stackwalk(); - // sample each thread, round-robin style in reverse order - // (so that thread zero gets notified last) - for (int i = nthreads; i-- > 0; ) { - // notify thread to stop - if (!jl_thread_suspend_and_get_state(i, 1, &signal_context)) - continue; - - // do backtrace on thread contexts for critical signals - // this part must be signal-handler safe - bt_size += rec_backtrace_ctx(bt_data + bt_size, - JL_MAX_BT_SIZE / nthreads - 1, - &signal_context, NULL); - bt_data[bt_size++].uintptr = 0; - jl_thread_resume(i); - } - jl_unlock_stackwalk(lockret); + jl_with_stackwalk_lock(do_critical_profile, NULL); } else if (profile) { if (profile_all_tasks) { @@ -1034,17 +1057,7 @@ static void *signal_listener(void *arg) jl_profile_task(); } else { - int lockret = jl_lock_stackwalk(); - int *randperm = profile_get_randperm(nthreads); - for (int idx = nthreads; idx-- > 0; ) { - // Stop the threads in the random order. - int i = randperm[idx]; - // do backtrace for profiler - if (profile_running) { - jl_profile_thread_unix(i, &signal_context); - } - } - jl_unlock_stackwalk(lockret); + jl_with_stackwalk_lock(do_profile, NULL); } } #ifndef HAVE_MACH @@ -1065,11 +1078,12 @@ static void *signal_listener(void *arg) //#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L && !HAVE_KEVENT // si_code = info.si_code; //#endif - jl_exit_thread0(sig, bt_data, bt_size); + jl_exit_thread0(sig, signal_bt_data, signal_bt_size); } else if (critical) { // critical in this case actually means SIGINFO request #ifndef SIGINFO // SIGINFO already prints something similar automatically + int nthreads = jl_atomic_load_acquire(&jl_n_threads); int n_threads_running = 0; for (int idx = nthreads; idx-- > 0; ) { jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[idx]; @@ -1080,8 +1094,8 @@ static void *signal_listener(void *arg) jl_safe_printf("\nsignal (%d): %s\n", sig, strsignal(sig)); size_t i; - for (i = 0; i < bt_size; i += jl_bt_entry_size(bt_data + i)) { - jl_print_bt_entry_codeloc(bt_data + i); + for (i = 0; i < signal_bt_size; i += jl_bt_entry_size(signal_bt_data + i)) { + jl_print_bt_entry_codeloc(signal_bt_data + i); } } } diff --git a/src/signals-win.c b/src/signals-win.c index dbf95fdb19791..c8ae74f52dba4 100644 --- a/src/signals-win.c +++ b/src/signals-win.c @@ -383,20 +383,25 @@ void jl_thread_resume(int tid) } } -int jl_lock_stackwalk(void) +void jl_lock_stackwalk(void) { uv_mutex_lock(&jl_in_stackwalk); jl_lock_profile(); - return 0; } -void jl_unlock_stackwalk(int lockret) +void jl_unlock_stackwalk(void) { - (void)lockret; jl_unlock_profile(); uv_mutex_unlock(&jl_in_stackwalk); } +void jl_with_stackwalk_lock(void (*f)(void*), void *ctx) +{ + jl_lock_stackwalk(); + f(ctx); + jl_unlock_stackwalk(); +} + static DWORD WINAPI profile_bt( LPVOID lparam ) { @@ -416,10 +421,10 @@ static DWORD WINAPI profile_bt( LPVOID lparam ) } else { // TODO: bring this up to parity with other OS by adding loop over tid here - int lockret = jl_lock_stackwalk(); + jl_lock_stackwalk(); CONTEXT ctxThread; if (!jl_thread_suspend_and_get_state(0, 0, &ctxThread)) { - jl_unlock_stackwalk(lockret); + jl_unlock_stackwalk(); fputs("failed to suspend main thread. aborting profiling.", stderr); jl_profile_stop_timer(); break; @@ -446,7 +451,7 @@ static DWORD WINAPI profile_bt( LPVOID lparam ) // Mark the end of this block with two 0's profile_bt_data_prof[profile_bt_size_cur++].uintptr = 0; profile_bt_data_prof[profile_bt_size_cur++].uintptr = 0; - jl_unlock_stackwalk(lockret); + jl_unlock_stackwalk(); jl_thread_resume(0); jl_check_profile_autostop(); } diff --git a/src/stackwalk.c b/src/stackwalk.c index 28adef030395e..f1d807908cf42 100644 --- a/src/stackwalk.c +++ b/src/stackwalk.c @@ -1249,6 +1249,17 @@ return 0; #endif } +typedef struct { + int16_t old; + bt_context_t *c; + int success; +} suspend_t; +static void suspend(void *ctx) +{ + suspend_t *suspenddata = (suspend_t*)ctx; + suspenddata->success = jl_thread_suspend_and_get_state(suspenddata->old, 1, suspenddata->c); +} + JL_DLLEXPORT jl_record_backtrace_result_t jl_record_backtrace(jl_task_t *t, jl_bt_element_t *bt_data, size_t max_bt_size, int all_tasks_profiler) JL_NOTSAFEPOINT { int16_t tid = INT16_MAX; @@ -1270,15 +1281,14 @@ JL_DLLEXPORT jl_record_backtrace_result_t jl_record_backtrace(jl_task_t *t, jl_b bt_context_t c; int16_t old; for (old = -1; !jl_atomic_cmpswap(&t->tid, &old, tid) && old != tid; old = -1) { - int lockret = jl_lock_stackwalk(); // if this task is already running somewhere, we need to stop the thread it is running on and query its state - if (!jl_thread_suspend_and_get_state(old, 1, &c)) { - jl_unlock_stackwalk(lockret); + suspend_t suspenddata = {old, &c}; + jl_with_stackwalk_lock(suspend, &suspenddata); + if (!suspenddata.success) { if (jl_atomic_load_relaxed(&t->tid) != old) continue; return result; } - jl_unlock_stackwalk(lockret); if (jl_atomic_load_relaxed(&t->tid) == old) { jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[old]; if (ptls2->previous_task == t || // we might print the wrong stack here, since we can't know whether we executed the swapcontext yet or not, but it at least avoids trying to access the state inside uc_mcontext which might not be set yet From 723c3e603c8b19e471b2f773047c9432471f0e68 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Wed, 15 Jan 2025 03:52:45 +0900 Subject: [PATCH 181/198] improve pcre.jl code a bit (#57031) - `PCRE._mth()` now uses `Base._maxthreadid` instead of manual inlining of `Threads.maxthreadid()` - `PCRE_COMPILE_LOCK` is now typed global --- base/Base.jl | 12 ++++++------ base/pcre.jl | 8 ++++---- base/regex.jl | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/base/Base.jl b/base/Base.jl index 1f737452fa17a..9119b3a482242 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -91,6 +91,12 @@ include("osutils.jl") include("io.jl") include("iobuffer.jl") +# Concurrency (part 1) +include("linked_list.jl") +include("condition.jl") +include("threads.jl") +include("lock.jl") + # strings & printing include("intfuncs.jl") include("strings/strings.jl") @@ -117,12 +123,6 @@ include("missing.jl") # version include("version.jl") -# Concurrency (part 1) -include("linked_list.jl") -include("condition.jl") -include("threads.jl") -include("lock.jl") - # system & environment include("sysinfo.jl") include("libc.jl") diff --git a/base/pcre.jl b/base/pcre.jl index b357bbc8f3bf9..e4567fe03e8f8 100644 --- a/base/pcre.jl +++ b/base/pcre.jl @@ -24,19 +24,19 @@ function create_match_context() return ctx end -THREAD_MATCH_CONTEXTS::Vector{Ptr{Cvoid}} = [C_NULL] +global THREAD_MATCH_CONTEXTS::Vector{Ptr{Cvoid}} = [C_NULL] -PCRE_COMPILE_LOCK = nothing +global PCRE_COMPILE_LOCK::Threads.SpinLock _tid() = Int(ccall(:jl_threadid, Int16, ())) + 1 -_mth() = Int(Core.Intrinsics.atomic_pointerref(cglobal(:jl_n_threads, Cint), :acquire)) +_mth() = Threads.maxthreadid() function get_local_match_context() tid = _tid() ctxs = THREAD_MATCH_CONTEXTS if length(ctxs) < tid # slow path to allocate it - l = PCRE_COMPILE_LOCK::Threads.SpinLock + l = PCRE_COMPILE_LOCK lock(l) try ctxs = THREAD_MATCH_CONTEXTS diff --git a/base/regex.jl b/base/regex.jl index 9444c9a9fb63e..09922b8a25111 100644 --- a/base/regex.jl +++ b/base/regex.jl @@ -69,11 +69,11 @@ Regex(pattern::AbstractString) = Regex(pattern, DEFAULT_COMPILER_OPTS, DEFAULT_M function compile(regex::Regex) if regex.regex == C_NULL - if PCRE.PCRE_COMPILE_LOCK === nothing + if !isdefinedglobal(PCRE, :PCRE_COMPILE_LOCK) regex.regex = PCRE.compile(regex.pattern, regex.compile_options) PCRE.jit_compile(regex.regex) else - l = PCRE.PCRE_COMPILE_LOCK::Threads.SpinLock + l = PCRE.PCRE_COMPILE_LOCK lock(l) try if regex.regex == C_NULL From 2cc296c8fd3cba6b7caa872d5fb13c947b190780 Mon Sep 17 00:00:00 2001 From: Erik Schnetter Date: Tue, 14 Jan 2025 17:13:24 -0500 Subject: [PATCH 182/198] MozillaCACerts_jll: Update to 2024.12.31 (#57039) --- deps/checksums/cacert-2024-11-26.pem/md5 | 1 - deps/checksums/cacert-2024-11-26.pem/sha512 | 1 - deps/checksums/cacert-2024-12-31.pem/md5 | 1 + deps/checksums/cacert-2024-12-31.pem/sha512 | 1 + deps/libgit2.version | 2 +- stdlib/MozillaCACerts_jll/Project.toml | 2 +- 6 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 deps/checksums/cacert-2024-11-26.pem/md5 delete mode 100644 deps/checksums/cacert-2024-11-26.pem/sha512 create mode 100644 deps/checksums/cacert-2024-12-31.pem/md5 create mode 100644 deps/checksums/cacert-2024-12-31.pem/sha512 diff --git a/deps/checksums/cacert-2024-11-26.pem/md5 b/deps/checksums/cacert-2024-11-26.pem/md5 deleted file mode 100644 index 865c6abf3e77a..0000000000000 --- a/deps/checksums/cacert-2024-11-26.pem/md5 +++ /dev/null @@ -1 +0,0 @@ -92c13373d7dbe43bdc167479274a43e2 diff --git a/deps/checksums/cacert-2024-11-26.pem/sha512 b/deps/checksums/cacert-2024-11-26.pem/sha512 deleted file mode 100644 index d51605348faf4..0000000000000 --- a/deps/checksums/cacert-2024-11-26.pem/sha512 +++ /dev/null @@ -1 +0,0 @@ -26c6fa1ac7bcfd523f9ab9e6c2d971103ccfc610ad0df504d4e9b064dad74576d77240c052b808f4c37c9240302a7e973a20f79ee39ac7bf3201a6fa9f0dfa96 diff --git a/deps/checksums/cacert-2024-12-31.pem/md5 b/deps/checksums/cacert-2024-12-31.pem/md5 new file mode 100644 index 0000000000000..b01bf68ddc247 --- /dev/null +++ b/deps/checksums/cacert-2024-12-31.pem/md5 @@ -0,0 +1 @@ +d9178b626f8b87f51b47987418d012bf diff --git a/deps/checksums/cacert-2024-12-31.pem/sha512 b/deps/checksums/cacert-2024-12-31.pem/sha512 new file mode 100644 index 0000000000000..c12b8215a7855 --- /dev/null +++ b/deps/checksums/cacert-2024-12-31.pem/sha512 @@ -0,0 +1 @@ +bf578937d7826106bae1ebe74a70bfbc439387445a1f41ef57430de9d9aea6fcfa1884381bf0ef14632f6b89e9543642c9b774fcca93837efffdc557c4958dbd diff --git a/deps/libgit2.version b/deps/libgit2.version index 57744b6c96d8e..6bfb6106e67d2 100644 --- a/deps/libgit2.version +++ b/deps/libgit2.version @@ -11,4 +11,4 @@ LIBGIT2_SHA1=338e6fb681369ff0537719095e22ce9dc602dbf0 # The versions of cacert.pem are identified by the date (YYYY-MM-DD) of their changes. # See https://curl.haxx.se/docs/caextract.html for more details. # Keep in sync with `stdlib/MozillaCACerts_jll/Project.toml`. -MOZILLA_CACERT_VERSION := 2024-11-26 +MOZILLA_CACERT_VERSION := 2024-12-31 diff --git a/stdlib/MozillaCACerts_jll/Project.toml b/stdlib/MozillaCACerts_jll/Project.toml index 5df9bd5949972..2f9bf67e22a74 100644 --- a/stdlib/MozillaCACerts_jll/Project.toml +++ b/stdlib/MozillaCACerts_jll/Project.toml @@ -1,7 +1,7 @@ name = "MozillaCACerts_jll" uuid = "14a3606d-f60d-562e-9121-12d972cd8159" # Keep in sync with `deps/libgit2.version`. -version = "2024.11.26" +version = "2024.12.31" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" From ef0405584dd3280f8e23906d9eef8f8799a236f9 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:13:44 +0900 Subject: [PATCH 183/198] aot: move `jl_insert_backedges` to Julia side (#56499) With JuliaLang/julia#56447, the dependency between `jl_insert_backedges` and method insertion has been eliminated, allowing `jl_insert_backedges` to be performed after loading. As a result, it is now possible to move `jl_insert_backedges` to the Julia side. Currently this commit simply moves the implementation without adding any new features. --------- Co-authored-by: Jameson Nash --- Compiler/src/typeinfer.jl | 5 +- base/Base.jl | 1 + base/loading.jl | 17 +- base/staticdata.jl | 296 +++++++++++++++++++++++++++++++ src/staticdata.c | 14 +- src/staticdata_utils.c | 362 -------------------------------------- test/precompile.jl | 12 +- 7 files changed, 323 insertions(+), 384 deletions(-) create mode 100644 base/staticdata.jl diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index ec1e62817106d..e3896870d82b8 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -560,12 +560,11 @@ function store_backedges(caller::CodeInstance, edges::SimpleVector) ccall(:jl_method_table_add_backedge, Cvoid, (Any, Any, Any), callee, item, caller) i += 2 continue - end - # `invoke` edge - if isa(callee, Method) + elseif isa(callee, Method) # ignore `Method`-edges (from e.g. failed `abstract_call_method`) i += 2 continue + # `invoke` edge elseif isa(callee, CodeInstance) callee = get_ci_mi(callee) end diff --git a/base/Base.jl b/base/Base.jl index 9119b3a482242..20b1636c29a8d 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -262,6 +262,7 @@ include("uuid.jl") include("pkgid.jl") include("toml_parser.jl") include("linking.jl") +include("staticdata.jl") include("loading.jl") # misc useful functions & macros diff --git a/base/loading.jl b/base/loading.jl index 024c4ceb356fd..4193aae13b96a 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -1280,17 +1280,20 @@ function _include_from_serialized(pkg::PkgId, path::String, ocachepath::Union{No sv = try if ocachepath !== nothing @debug "Loading object cache file $ocachepath for $(repr("text/plain", pkg))" - ccall(:jl_restore_package_image_from_file, Any, (Cstring, Any, Cint, Cstring, Cint), ocachepath, depmods, false, pkg.name, ignore_native) + ccall(:jl_restore_package_image_from_file, Ref{SimpleVector}, (Cstring, Any, Cint, Cstring, Cint), + ocachepath, depmods, #=completeinfo=#false, pkg.name, ignore_native) else @debug "Loading cache file $path for $(repr("text/plain", pkg))" - ccall(:jl_restore_incremental, Any, (Cstring, Any, Cint, Cstring), path, depmods, false, pkg.name) + ccall(:jl_restore_incremental, Ref{SimpleVector}, (Cstring, Any, Cint, Cstring), + path, depmods, #=completeinfo=#false, pkg.name) end finally lock(require_lock) end - if isa(sv, Exception) - return sv - end + + edges = sv[3]::Vector{Any} + ext_edges = sv[4]::Union{Nothing,Vector{Any}} + StaticData.insert_backedges(edges, ext_edges) restored = register_restored_modules(sv, pkg, path) @@ -4198,7 +4201,7 @@ function precompile(@nospecialize(argt::Type)) end # Variants that work for `invoke`d calls for which the signature may not be sufficient -precompile(mi::Core.MethodInstance, world::UInt=get_world_counter()) = +precompile(mi::MethodInstance, world::UInt=get_world_counter()) = (ccall(:jl_compile_method_instance, Cvoid, (Any, Ptr{Cvoid}, UInt), mi, C_NULL, world); return true) """ @@ -4214,7 +4217,7 @@ end function precompile(@nospecialize(argt::Type), m::Method) atype, sparams = ccall(:jl_type_intersection_with_env, Any, (Any, Any), argt, m.sig)::SimpleVector - mi = Core.Compiler.specialize_method(m, atype, sparams) + mi = Base.Compiler.specialize_method(m, atype, sparams) return precompile(mi) end diff --git a/base/staticdata.jl b/base/staticdata.jl new file mode 100644 index 0000000000000..79d81788cc16a --- /dev/null +++ b/base/staticdata.jl @@ -0,0 +1,296 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +module StaticData + +using Core: CodeInstance, MethodInstance +using Base: get_world_counter + +const WORLD_AGE_REVALIDATION_SENTINEL::UInt = 1 +const _jl_debug_method_invalidation = Ref{Union{Nothing,Vector{Any}}}(nothing) +debug_method_invalidation(onoff::Bool) = + _jl_debug_method_invalidation[] = onoff ? Any[] : nothing + +function get_ci_mi(codeinst::CodeInstance) + def = codeinst.def + if def isa Core.ABIOverride + return def.def + else + return def::MethodInstance + end +end + +# Restore backedges to external targets +# `edges` = [caller1, ...], the list of worklist-owned code instances internally +# `ext_ci_list` = [caller1, ...], the list of worklist-owned code instances externally +function insert_backedges(edges::Vector{Any}, ext_ci_list::Union{Nothing,Vector{Any}}) + # determine which CodeInstance objects are still valid in our image + # to enable any applicable new codes + stack = CodeInstance[] + visiting = IdDict{CodeInstance,Int}() + _insert_backedges(edges, stack, visiting) + if ext_ci_list !== nothing + _insert_backedges(ext_ci_list, stack, visiting, #=external=#true) + end +end + +function _insert_backedges(edges::Vector{Any}, stack::Vector{CodeInstance}, visiting::IdDict{CodeInstance,Int}, external::Bool=false) + for i = 1:length(edges) + codeinst = edges[i]::CodeInstance + verify_method_graph(codeinst, stack, visiting) + minvalid = codeinst.min_world + maxvalid = codeinst.max_world + if maxvalid ≥ minvalid + if get_world_counter() == maxvalid + # if this callee is still valid, add all the backedges + Base.Compiler.store_backedges(codeinst, codeinst.edges) + end + if get_world_counter() == maxvalid + maxvalid = typemax(UInt) + @atomic :monotonic codeinst.max_world = maxvalid + end + if external + caller = get_ci_mi(codeinst) + @assert isdefined(codeinst, :inferred) # See #53586, #53109 + inferred = @ccall jl_rettype_inferred( + codeinst.owner::Any, caller::Any, minvalid::UInt, maxvalid::UInt)::Any + if inferred !== nothing + # We already got a code instance for this world age range from + # somewhere else - we don't need this one. + else + @ccall jl_mi_cache_insert(caller::Any, codeinst::Any)::Cvoid + end + end + end + end +end + +function verify_method_graph(codeinst::CodeInstance, stack::Vector{CodeInstance}, visiting::IdDict{CodeInstance,Int}) + @assert isempty(stack); @assert isempty(visiting); + child_cycle, minworld, maxworld = verify_method(codeinst, stack, visiting) + @assert child_cycle == 0 + @assert isempty(stack); @assert isempty(visiting); + nothing +end + +# Test all edges relevant to a method: +# - Visit the entire call graph, starting from edges[idx] to determine if that method is valid +# - Implements Tarjan's SCC (strongly connected components) algorithm, simplified to remove the count variable +# and slightly modified with an early termination option once the computation reaches its minimum +function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visiting::IdDict{CodeInstance,Int}) + world = codeinst.min_world + let max_valid2 = codeinst.max_world + if max_valid2 ≠ WORLD_AGE_REVALIDATION_SENTINEL + return 0, world, max_valid2 + end + end + current_world = get_world_counter() + local minworld::UInt, maxworld::UInt = 1, current_world + @assert get_ci_mi(codeinst).def isa Method + if haskey(visiting, codeinst) + return visiting[codeinst], minworld, maxworld + end + push!(stack, codeinst) + depth = length(stack) + visiting[codeinst] = depth + # TODO JL_TIMING(VERIFY_IMAGE, VERIFY_Methods) + callees = codeinst.edges + # verify current edges + if isempty(callees) + # quick return: no edges to verify (though we probably shouldn't have gotten here from WORLD_AGE_REVALIDATION_SENTINEL) + elseif maxworld == unsafe_load(cglobal(:jl_require_world, UInt)) + # if no new worlds were allocated since serializing the base module, then no new validation is worth doing right now either + minworld = maxworld + else + j = 1 + while j ≤ length(callees) + local min_valid2::UInt, max_valid2::UInt + edge = callees[j] + @assert !(edge isa Method) # `Method`-edge isn't allowed for the optimized one-edge format + if edge isa Core.BindingPartition + j += 1 + continue + end + if edge isa CodeInstance + edge = get_ci_mi(edge) + end + if edge isa MethodInstance + sig = typeintersect((edge.def::Method).sig, edge.specTypes) # TODO?? + min_valid2, max_valid2, matches = verify_call(sig, callees, j, 1, world) + j += 1 + elseif edge isa Int + sig = callees[j+1] + min_valid2, max_valid2, matches = verify_call(sig, callees, j+2, edge, world) + j += 2 + edge + edge = sig + else + callee = callees[j+1] + if callee isa Core.MethodTable # skip the legacy edge (missing backedge) + j += 2 + continue + end + if callee isa CodeInstance + callee = get_ci_mi(callee) + end + if callee isa MethodInstance + meth = callee.def::Method + else + meth = callee::Method + end + min_valid2, max_valid2 = verify_invokesig(edge, meth, world) + matches = nothing + j += 2 + end + if minworld < min_valid2 + minworld = min_valid2 + end + if maxworld > max_valid2 + maxworld = max_valid2 + end + invalidations = _jl_debug_method_invalidation[] + if max_valid2 ≠ typemax(UInt) && invalidations !== nothing + push!(invalidations, edge, "insert_backedges_callee", codeinst, matches) + end + if max_valid2 == 0 && invalidations === nothing + break + end + end + end + # verify recursive edges (if valid, or debugging) + cycle = depth + cause = codeinst + if maxworld ≠ 0 || _jl_debug_method_invalidation[] !== nothing + for j = 1:length(callees) + edge = callees[j] + if !(edge isa CodeInstance) + continue + end + callee = edge + local min_valid2::UInt, max_valid2::UInt + child_cycle, min_valid2, max_valid2 = verify_method(callee, stack, visiting) + if minworld < min_valid2 + minworld = min_valid2 + end + if minworld > max_valid2 + max_valid2 = 0 + end + if maxworld > max_valid2 + cause = callee + maxworld = max_valid2 + end + if max_valid2 == 0 + # found what we were looking for, so terminate early + break + elseif child_cycle ≠ 0 && child_cycle < cycle + # record the cycle will resolve at depth "cycle" + cycle = child_cycle + end + end + end + if maxworld ≠ 0 && cycle ≠ depth + return cycle, minworld, maxworld + end + # If we are the top of the current cycle, now mark all other parts of + # our cycle with what we found. + # Or if we found a failed edge, also mark all of the other parts of the + # cycle as also having a failed edge. + while length(stack) ≥ depth + child = pop!(stack) + if maxworld ≠ 0 + @atomic :monotonic child.min_world = minworld + end + @atomic :monotonic child.max_world = maxworld + @assert visiting[child] == length(stack) + 1 + delete!(visiting, child) + invalidations = _jl_debug_method_invalidation[] + if invalidations !== nothing && maxworld < current_world + push!(invalidations, child, "verify_methods", cause) + end + end + return 0, minworld, maxworld +end + +function verify_call(@nospecialize(sig), expecteds::Core.SimpleVector, i::Int, n::Int, world::UInt) + # verify that these edges intersect with the same methods as before + lim = _jl_debug_method_invalidation[] !== nothing ? Int(typemax(Int32)) : n + minworld = Ref{UInt}(1) + maxworld = Ref{UInt}(typemax(UInt)) + has_ambig = Ref{Int32}(0) + result = Base._methods_by_ftype(sig, nothing, lim, world, #=ambig=#false, minworld, maxworld, has_ambig) + if result === nothing + maxworld[] = 0 + else + # setdiff!(result, expected) + if length(result) ≠ n + maxworld[] = 0 + end + ins = 0 + for k = 1:length(result) + match = result[k]::Core.MethodMatch + local found = false + for j = 1:n + t = expecteds[i+j-1] + if t isa Method + meth = t + else + if t isa CodeInstance + t = get_ci_mi(t) + else + t = t::MethodInstance + end + meth = t.def::Method + end + if match.method == meth + found = true + break + end + end + if !found + # intersection has a new method or a method was + # deleted--this is now probably no good, just invalidate + # everything about it now + maxworld[] = 0 + if _jl_debug_method_invalidation[] === nothing + break + end + ins += 1 + result[ins] = match.method + end + end + if maxworld[] ≠ typemax(UInt) && _jl_debug_method_invalidation[] !== nothing + resize!(result, ins) + end + end + return minworld[], maxworld[], result +end + +function verify_invokesig(@nospecialize(invokesig), expected::Method, world::UInt) + @assert invokesig isa Type + local minworld::UInt, maxworld::UInt + if invokesig === expected.sig + # the invoke match is `expected` for `expected->sig`, unless `expected` is invalid + minworld = expected.primary_world + maxworld = expected.deleted_world + @assert minworld ≤ world + if maxworld < world + maxworld = 0 + end + else + minworld = 1 + maxworld = typemax(UInt) + mt = Base.get_methodtable(expected) + if mt === nothing + maxworld = 0 + else + matched, valid_worlds = Base.Compiler._findsup(invokesig, mt, world) + minworld, maxworld = valid_worlds.min_world, valid_worlds.max_world + if matched === nothing + maxworld = 0 + elseif matched.method != expected + maxworld = 0 + end + end + end + return minworld, maxworld +end + +end # module StaticData diff --git a/src/staticdata.c b/src/staticdata.c index 4124d3b481bb3..7fad87652b26a 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -89,7 +89,7 @@ External links: #include "julia_assert.h" static const size_t WORLD_AGE_REVALIDATION_SENTINEL = 0x1; -size_t jl_require_world = ~(size_t)0; +JL_DLLEXPORT size_t jl_require_world = ~(size_t)0; #include "staticdata_utils.c" #include "precompile_utils.c" @@ -4110,12 +4110,13 @@ static jl_value_t *jl_restore_package_image_from_stream(void* pkgimage_handle, i jl_atomic_store_release(&jl_world_counter, world); // now permit more methods to be added again JL_UNLOCK(&world_counter_lock); - // but one of those immediate users is going to be our cache insertions - jl_insert_backedges((jl_array_t*)edges, (jl_array_t*)new_ext_cis); // restore existing caches (needs to be last) + // reinit ccallables jl_reinit_ccallable(&ccallable_list, base, pkgimage_handle); arraylist_free(&ccallable_list); + jl_value_t *ext_edges = new_ext_cis ? (jl_value_t*)new_ext_cis : jl_nothing; + if (completeinfo) { cachesizes_sv = jl_alloc_svec(7); jl_svecset(cachesizes_sv, 0, jl_box_long(cachesizes.sysdata)); @@ -4125,12 +4126,11 @@ static jl_value_t *jl_restore_package_image_from_stream(void* pkgimage_handle, i jl_svecset(cachesizes_sv, 4, jl_box_long(cachesizes.reloclist)); jl_svecset(cachesizes_sv, 5, jl_box_long(cachesizes.gvarlist)); jl_svecset(cachesizes_sv, 6, jl_box_long(cachesizes.fptrlist)); - restored = (jl_value_t*)jl_svec(7, restored, init_order, extext_methods, - new_ext_cis ? (jl_value_t*)new_ext_cis : jl_nothing, - method_roots_list, edges, cachesizes_sv); + restored = (jl_value_t*)jl_svec(7, restored, init_order, edges, ext_edges, + extext_methods, method_roots_list, cachesizes_sv); } else { - restored = (jl_value_t*)jl_svec(2, restored, init_order); + restored = (jl_value_t*)jl_svec(4, restored, init_order, edges, ext_edges); } } } diff --git a/src/staticdata_utils.c b/src/staticdata_utils.c index 79d2909970d99..1985357321a3a 100644 --- a/src/staticdata_utils.c +++ b/src/staticdata_utils.c @@ -750,368 +750,6 @@ static void jl_copy_roots(jl_array_t *method_roots_list, uint64_t key) } } -static void verify_invokesig(jl_value_t *invokesig, jl_method_t *expected, size_t world, size_t *minworld, size_t *maxworld) -{ - assert(jl_is_type(invokesig)); - assert(jl_is_method(expected)); - if (jl_egal(invokesig, expected->sig)) { - // the invoke match is `expected` for `expected->sig`, unless `expected` is invalid - *minworld = jl_atomic_load_relaxed(&expected->primary_world); - *maxworld = jl_atomic_load_relaxed(&expected->deleted_world); - assert(*minworld <= world); - if (*maxworld < world) - *maxworld = 0; - } - else { - *minworld = 1; - *maxworld = ~(size_t)0; - jl_methtable_t *mt = jl_method_get_table(expected); - if ((jl_value_t*)mt == jl_nothing) { - *maxworld = 0; - } - else { - jl_value_t *matches = jl_gf_invoke_lookup_worlds(invokesig, (jl_value_t*)mt, world, minworld, maxworld); - if (matches == jl_nothing) { - *maxworld = 0; - } - else { - if (((jl_method_match_t*)matches)->method != expected) { - *maxworld = 0; - } - } - } - } -} - -static void verify_call(jl_value_t *sig, jl_svec_t *expecteds, size_t i, size_t n, size_t world, size_t *minworld, size_t *maxworld, jl_value_t **matches JL_REQUIRE_ROOTED_SLOT) -{ - // verify that these edges intersect with the same methods as before - *minworld = 1; - *maxworld = ~(size_t)0; - int ambig = 0; - // TODO: possibly need to included ambiguities too (for the optimizer correctness)? - jl_value_t *result = jl_matching_methods((jl_tupletype_t*)sig, jl_nothing, - _jl_debug_method_invalidation ? INT32_MAX : n, - 0, world, minworld, maxworld, &ambig); - *matches = result; - if (result == jl_nothing) { - *maxworld = 0; - } - else { - // setdiff!(result, expected) - size_t j, k, ins = 0; - if (jl_array_nrows(result) != n) { - *maxworld = 0; - } - for (k = 0; k < jl_array_nrows(result); k++) { - jl_method_t *match = ((jl_method_match_t*)jl_array_ptr_ref(result, k))->method; - for (j = 0; j < n; j++) { - jl_value_t *t = jl_svecref(expecteds, j + i); - if (jl_is_code_instance(t)) - t = (jl_value_t*)((jl_code_instance_t*)t)->def; - jl_method_t *meth; - if (jl_is_method(t)) - meth = (jl_method_t*)t; - else { - assert(jl_is_method_instance(t)); - meth = ((jl_method_instance_t*)t)->def.method; - } - if (match == meth) - break; - } - if (j == n) { - // intersection has a new method or a method was - // deleted--this is now probably no good, just invalidate - // everything about it now - *maxworld = 0; - if (!_jl_debug_method_invalidation) - break; - jl_array_ptr_set(result, ins++, match); - } - } - if (*maxworld != ~(size_t)0 && _jl_debug_method_invalidation) - jl_array_del_end((jl_array_t*)result, jl_array_nrows(result) - ins); - } -} - -// Test all edges relevant to a method: -//// Visit the entire call graph, starting from edges[idx] to determine if that method is valid -//// Implements Tarjan's SCC (strongly connected components) algorithm, simplified to remove the count variable -//// and slightly modified with an early termination option once the computation reaches its minimum -static int jl_verify_method(jl_code_instance_t *codeinst, size_t *minworld, size_t *maxworld, arraylist_t *stack, htable_t *visiting) -{ - size_t world = jl_atomic_load_relaxed(&codeinst->min_world); - size_t max_valid2 = jl_atomic_load_relaxed(&codeinst->max_world); - if (max_valid2 != WORLD_AGE_REVALIDATION_SENTINEL) { - *minworld = world; - *maxworld = max_valid2; - return 0; - } - *minworld = 1; - size_t current_world = jl_atomic_load_relaxed(&jl_world_counter); - *maxworld = current_world; - assert(jl_is_method_instance(jl_get_ci_mi(codeinst)) && jl_is_method(jl_get_ci_mi(codeinst)->def.method)); - void **bp = ptrhash_bp(visiting, codeinst); - if (*bp != HT_NOTFOUND) - return (char*)*bp - (char*)HT_NOTFOUND; // cycle idx - arraylist_push(stack, (void*)codeinst); - size_t depth = stack->len; - *bp = (char*)HT_NOTFOUND + depth; - JL_TIMING(VERIFY_IMAGE, VERIFY_Methods); - jl_svec_t *callees = jl_atomic_load_relaxed(&codeinst->edges); - assert(jl_is_svec((jl_value_t*)callees)); - // verify current edges - if (callees == jl_emptysvec) { - // quick return: no edges to verify (though we probably shouldn't have gotten here from WORLD_AGE_REVALIDATION_SENTINEL) - } - else if (*maxworld == jl_require_world) { - // if no new worlds were allocated since serializing the base module, then no new validation is worth doing right now either - *minworld = *maxworld; - } - else { - jl_value_t *loctag = NULL; - jl_value_t *sig = NULL; - jl_value_t *matches = NULL; - JL_GC_PUSH3(&loctag, &matches, &sig); - for (size_t j = 0; j < jl_svec_len(callees); ) { - jl_value_t *edge = jl_svecref(callees, j); - size_t min_valid2; - size_t max_valid2; - assert(!jl_is_method(edge)); // `Method`-edge isn't allowed for the optimized one-edge format - if (jl_is_binding_partition(edge)) { - j += 1; - continue; - } - if (jl_is_code_instance(edge)) - edge = (jl_value_t*)jl_get_ci_mi((jl_code_instance_t*)edge); - if (jl_is_method_instance(edge)) { - jl_method_instance_t *mi = (jl_method_instance_t*)edge; - sig = jl_type_intersection(mi->def.method->sig, (jl_value_t*)mi->specTypes); // TODO: ?? - verify_call(sig, callees, j, 1, world, &min_valid2, &max_valid2, &matches); - sig = NULL; - j += 1; - } - else if (jl_is_long(edge)) { - jl_value_t *sig = jl_svecref(callees, j + 1); - size_t nedges = jl_unbox_long(edge); - verify_call(sig, callees, j + 2, nedges, world, &min_valid2, &max_valid2, &matches); - j += 2 + nedges; - edge = sig; - } - else { - jl_method_instance_t *callee = (jl_method_instance_t*)jl_svecref(callees, j + 1); - jl_method_t *meth; - if (jl_is_mtable(callee)) { - // skip the legacy edge (missing backedge) - j += 2; - continue; - } - if (jl_is_code_instance(callee)) - callee = jl_get_ci_mi((jl_code_instance_t*)callee); - if (jl_is_method_instance(callee)) { - meth = callee->def.method; - } - else { - assert(jl_is_method(callee)); - meth = (jl_method_t*)callee; - } - verify_invokesig(edge, meth, world, &min_valid2, &max_valid2); - j += 2; - } - if (*minworld < min_valid2) - *minworld = min_valid2; - if (*maxworld > max_valid2) - *maxworld = max_valid2; - if (max_valid2 != ~(size_t)0 && _jl_debug_method_invalidation) { - jl_array_ptr_1d_push(_jl_debug_method_invalidation, edge); - loctag = jl_cstr_to_string("insert_backedges_callee"); - jl_array_ptr_1d_push(_jl_debug_method_invalidation, loctag); - jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)codeinst); - jl_array_ptr_1d_push(_jl_debug_method_invalidation, matches); - } - //jl_static_show((JL_STREAM*)ios_stderr, (jl_value_t*)edge); - //ios_puts(max_valid2 == ~(size_t)0 ? "valid\n" : "INVALID\n", ios_stderr); - if (max_valid2 == 0 && !_jl_debug_method_invalidation) - break; - } - JL_GC_POP(); - } - // verify recursive edges (if valid, or debugging) - size_t cycle = depth; - jl_code_instance_t *cause = codeinst; - if (*maxworld != 0 || _jl_debug_method_invalidation) { - for (size_t j = 0; j < jl_svec_len(callees); j++) { - jl_value_t *edge = jl_svecref(callees, j); - if (!jl_is_code_instance(edge)) - continue; - jl_code_instance_t *callee = (jl_code_instance_t*)edge; - size_t min_valid2; - size_t max_valid2; - size_t child_cycle = jl_verify_method(callee, &min_valid2, &max_valid2, stack, visiting); - if (*minworld < min_valid2) - *minworld = min_valid2; - if (*minworld > max_valid2) - max_valid2 = 0; - if (*maxworld > max_valid2) { - cause = callee; - *maxworld = max_valid2; - } - if (max_valid2 == 0) { - // found what we were looking for, so terminate early - break; - } - else if (child_cycle && child_cycle < cycle) { - // record the cycle will resolve at depth "cycle" - cycle = child_cycle; - } - } - } - if (*maxworld != 0 && cycle != depth) - return cycle; - // If we are the top of the current cycle, now mark all other parts of - // our cycle with what we found. - // Or if we found a failed edge, also mark all of the other parts of the - // cycle as also having a failed edge. - while (stack->len >= depth) { - jl_code_instance_t *child = (jl_code_instance_t*)arraylist_pop(stack); - if (jl_atomic_load_relaxed(&jl_n_threads) == 1) { - // a different thread might simultaneously come to a different, but equally valid, alternative result - assert(jl_atomic_load_relaxed(&child->max_world) == WORLD_AGE_REVALIDATION_SENTINEL); - assert(*minworld <= jl_atomic_load_relaxed(&child->min_world)); - } - if (*maxworld != 0) - jl_atomic_store_relaxed(&child->min_world, *minworld); - jl_atomic_store_relaxed(&child->max_world, *maxworld); - void **bp = ptrhash_bp(visiting, child); - assert(*bp == (char*)HT_NOTFOUND + stack->len + 1); - *bp = HT_NOTFOUND; - if (_jl_debug_method_invalidation && *maxworld < current_world) { - jl_value_t *loctag; - jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)child); - loctag = jl_cstr_to_string("verify_methods"); - JL_GC_PUSH1(&loctag); - jl_array_ptr_1d_push(_jl_debug_method_invalidation, loctag); - jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)cause); - JL_GC_POP(); - } - } - //jl_static_show((JL_STREAM*)ios_stderr, (jl_value_t*)codeinst->def); - //ios_puts(max_valid == ~(size_t)0 ? "valid\n\n" : "INVALID\n\n", ios_stderr); - return 0; -} - -static void jl_verify_method_graph(jl_code_instance_t *codeinst, arraylist_t *stack, htable_t *visiting) -{ - size_t minworld; - size_t maxworld; - assert(stack->len == 0); - for (size_t i = 0, hsz = visiting->size; i < hsz; i++) - assert(visiting->table[i] == HT_NOTFOUND); - int child_cycle = jl_verify_method(codeinst, &minworld, &maxworld, stack, visiting); - assert(child_cycle == 0); (void)child_cycle; - assert(stack->len == 0); - for (size_t i = 0, hsz = visiting->size / 2; i < hsz; i++) { - assert(visiting->table[2 * i + 1] == HT_NOTFOUND); - visiting->table[2 * i] = HT_NOTFOUND; - } - if (jl_atomic_load_relaxed(&jl_n_threads) == 1) { // a different thread might simultaneously come to a different, but equally valid, alternative result - assert(maxworld == 0 || jl_atomic_load_relaxed(&codeinst->min_world) == minworld); - assert(jl_atomic_load_relaxed(&codeinst->max_world) == maxworld); - } -} - -// Restore backedges to external targets -// `edges` = [caller1, ...], the list of worklist-owned code instances internally -// `ext_ci_list` = [caller1, ...], the list of worklist-owned code instances externally -static void jl_insert_backedges(jl_array_t *edges, jl_array_t *ext_ci_list) -{ - // determine which CodeInstance objects are still valid in our image - // to enable any applicable new codes - arraylist_t stack; - arraylist_new(&stack, 0); - htable_t visiting; - htable_new(&visiting, 0); - for (size_t external = 0; external < (ext_ci_list ? 2 : 1); external++) { - if (external) - edges = ext_ci_list; - size_t nedges = jl_array_nrows(edges); - for (size_t i = 0; i < nedges; i++) { - jl_code_instance_t *codeinst = (jl_code_instance_t*)jl_array_ptr_ref(edges, i); - jl_svec_t *callees = jl_atomic_load_relaxed(&codeinst->edges); - jl_method_instance_t *caller = jl_get_ci_mi(codeinst); - jl_verify_method_graph(codeinst, &stack, &visiting); - size_t minvalid = jl_atomic_load_relaxed(&codeinst->min_world); - size_t maxvalid = jl_atomic_load_relaxed(&codeinst->max_world); - if (maxvalid >= minvalid) { - if (jl_atomic_load_relaxed(&jl_world_counter) == maxvalid) { - // if this callee is still valid, add all the backedges - for (size_t j = 0; j < jl_svec_len(callees); ) { - jl_value_t *edge = jl_svecref(callees, j); - if (jl_is_long(edge)) { - j += 2; // skip over signature and count but not methods - continue; - } - else if (jl_is_method(edge)) { - j += 1; - continue; - } - else if (jl_is_binding_partition(edge)) { - j += 1; - continue; - } - if (jl_is_code_instance(edge)) - edge = (jl_value_t*)((jl_code_instance_t*)edge)->def; - if (jl_is_method_instance(edge)) { - jl_method_instance_add_backedge((jl_method_instance_t*)edge, NULL, codeinst); - j += 1; - } - else { - jl_value_t *callee = jl_svecref(callees, j + 1); - if (jl_is_mtable(callee)) { - jl_methtable_t *mt = (jl_methtable_t*)callee; - jl_method_table_add_backedge(mt, edge, codeinst); - j += 2; - continue; - } - else if (jl_is_code_instance(callee)) { - callee = (jl_value_t*)((jl_code_instance_t*)callee)->def; - } - else if (jl_is_method(callee)) { - j += 2; - continue; - } - jl_method_instance_add_backedge((jl_method_instance_t*)callee, edge, codeinst); - j += 2; - } - } - } - if (jl_atomic_load_relaxed(&jl_world_counter) == maxvalid) { - maxvalid = ~(size_t)0; - jl_atomic_store_relaxed(&codeinst->max_world, maxvalid); - } - if (external) { - jl_value_t *owner = codeinst->owner; - JL_GC_PROMISE_ROOTED(owner); - - // See #53586, #53109 - assert(jl_atomic_load_relaxed(&codeinst->inferred)); - - if (jl_rettype_inferred(owner, caller, minvalid, maxvalid) != jl_nothing) { - // We already got a code instance for this world age range from somewhere else - we don't need - // this one. - } - else { - jl_mi_cache_insert(caller, codeinst); - } - } - } - } - } - - htable_free(&visiting); - arraylist_free(&stack); -} - static jl_value_t *read_verify_mod_list(ios_t *s, jl_array_t *depmods) { if (!jl_main_module->build_id.lo) { diff --git a/test/precompile.jl b/test/precompile.jl index 3b193e1facd7c..78a96250600a4 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -1004,9 +1004,9 @@ precompile_test_harness("code caching") do dir MA = getfield(@__MODULE__, StaleA) Base.eval(MA, :(nbits(::UInt8) = 8)) @eval using $StaleC - invalidations = ccall(:jl_debug_method_invalidation, Any, (Cint,), 1) + invalidations = Base.StaticData.debug_method_invalidation(true) @eval using $StaleB - ccall(:jl_debug_method_invalidation, Any, (Cint,), 0) + Base.StaticData.debug_method_invalidation(false) MB = getfield(@__MODULE__, StaleB) MC = getfield(@__MODULE__, StaleC) world = Base.get_world_counter() @@ -1820,12 +1820,14 @@ precompile_test_harness("PkgCacheInspector") do load_path end if ocachefile !== nothing - sv = ccall(:jl_restore_package_image_from_file, Any, (Cstring, Any, Cint, Cstring, Cint), ocachefile, depmods, true, "PCI", false) + sv = ccall(:jl_restore_package_image_from_file, Any, (Cstring, Any, Cint, Cstring, Cint), + ocachefile, depmods, #=completeinfo=#true, "PCI", false) else - sv = ccall(:jl_restore_incremental, Any, (Cstring, Any, Cint, Cstring), cachefile, depmods, true, "PCI") + sv = ccall(:jl_restore_incremental, Any, (Cstring, Any, Cint, Cstring), + cachefile, depmods, #=completeinfo=#true, "PCI") end - modules, init_order, external_methods, new_ext_cis, new_method_roots, external_targets, edges = sv + modules, init_order, edges, new_ext_cis, external_methods, new_method_roots, cache_sizes = sv m = only(external_methods).func::Method @test m.name == :repl_cmd && m.nargs < 2 @test new_ext_cis === nothing || any(new_ext_cis) do ci From 6cf2b146c68e85ea62f233b2f6e4bbb9e7e32e93 Mon Sep 17 00:00:00 2001 From: NegaScout <42321060+NegaScout@users.noreply.github.com> Date: Wed, 15 Jan 2025 14:13:39 +0100 Subject: [PATCH 184/198] remove unused Base.GMP.MPZ.import! and test Base.GMP.MPZ.export! (#56903) --- base/gmp.jl | 2 -- test/gmp.jl | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/base/gmp.jl b/base/gmp.jl index d5db71b0630d6..4d2b4b66ac41b 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -264,8 +264,6 @@ end limbs_write!(x::BigInt, a) = ccall((:__gmpz_limbs_write, libgmp), Ptr{Limb}, (mpz_t, Clong), x, a) limbs_finish!(x::BigInt, a) = ccall((:__gmpz_limbs_finish, libgmp), Cvoid, (mpz_t, Clong), x, a) -import!(x::BigInt, a, b, c, d, e, f) = ccall((:__gmpz_import, libgmp), Cvoid, - (mpz_t, Csize_t, Cint, Csize_t, Cint, Csize_t, Ptr{Cvoid}), x, a, b, c, d, e, f) setbit!(x, a) = (ccall((:__gmpz_setbit, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a); x) tstbit(a::BigInt, b) = ccall((:__gmpz_tstbit, libgmp), Cint, (mpz_t, bitcnt_t), a, b) % Bool diff --git a/test/gmp.jl b/test/gmp.jl index 9ca327e63493b..0812775672969 100644 --- a/test/gmp.jl +++ b/test/gmp.jl @@ -445,6 +445,44 @@ end @test string(big(0), base = rand(2:62), pad = 0) == "" end +@testset "Base.GMP.MPZ.export!" begin + + function Base_GMP_MPZ_import!(x::BigInt, n::AbstractVector{T}; order::Integer=-1, nails::Integer=0, endian::Integer=0) where {T<:Base.BitInteger} + ccall((:__gmpz_import, Base.GMP.MPZ.libgmp), + Cvoid, + (Base.GMP.MPZ.mpz_t, Csize_t, Cint, Csize_t, Cint, Csize_t, Ptr{Cvoid}), + x, length(n), order, sizeof(T), endian, nails, n) + return x + end + # test import + bytes_to_import_from = Vector{UInt8}([1, 0]) + int_to_import_to = BigInt() + Base_GMP_MPZ_import!(int_to_import_to, bytes_to_import_from, order=0) + @test int_to_import_to == BigInt(256) + + # test export + int_to_export_from = BigInt(256) + bytes_to_export_to = Vector{UInt8}(undef, 2) + Base.GMP.MPZ.export!(bytes_to_export_to, int_to_export_from, order=0) + @test all(bytes_to_export_to .== bytes_to_import_from) + + # test both composed import(export) is identity + int_to_export_from = BigInt(256) + bytes_to_export_to = Vector{UInt8}(undef, 2) + Base.GMP.MPZ.export!(bytes_to_export_to, int_to_export_from, order=0) + int_to_import_to = BigInt() + Base_GMP_MPZ_import!(int_to_import_to, bytes_to_export_to, order=0) + @test int_to_export_from == int_to_import_to + + # test both composed export(import) is identity + bytes_to_import_from = Vector{UInt8}([1, 0]) + int_to_import_to = BigInt() + Base_GMP_MPZ_import!(int_to_import_to, bytes_to_import_from, order=0) + bytes_to_export_to = Vector{UInt8}(undef, 2) + Base.GMP.MPZ.export!(bytes_to_export_to, int_to_export_from, order=0) + @test all(bytes_to_export_to .== bytes_to_import_from) +end + @test isqrt(big(4)) == 2 @test isqrt(big(5)) == 2 From 30177d0578d283cda3bace0c2984b5fdcd114c2f Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Wed, 15 Jan 2025 22:49:18 +0100 Subject: [PATCH 185/198] cleanup: Remove fallback post-lowering global resolution (#57051) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After recent changes, essentially all global symbol scopes are resolved by lowering, so the code in method.c that replaces symbols by globalrefs is no longer necessary. The one small exception to this were symbols resulting from closure conversion, because these get inserted after the point at which lowering converts symbols to globalrefs. However, in the current design, I think that's basically a bug (and easily addressed by inserting `globalref`s where appropriate). Removing this extra resolution step is not particularly necessary, but for the upcoming binding partition backedges, it removes an ambiguity as to which version of the lowered code to scan. It also partially resolves a very old todo about not performing post-hoc mutation of lowered code (although we still do this for ccall). --- src/jl_exported_funcs.inc | 2 +- src/julia-syntax.scm | 14 +- src/julia_internal.h | 4 +- src/method.c | 355 ++++++++++++----------------- src/toplevel.c | 4 +- stdlib/REPL/src/REPLCompletions.jl | 2 +- 6 files changed, 156 insertions(+), 225 deletions(-) diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index cb48cf6f9962c..b92380df7a49c 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -388,7 +388,7 @@ XX(jl_read_verify_header) \ XX(jl_realloc) \ XX(jl_register_newmeth_tracer) \ - XX(jl_resolve_globals_in_ir) \ + XX(jl_resolve_definition_effects_in_ir) \ XX(jl_restore_excstack) \ XX(jl_restore_incremental) \ XX(jl_restore_package_image_from_file) \ diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 007c3ce820820..7fd2dc7409c0e 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -3683,11 +3683,17 @@ f(x) = yt(x) (else (error (string "invalid assignment location \"" (deparse var) "\""))))) +(define (sig-type-expr namemap name expr) + (let ((newname (get namemap name expr))) + (if (symbol? newname) + `(globalref (thismodule) ,newname) + newname))) + (define (rename-sig-types ex namemap) (pattern-replace (pattern-set (pattern-lambda (call (core (-/ Typeof)) name) - (get namemap name __))) + (sig-type-expr namemap name __))) ex)) ;; replace leading (function) argument type with `typ` @@ -4242,7 +4248,7 @@ f(x) = yt(x) (contains (lambda (x) (eq? x 'kwftype)) sig)) (renamemap (map cons closure-param-names closure-param-syms)) (arg-defs (replace-vars - (fix-function-arg-type sig type-name iskw namemap closure-param-syms) + (fix-function-arg-type sig `(globalref (thismodule) ,type-name) iskw namemap closure-param-syms) renamemap))) (append (map (lambda (gs tvar) (make-assignment gs `(call (core TypeVar) ',tvar (core Any)))) @@ -4270,8 +4276,8 @@ f(x) = yt(x) `(call (core _typeof_captured_variable) ,ve))) capt-vars var-exprs))))) `(new ,(if (null? P) - type-name - `(call (core apply_type) ,type-name ,@P)) + `(globalref (thismodule) ,type-name) + `(call (core apply_type) (globalref (thismodule) ,type-name) ,@P)) ,@var-exprs)))) (if (pair? moved-vars) (set-car! (lam:vinfo lam) diff --git a/src/julia_internal.h b/src/julia_internal.h index a464025edf856..00d603f26c7f2 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -717,8 +717,8 @@ jl_value_t *jl_code_or_ci_for_interpreter(jl_method_instance_t *lam JL_PROPAGATE int jl_code_requires_compiler(jl_code_info_t *src, int include_force_compile); jl_code_info_t *jl_new_code_info_from_ir(jl_expr_t *ast); JL_DLLEXPORT jl_code_info_t *jl_new_code_info_uninit(void); -JL_DLLEXPORT void jl_resolve_globals_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *sparam_vals, - int binding_effects); +JL_DLLEXPORT void jl_resolve_definition_effects_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *sparam_vals, + int binding_effects); int get_next_edge(jl_array_t *list, int i, jl_value_t** invokesig, jl_code_instance_t **caller) JL_NOTSAFEPOINT; int set_next_edge(jl_array_t *list, int i, jl_value_t *invokesig, jl_code_instance_t *caller); diff --git a/src/method.c b/src/method.c index 0d173d960c90f..0a58f0d5c482c 100644 --- a/src/method.c +++ b/src/method.c @@ -41,235 +41,160 @@ static void check_c_types(const char *where, jl_value_t *rt, jl_value_t *at) // Resolve references to non-locally-defined variables to become references to global // variables in `module` (unless the rvalue is one of the type parameters in `sparam_vals`). -static jl_value_t *resolve_globals(jl_value_t *expr, jl_module_t *module, jl_svec_t *sparam_vals, +static jl_value_t *resolve_definition_effects(jl_value_t *expr, jl_module_t *module, jl_svec_t *sparam_vals, int binding_effects, int eager_resolve) { if (jl_is_symbol(expr)) { - if (module == NULL) - return expr; - return jl_module_globalref(module, (jl_sym_t*)expr); + jl_error("Found raw symbol in code returned from lowering. Expected all symbols to have been resolved to GlobalRef or slots."); } - else if (jl_is_returnnode(expr)) { - jl_value_t *retval = jl_returnnode_value(expr); - if (retval) { - jl_value_t *val = resolve_globals(retval, module, sparam_vals, binding_effects, eager_resolve); - if (val != retval) { - JL_GC_PUSH1(&val); - expr = jl_new_struct(jl_returnnode_type, val); - JL_GC_POP(); - } - } + if (!jl_is_expr(expr)) { return expr; } - else if (jl_is_enternode(expr)) { - jl_value_t *scope = jl_enternode_scope(expr); - if (scope) { - jl_value_t *val = resolve_globals(scope, module, sparam_vals, binding_effects, eager_resolve); - if (val != scope) { - intptr_t catch_dest = jl_enternode_catch_dest(expr); - JL_GC_PUSH1(&val); - expr = jl_new_struct_uninit(jl_enternode_type); - jl_enternode_catch_dest(expr) = catch_dest; - jl_enternode_scope(expr) = val; - JL_GC_POP(); - } - } + + jl_expr_t *e = (jl_expr_t*)expr; + if (e->head == jl_global_sym && binding_effects) { + // execute the side-effects of "global x" decl immediately: + // creates uninitialized mutable binding in module for each global + jl_eval_global_expr(module, e, 1); + return jl_nothing; + } + // These exprs are not fully linearized + if (e->head == jl_assign_sym) { + jl_exprargset(e, 1, resolve_definition_effects(jl_exprarg(e, 1), module, sparam_vals, binding_effects, eager_resolve)); + return expr; + } else if (e->head == jl_new_opaque_closure_sym) { + jl_exprargset(e, 4, resolve_definition_effects(jl_exprarg(e, 4), module, sparam_vals, binding_effects, eager_resolve)); return expr; } - else if (jl_is_gotoifnot(expr)) { - jl_value_t *cond = resolve_globals(jl_gotoifnot_cond(expr), module, sparam_vals, binding_effects, eager_resolve); - if (cond != jl_gotoifnot_cond(expr)) { - intptr_t label = jl_gotoifnot_label(expr); - JL_GC_PUSH1(&cond); - expr = jl_new_struct_uninit(jl_gotoifnot_type); - set_nth_field(jl_gotoifnot_type, expr, 0, cond, 0); - jl_gotoifnot_label(expr) = label; - JL_GC_POP(); + size_t nargs = jl_array_nrows(e->args); + if (e->head == jl_opaque_closure_method_sym) { + if (nargs != 5) { + jl_error("opaque_closure_method: invalid syntax"); } - return expr; + jl_value_t *name = jl_exprarg(e, 0); + jl_value_t *oc_nargs = jl_exprarg(e, 1); + int isva = jl_exprarg(e, 2) == jl_true; + jl_value_t *functionloc = jl_exprarg(e, 3); + jl_value_t *ci = jl_exprarg(e, 4); + if (!jl_is_code_info(ci)) { + jl_error("opaque_closure_method: lambda should be a CodeInfo"); + } else if (!jl_is_long(oc_nargs)) { + jl_type_error("opaque_closure_method", (jl_value_t*)jl_long_type, oc_nargs); + } + jl_method_t *m = jl_make_opaque_closure_method(module, name, + jl_unbox_long(oc_nargs), functionloc, (jl_code_info_t*)ci, isva, /*isinferred*/0); + return (jl_value_t*)m; } - else if (jl_is_expr(expr)) { - jl_expr_t *e = (jl_expr_t*)expr; - if (e->head == jl_global_sym && binding_effects) { - // execute the side-effects of "global x" decl immediately: - // creates uninitialized mutable binding in module for each global - jl_eval_global_expr(module, e, 1); - expr = jl_nothing; + if (e->head == jl_cfunction_sym) { + JL_NARGS(cfunction method definition, 5, 5); // (type, func, rt, at, cc) + jl_task_t *ct = jl_current_task; + jl_value_t *typ = jl_exprarg(e, 0); + if (!jl_is_type(typ)) + jl_error("first parameter to :cfunction must be a type"); + if (typ == (jl_value_t*)jl_voidpointer_type) { + jl_value_t *a = jl_exprarg(e, 1); + JL_TYPECHK(cfunction method definition, quotenode, a); + *(jl_value_t**)a = jl_toplevel_eval(module, *(jl_value_t**)a); + jl_gc_wb(a, *(jl_value_t**)a); } - if (jl_is_toplevel_only_expr(expr) || e->head == jl_const_sym || - e->head == jl_coverageeffect_sym || e->head == jl_copyast_sym || - e->head == jl_quote_sym || e->head == jl_inert_sym || - e->head == jl_meta_sym || e->head == jl_inbounds_sym || - e->head == jl_boundscheck_sym || e->head == jl_loopinfo_sym || - e->head == jl_aliasscope_sym || e->head == jl_popaliasscope_sym || - e->head == jl_inline_sym || e->head == jl_noinline_sym) { - // ignore these + jl_value_t *rt = jl_exprarg(e, 2); + jl_value_t *at = jl_exprarg(e, 3); + if (!jl_is_type(rt)) { + JL_TRY { + rt = jl_interpret_toplevel_expr_in(module, rt, NULL, sparam_vals); + } + JL_CATCH { + if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) + jl_error("could not evaluate cfunction return type (it might depend on a local variable)"); + else + jl_rethrow(); + } + jl_exprargset(e, 2, rt); } - else { - size_t i = 0, nargs = jl_array_nrows(e->args); - if (e->head == jl_opaque_closure_method_sym) { - if (nargs != 5) { - jl_error("opaque_closure_method: invalid syntax"); - } - jl_value_t *name = jl_exprarg(e, 0); - jl_value_t *oc_nargs = jl_exprarg(e, 1); - int isva = jl_exprarg(e, 2) == jl_true; - jl_value_t *functionloc = jl_exprarg(e, 3); - jl_value_t *ci = jl_exprarg(e, 4); - if (!jl_is_code_info(ci)) { - jl_error("opaque_closure_method: lambda should be a CodeInfo"); - } else if (!jl_is_long(oc_nargs)) { - jl_type_error("opaque_closure_method", (jl_value_t*)jl_long_type, oc_nargs); - } - jl_method_t *m = jl_make_opaque_closure_method(module, name, - jl_unbox_long(oc_nargs), functionloc, (jl_code_info_t*)ci, isva, /*isinferred*/0); - return (jl_value_t*)m; + if (!jl_is_svec(at)) { + JL_TRY { + at = jl_interpret_toplevel_expr_in(module, at, NULL, sparam_vals); } - if (e->head == jl_cfunction_sym) { - JL_NARGS(cfunction method definition, 5, 5); // (type, func, rt, at, cc) - jl_task_t *ct = jl_current_task; - jl_value_t *typ = jl_exprarg(e, 0); - if (!jl_is_type(typ)) - jl_error("first parameter to :cfunction must be a type"); - if (typ == (jl_value_t*)jl_voidpointer_type) { - jl_value_t *a = jl_exprarg(e, 1); - JL_TYPECHK(cfunction method definition, quotenode, a); - *(jl_value_t**)a = jl_toplevel_eval(module, *(jl_value_t**)a); - jl_gc_wb(a, *(jl_value_t**)a); - } - jl_value_t *rt = jl_exprarg(e, 2); - jl_value_t *at = jl_exprarg(e, 3); - if (!jl_is_type(rt)) { - JL_TRY { - rt = jl_interpret_toplevel_expr_in(module, rt, NULL, sparam_vals); - } - JL_CATCH { - if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) - jl_error("could not evaluate cfunction return type (it might depend on a local variable)"); - else - jl_rethrow(); - } - jl_exprargset(e, 2, rt); - } - if (!jl_is_svec(at)) { - JL_TRY { - at = jl_interpret_toplevel_expr_in(module, at, NULL, sparam_vals); - } - JL_CATCH { - if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) - jl_error("could not evaluate cfunction argument type (it might depend on a local variable)"); - else - jl_rethrow(); - } - jl_exprargset(e, 3, at); - } - check_c_types("cfunction method definition", rt, at); - JL_TYPECHK(cfunction method definition, quotenode, jl_exprarg(e, 4)); - JL_TYPECHK(cfunction method definition, symbol, *(jl_value_t**)jl_exprarg(e, 4)); - return expr; + JL_CATCH { + if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) + jl_error("could not evaluate cfunction argument type (it might depend on a local variable)"); + else + jl_rethrow(); } - if (e->head == jl_foreigncall_sym) { - JL_NARGSV(ccall method definition, 5); // (fptr, rt, at, nreq, (cc, effects)) - jl_task_t *ct = jl_current_task; - jl_value_t *rt = jl_exprarg(e, 1); - jl_value_t *at = jl_exprarg(e, 2); - if (!jl_is_type(rt)) { - JL_TRY { - rt = jl_interpret_toplevel_expr_in(module, rt, NULL, sparam_vals); - } - JL_CATCH { - if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) - jl_error("could not evaluate ccall return type (it might depend on a local variable)"); - else - jl_rethrow(); - } - jl_exprargset(e, 1, rt); - } - if (!jl_is_svec(at)) { - JL_TRY { - at = jl_interpret_toplevel_expr_in(module, at, NULL, sparam_vals); - } - JL_CATCH { - if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) - jl_error("could not evaluate ccall argument type (it might depend on a local variable)"); - else - jl_rethrow(); - } - jl_exprargset(e, 2, at); - } - check_c_types("ccall method definition", rt, at); - JL_TYPECHK(ccall method definition, long, jl_exprarg(e, 3)); - JL_TYPECHK(ccall method definition, quotenode, jl_exprarg(e, 4)); - jl_value_t *cc = jl_quotenode_value(jl_exprarg(e, 4)); - if (!jl_is_symbol(cc)) { - JL_TYPECHK(ccall method definition, tuple, cc); - if (jl_nfields(cc) != 2) { - jl_error("In ccall calling convention, expected two argument tuple or symbol."); - } - JL_TYPECHK(ccall method definition, symbol, jl_get_nth_field(cc, 0)); - JL_TYPECHK(ccall method definition, uint16, jl_get_nth_field(cc, 1)); - } - jl_exprargset(e, 0, resolve_globals(jl_exprarg(e, 0), module, sparam_vals, binding_effects, 1)); - i++; + jl_exprargset(e, 3, at); + } + check_c_types("cfunction method definition", rt, at); + JL_TYPECHK(cfunction method definition, quotenode, jl_exprarg(e, 4)); + JL_TYPECHK(cfunction method definition, symbol, *(jl_value_t**)jl_exprarg(e, 4)); + return expr; + } + if (e->head == jl_foreigncall_sym) { + JL_NARGSV(ccall method definition, 5); // (fptr, rt, at, nreq, (cc, effects)) + jl_task_t *ct = jl_current_task; + jl_value_t *rt = jl_exprarg(e, 1); + jl_value_t *at = jl_exprarg(e, 2); + if (!jl_is_type(rt)) { + JL_TRY { + rt = jl_interpret_toplevel_expr_in(module, rt, NULL, sparam_vals); + } + JL_CATCH { + if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) + jl_error("could not evaluate ccall return type (it might depend on a local variable)"); + else + jl_rethrow(); } - if (e->head == jl_method_sym || e->head == jl_module_sym || e->head == jl_throw_undef_if_not_sym) { - i++; + jl_exprargset(e, 1, rt); + } + if (!jl_is_svec(at)) { + JL_TRY { + at = jl_interpret_toplevel_expr_in(module, at, NULL, sparam_vals); } - for (; i < nargs; i++) { - // TODO: this should be making a copy, not mutating the source - jl_exprargset(e, i, resolve_globals(jl_exprarg(e, i), module, sparam_vals, binding_effects, eager_resolve)); + JL_CATCH { + if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) + jl_error("could not evaluate ccall argument type (it might depend on a local variable)"); + else + jl_rethrow(); } - if (e->head == jl_call_sym && jl_expr_nargs(e) == 3 && - jl_is_globalref(jl_exprarg(e, 0)) && - jl_is_globalref(jl_exprarg(e, 1)) && - jl_is_quotenode(jl_exprarg(e, 2))) { - // replace module_expr.sym with GlobalRef(module, sym) - // for expressions pattern-matching to `getproperty(module_expr, :sym)` in a top-module - // (this is expected to help inference performance) - // TODO: this was broken by linear-IR - jl_value_t *s = jl_fieldref(jl_exprarg(e, 2), 0); - jl_value_t *me = jl_exprarg(e, 1); - jl_value_t *fe = jl_exprarg(e, 0); - jl_module_t *fe_mod = jl_globalref_mod(fe); - jl_sym_t *fe_sym = jl_globalref_name(fe); - jl_module_t *me_mod = jl_globalref_mod(me); - jl_sym_t *me_sym = jl_globalref_name(me); - if (fe_mod->istopmod && !strcmp(jl_symbol_name(fe_sym), "getproperty") && jl_is_symbol(s)) { - if (eager_resolve || jl_binding_resolved_p(me_mod, me_sym)) { - jl_binding_t *b = jl_get_binding(me_mod, me_sym); - jl_value_t *v = jl_get_binding_value_if_const(b); - if (v && jl_is_module(v)) - return jl_module_globalref((jl_module_t*)v, (jl_sym_t*)s); - } - } + jl_exprargset(e, 2, at); + } + check_c_types("ccall method definition", rt, at); + JL_TYPECHK(ccall method definition, long, jl_exprarg(e, 3)); + JL_TYPECHK(ccall method definition, quotenode, jl_exprarg(e, 4)); + jl_value_t *cc = jl_quotenode_value(jl_exprarg(e, 4)); + if (!jl_is_symbol(cc)) { + JL_TYPECHK(ccall method definition, tuple, cc); + if (jl_nfields(cc) != 2) { + jl_error("In ccall calling convention, expected two argument tuple or symbol."); } - if (e->head == jl_call_sym && nargs > 0 && - jl_is_globalref(jl_exprarg(e, 0))) { - // TODO: this hack should be deleted once llvmcall is fixed - jl_value_t *fe = jl_exprarg(e, 0); - jl_module_t *fe_mod = jl_globalref_mod(fe); - jl_sym_t *fe_sym = jl_globalref_name(fe); - if (jl_binding_resolved_p(fe_mod, fe_sym)) { - // look at some known called functions - jl_binding_t *b = jl_get_binding(fe_mod, fe_sym); - if (jl_get_binding_value_if_const(b) == jl_builtin_tuple) { - size_t j; - for (j = 1; j < nargs; j++) { - if (!jl_is_quotenode(jl_exprarg(e, j))) - break; - } - if (j == nargs) { - jl_value_t *val = NULL; - JL_TRY { - val = jl_interpret_toplevel_expr_in(module, (jl_value_t*)e, NULL, sparam_vals); - } - JL_CATCH { - val = NULL; // To make the analyzer happy see #define JL_TRY - } - if (val) - return val; - } + JL_TYPECHK(ccall method definition, symbol, jl_get_nth_field(cc, 0)); + JL_TYPECHK(ccall method definition, uint16, jl_get_nth_field(cc, 1)); + } + } + if (e->head == jl_call_sym && nargs > 0 && + jl_is_globalref(jl_exprarg(e, 0))) { + // TODO: this hack should be deleted once llvmcall is fixed + jl_value_t *fe = jl_exprarg(e, 0); + jl_module_t *fe_mod = jl_globalref_mod(fe); + jl_sym_t *fe_sym = jl_globalref_name(fe); + if (jl_binding_resolved_p(fe_mod, fe_sym)) { + // look at some known called functions + jl_binding_t *b = jl_get_binding(fe_mod, fe_sym); + if (jl_get_binding_value_if_const(b) == jl_builtin_tuple) { + size_t j; + for (j = 1; j < nargs; j++) { + if (!jl_is_quotenode(jl_exprarg(e, j))) + break; + } + if (j == nargs) { + jl_value_t *val = NULL; + JL_TRY { + val = jl_interpret_toplevel_expr_in(module, (jl_value_t*)e, NULL, sparam_vals); + } + JL_CATCH { + val = NULL; // To make the analyzer happy see #define JL_TRY } + if (val) + return val; } } } @@ -277,13 +202,13 @@ static jl_value_t *resolve_globals(jl_value_t *expr, jl_module_t *module, jl_sve return expr; } -JL_DLLEXPORT void jl_resolve_globals_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *sparam_vals, +JL_DLLEXPORT void jl_resolve_definition_effects_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *sparam_vals, int binding_effects) { size_t i, l = jl_array_nrows(stmts); for (i = 0; i < l; i++) { jl_value_t *stmt = jl_array_ptr_ref(stmts, i); - jl_array_ptr_set(stmts, i, resolve_globals(stmt, m, sparam_vals, binding_effects, 0)); + jl_array_ptr_set(stmts, i, resolve_definition_effects(stmt, m, sparam_vals, binding_effects, 0)); } } @@ -697,7 +622,7 @@ JL_DLLEXPORT jl_code_info_t *jl_expand_and_resolve(jl_value_t *ex, jl_module_t * JL_GC_PUSH1(&func); if (jl_is_code_info(func)) { jl_array_t *stmts = (jl_array_t*)func->code; - jl_resolve_globals_in_ir(stmts, module, sparam_vals, 1); + jl_resolve_definition_effects_in_ir(stmts, module, sparam_vals, 1); } JL_GC_POP(); return func; @@ -777,7 +702,7 @@ JL_DLLEXPORT jl_code_info_t *jl_code_for_staged(jl_method_instance_t *mi, size_t if (jl_is_code_info(ex)) { func = (jl_code_info_t*)ex; jl_array_t *stmts = (jl_array_t*)func->code; - jl_resolve_globals_in_ir(stmts, def->module, mi->sparam_vals, 1); + jl_resolve_definition_effects_in_ir(stmts, def->module, mi->sparam_vals, 1); } else { // Lower the user's expression and resolve references to the type parameters @@ -1000,7 +925,7 @@ JL_DLLEXPORT void jl_method_set_source(jl_method_t *m, jl_code_info_t *src) } } else { - st = resolve_globals(st, m->module, sparam_vars, 1, 0); + st = resolve_definition_effects(st, m->module, sparam_vars, 1, 0); } jl_array_ptr_set(copy, i, st); } diff --git a/src/toplevel.c b/src/toplevel.c index 95a053f6135f6..fb217ec7cb52e 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -1048,7 +1048,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val jl_get_module_compile(m) != JL_OPTIONS_COMPILE_MIN)) { // use codegen mfunc = jl_method_instance_for_thunk(thk, m); - jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0); + jl_resolve_definition_effects_in_ir((jl_array_t*)thk->code, m, NULL, 0); // Don't infer blocks containing e.g. method definitions, since it's probably not worthwhile. size_t world = jl_atomic_load_acquire(&jl_world_counter); ct->world_age = world; @@ -1062,7 +1062,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val // use interpreter assert(thk); if (has_opaque) { - jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0); + jl_resolve_definition_effects_in_ir((jl_array_t*)thk->code, m, NULL, 0); } size_t world = jl_atomic_load_acquire(&jl_world_counter); ct->world_age = world; diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 723a008b10f28..e8aa1188ec213 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -716,7 +716,7 @@ function CC.const_prop_argument_heuristic(interp::REPLInterpreter, arginfo::CC.A end function resolve_toplevel_symbols!(src::Core.CodeInfo, mod::Module) - @ccall jl_resolve_globals_in_ir( + @ccall jl_resolve_definition_effects_in_ir( #=jl_array_t *stmts=# src.code::Any, #=jl_module_t *m=# mod::Any, #=jl_svec_t *sparam_vals=# Core.svec()::Any, From 2dc3337626cd1fa09d358e3f4b769720c0a0d527 Mon Sep 17 00:00:00 2001 From: Erik Schnetter Date: Wed, 15 Jan 2025 21:22:35 -0500 Subject: [PATCH 186/198] base/strings: Add documentation to unicode conversion table (#56929) Co-authored-by: Neven Sajko <4944410+nsajko@users.noreply.github.com> --- base/strings/unicode.jl | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/base/strings/unicode.jl b/base/strings/unicode.jl index fcb4a371e9898..f2938ba6021f2 100644 --- a/base/strings/unicode.jl +++ b/base/strings/unicode.jl @@ -174,14 +174,21 @@ function utf8proc_map(str::Union{String,SubString{String}}, options::Integer, ch return String(resize!(buffer, nbytes)) end -# from julia_charmap.h, used by julia_chartransform in the Unicode stdlib +""" +`Dict` of `original codepoint => replacement codepoint` normalizations +to perform on Julia identifiers, to canonicalize characters that +are both easily confused and easily inputted by accident. + +!!! warning + When this table is updated, also update the corresponding table in `src/flisp/julia_charmap.h`. +""" const _julia_charmap = Dict{UInt32,UInt32}( - 0x025B => 0x03B5, - 0x00B5 => 0x03BC, - 0x00B7 => 0x22C5, - 0x0387 => 0x22C5, - 0x2212 => 0x002D, - 0x210F => 0x0127, + 0x025B => 0x03B5, # latin small letter open e -> greek small letter epsilon + 0x00B5 => 0x03BC, # micro sign -> greek small letter mu + 0x00B7 => 0x22C5, # middot char -> dot operator (#25098) + 0x0387 => 0x22C5, # Greek interpunct -> dot operator (#25098) + 0x2212 => 0x002D, # minus -> hyphen-minus (#26193) + 0x210F => 0x0127, # hbar -> small letter h with stroke (#48870) ) utf8proc_map(s::AbstractString, flags::Integer, chartransform::F = identity) where F = utf8proc_map(String(s), flags, chartransform) From b0ae24ffada04c16c1ab278027824e210693df08 Mon Sep 17 00:00:00 2001 From: Neven Sajko <4944410+nsajko@users.noreply.github.com> Date: Thu, 16 Jan 2025 03:23:17 +0100 Subject: [PATCH 187/198] test: add a bunch of `@inferred` to the iterators test set (#56885) The `@inferred` macro is applied to the following functions: * `Base.IteratorSize` * `Base.IteratorEltype` * `eltype` * `axes` * `size` * `length` * `ndims` * `isempty` xref #56802 xref #56838 --- test/iterators.jl | 430 +++++++++++++++++++++++----------------------- 1 file changed, 215 insertions(+), 215 deletions(-) diff --git a/test/iterators.jl b/test/iterators.jl index 1feccf5fb1d3e..06f08cff4f6ad 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -5,7 +5,7 @@ using Random using Base: IdentityUnitRange using Dates: Date, Day -@test Base.IteratorSize(Any) isa Base.SizeUnknown +@test (@inferred Base.IteratorSize(Any)) isa Base.SizeUnknown # zip and filter iterators # issue #4718 @@ -16,27 +16,27 @@ using Dates: Date, Day @test_throws ArgumentError Iterators.reverse(zip("abc", Iterators.cycle("ab"))) let z = zip(1:2) - @test size(z) == (2,) + @test (@inferred size(z)) == (2,) @test collect(z) == [(1,), (2,)] # Issue #13979 - @test eltype(z) == Tuple{Int} + @test (@inferred eltype(z)) == Tuple{Int} end for z in (zip(1:2, 3:4), zip(1:2, 3:5)) @test collect(z) == [(1,3), (2,4)] - @test eltype(z) == Tuple{Int,Int} - @test size(z) == (2,) - @test axes(z) == (Base.OneTo(2),) - @test length(z) == 2 + @test (@inferred eltype(z)) == Tuple{Int,Int} + @test (@inferred size(z)) == (2,) + @test (@inferred axes(z)) == (Base.OneTo(2),) + @test (@inferred length(z)) == 2 end let z = zip(1:2, Iterators.countfrom(3)) @test collect(z) == [(1,3), (2,4)] - @test eltype(z) == Tuple{Int,Int} + @test (@inferred eltype(z)) == Tuple{Int,Int} @test_throws MethodError size(z) # by convention, the zip of a finite and # an infinite iterator has only `length` @test_throws MethodError axes(z) - @test length(z) == 2 + @test (@inferred length(z)) == 2 end let z = zip([i*j for i in 1:3, j in -1:2:1], 1:6) @@ -46,29 +46,29 @@ let z = zip([i*j for i in 1:3, j in -1:2:1], 1:6) (1, 4) (2, 5) (3, 6) ] - @test eltype(z) == Tuple{Int,Int} + @test (@inferred eltype(z)) == Tuple{Int,Int} @test_throws DimensionMismatch size(z) @test_throws DimensionMismatch axes(z) - @test length(z) == 6 + @test (@inferred length(z)) == 6 end let z = zip([i*j for i in 1:3, j in -1:2:1], [i*j for i in 1:3, j in -1:2:1]) @test collect(z) == [(-1, -1) (1, 1) (-2, -2) (2, 2) (-3, -3) (3, 3)] - @test eltype(z) == Tuple{Int,Int} - @test size(z) == (3, 2) - @test axes(z) == (Base.OneTo(3), Base.OneTo(2)) - @test length(z) == 6 + @test (@inferred eltype(z)) == Tuple{Int,Int} + @test (@inferred size(z)) == (3, 2) + @test (@inferred axes(z)) == (Base.OneTo(3), Base.OneTo(2)) + @test (@inferred length(z)) == 6 end let z = zip(1:2, 3:4, 5:6) - @test size(z) == (2,) + @test (@inferred size(z)) == (2,) @test collect(z) == [(1,3,5), (2,4,6)] - @test eltype(z) == Tuple{Int,Int,Int} + @test (@inferred eltype(z)) == Tuple{Int,Int,Int} end -@test eltype(Iterators.filter(isodd, 1:5)) == Int +@test (@inferred eltype(Iterators.filter(isodd, 1:5))) == Int # typed `collect` @test collect(Float64, Iterators.filter(isodd, [1,2,3,4]))[1] === 1.0 @@ -102,10 +102,10 @@ let zeb = IOBuffer("1\n2\n3\n4\n5\n"), @test res == [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')] end -@test length(zip(cycle(1:3), 1:7)) == 7 -@test length(zip(cycle(1:3), 1:7, cycle(1:3))) == 7 -@test length(zip(1:3,product(1:7,cycle(1:3)))) == 3 -@test length(zip(1:3,product(1:7,cycle(1:3)),8)) == 1 +@test (@inferred length(zip(cycle(1:3), 1:7))) == 7 +@test (@inferred length(zip(cycle(1:3), 1:7, cycle(1:3)))) == 7 +@test (@inferred length(zip(1:3,product(1:7,cycle(1:3))))) == 3 +@test (@inferred length(zip(1:3,product(1:7,cycle(1:3)),8))) == 1 @test_throws ArgumentError length(zip()) # length of zip of empty tuple # map @@ -154,7 +154,7 @@ end # take # ---- let t = take(0:2:8, 10), i = 0 - @test length(collect(t)) == 5 == length(t) + @test length(collect(t)) == 5 == @inferred length(t) for j = t @test j == i*2 @@ -171,11 +171,11 @@ let i = 0 @test i == 10 end -@test isempty(take(0:2:8, 0)) +@test @inferred isempty(take(0:2:8, 0)) @test_throws ArgumentError take(0:2:8, -1) -@test length(take(1:3,typemax(Int))) == 3 -@test length(take(countfrom(1),3)) == 3 -@test length(take(1:6,3)) == 3 +@test (@inferred length(take(1:3,typemax(Int)))) == 3 +@test (@inferred length(take(countfrom(1),3))) == 3 +@test (@inferred length(take(1:6,3))) == 3 # drop # ---- @@ -187,15 +187,15 @@ let i = 0 @test i == 4 end -@test isempty(drop(0:2:10, 100)) -@test isempty(collect(drop(0:2:10, 100))) +@test @inferred isempty(drop(0:2:10, 100)) +@test @inferred isempty(collect(drop(0:2:10, 100))) @test_throws ArgumentError drop(0:2:8, -1) -@test length(drop(1:3,typemax(Int))) == 0 -@test length(drop(UInt(1):2, 3)) == 0 -@test length(drop(StepRangeLen(1, 1, UInt(2)), 3)) == 0 -@test Base.IteratorSize(drop(countfrom(1),3)) == Base.IsInfinite() +@test (@inferred length(drop(1:3,typemax(Int)))) == 0 +@test (@inferred length(drop(UInt(1):2, 3))) == 0 +@test (@inferred length(drop(StepRangeLen(1, 1, UInt(2)), 3))) == 0 +@test (@inferred Base.IteratorSize(drop(countfrom(1),3))) == Base.IsInfinite() @test_throws MethodError length(drop(countfrom(1), 3)) -@test Base.IteratorSize(Iterators.drop(Iterators.filter(i -> i>0, 1:10), 2)) == Base.SizeUnknown() +@test (@inferred Base.IteratorSize(Iterators.drop(Iterators.filter(i -> i>0, 1:10), 2))) == Base.SizeUnknown() let x = Iterators.drop(Iterators.Stateful("abc"), 2) @test !Base.isdone(x, nothing) @@ -212,7 +212,7 @@ for xs in Any["abc", [1, 2, 3]] @test drop(drop(xs, 1), 1) === drop(xs, 2) @test take(drop(xs, 1), 1) === drop(take(xs, 2), 1) @test take(drop(xs, 3), 0) === drop(take(xs, 2), 3) - @test isempty(drop(drop(xs, 2), 2)) + @test @inferred isempty(drop(drop(xs, 2), 2)) @test drop(take(drop(xs, 1), 2), 1) === take(drop(xs, 2), 1) @test take(drop(take(xs, 3), 1), 1) === take(drop(xs, 1), 1) end @@ -226,7 +226,7 @@ end @test collect(takewhile(Returns(true),5:10)) == 5:10 @test collect(takewhile(isodd,[1,1,2,3])) == [1,1] @test collect(takewhile(<(2), takewhile(<(3), [1,1,2,3]))) == [1,1] - @test Base.IteratorEltype(typeof(takewhile(<(4),Iterators.map(identity, 1:10)))) isa Base.EltypeUnknown + @test (@inferred Base.IteratorEltype(typeof(takewhile(<(4),Iterators.map(identity, 1:10))))) isa Base.EltypeUnknown end # dropwhile @@ -234,12 +234,12 @@ end @testset begin @test collect(dropwhile(<(4), 1:10)) == 4:10 @test collect(dropwhile(<(4), 1:10)) isa Vector{Int} - @test isempty(dropwhile(<(4), [])) + @test @inferred isempty(dropwhile(<(4), [])) @test collect(dropwhile(Returns(false),1:3)) == 1:3 - @test isempty(dropwhile(Returns(true), 1:3)) + @test @inferred isempty(dropwhile(Returns(true), 1:3)) @test collect(dropwhile(isodd,[1,1,2,3])) == [2,3] @test collect(dropwhile(iseven,dropwhile(isodd,[1,1,2,3]))) == [3] - @test Base.IteratorEltype(typeof(dropwhile(<(4),Iterators.map(identity, 1:10)))) isa Base.EltypeUnknown + @test (@inferred Base.IteratorEltype(typeof(dropwhile(<(4),Iterators.map(identity, 1:10))))) isa Base.EltypeUnknown end # cycle @@ -259,15 +259,15 @@ end @test collect(cycle(Iterators.filter(iseven, 1:4), 2)) == [2, 4, 2, 4] @test collect(take(cycle(countfrom(11), 3), 4)) == 11:14 - @test isempty(cycle(1:0)) == isempty(cycle(1:0, 3)) == true - @test isempty(cycle(1:5, 0)) - @test isempty(cycle(Iterators.filter(iseven, 1:4), 0)) + @test (@inferred isempty(cycle(1:0))) == (@inferred isempty(cycle(1:0, 3))) == true + @test @inferred isempty(cycle(1:5, 0)) + @test @inferred isempty(cycle(Iterators.filter(iseven, 1:4), 0)) - @test eltype(cycle(0:3, 2)) === Int - @test Base.IteratorEltype(cycle(0:3, 2)) == Base.HasEltype() + @test (@inferred eltype(cycle(0:3, 2))) === Int + @test (@inferred Base.IteratorEltype(cycle(0:3, 2))) == Base.HasEltype() Base.haslength(cycle(0:3, 2)) == false # but not sure we should test these - Base.IteratorSize(cycle(0:3, 2)) == Base.SizeUnknown() + (@inferred Base.IteratorSize(cycle(0:3, 2))) == Base.SizeUnknown() end # repeated @@ -286,13 +286,13 @@ let i = 0 i <= 10 || break end end -@test eltype(repeated(0)) == Int -@test eltype(repeated(0, 5)) == Int -@test Base.IteratorSize(repeated(0)) == Base.IsInfinite() -@test Base.IteratorSize(repeated(0, 5)) == Base.HasLength() -@test Base.IteratorEltype(repeated(0)) == Base.HasEltype() -@test Base.IteratorEltype(repeated(0, 5)) == Base.HasEltype() -@test Base.IteratorSize(zip(repeated(0), repeated(0))) == Base.IsInfinite() +@test (@inferred eltype(repeated(0))) == Int +@test (@inferred eltype(repeated(0, 5))) == Int +@test (@inferred Base.IteratorSize(repeated(0))) == Base.IsInfinite() +@test (@inferred Base.IteratorSize(repeated(0, 5))) == Base.HasLength() +@test (@inferred Base.IteratorEltype(repeated(0))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(repeated(0, 5))) == Base.HasEltype() +@test (@inferred Base.IteratorSize(zip(repeated(0), repeated(0)))) == Base.IsInfinite() # product # ------- @@ -304,8 +304,8 @@ for itr in [product(1:0), product(1:0, 1:1, 1:2), product(1:1, 1:0, 1:2), product(1:1, 1:2 ,1:0)] - @test isempty(itr) - @test isempty(collect(itr)) + @test @inferred isempty(itr) + @test @inferred isempty(collect(itr)) end # collect a product - first iterators runs faster @@ -325,10 +325,10 @@ end let (a, b) = (1:3, [4 6; 5 7]) p = product(a, b) - @test size(p) == (3, 2, 2) - @test length(p) == 12 - @test ndims(p) == 3 - @test eltype(p) == NTuple{2, Int} + @test (@inferred size(p)) == (3, 2, 2) + @test (@inferred length(p)) == 12 + @test (@inferred ndims(p)) == 3 + @test (@inferred eltype(p)) == NTuple{2, Int} cp = collect(p) for i = 1:3 @test cp[i, :, :] == [(i, 4) (i, 6); @@ -356,28 +356,28 @@ let a = 1:2, c = Int32(1):Int32(0) # length - @test length(product()) == 1 - @test length(product(a)) == 2 - @test length(product(a, b)) == 20 - @test length(product(a, b, c)) == 0 + @test (@inferred length(product())) == 1 + @test (@inferred length(product(a))) == 2 + @test (@inferred length(product(a, b))) == 20 + @test (@inferred length(product(a, b, c))) == 0 # size - @test size(product()) == tuple() - @test size(product(a)) == (2,) - @test size(product(a, b)) == (2, 10) - @test size(product(a, b, c)) == (2, 10, 0) + @test (@inferred size(product())) == tuple() + @test (@inferred size(product(a))) == (2,) + @test (@inferred size(product(a, b))) == (2, 10) + @test (@inferred size(product(a, b, c))) == (2, 10, 0) # eltype - @test eltype(product()) == Tuple{} - @test eltype(product(a)) == Tuple{Int} - @test eltype(product(a, b)) == Tuple{Int, Float64} - @test eltype(product(a, b, c)) == Tuple{Int, Float64, Int32} + @test (@inferred eltype(product())) == Tuple{} + @test (@inferred eltype(product(a))) == Tuple{Int} + @test (@inferred eltype(product(a, b))) == Tuple{Int, Float64} + @test (@inferred eltype(product(a, b, c))) == Tuple{Int, Float64, Int32} # ndims - @test ndims(product()) == 0 - @test ndims(product(a)) == 1 - @test ndims(product(a, b)) == 2 - @test ndims(product(a, b, c)) == 3 + @test (@inferred ndims(product())) == 0 + @test (@inferred ndims(product(a))) == 1 + @test (@inferred ndims(product(a, b))) == 2 + @test (@inferred ndims(product(a, b, c))) == 3 end # with multidimensional inputs @@ -397,7 +397,7 @@ let a = randn(4, 4), (4, 4, 3, 3, 3, 2, 2, 2, 2)] for (method, fun) in zip([size, ndims, length], [x->x, length, prod]) for i in 1:length(args) - @test method(product(args[i]...)) == method(collect(product(args[i]...))) == fun(sizes[i]) + @test (@inferred method(product(args[i]...))) == method(collect(product(args[i]...))) == fun(sizes[i]) end end end @@ -413,7 +413,7 @@ let iters = (1:2, for method in [size, length, ndims, eltype] for i = 1:length(iters) args = (iters[i],) - @test method(product(args...)) == method(collect(product(args...))) + @test (@inferred method(product(args...))) == method(collect(product(args...))) for j = 1:length(iters) args = iters[i], iters[j] @test method(product(args...)) == method(collect(product(args...))) @@ -455,48 +455,48 @@ end # IteratorSize trait business let f1 = Iterators.filter(i->i>0, 1:10) - @test Base.IteratorSize(product(f1)) == Base.SizeUnknown() - @test Base.IteratorSize(product(1:2, f1)) == Base.SizeUnknown() - @test Base.IteratorSize(product(f1, 1:2)) == Base.SizeUnknown() - @test Base.IteratorSize(product(f1, f1)) == Base.SizeUnknown() - @test Base.IteratorSize(product(f1, countfrom(1))) == Base.IsInfinite() - @test Base.IteratorSize(product(countfrom(1), f1)) == Base.IsInfinite() -end -@test Base.IteratorSize(product(1:2, countfrom(1))) == Base.IsInfinite() -@test Base.IteratorSize(product(countfrom(2), countfrom(1))) == Base.IsInfinite() -@test Base.IteratorSize(product(countfrom(1), 1:2)) == Base.IsInfinite() -@test Base.IteratorSize(product(1:2)) == Base.HasShape{1}() -@test Base.IteratorSize(product(1:2, 1:2)) == Base.HasShape{2}() -@test Base.IteratorSize(product(take(1:2, 1), take(1:2, 1))) == Base.HasShape{2}() -@test Base.IteratorSize(product(take(1:2, 2))) == Base.HasShape{1}() -@test Base.IteratorSize(product([1 2; 3 4])) == Base.HasShape{2}() -@test Base.IteratorSize(product((1,2,3,4), (5, 6, 7, 8))) == Base.HasShape{2}() # product of ::HasLength and ::HasLength -@test Base.IteratorSize(product(1:2, 3:5, 5:6)) == Base.HasShape{3}() # product of 3 iterators -@test Base.IteratorSize(product([1 2; 3 4], 1:4)) == Base.HasShape{3}() # product of ::HasShape{2} with ::HasShape{1} -@test Base.IteratorSize(product([1 2; 3 4], (1,2))) == Base.HasShape{3}() # product of ::HasShape{2} with ::HasLength + @test (@inferred Base.IteratorSize(product(f1))) == Base.SizeUnknown() + @test (@inferred Base.IteratorSize(product(1:2, f1))) == Base.SizeUnknown() + @test (@inferred Base.IteratorSize(product(f1, 1:2))) == Base.SizeUnknown() + @test (@inferred Base.IteratorSize(product(f1, f1))) == Base.SizeUnknown() + @test (@inferred Base.IteratorSize(product(f1, countfrom(1)))) == Base.IsInfinite() + @test (@inferred Base.IteratorSize(product(countfrom(1), f1))) == Base.IsInfinite() +end +@test (@inferred Base.IteratorSize(product(1:2, countfrom(1)))) == Base.IsInfinite() +@test (@inferred Base.IteratorSize(product(countfrom(2), countfrom(1)))) == Base.IsInfinite() +@test (@inferred Base.IteratorSize(product(countfrom(1), 1:2))) == Base.IsInfinite() +@test (@inferred Base.IteratorSize(product(1:2))) == Base.HasShape{1}() +@test (@inferred Base.IteratorSize(product(1:2, 1:2))) == Base.HasShape{2}() +@test (@inferred Base.IteratorSize(product(take(1:2, 1), take(1:2, 1)))) == Base.HasShape{2}() +@test (@inferred Base.IteratorSize(product(take(1:2, 2)))) == Base.HasShape{1}() +@test (@inferred Base.IteratorSize(product([1 2; 3 4]))) == Base.HasShape{2}() +@test (@inferred Base.IteratorSize(product((1,2,3,4), (5, 6, 7, 8)))) == Base.HasShape{2}() # product of ::HasLength and ::HasLength +@test (@inferred Base.IteratorSize(product(1:2, 3:5, 5:6))) == Base.HasShape{3}() # product of 3 iterators +@test (@inferred Base.IteratorSize(product([1 2; 3 4], 1:4))) == Base.HasShape{3}() # product of ::HasShape{2} with ::HasShape{1} +@test (@inferred Base.IteratorSize(product([1 2; 3 4], (1,2)))) == Base.HasShape{3}() # product of ::HasShape{2} with ::HasLength # IteratorEltype trait business let f1 = Iterators.filter(i->i>0, 1:10) - @test Base.IteratorEltype(product(f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.IteratorEltype(product(1:2, f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.IteratorEltype(product(f1, 1:2)) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.IteratorEltype(product(f1, f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.IteratorEltype(product(f1, countfrom(1))) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.IteratorEltype(product(countfrom(1), f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any -end -@test Base.IteratorEltype(product(1:2, countfrom(1))) == Base.HasEltype() -@test Base.IteratorEltype(product(countfrom(1), 1:2)) == Base.HasEltype() -@test Base.IteratorEltype(product(1:2)) == Base.HasEltype() -@test Base.IteratorEltype(product(1:2, 1:2)) == Base.HasEltype() -@test Base.IteratorEltype(product(take(1:2, 1), take(1:2, 1))) == Base.HasEltype() -@test Base.IteratorEltype(product(take(1:2, 2))) == Base.HasEltype() -@test Base.IteratorEltype(product([1 2; 3 4])) == Base.HasEltype() -@test Base.IteratorEltype(product()) == Base.HasEltype() + @test (@inferred Base.IteratorEltype(product(f1))) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test (@inferred Base.IteratorEltype(product(1:2, f1))) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test (@inferred Base.IteratorEltype(product(f1, 1:2))) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test (@inferred Base.IteratorEltype(product(f1, f1))) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test (@inferred Base.IteratorEltype(product(f1, countfrom(1)))) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test (@inferred Base.IteratorEltype(product(countfrom(1), f1))) == Base.HasEltype() # FIXME? eltype(f1) is Any +end +@test (@inferred Base.IteratorEltype(product(1:2, countfrom(1)))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product(countfrom(1), 1:2))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product(1:2))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product(1:2, 1:2))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product(take(1:2, 1), take(1:2, 1)))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product(take(1:2, 2)))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product([1 2; 3 4]))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product())) == Base.HasEltype() @test collect(product(1:2,3:4)) == [(1,3) (1,4); (2,3) (2,4)] -@test isempty(collect(product(1:0,1:2))) -@test length(product(1:2,1:10,4:6)) == 60 -@test Base.IteratorSize(product(1:2, countfrom(1))) == Base.IsInfinite() +@test @inferred isempty(collect(product(1:0,1:2))) +@test (@inferred length(product(1:2,1:10,4:6))) == 60 +@test (@inferred Base.IteratorSize(product(1:2, countfrom(1)))) == Base.IsInfinite() @test Base.iterate(product()) == ((), true) @test Base.iterate(product(), 1) === nothing @@ -512,31 +512,31 @@ end @test collect(flatten(Any[flatten(Any[1:2, 4:5]), flatten(Any[6:7, 8:9])])) == Any[1,2,4,5,6,7,8,9] @test collect(flatten(Any[flatten(Any[1:2, 6:5]), flatten(Any[6:7, 8:9])])) == Any[1,2,6,7,8,9] @test collect(flatten(Any[2:1])) == Any[] -@test eltype(flatten(UnitRange{Int8}[1:2, 3:4])) == Int8 -@test eltype(flatten(([1, 2], [3.0, 4.0]))) == Real -@test eltype(flatten((a = [1, 2], b = Int8[3, 4]))) == Signed -@test eltype(flatten((Int[], Nothing[], Int[]))) == Union{Int, Nothing} -@test eltype(flatten((String[],))) == String -@test eltype(flatten((Int[], UInt[], Int8[],))) == Integer -@test eltype(flatten((; a = Int[], b = Nothing[], c = Int[]))) == Union{Int, Nothing} -@test eltype(flatten((; a = String[],))) == String -@test eltype(flatten((; a = Int[], b = UInt[], c = Int8[],))) == Integer -@test eltype(flatten(())) == Union{} -@test eltype(flatten((;))) == Union{} -@test length(flatten(zip(1:3, 4:6))) == 6 -@test length(flatten(1:6)) == 6 +@test (@inferred eltype(flatten(UnitRange{Int8}[1:2, 3:4]))) == Int8 +@test (@inferred eltype(flatten(([1, 2], [3.0, 4.0])))) == Real +@test (@inferred eltype(flatten((a = [1, 2], b = Int8[3, 4])))) == Signed +@test (@inferred eltype(flatten((Int[], Nothing[], Int[])))) == Union{Int, Nothing} +@test (@inferred eltype(flatten((String[],)))) == String +@test (@inferred eltype(flatten((Int[], UInt[], Int8[],)))) == Integer +@test (@inferred eltype(flatten((; a = Int[], b = Nothing[], c = Int[])))) == Union{Int, Nothing} +@test (@inferred eltype(flatten((; a = String[],)))) == String +@test (@inferred eltype(flatten((; a = Int[], b = UInt[], c = Int8[],)))) == Integer +@test (@inferred eltype(flatten(()))) == Union{} +@test (@inferred eltype(flatten((;)))) == Union{} +@test (@inferred length(flatten(zip(1:3, 4:6)))) == 6 +@test (@inferred length(flatten(1:6))) == 6 @test collect(flatten(Any[])) == Any[] @test collect(flatten(())) == Union{}[] @test_throws ArgumentError length(flatten(NTuple[(1,), ()])) # #16680 @test_throws ArgumentError length(flatten([[1], [1]])) @testset "IteratorSize trait for flatten" begin - @test Base.IteratorSize(Base.Flatten((i for i=1:2) for j=1:1)) == Base.SizeUnknown() - @test Base.IteratorSize(Base.Flatten((1,2))) == Base.HasLength() - @test Base.IteratorSize(Base.Flatten(1:2:4)) == Base.HasLength() + @test (@inferred Base.IteratorSize(Base.Flatten((i for i=1:2) for j=1:1))) == Base.SizeUnknown() + @test (@inferred Base.IteratorSize(Base.Flatten((1,2)))) == Base.HasLength() + @test (@inferred Base.IteratorSize(Base.Flatten(1:2:4))) == Base.HasLength() end -@test Base.IteratorEltype(Base.Flatten((i for i=1:2) for j=1:1)) == Base.EltypeUnknown() +@test (@inferred Base.IteratorEltype(Base.Flatten((i for i=1:2) for j=1:1))) == Base.EltypeUnknown() # see #29112, #29464, #29548 @test Base.return_types(Base.IteratorEltype, Tuple{Array}) == [Base.HasEltype] @@ -656,21 +656,21 @@ end @test_throws ArgumentError partition(1:10, -1) @test_throws ArgumentError partition(1:0, 0) @test_throws ArgumentError partition(1:0, -1) - @test isempty(partition(1:0, 1)) - @test isempty(partition(CartesianIndices((0,1)), 1)) + @test @inferred isempty(partition(1:0, 1)) + @test @inferred isempty(partition(CartesianIndices((0,1)), 1)) end @testset "exact partition eltypes" for a in (Base.OneTo(24), 1:24, 1:1:24, LinRange(1,10,24), .1:.1:2.4, Vector(1:24), CartesianIndices((4, 6)), Dict((1:24) .=> (1:24))) P = partition(a, 2) - @test eltype(P) === typeof(first(P)) - @test Iterators.IteratorEltype(P) == Iterators.HasEltype() + @test (@inferred eltype(P)) === typeof(first(P)) + @test (@inferred Iterators.IteratorEltype(P)) == Iterators.HasEltype() if a isa AbstractArray P = partition(vec(a), 2) - @test eltype(P) === typeof(first(P)) + @test (@inferred eltype(P)) === typeof(first(P)) P = partition(reshape(a, 6, 4), 2) - @test eltype(P) === typeof(first(P)) + @test (@inferred eltype(P)) === typeof(first(P)) P = partition(reshape(a, 2, 3, 4), 2) - @test eltype(P) === typeof(first(P)) + @test (@inferred eltype(P)) === typeof(first(P)) end end @@ -691,19 +691,19 @@ let s = "Monkey 🙈🙊🙊" @test tf(1) == "M|o|n|k|e|y| |🙈|🙊|🙊" end -@test Base.IteratorEltype(partition([1,2,3,4], 2)) == Base.HasEltype() -@test Base.IteratorEltype(partition((2x for x in 1:3), 2)) == Base.EltypeUnknown() +@test (@inferred Base.IteratorEltype(partition([1,2,3,4], 2))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(partition((2x for x in 1:3), 2))) == Base.EltypeUnknown() # take and friends with arbitrary integers (#19214) for T in (UInt8, UInt16, UInt32, UInt64, UInt128, Int8, Int16, Int128, BigInt) - @test length(take(1:6, T(3))) == 3 - @test length(drop(1:6, T(3))) == 3 - @test length(repeated(1, T(5))) == 5 + @test (@inferred length(take(1:6, T(3)))) == 3 + @test (@inferred length(drop(1:6, T(3)))) == 3 + @test (@inferred length(repeated(1, T(5)))) == 5 @test collect(partition(1:5, T(5)))[1] == 1:5 end @testset "collect finite iterators issue #12009" begin - @test eltype(collect(enumerate(Iterators.Filter(x -> x>0, randn(10))))) == Tuple{Int, Float64} + @test (@inferred eltype(collect(enumerate(Iterators.Filter(x -> x>0, randn(10)))))) == Tuple{Int, Float64} end @testset "product iterator infinite loop" begin @@ -712,8 +712,8 @@ end @testset "filter empty iterable #16704" begin arr = filter(Returns(true), 1:0) - @test length(arr) == 0 - @test eltype(arr) == Int + @test (@inferred length(arr)) == 0 + @test (@inferred eltype(arr)) == Int end @testset "Pairs type" begin @@ -727,19 +727,19 @@ end ) d = pairs(A) @test d === pairs(d) - @test isempty(d) == isempty(A) - @test length(d) == length(A) + @test (@inferred isempty(d)) == isempty(A) + @test (@inferred length(d)) == length(A) @test keys(d) == keys(A) @test values(d) == A - @test Base.IteratorSize(d) == Base.IteratorSize(A) - @test Base.IteratorEltype(d) == Base.HasEltype() - @test Base.IteratorSize(pairs([1 2;3 4])) isa Base.HasShape{2} - @test isempty(d) || haskey(d, first(keys(d))) + @test (@inferred Base.IteratorSize(d)) == Base.IteratorSize(A) + @test (@inferred Base.IteratorEltype(d)) == Base.HasEltype() + @test (@inferred Base.IteratorSize(pairs([1 2;3 4]))) isa Base.HasShape{2} + @test (@inferred isempty(d)) || haskey(d, first(keys(d))) @test collect(v for (k, v) in d) == collect(A) if A isa NamedTuple K = Symbol V = isempty(d) ? Union{} : Float64 - @test isempty(d) || haskey(d, :a) + @test (@inferred isempty(d)) || haskey(d, :a) @test !haskey(d, :abc) @test !haskey(d, 1) @test get(A, :key) do; 99; end == 99 @@ -759,7 +759,7 @@ end end @test keytype(d) == K @test valtype(d) == V - @test eltype(d) == Pair{K, V} + @test (@inferred eltype(d)) == Pair{K, V} end let io = IOBuffer() @@ -806,7 +806,7 @@ end @testset "Iterators.Stateful" begin let a = @inferred(Iterators.Stateful("abcdef")) - @test !isempty(a) + @test !(@inferred isempty(a)) @test popfirst!(a) == 'a' @test collect(Iterators.take(a, 3)) == ['b','c','d'] @test collect(a) == ['e', 'f'] @@ -817,63 +817,63 @@ end @test peek(a) == 3 @test sum(a) == 7 end - @test eltype(Iterators.Stateful("a")) == Char + @test (@inferred eltype(Iterators.Stateful("a"))) == Char # Interaction of zip/Stateful let a = Iterators.Stateful("a"), b = "" - @test isempty(collect(zip(a,b))) - @test !isempty(a) - @test isempty(collect(zip(b,a))) - @test !isempty(a) + @test @inferred isempty(collect(zip(a,b))) + @test !(@inferred isempty(a)) + @test @inferred isempty(collect(zip(b,a))) + @test !(@inferred isempty(a)) end let a = Iterators.Stateful("a"), b = "", c = Iterators.Stateful("c") - @test isempty(collect(zip(a,b,c))) - @test !isempty(a) - @test !isempty(c) - @test isempty(collect(zip(a,c,b))) - @test !isempty(a) - @test !isempty(c) - @test isempty(collect(zip(b,a,c))) - @test !isempty(a) - @test !isempty(c) - @test isempty(collect(zip(b,c,a))) - @test !isempty(a) - @test !isempty(c) - @test isempty(collect(zip(c,a,b))) - @test !isempty(a) - @test !isempty(c) - @test isempty(collect(zip(c,b,a))) - @test !isempty(a) - @test !isempty(c) + @test @inferred isempty(collect(zip(a,b,c))) + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) + @test @inferred isempty(collect(zip(a,c,b))) + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) + @test @inferred isempty(collect(zip(b,a,c))) + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) + @test @inferred isempty(collect(zip(b,c,a))) + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) + @test @inferred isempty(collect(zip(c,a,b))) + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) + @test @inferred isempty(collect(zip(c,b,a))) + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let a = Iterators.Stateful("aa"), b = "b", c = Iterators.Stateful("cc") - @test length(collect(zip(a,b,c))) == 1 - @test !isempty(a) - @test !isempty(c) + @test (@inferred length(collect(zip(a,b,c)))) == 1 + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let a = Iterators.Stateful("aa"), b = "b", c = Iterators.Stateful("cc") - @test length(collect(zip(a,c,b))) == 1 - @test !isempty(a) - @test !isempty(c) + @test (@inferred length(collect(zip(a,c,b)))) == 1 + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let a = Iterators.Stateful("aa"), b = "b", c = Iterators.Stateful("cc") - @test length(collect(zip(b,a,c))) == 1 - @test !isempty(a) - @test !isempty(c) + @test (@inferred length(collect(zip(b,a,c)))) == 1 + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let a = Iterators.Stateful("aa"), b = "b", c = Iterators.Stateful("cc") - @test length(collect(zip(b,c,a))) == 1 - @test !isempty(a) - @test !isempty(c) + @test (@inferred length(collect(zip(b,c,a)))) == 1 + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let a = Iterators.Stateful("aa"), b = "b", c = Iterators.Stateful("cc") - @test length(collect(zip(c,a,b))) == 1 - @test !isempty(a) - @test !isempty(c) + @test (@inferred length(collect(zip(c,a,b)))) == 1 + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let a = Iterators.Stateful("aa"), b = "b", c = Iterators.Stateful("cc") - @test length(collect(zip(c,b,a))) == 1 - @test !isempty(a) - @test !isempty(c) + @test (@inferred length(collect(zip(c,b,a)))) == 1 + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let z = zip(Iterators.Stateful("ab"), Iterators.Stateful("b"), Iterators.Stateful("c")) v, s = iterate(z) @@ -894,10 +894,10 @@ end @testset "inference for large zip #26765" begin x = zip(1:2, ["a", "b"], (1.0, 2.0), Base.OneTo(2), Iterators.repeated("a"), 1.0:0.2:2.0, (1 for i in 1:2), Iterators.Stateful(["a", "b", "c"]), (1.0 for i in 1:2, j in 1:3)) - @test Base.IteratorSize(x) isa Base.SizeUnknown + @test (@inferred Base.IteratorSize(x)) isa Base.SizeUnknown x = zip(1:2, ["a", "b"], (1.0, 2.0), Base.OneTo(2), Iterators.repeated("a"), 1.0:0.2:2.0, (1 for i in 1:2), Iterators.cycle(Iterators.Stateful(["a", "b", "c"])), (1.0 for i in 1:2, j in 1:3)) - @test Base.IteratorSize(x) isa Base.HasLength + @test (@inferred Base.IteratorSize(x)) isa Base.HasLength @test @inferred(length(x)) == 2 z = Iterators.filter(x -> x[1] >= 1, x) @test @inferred(eltype(z)) <: Tuple{Int,String,Float64,Int,String,Float64,Any,String,Any} @@ -906,23 +906,23 @@ end end @testset "Stateful fix #30643" begin - @test Base.IteratorSize(1:10) isa Base.HasShape{1} + @test (@inferred Base.IteratorSize(1:10)) isa Base.HasShape{1} a = Iterators.Stateful(1:10) - @test Base.IteratorSize(a) isa Base.SizeUnknown + @test (@inferred Base.IteratorSize(a)) isa Base.SizeUnknown @test !Base.isdone(a) @test length(collect(a)) == 10 @test Base.isdone(a) b = Iterators.Stateful(Iterators.take(1:10,3)) - @test Base.IteratorSize(b) isa Base.SizeUnknown + @test (@inferred Base.IteratorSize(b)) isa Base.SizeUnknown @test !Base.isdone(b) @test length(collect(b)) == 3 @test Base.isdone(b) c = Iterators.Stateful(Iterators.countfrom(1)) - @test Base.IteratorSize(c) isa Base.IsInfinite + @test (@inferred Base.IteratorSize(c)) isa Base.IsInfinite @test !Base.isdone(Iterators.take(c,3)) @test length(collect(Iterators.take(c,3))) == 3 d = Iterators.Stateful(Iterators.filter(isodd,1:10)) - @test Base.IteratorSize(d) isa Base.SizeUnknown + @test (@inferred Base.IteratorSize(d)) isa Base.SizeUnknown @test length(collect(Iterators.take(d,3))) == 3 @test length(collect(d)) == 2 @test length(collect(d)) == 0 @@ -964,7 +964,7 @@ end end @testset "flatten empty tuple" begin - @test isempty(collect(Iterators.flatten(()))) + @test @inferred isempty(collect(Iterators.flatten(()))) end @testset "Iterators.accumulate" begin @@ -976,10 +976,10 @@ end @test collect(Iterators.accumulate(+, (x for x in [true])))::Vector{Int} == [1] @test collect(Iterators.accumulate(+, (x for x in [true, true, false])))::Vector{Int} == [1, 2, 2] @test collect(Iterators.accumulate(+, (x for x in [true]), init=10.0))::Vector{Float64} == [11.0] - @test length(Iterators.accumulate(+, [10,20,30])) == 3 - @test size(Iterators.accumulate(max, rand(2,3))) == (2,3) - @test Base.IteratorSize(Iterators.accumulate(max, rand(2,3))) === Base.IteratorSize(rand(2,3)) - @test Base.IteratorEltype(Iterators.accumulate(*, ())) isa Base.EltypeUnknown + @test (@inferred length(Iterators.accumulate(+, [10,20,30]))) == 3 + @test (@inferred size(Iterators.accumulate(max, rand(2,3)))) == (2,3) + @test (@inferred Base.IteratorSize(Iterators.accumulate(max, rand(2,3)))) === Base.IteratorSize(rand(2,3)) + @test (@inferred Base.IteratorEltype(Iterators.accumulate(*, ()))) isa Base.EltypeUnknown end @testset "Base.accumulate" begin @@ -989,13 +989,13 @@ end end @testset "IteratorSize trait for zip" begin - @test Base.IteratorSize(zip()) == Base.IsInfinite() # for zip of empty tuple - @test Base.IteratorSize(zip((1,2,3), repeated(0))) == Base.HasLength() # for zip of ::HasLength and ::IsInfinite - @test Base.IteratorSize(zip( 1:5, repeated(0) )) == Base.HasLength() # for zip of ::HasShape and ::IsInfinite - @test Base.IteratorSize(zip(repeated(0), (1,2,3))) == Base.HasLength() # for zip of ::IsInfinite and ::HasLength - @test Base.IteratorSize(zip(repeated(0), 1:5 )) == Base.HasLength() # for zip of ::IsInfinite and ::HasShape - @test Base.IteratorSize(zip((1,2,3), 1:5) ) == Base.HasLength() # for zip of ::HasLength and ::HasShape - @test Base.IteratorSize(zip(1:5, (1,2,3)) ) == Base.HasLength() # for zip of ::HasShape and ::HasLength + @test (@inferred Base.IteratorSize(zip())) == Base.IsInfinite() # for zip of empty tuple + @test (@inferred Base.IteratorSize(zip((1,2,3), repeated(0)))) == Base.HasLength() # for zip of ::HasLength and ::IsInfinite + @test (@inferred Base.IteratorSize(zip( 1:5, repeated(0) ))) == Base.HasLength() # for zip of ::HasShape and ::IsInfinite + @test (@inferred Base.IteratorSize(zip(repeated(0), (1,2,3)))) == Base.HasLength() # for zip of ::IsInfinite and ::HasLength + @test (@inferred Base.IteratorSize(zip(repeated(0), 1:5 ))) == Base.HasLength() # for zip of ::IsInfinite and ::HasShape + @test (@inferred Base.IteratorSize(zip((1,2,3), 1:5) )) == Base.HasLength() # for zip of ::HasLength and ::HasShape + @test (@inferred Base.IteratorSize(zip(1:5, (1,2,3)) )) == Base.HasLength() # for zip of ::HasShape and ::HasLength end @testset "proper partition for non-1-indexed vector" begin @@ -1018,7 +1018,7 @@ end @testset "isempty and isdone for Generators" begin itr = eachline(IOBuffer("foo\n")) gen = (x for x in itr) - @test !isempty(gen) + @test !(@inferred isempty(gen)) @test !Base.isdone(gen) @test collect(gen) == ["foo"] end From 316f0fe0b0e454093b44095bb99b273d4158bdc0 Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Thu, 16 Jan 2025 08:05:28 -0500 Subject: [PATCH 188/198] Construct proper URIs for paths when run on WSL in tests (#57061) https://github.com/JuliaLang/julia/pull/55454 produces the correct URIs when run on WSL, but the tests don't use the same logic and so they fail on WSL at the moment. This fixes the tests on WSL. CC @tecosaur --- test/path.jl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/path.jl b/test/path.jl index 4c2c7034577d5..2515d765d8ca9 100644 --- a/test/path.jl +++ b/test/path.jl @@ -312,7 +312,14 @@ end @testset "uripath" begin - host = if Sys.iswindows() "" else gethostname() end + host = if Sys.iswindows() + "" + elseif ispath("/proc/sys/fs/binfmt_misc/WSLInterop") + distro = get(ENV, "WSL_DISTRO_NAME", "") # See + "wsl%24/$distro" # See and + else + gethostname() + end sysdrive, uridrive = if Sys.iswindows() "C:\\", "C:/" else "/", "" end @test Base.Filesystem.uripath("$(sysdrive)some$(sep)file.txt") == "file://$host/$(uridrive)some/file.txt" @test Base.Filesystem.uripath("$(sysdrive)another$(sep)$(sep)folder$(sep)file.md") == "file://$host/$(uridrive)another/folder/file.md" From 0c7dd964f67d5a31750f5779d858c3d52aba931e Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Fri, 17 Jan 2025 01:54:24 -0500 Subject: [PATCH 189/198] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?SparseArrays=20stdlib=20from=205f52721=20to=20212981b=20(#57065?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: SparseArrays URL: https://github.com/JuliaSparse/SparseArrays.jl.git Stdlib branch: main Julia branch: master Old commit: 5f52721 New commit: 212981b Julia version: 1.12.0-DEV SparseArrays version: 1.12.0 Bump invoked by: @dkarrasch Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaSparse/SparseArrays.jl/compare/5f527215c188ee99247cdce31ba8ce9e11f35055...212981bf29b03ba460d3251ee9aa4399931b3f2d ``` $ git log --oneline 5f52721..212981b 212981b Solve with `AdjointFactorization` of Cholmod and `Adjoint` rhs (#595) ``` Co-authored-by: dkarrasch <26658441+dkarrasch@users.noreply.github.com> --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/SparseArrays.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/md5 create mode 100644 deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/sha512 delete mode 100644 deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 delete mode 100644 deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 diff --git a/deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/md5 b/deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/md5 new file mode 100644 index 0000000000000..3fddcf07235f8 --- /dev/null +++ b/deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/md5 @@ -0,0 +1 @@ +621e67dc98707b587fb0f6e319dadbb2 diff --git a/deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/sha512 b/deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/sha512 new file mode 100644 index 0000000000000..68885439a1213 --- /dev/null +++ b/deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/sha512 @@ -0,0 +1 @@ +5608adf92eaf7479eacf5ed75b3139438d0d4acf53d55a38c73a553c7fd899f553e1648fa657d35b9a0289e69fc461025dae5f8d15ec891eafcab3a663a8413a diff --git a/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 b/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 deleted file mode 100644 index 946bec189c1bd..0000000000000 --- a/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -4b07db52a5a6d3cc6eeab380bd783a1e diff --git a/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 b/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 deleted file mode 100644 index 846867193d932..0000000000000 --- a/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -4c631f1046ad0a6b972a4dce285c2092372ecbed269c83524c10b4be5124035670d703af53e1f8058d23230be20c06aa554097cc9bc7a12b3de3c039d3c545e8 diff --git a/stdlib/SparseArrays.version b/stdlib/SparseArrays.version index 3f6ab5b878069..0234c754191f8 100644 --- a/stdlib/SparseArrays.version +++ b/stdlib/SparseArrays.version @@ -1,4 +1,4 @@ SPARSEARRAYS_BRANCH = main -SPARSEARRAYS_SHA1 = 5f527215c188ee99247cdce31ba8ce9e11f35055 +SPARSEARRAYS_SHA1 = 212981bf29b03ba460d3251ee9aa4399931b3f2d SPARSEARRAYS_GIT_URL := https://github.com/JuliaSparse/SparseArrays.jl.git SPARSEARRAYS_TAR_URL = https://api.github.com/repos/JuliaSparse/SparseArrays.jl/tarball/$1 From 81e79e5bfc5ccfd9d8a8d5825d5a508f1009d7b2 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 17 Jan 2025 06:31:59 -0500 Subject: [PATCH 190/198] codegen: handle recursive sparam calls in API (#57047) Fixes #56690 --- src/ccall.cpp | 5 +--- src/codegen.cpp | 56 +++++++++++++++++++-------------------- src/llvm-codegen-shared.h | 23 ++++++++-------- 3 files changed, 40 insertions(+), 44 deletions(-) diff --git a/src/ccall.cpp b/src/ccall.cpp index 1b635ca40840f..eb64adef447f4 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -461,10 +461,7 @@ static Value *runtime_apply_type_env(jl_codectx_t &ctx, jl_value_t *ty) Value *args[] = { literal_pointer_val(ctx, ty), literal_pointer_val(ctx, (jl_value_t*)ctx.linfo->def.method->sig), - ctx.builder.CreateInBoundsGEP( - ctx.types().T_prjlvalue, - ctx.spvals_ptr, - ConstantInt::get(ctx.types().T_size, sizeof(jl_svec_t) / sizeof(jl_value_t*))) + emit_ptrgep(ctx, maybe_decay_tracked(ctx, ctx.spvals_ptr), sizeof(jl_svec_t)) }; auto call = ctx.builder.CreateCall(prepare_call(jlapplytype_func), ArrayRef(args)); addRetAttr(call, Attribute::getWithAlignment(ctx.builder.getContext(), Align(16))); diff --git a/src/codegen.cpp b/src/codegen.cpp index 7bc14d2d0347f..eefc675bdd665 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1263,12 +1263,11 @@ static const auto jlsubtype_func = new JuliaFunction<>{ static const auto jlapplytype_func = new JuliaFunction<>{ XSTR(jl_instantiate_type_in_env), [](LLVMContext &C) { - auto T_jlvalue = JuliaType::get_jlvalue_ty(C); - auto T_pjlvalue = PointerType::get(T_jlvalue, 0); - auto T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked); - auto T_pprjlvalue = PointerType::get(T_prjlvalue, 0); - return FunctionType::get(T_prjlvalue, - {T_pjlvalue, T_pjlvalue, T_pprjlvalue}, false); + auto T_ptr = PointerType::get(C, 0); + auto T_tracked = PointerType::get(C, AddressSpace::Tracked); + auto T_derived = PointerType::get(C, AddressSpace::Derived); + return FunctionType::get(T_tracked, + {T_ptr, T_ptr, T_derived}, false); }, [](LLVMContext &C) { return AttributeList::get(C, @@ -1377,11 +1376,10 @@ static const auto jlfieldisdefinedchecked_func = new JuliaFunction{ XSTR(jl_get_cfunction_trampoline), [](LLVMContext &C) { - auto T_jlvalue = JuliaType::get_jlvalue_ty(C); - auto T_pjlvalue = PointerType::get(T_jlvalue, 0); - auto T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked); - auto T_ppjlvalue = PointerType::get(T_pjlvalue, 0); - auto T_pprjlvalue = PointerType::get(T_prjlvalue, 0); + auto T_pjlvalue = PointerType::get(C, 0); + auto T_prjlvalue = PointerType::get(C, AddressSpace::Tracked); + auto T_ppjlvalue = PointerType::get(C, 0); + auto T_derived = PointerType::get(C, AddressSpace::Derived); return FunctionType::get(T_prjlvalue, { T_prjlvalue, // f (object) @@ -1390,7 +1388,7 @@ static const auto jlgetcfunctiontrampoline_func = new JuliaFunction<>{ T_pjlvalue, // fill FunctionType::get(getPointerTy(C), { getPointerTy(C), T_ppjlvalue }, false)->getPointerTo(), // trampoline T_pjlvalue, // env - T_pprjlvalue, // vals + T_derived, // vals }, false); }, [](LLVMContext &C) { return AttributeList::get(C, @@ -5610,18 +5608,23 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR assert(jl_is_method_instance(mi)); if (mi == ctx.linfo) { // handle self-recursion specially (TODO: assuming ci is a valid invoke for mi?) - jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; - FunctionType *ft = ctx.f->getFunctionType(); - StringRef protoname = ctx.f->getName(); + Function *f = ctx.f; + FunctionType *ft = f->getFunctionType(); if (ft == ctx.types().T_jlfunc) { - result = emit_call_specfun_boxed(ctx, ctx.rettype, protoname, nullptr, argv, nargs, rt, age_ok); - handled = true; + Value *ret = emit_jlcall(ctx, f, nullptr, argv, nargs, julia_call); + result = update_julia_type(ctx, mark_julia_type(ctx, ret, true, ctx.rettype), rt); } - else if (ft != ctx.types().T_jlfuncparams) { + else if (ft == ctx.types().T_jlfuncparams) { + Value *ret = emit_jlcall(ctx, f, ctx.spvals_ptr, argv, nargs, julia_call2); + result = update_julia_type(ctx, mark_julia_type(ctx, ret, true, ctx.rettype), rt); + } + else { unsigned return_roots = 0; + jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; + StringRef protoname = f->getName(); result = emit_call_specfun_other(ctx, mi, ctx.rettype, protoname, nullptr, argv, nargs, &cc, &return_roots, rt, age_ok); - handled = true; } + handled = true; } else { if (ci) { @@ -5630,7 +5633,6 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR // check if we know how to handle this specptr if (invoke == jl_fptr_const_return_addr) { result = mark_julia_const(ctx, codeinst->rettype_const); - handled = true; } else { bool specsig, needsparams; @@ -5640,8 +5642,8 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR push_frames(ctx, ctx.linfo, mi); Value *r = emit_jlcall(ctx, jlinvoke_func, track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)mi)), argv, nargs, julia_call2); result = mark_julia_type(ctx, r, true, rt); - handled = true; - } else { + } + else { std::string name; StringRef protoname; bool need_to_emit = true; @@ -5689,7 +5691,6 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR result = emit_call_specfun_other(ctx, codeinst, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt, age_ok); else result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, rt, age_ok); - handled = true; if (need_to_emit) { Function *trampoline_decl = cast(jl_Module->getNamedValue(protoname)); ctx.call_targets[codeinst] = {cc, return_roots, trampoline_decl, nullptr, specsig}; @@ -5698,6 +5699,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR } } } + handled = true; } } } @@ -6078,8 +6080,7 @@ static jl_cgval_t emit_sparam(jl_codectx_t &ctx, size_t i) return mark_julia_const(ctx, e); } } - assert(ctx.spvals_ptr != NULL); - Value *bp = emit_ptrgep(ctx, ctx.spvals_ptr, i * sizeof(jl_value_t*) + sizeof(jl_svec_t)); + Value *bp = emit_ptrgep(ctx, maybe_decay_tracked(ctx, ctx.spvals_ptr), i * sizeof(jl_value_t*) + sizeof(jl_svec_t)); jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); Value *sp = ai.decorateInst(ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*)))); setName(ctx.emission_context, sp, "sparam"); @@ -6131,8 +6132,7 @@ static jl_cgval_t emit_isdefined(jl_codectx_t &ctx, jl_value_t *sym, int allow_i return mark_julia_const(ctx, jl_true); } } - assert(ctx.spvals_ptr != NULL); - Value *bp = emit_ptrgep(ctx, ctx.spvals_ptr, i * sizeof(jl_value_t*) + sizeof(jl_svec_t)); + Value *bp = emit_ptrgep(ctx, maybe_decay_tracked(ctx, ctx.spvals_ptr), i * sizeof(jl_value_t*) + sizeof(jl_svec_t)); jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); Value *sp = ai.decorateInst(ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*)))); isnull = ctx.builder.CreateICmpNE(emit_typeof(ctx, sp, false, true), emit_tagfrom(ctx, jl_tvar_type)); @@ -8000,7 +8000,7 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con literal_pointer_val(ctx, (jl_value_t*)fill), F, closure_types ? literal_pointer_val(ctx, (jl_value_t*)unionall_env) : Constant::getNullValue(ctx.types().T_pjlvalue), - closure_types ? ctx.spvals_ptr : ConstantPointerNull::get(cast(ctx.types().T_pprjlvalue)) + closure_types ? decay_derived(ctx, ctx.spvals_ptr) : ConstantPointerNull::get(ctx.builder.getPtrTy(AddressSpace::Derived)) }); outboxed = true; } diff --git a/src/llvm-codegen-shared.h b/src/llvm-codegen-shared.h index d9551e0552f9c..ff6f5a97299d7 100644 --- a/src/llvm-codegen-shared.h +++ b/src/llvm-codegen-shared.h @@ -51,9 +51,9 @@ namespace JuliaType { static inline auto get_jlfunc_ty(llvm::LLVMContext &C) { auto T_prjlvalue = get_prjlvalue_ty(C); - auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0); + auto T_pprjlvalue = llvm::PointerType::get(C, 0); return llvm::FunctionType::get(T_prjlvalue, { - T_prjlvalue, // function + T_prjlvalue, // function T_pprjlvalue, // args[] llvm::Type::getInt32Ty(C)}, // nargs false); @@ -61,21 +61,21 @@ namespace JuliaType { static inline auto get_jlfunc2_ty(llvm::LLVMContext &C) { auto T_prjlvalue = get_prjlvalue_ty(C); - auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0); + auto T_pprjlvalue = llvm::PointerType::get(C, 0); return llvm::FunctionType::get(T_prjlvalue, { - T_prjlvalue, // function + T_prjlvalue, // function T_pprjlvalue, // args[] llvm::Type::getInt32Ty(C), // nargs - T_prjlvalue}, // linfo + T_prjlvalue}, // linfo false); } static inline auto get_jlfunc3_ty(llvm::LLVMContext &C) { auto T_prjlvalue = get_prjlvalue_ty(C); - auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0); + auto T_pprjlvalue = llvm::PointerType::get(C, 0); auto T = get_pjlvalue_ty(C, Derived); return llvm::FunctionType::get(T_prjlvalue, { - T, // function + T, // function T_pprjlvalue, // args[] llvm::Type::getInt32Ty(C)}, // nargs false); @@ -83,13 +83,12 @@ namespace JuliaType { static inline auto get_jlfuncparams_ty(llvm::LLVMContext &C) { auto T_prjlvalue = get_prjlvalue_ty(C); - auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0); + auto T_pprjlvalue = llvm::PointerType::get(C, 0); return llvm::FunctionType::get(T_prjlvalue, { - T_prjlvalue, // function + T_prjlvalue, // function T_pprjlvalue, // args[] - llvm::Type::getInt32Ty(C), - T_pprjlvalue, // linfo->sparam_vals - }, // nargs + llvm::Type::getInt32Ty(C), // nargs + T_prjlvalue}, // linfo->sparam_vals false); } From 9ea547a36e4d3e0d36bd45ec20552508a3075722 Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Fri, 17 Jan 2025 10:28:20 -0700 Subject: [PATCH 191/198] Add try/catch around handle_message() to catch errors during logging. (#57004) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/JuliaLang/julia/issues/56889. Before this PR, an exception thrown while constructing the objects to log (the `msg`) would be caught and logged. However, an exception thrown while _printing_ the msg to an IO would _not_ be caught, and can abort the program. This breaks the promise that enabling verbose debug logging shouldn't introduce new crashes. After this PR, an exception thrown during handle_message is caught and logged, just like an exception during `msg` construction: ```julia julia> struct Foo end julia> Base.show(::IO, ::Foo) = error("oh no") julia> begin # Unexpectedly, the execption thrown while printing `Foo()` escapes @info Foo() # So we never reach this line! :'( println("~~~~~ ALL DONE ~~~~~~~~") end ┌ Error: Exception while generating log record in module Main at REPL[10]:3 │ exception = │ oh no │ Stacktrace: │ [1] error(s::String) │ @ Base ./error.jl:44 │ [2] show(::IOBuffer, ::Foo) │ @ Main ./REPL[9]:1 ... │ [30] repl_main │ @ ./client.jl:593 [inlined] │ [31] _start() │ @ Base ./client.jl:568 └ @ Main REPL[10]:3 ~~~~~ ALL DONE ~~~~~~~~ ``` This PR respects the change made in https://github.com/JuliaLang/julia/pull/36600 to keep the codegen as small as possible, by putting the new try/catch into a no-inlined function, so that we don't have to introduce a new try/catch in the macro-generated code body. --------- Co-authored-by: Jameson Nash --- base/logging/logging.jl | 14 +++++++++++++- test/corelogging.jl | 13 +++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/base/logging/logging.jl b/base/logging/logging.jl index 5cf3882a300ec..41721e84cc934 100644 --- a/base/logging/logging.jl +++ b/base/logging/logging.jl @@ -409,7 +409,7 @@ function logmsg_code(_module, file, line, level, message, exs...) end line = $(log_data._line) local msg, kwargs - $(logrecord) && invokelatest($handle_message, + $(logrecord) && $handle_message_nothrow( logger, level, msg, _module, group, id, file, line; kwargs...) end @@ -420,6 +420,18 @@ function logmsg_code(_module, file, line, level, message, exs...) end end +@noinline function handle_message_nothrow(logger, level, msg, _module, group, id, file, line; kwargs...) + @nospecialize + try + @invokelatest handle_message( + logger, level, msg, _module, group, id, file, line; + kwargs...) + + catch err + @invokelatest logging_error(logger, level, _module, group, id, file, line, err, true) + end +end + function process_logmsg_exs(_orig_module, _file, _line, level, message, exs...) @nospecialize local _group, _id diff --git a/test/corelogging.jl b/test/corelogging.jl index b8cd3716cad2e..154202da759c2 100644 --- a/test/corelogging.jl +++ b/test/corelogging.jl @@ -114,6 +114,19 @@ end @test only(collect_test_logs(logmsg)[1]).kwargs[:x] === "the y" end end +@testset "Log message handle_message exception handling" begin + # Exceptions in log handling (printing) of msg are caught by default. + struct Foo end + Base.show(::IO, ::Foo) = 1 ÷ 0 + + # We cannot use `@test_logs` here, since test_logs does not actually _print_ the message + # (i.e. it does not invoke handle_message). To test exception handling during printing, + # we have to use `@test_warn` to see what was printed. + @test_warn r"Error: Exception while generating log record in module .*DivideError: integer division error"s @info Foo() + + # Exceptions in log handling (printing) of attributes are caught by default + @test_warn r"Error: Exception while generating log record in module .*DivideError: integer division error"s @info "foo" x=Foo() +end @testset "Special keywords" begin logger = TestLogger() From 98f8aca9ac8eb1c9467b685c7e8594d981192d96 Mon Sep 17 00:00:00 2001 From: Eduardo Souza Date: Sat, 18 Jan 2025 04:53:52 +1100 Subject: [PATCH 192/198] Adding `precompile_field_replace` to MMTk's roots (#57073) Add `precompile_field_replace` and update the `mmtk_julia` binding version to account for the change from https://github.com/JuliaLang/julia/commit/b8ab9f37469d9c19eeac1f9b5d40a499d3a176e8. --- deps/checksums/mmtk_julia | 4 ++++ .../md5 | 1 - .../sha512 | 1 - deps/mmtk_julia.version | 4 ++-- src/gc-mmtk.c | 3 +++ 5 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 deps/checksums/mmtk_julia delete mode 100644 deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5 delete mode 100644 deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512 diff --git a/deps/checksums/mmtk_julia b/deps/checksums/mmtk_julia new file mode 100644 index 0000000000000..49b7a50a8e136 --- /dev/null +++ b/deps/checksums/mmtk_julia @@ -0,0 +1,4 @@ +mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5/1911cf084d26c48e2ed58af3d268b4b6 +mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512/75beab54398989c46b62e714b242cf6705d88d220f40c21e494e0f29161437f5fbe9ba05b543d2353a1ad76f4239ac4025b476be0be864649f310f14935289fe +mmtk_julia-f07d66aafc86af84ea988b35335acc9bbc770fa1.tar.gz/md5/38afb5db6d8c55413a4ec96aefa2ebb4 +mmtk_julia-f07d66aafc86af84ea988b35335acc9bbc770fa1.tar.gz/sha512/78525582a46a6baf8d33df7b622e55cf244439afcd7192ba55489c1bc18393d1237d2903d517c610484bf9e2a7338ad31435a9cbf70889d6bcf87c40cec829e5 \ No newline at end of file diff --git a/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5 b/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5 deleted file mode 100644 index fc6955c8f2e7b..0000000000000 --- a/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -1911cf084d26c48e2ed58af3d268b4b6 diff --git a/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512 b/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512 deleted file mode 100644 index ea916976895a3..0000000000000 --- a/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -75beab54398989c46b62e714b242cf6705d88d220f40c21e494e0f29161437f5fbe9ba05b543d2353a1ad76f4239ac4025b476be0be864649f310f14935289fe diff --git a/deps/mmtk_julia.version b/deps/mmtk_julia.version index 60f7cffe7b4de..4d821bffd5b9b 100644 --- a/deps/mmtk_julia.version +++ b/deps/mmtk_julia.version @@ -1,4 +1,4 @@ MMTK_JULIA_BRANCH = master -MMTK_JULIA_SHA1 = b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214 +MMTK_JULIA_SHA1 = f07d66aafc86af84ea988b35335acc9bbc770fa1 MMTK_JULIA_GIT_URL := https://github.com/mmtk/mmtk-julia.git -MMTK_JULIA_TAR_URL = https://github.com/mmtk/mmtk-julia/archive/refs/tags/v0.30.2.tar.gz +MMTK_JULIA_TAR_URL = https://github.com/mmtk/mmtk-julia/archive/refs/tags/v0.30.3.tar.gz diff --git a/src/gc-mmtk.c b/src/gc-mmtk.c index 78882c8eb0225..5ec1e34cc1acd 100644 --- a/src/gc-mmtk.c +++ b/src/gc-mmtk.c @@ -497,6 +497,9 @@ JL_DLLEXPORT void jl_gc_scan_vm_specific_roots(RootsWorkClosure* closure) add_node_to_tpinned_roots_buffer(closure, &tpinned_buf, &tpinned_len, jl_global_roots_list); add_node_to_tpinned_roots_buffer(closure, &tpinned_buf, &tpinned_len, jl_global_roots_keyset); + // FIXME: transivitely pinning for now, should be removed after we add moving Immix + add_node_to_tpinned_roots_buffer(closure, &tpinned_buf, &tpinned_len, precompile_field_replace); + // Push the result of the work. (closure->report_nodes_func)(buf.ptr, len, buf.cap, closure->data, false); (closure->report_tpinned_nodes_func)(tpinned_buf.ptr, tpinned_len, tpinned_buf.cap, closure->data, false); From 647b9f4c53f66fed106e2dcac3906fe55a280e7c Mon Sep 17 00:00:00 2001 From: Kiran Pamnany Date: Fri, 17 Jan 2025 18:19:01 -0500 Subject: [PATCH 193/198] Add timeout parameter to `wait(::Condition)` (#56974) We have a need for this capability. I believe this closes https://github.com/JuliaLang/julia/issues/36217. The implementation is straightforward and there are a couple of tests. --- base/condition.jl | 90 +++++++++++++++++++++++++++++++++++++++++++++-- test/channels.jl | 17 +++++++++ 2 files changed, 104 insertions(+), 3 deletions(-) diff --git a/base/condition.jl b/base/condition.jl index fd771c9be346a..90c53b7ad310d 100644 --- a/base/condition.jl +++ b/base/condition.jl @@ -125,20 +125,104 @@ proceeding. """ function wait end +# wait with timeout +# +# The behavior of wait changes if a timeout is specified. There are +# three concurrent entities that can interact: +# 1. Task W: the task that calls wait w/timeout. +# 2. Task T: the task created to handle a timeout. +# 3. Task N: the task that notifies the Condition being waited on. +# +# Typical flow: +# - W enters the Condition's wait queue. +# - W creates T and stops running (calls wait()). +# - T, when scheduled, waits on a Timer. +# - Two common outcomes: +# - N notifies the Condition. +# - W starts running, closes the Timer, sets waiter_left and returns +# the notify'ed value. +# - The closed Timer throws an EOFError to T which simply ends. +# - The Timer expires. +# - T starts running and locks the Condition. +# - T confirms that waiter_left is unset and that W is still in the +# Condition's wait queue; it then removes W from the wait queue, +# sets dosched to true and unlocks the Condition. +# - If dosched is true, T schedules W with the special :timed_out +# value. +# - T ends. +# - W runs and returns :timed_out. +# +# Some possible interleavings: +# - N notifies the Condition but the Timer expires and T starts running +# before W: +# - W closing the expired Timer is benign. +# - T will find that W is no longer in the Condition's wait queue +# (which is protected by a lock) and will not schedule W. +# - N notifies the Condition; W runs and calls wait on the Condition +# again before the Timer expires: +# - W sets waiter_left before leaving. When T runs, it will find that +# waiter_left is set and will not schedule W. +# +# The lock on the Condition's wait queue and waiter_left together +# ensure proper synchronization and behavior of the tasks involved. + """ - wait(c::GenericCondition; first::Bool=false) + wait(c::GenericCondition; first::Bool=false, timeout::Real=0.0) Wait for [`notify`](@ref) on `c` and return the `val` parameter passed to `notify`. If the keyword `first` is set to `true`, the waiter will be put _first_ in line to wake up on `notify`. Otherwise, `wait` has first-in-first-out (FIFO) behavior. + +If `timeout` is specified, cancel the `wait` when it expires and return +`:timed_out`. The minimum value for `timeout` is 0.001 seconds, i.e. 1 +millisecond. """ -function wait(c::GenericCondition; first::Bool=false) +function wait(c::GenericCondition; first::Bool=false, timeout::Real=0.0) + timeout == 0.0 || timeout ≥ 1e-3 || throw(ArgumentError("timeout must be ≥ 1 millisecond")) + ct = current_task() _wait2(c, ct, first) token = unlockall(c.lock) + + timer::Union{Timer, Nothing} = nothing + waiter_left::Union{Threads.Atomic{Bool}, Nothing} = nothing + if timeout > 0.0 + timer = Timer(timeout) + waiter_left = Threads.Atomic{Bool}(false) + # start a task to wait on the timer + t = Task() do + try + wait(timer) + catch e + # if the timer was closed, the waiting task has been scheduled; do nothing + e isa EOFError && return + end + dosched = false + lock(c.lock) + # Confirm that the waiting task is still in the wait queue and remove it. If + # the task is not in the wait queue, it must have been notified already so we + # don't do anything here. + if !waiter_left[] && ct.queue == c.waitq + dosched = true + Base.list_deletefirst!(c.waitq, ct) + end + unlock(c.lock) + # send the waiting task a timeout + dosched && schedule(ct, :timed_out) + end + t.sticky = false + Threads._spawn_set_thrpool(t, :interactive) + schedule(t) + end + try - return wait() + res = wait() + if timer !== nothing + close(timer) + waiter_left[] = true + end + return res catch q = ct.queue; q === nothing || Base.list_deletefirst!(q::IntrusiveLinkedList{Task}, ct) rethrow() diff --git a/test/channels.jl b/test/channels.jl index 4acf6c94da1b6..6e74a2079234c 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using Random +using Base.Threads using Base: Experimental using Base: n_avail @@ -39,6 +40,22 @@ end @test fetch(t) == "finished" end +@testset "timed wait on Condition" begin + a = Threads.Condition() + @test_throws ArgumentError @lock a wait(a; timeout=0.0005) + @test @lock a wait(a; timeout=0.1)==:timed_out + lock(a) + @spawn begin + @lock a notify(a) + end + @test try + wait(a; timeout=2) + true + finally + unlock(a) + end +end + @testset "various constructors" begin c = Channel() @test eltype(c) == Any From 11c692e1084a631bb40d5348b7074ed58c634714 Mon Sep 17 00:00:00 2001 From: Diogo Netto <61364108+d-netto@users.noreply.github.com> Date: Fri, 17 Jan 2025 20:54:15 -0300 Subject: [PATCH 194/198] add option to dump backtrace of stop-the-world straggler (#57045) This is still a work in progress, but it should help determine what a straggler thread was doing during the stop-the-world phase and why it failed to reach a safepoint in a timely manner. We've encountered long TTSP issues in production, and this tool should provide a valuable means to accurately diagnose them. --- base/options.jl | 1 + src/jloptions.c | 12 ++++++++++++ src/jloptions.h | 1 + src/julia_internal.h | 2 ++ src/safepoint.c | 31 +++++++++++++++++++++++++++---- src/stackwalk.c | 19 +++++++++++++++++++ test/cmdlineargs.jl | 6 ++++++ test/threads_exec.jl | 25 +++++++++++++++++++++++++ 8 files changed, 93 insertions(+), 4 deletions(-) diff --git a/base/options.jl b/base/options.jl index 7e7808bd5c047..3281ec0de98d2 100644 --- a/base/options.jl +++ b/base/options.jl @@ -62,6 +62,7 @@ struct JLOptions trace_compile_timing::Int8 trim::Int8 task_metrics::Int8 + timeout_for_safepoint_straggler_s::Int16 end # This runs early in the sysimage != is not defined yet diff --git a/src/jloptions.c b/src/jloptions.c index c68b5ce193d98..2c5a9074eb465 100644 --- a/src/jloptions.c +++ b/src/jloptions.c @@ -153,6 +153,7 @@ JL_DLLEXPORT void jl_init_options(void) 0, // trace_compile_timing JL_TRIM_NO, // trim 0, // task_metrics + -1, // timeout_for_safepoint_straggler_s }; jl_options_initialized = 1; } @@ -311,6 +312,8 @@ static const char opts_hidden[] = " --output-asm Generate an assembly file (.s)\n" " --output-incremental={yes|no*} Generate an incremental output file (rather than\n" " complete)\n" + " --timeout-for-safepoint-straggler If this value is set, then we will dump the backtrace for a thread\n" + " that fails to reach a safepoint within the specified time\n" " --trace-compile={stderr|name} Print precompile statements for methods compiled\n" " during execution or save to stderr or a path. Methods that\n" " were recompiled are printed in yellow or with a trailing\n" @@ -346,6 +349,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) opt_warn_scope, opt_inline, opt_polly, + opt_timeout_for_safepoint_straggler, opt_trace_compile, opt_trace_compile_timing, opt_trace_dispatch, @@ -427,6 +431,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) { "warn-scope", required_argument, 0, opt_warn_scope }, { "inline", required_argument, 0, opt_inline }, { "polly", required_argument, 0, opt_polly }, + { "timeout-for-safepoint-straggler", required_argument, 0, opt_timeout_for_safepoint_straggler }, { "trace-compile", required_argument, 0, opt_trace_compile }, { "trace-compile-timing", no_argument, 0, opt_trace_compile_timing }, { "trace-dispatch", required_argument, 0, opt_trace_dispatch }, @@ -970,6 +975,13 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) else jl_errorf("julia: invalid argument to --permalloc-pkgimg={yes|no} (%s)", optarg); break; + case opt_timeout_for_safepoint_straggler: + errno = 0; + long timeout = strtol(optarg, &endptr, 10); + if (errno != 0 || optarg == endptr || timeout < 1 || timeout > INT16_MAX) + jl_errorf("julia: --timeout-for-safepoint-straggler=; seconds must be an integer between 1 and %d", INT16_MAX); + jl_options.timeout_for_safepoint_straggler_s = (int16_t)timeout; + break; case opt_trim: if (optarg == NULL || !strcmp(optarg,"safe")) jl_options.trim = JL_TRIM_SAFE; diff --git a/src/jloptions.h b/src/jloptions.h index 211122242cbbd..a8cc4a9a9e33d 100644 --- a/src/jloptions.h +++ b/src/jloptions.h @@ -66,6 +66,7 @@ typedef struct { int8_t trace_compile_timing; int8_t trim; int8_t task_metrics; + int16_t timeout_for_safepoint_straggler_s; } jl_options_t; #endif diff --git a/src/julia_internal.h b/src/julia_internal.h index 00d603f26c7f2..3e4967c9d4dca 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -215,6 +215,8 @@ typedef struct { size_t bt_size; int tid; } jl_record_backtrace_result_t; +JL_DLLEXPORT JL_DLLEXPORT size_t jl_try_record_thread_backtrace(jl_ptls_t ptls2, struct _jl_bt_element_t *bt_data, + size_t max_bt_size) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_record_backtrace_result_t jl_record_backtrace(jl_task_t *t, struct _jl_bt_element_t *bt_data, size_t max_bt_size, int all_tasks_profiler) JL_NOTSAFEPOINT; extern volatile struct _jl_bt_element_t *profile_bt_data_prof; diff --git a/src/safepoint.c b/src/safepoint.c index 7eab653edd089..66bea539861f8 100644 --- a/src/safepoint.c +++ b/src/safepoint.c @@ -149,10 +149,33 @@ void jl_gc_wait_for_the_world(jl_ptls_t* gc_all_tls_states, int gc_n_threads) // Use system mutexes rather than spin locking to minimize wasted CPU time // while we wait for other threads reach a safepoint. // This is particularly important when run under rr. - uv_mutex_lock(&safepoint_lock); - if (!jl_atomic_load_relaxed(&ptls2->gc_state)) - uv_cond_wait(&safepoint_cond_begin, &safepoint_lock); - uv_mutex_unlock(&safepoint_lock); + if (jl_options.timeout_for_safepoint_straggler_s == -1) { // timeout was not specified: no need to dump the backtrace + uv_mutex_lock(&safepoint_lock); + if (!jl_atomic_load_relaxed(&ptls2->gc_state)) { + uv_cond_wait(&safepoint_cond_begin, &safepoint_lock); + } + uv_mutex_unlock(&safepoint_lock); + } + else { + const int64_t timeout = jl_options.timeout_for_safepoint_straggler_s * 1000000000; // convert to nanoseconds + int ret = 0; + uv_mutex_lock(&safepoint_lock); + if (!jl_atomic_load_relaxed(&ptls2->gc_state)) { + ret = uv_cond_timedwait(&safepoint_cond_begin, &safepoint_lock, timeout); + } + uv_mutex_unlock(&safepoint_lock); + // If we woke up because of a timeout, print the backtrace of the straggler + if (ret == UV_ETIMEDOUT) { + jl_safe_printf("===== Thread %d failed to reach safepoint after %d seconds, printing backtrace below =====\n", ptls2->tid + 1, jl_options.timeout_for_safepoint_straggler_s); + // Try to record the backtrace of the straggler using `jl_try_record_thread_backtrace` + jl_ptls_t ptls = jl_current_task->ptls; + size_t bt_size = jl_try_record_thread_backtrace(ptls2, ptls->bt_data, JL_MAX_BT_SIZE); + // Print the backtrace of the straggler + for (size_t i = 0; i < bt_size; i += jl_bt_entry_size(ptls->bt_data + i)) { + jl_print_bt_entry_codeloc(ptls->bt_data + i); + } + } + } } } } diff --git a/src/stackwalk.c b/src/stackwalk.c index f1d807908cf42..14dc5709671dc 100644 --- a/src/stackwalk.c +++ b/src/stackwalk.c @@ -1260,6 +1260,25 @@ static void suspend(void *ctx) suspenddata->success = jl_thread_suspend_and_get_state(suspenddata->old, 1, suspenddata->c); } +JL_DLLEXPORT size_t jl_try_record_thread_backtrace(jl_ptls_t ptls2, jl_bt_element_t *bt_data, size_t max_bt_size) JL_NOTSAFEPOINT +{ + int16_t tid = ptls2->tid; + jl_task_t *t = NULL; + bt_context_t *context = NULL; + bt_context_t c; + suspend_t suspenddata = {tid, &c}; + jl_with_stackwalk_lock(suspend, &suspenddata); + if (!suspenddata.success) { + return 0; + } + // thread is stopped, safe to read the task it was running before we stopped it + t = jl_atomic_load_relaxed(&ptls2->current_task); + context = &c; + size_t bt_size = rec_backtrace_ctx(bt_data, max_bt_size, context, ptls2->previous_task ? NULL : t->gcstack); + jl_thread_resume(tid); + return bt_size; +} + JL_DLLEXPORT jl_record_backtrace_result_t jl_record_backtrace(jl_task_t *t, jl_bt_element_t *bt_data, size_t max_bt_size, int all_tasks_profiler) JL_NOTSAFEPOINT { int16_t tid = INT16_MAX; diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index 74f953250cd37..3ff7836223b84 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -1238,3 +1238,9 @@ end @test parse(UInt64,read(`$exename --heap-size-hint=$str -E "Base.JLOptions().heap_size_hint"`, String)) == val end end + +@testset "--timeout-for-safepoint-straggler" begin + exename = `$(Base.julia_cmd())` + timeout = 120 + @test parse(Int,read(`$exename --timeout-for-safepoint-straggler=$timeout -E "Base.JLOptions().timeout_for_safepoint_straggler_s"`, String)) == timeout +end diff --git a/test/threads_exec.jl b/test/threads_exec.jl index d77cf06905f44..65e5ef57c911b 100644 --- a/test/threads_exec.jl +++ b/test/threads_exec.jl @@ -1536,4 +1536,29 @@ end end end +@testset "--timeout-for-safepoint-straggler command-line flag" begin + program = " + function main() + t = Threads.@spawn begin + ccall(:uv_sleep, Cvoid, (Cuint,), 5000) + end + # Force a GC + ccall(:uv_sleep, Cvoid, (Cuint,), 1000) + GC.gc() + wait(t) + end + main() + " + tmp_output_filename = tempname() + tmp_output_file = open(tmp_output_filename, "w") + if isnothing(tmp_output_file) + error("Failed to open file $tmp_output_filename") + end + run(pipeline(`$(Base.julia_cmd()) --threads=4 --timeout-for-safepoint-straggler=1 -e $program`, stderr=tmp_output_file)) + # Check whether we printed the straggler's backtrace + @test !isempty(read(tmp_output_filename, String)) + close(tmp_output_file) + rm(tmp_output_filename) +end + end # main testset From 1262bf8484f2d70226dd2345fd77475ff3d71c94 Mon Sep 17 00:00:00 2001 From: Eduardo Souza Date: Sat, 18 Jan 2025 15:57:49 +1100 Subject: [PATCH 195/198] Building Julia with MMTk using BinaryBuilder (#56989) Adding `mmtk-julia` as a BinaryBuilder dependency and using that as the default setup for building Julia with MMTk. ~NB: still have to update the version and checksum files after https://github.com/JuliaPackaging/Yggdrasil/pull/10288 gets merged.~ --- Make.inc | 2 +- Makefile | 4 ++++ deps/checksums/mmtk_julia | 4 +++- deps/mmtk_julia.mk | 8 ++++++++ deps/mmtk_julia.version | 2 ++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Make.inc b/Make.inc index 26b5ae7752555..16e238c6f0683 100644 --- a/Make.inc +++ b/Make.inc @@ -1402,7 +1402,7 @@ CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.34|GLIBCXX_3\.5\.|GLIBCXX_4\. # Note: we explicitly _do not_ define `CSL` here, since it requires some more # advanced techniques to decide whether it should be installed from a BB source # or not. See `deps/csl.mk` for more detail. -BB_PROJECTS := BLASTRAMPOLINE OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP OPENSSL LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB P7ZIP LLD LIBTRACYCLIENT BOLT +BB_PROJECTS := BLASTRAMPOLINE OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP OPENSSL LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB P7ZIP LLD LIBTRACYCLIENT BOLT MMTK_JULIA define SET_BB_DEFAULT # First, check to see if BB is disabled on a global setting ifeq ($$(USE_BINARYBUILDER),0) diff --git a/Makefile b/Makefile index 20d131ee8524c..b193b3849c6aa 100644 --- a/Makefile +++ b/Makefile @@ -281,6 +281,10 @@ endif endif endif +ifneq (${MMTK_PLAN},None) +JL_PRIVATE_LIBS-0 += libmmtk_julia +endif + # Note that we disable MSYS2's path munging here, as otherwise # it replaces our `:`-separated list as a `;`-separated one. define stringreplace diff --git a/deps/checksums/mmtk_julia b/deps/checksums/mmtk_julia index 49b7a50a8e136..979ab79e52207 100644 --- a/deps/checksums/mmtk_julia +++ b/deps/checksums/mmtk_julia @@ -1,4 +1,6 @@ mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5/1911cf084d26c48e2ed58af3d268b4b6 mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512/75beab54398989c46b62e714b242cf6705d88d220f40c21e494e0f29161437f5fbe9ba05b543d2353a1ad76f4239ac4025b476be0be864649f310f14935289fe mmtk_julia-f07d66aafc86af84ea988b35335acc9bbc770fa1.tar.gz/md5/38afb5db6d8c55413a4ec96aefa2ebb4 -mmtk_julia-f07d66aafc86af84ea988b35335acc9bbc770fa1.tar.gz/sha512/78525582a46a6baf8d33df7b622e55cf244439afcd7192ba55489c1bc18393d1237d2903d517c610484bf9e2a7338ad31435a9cbf70889d6bcf87c40cec829e5 \ No newline at end of file +mmtk_julia-f07d66aafc86af84ea988b35335acc9bbc770fa1.tar.gz/sha512/78525582a46a6baf8d33df7b622e55cf244439afcd7192ba55489c1bc18393d1237d2903d517c610484bf9e2a7338ad31435a9cbf70889d6bcf87c40cec829e5 +mmtk_julia.v0.30.3+1.x86_64-linux-gnu.tar.gz/md5/631b204574da7062802dac501a4b711f +mmtk_julia.v0.30.3+1.x86_64-linux-gnu.tar.gz/sha512/daaed59d08fc49621479ed638dea0aac0cba123986e486571447e8e21e9a098776ce2e87fbd92ddea276782fc44621f23d40fa213296b28e1d4480553c7de4f7 diff --git a/deps/mmtk_julia.mk b/deps/mmtk_julia.mk index 7ec55426821c3..424113fd4164c 100644 --- a/deps/mmtk_julia.mk +++ b/deps/mmtk_julia.mk @@ -6,6 +6,7 @@ MMTK_MOVING := 0 MMTK_VARS := MMTK_PLAN=$(MMTK_PLAN) MMTK_MOVING=$(MMTK_MOVING) +ifneq ($(USE_BINARYBUILDER_MMTK_JULIA),1) $(eval $(call git-external,mmtk_julia,MMTK_JULIA,,,$(BUILDDIR))) get-mmtk_julia: $(MMTK_JULIA_SRC_FILE) @@ -70,3 +71,10 @@ $(build_prefix)/manifest/mmtk_julia: $(BUILDROOT)/usr/lib/libmmtk_julia.so @echo $(UNINSTALL_mmtk_julia) > $@ endif # MMTK_JULIA_DIR + +else +# We are building using the BinaryBuilder version of the binding + +$(eval $(call bb-install,mmtk_julia,MMTK_JULIA,false)) + +endif # USE_BINARYBUILDER_MMTK_JULIA diff --git a/deps/mmtk_julia.version b/deps/mmtk_julia.version index 4d821bffd5b9b..cb1e8064f9825 100644 --- a/deps/mmtk_julia.version +++ b/deps/mmtk_julia.version @@ -2,3 +2,5 @@ MMTK_JULIA_BRANCH = master MMTK_JULIA_SHA1 = f07d66aafc86af84ea988b35335acc9bbc770fa1 MMTK_JULIA_GIT_URL := https://github.com/mmtk/mmtk-julia.git MMTK_JULIA_TAR_URL = https://github.com/mmtk/mmtk-julia/archive/refs/tags/v0.30.3.tar.gz +MMTK_JULIA_JLL_VER := 0.30.3+1 +MMTK_JULIA_JLL_NAME := mmtk_julia From 17402876ec235dd66452983a39f8521f9ff62936 Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Fri, 17 Jan 2025 23:33:23 -0800 Subject: [PATCH 196/198] Block thread from receiving profile signal with stackwalk lock (#57089) This is Jameson's proposed amendment to the changes made in #57035 that introduced a deadlock on FreeBSD, amusingly in service of fixing a deadlock on Linux. On Linux and (non-macOS) BSD, instead of acquiring and releasing a lock on the profiler in `jl_with_stackwalk_lock`, we're just blocking the thread from receiving the profiler's `SIGUSR2` signal at all. This should fix #57058; I don't get the deadlock locally on FreeBSD with this change, but it's AArch64 instead of x86-64 like on CI, so let's see if this also makes CI happy. If so, closes #57059. Co-authored-by: Jameson Nash --- src/signals-unix.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/signals-unix.c b/src/signals-unix.c index 91d3378068f84..788539b1f5096 100644 --- a/src/signals-unix.c +++ b/src/signals-unix.c @@ -310,23 +310,14 @@ int exc_reg_is_write_fault(uintptr_t esr) { #include #include -typedef struct { - void (*f)(void*) JL_NOTSAFEPOINT; - void *ctx; -} callback_t; -static int with_dl_iterate_phdr_lock(struct dl_phdr_info *info, size_t size, void *data) -{ - jl_lock_profile(); - callback_t *callback = (callback_t*)data; - callback->f(callback->ctx); - jl_unlock_profile(); - return 1; // only call this once -} - void jl_with_stackwalk_lock(void (*f)(void*), void *ctx) { - callback_t callback = {f, ctx}; - dl_iterate_phdr(with_dl_iterate_phdr_lock, &callback); + sigset_t sset, oset; + sigemptyset(&sset); + sigaddset(&sset, SIGUSR2); + pthread_sigmask(SIG_BLOCK, &sset, &oset); + f(ctx); + pthread_sigmask(SIG_SETMASK, &oset, NULL); } #if defined(_OS_LINUX_) && (defined(_CPU_X86_64_) || defined(_CPU_X86_)) From fa9478b5178052ef00690732fe363601182b6922 Mon Sep 17 00:00:00 2001 From: Markus Hauru Date: Sat, 18 Jan 2025 12:00:51 +0000 Subject: [PATCH 197/198] Fix regular expressions in Test tests (#57085) Several tests for Test.jl weren't really testing for much because `|` characters were taken to be or operators in the regular expressions. Co-authored-by: Chengyu Han --- stdlib/Test/test/runtests.jl | 54 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/stdlib/Test/test/runtests.jl b/stdlib/Test/test/runtests.jl index 995d2c983437c..98755590a5291 100644 --- a/stdlib/Test/test/runtests.jl +++ b/stdlib/Test/test/runtests.jl @@ -870,12 +870,12 @@ let msg = read(pipeline(ignorestatus(`$(Base.julia_cmd()) --startup-file=no --co end end'`), stderr=devnull), String) @test occursin(r""" - Test Summary: | Pass Fail Total Time - Foo Tests | 2 2 4 \s*\d*.\ds - Animals | 1 1 2 \s*\d*.\ds - Felines | 1 1 \s*\d*.\ds - Canines | 1 1 \s*\d*.\ds - Arrays | 1 1 2 \s*\d*.\ds + Test Summary: \| Pass Fail Total Time + Foo Tests \| 2 2 4 \s*\d*\.\ds + Animals \| 1 1 2 \s*\d*\.\ds + Felines \| 1 1 \s*\d*\.\ds + Canines \| 1 1 \s*\d*\.\ds + Arrays \| 1 1 2 \s*\d*\.\ds """, msg) end @@ -1253,17 +1253,17 @@ end @testset "verbose option" begin expected = r""" - Test Summary: | Pass Total Time - Parent | 9 9 \s*\d*.\ds - Child 1 | 3 3 \s*\d*.\ds - Child 1.1 (long name) | 1 1 \s*\d*.\ds - Child 1.2 | 1 1 \s*\d*.\ds - Child 1.3 | 1 1 \s*\d*.\ds - Child 2 | 3 3 \s*\d*.\ds - Child 3 | 3 3 \s*\d*.\ds - Child 3.1 | 1 1 \s*\d*.\ds - Child 3.2 | 1 1 \s*\d*.\ds - Child 3.3 | 1 1 \s*\d*.\ds + Test Summary: \| Pass Total Time + Parent \| 9 9 \s*\d*\.\ds + Child 1 \| 3 3 \s*\d*\.\ds + Child 1\.1 \(long name\) \| 1 1 \s*\d*\.\ds + Child 1\.2 \| 1 1 \s*\d*\.\ds + Child 1\.3 \| 1 1 \s*\d*\.\ds + Child 2 \| 3 3 \s*\d*\.\ds + Child 3 \| 3 3 \s*\d*\.\ds + Child 3\.1 \| 1 1 \s*\d*\.\ds + Child 3\.2 \| 1 1 \s*\d*\.\ds + Child 3\.3 \| 1 1 \s*\d*\.\ds """ mktemp() do f, _ @@ -1324,9 +1324,9 @@ end @testset "failfast option" begin @testset "non failfast (default)" begin expected = r""" - Test Summary: | Pass Fail Error Total Time - Foo | 1 2 1 4 \s*\d*.\ds - Bar | 1 1 2 \s*\d*.\ds + Test Summary: \| Pass Fail Error Total Time + Foo \| 1 2 1 4 \s*\d*\.\ds + Bar \| 1 1 2 \s*\d*\.\ds """ mktemp() do f, _ @@ -1350,8 +1350,8 @@ end end @testset "failfast" begin expected = r""" - Test Summary: | Fail Total Time - Foo | 1 1 \s*\d*.\ds + Test Summary: \| Fail Total Time + Foo \| 1 1 \s*\d*\.\ds """ mktemp() do f, _ @@ -1375,9 +1375,9 @@ end end @testset "failfast passes to child testsets" begin expected = r""" - Test Summary: | Fail Total Time - PackageName | 1 1 \s*\d*.\ds - 1 | 1 1 \s*\d*.\ds + Test Summary: \| Fail Total Time + Foo \| 1 1 \s*\d*\.\ds + 1 \| 1 1 \s*\d*\.\ds """ mktemp() do f, _ @@ -1401,8 +1401,8 @@ end end @testset "failfast via env var" begin expected = r""" - Test Summary: | Fail Total Time - Foo | 1 1 \s*\d*.\ds + Test Summary: \| Fail Total Time + Foo \| 1 1 \s*\d*\.\ds """ mktemp() do f, _ From cbc47c9fb852773e379cce062d6bd2aec743a7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Sun, 19 Jan 2025 00:10:33 +0100 Subject: [PATCH 198/198] [Test] Improve regex matching expected test summaries (#57096) Allow for more spaces between the "Total" and "Time" columns, in case tests take occasionally longer than usual. Fix #57095. --- stdlib/Test/test/runtests.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/stdlib/Test/test/runtests.jl b/stdlib/Test/test/runtests.jl index 98755590a5291..02523dc6fd911 100644 --- a/stdlib/Test/test/runtests.jl +++ b/stdlib/Test/test/runtests.jl @@ -870,7 +870,7 @@ let msg = read(pipeline(ignorestatus(`$(Base.julia_cmd()) --startup-file=no --co end end'`), stderr=devnull), String) @test occursin(r""" - Test Summary: \| Pass Fail Total Time + Test Summary: \| Pass Fail Total +Time Foo Tests \| 2 2 4 \s*\d*\.\ds Animals \| 1 1 2 \s*\d*\.\ds Felines \| 1 1 \s*\d*\.\ds @@ -1253,7 +1253,7 @@ end @testset "verbose option" begin expected = r""" - Test Summary: \| Pass Total Time + Test Summary: \| Pass Total +Time Parent \| 9 9 \s*\d*\.\ds Child 1 \| 3 3 \s*\d*\.\ds Child 1\.1 \(long name\) \| 1 1 \s*\d*\.\ds @@ -1324,7 +1324,7 @@ end @testset "failfast option" begin @testset "non failfast (default)" begin expected = r""" - Test Summary: \| Pass Fail Error Total Time + Test Summary: \| Pass Fail Error Total +Time Foo \| 1 2 1 4 \s*\d*\.\ds Bar \| 1 1 2 \s*\d*\.\ds """ @@ -1350,7 +1350,7 @@ end end @testset "failfast" begin expected = r""" - Test Summary: \| Fail Total Time + Test Summary: \| Fail Total +Time Foo \| 1 1 \s*\d*\.\ds """ @@ -1375,7 +1375,7 @@ end end @testset "failfast passes to child testsets" begin expected = r""" - Test Summary: \| Fail Total Time + Test Summary: \| Fail Total +Time Foo \| 1 1 \s*\d*\.\ds 1 \| 1 1 \s*\d*\.\ds """ @@ -1401,7 +1401,7 @@ end end @testset "failfast via env var" begin expected = r""" - Test Summary: \| Fail Total Time + Test Summary: \| Fail Total +Time Foo \| 1 1 \s*\d*\.\ds """ @@ -1712,7 +1712,7 @@ end # this tests both the `TestCounts` parts as well as the fallback `x`s expected = r""" - Test Summary: \| Pass Fail Error Broken Total Time + Test Summary: \| Pass Fail Error Broken Total +Time outer \| 3 1 1 1 6 \s*\d*.\ds a \| 1 1 \s*\d*.\ds custom \| 1 1 1 1 4 \s*\?s