Skip to content

Commit 449e10d

Browse files
authored
Merge pull request #18720 from JuliaLang/jb/fix10981
fix #10981, splatting very long argument lists
2 parents 862fb74 + f8a92df commit 449e10d

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

src/alloc.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,12 @@ void jl_compute_field_offsets(jl_datatype_t *st)
10061006
uint64_t max_size = max_offset >> 1;
10071007

10081008
uint32_t nfields = jl_svec_len(st->types);
1009-
jl_fielddesc32_t* desc = (jl_fielddesc32_t*) alloca(nfields * sizeof(jl_fielddesc32_t));
1009+
size_t descsz = nfields * sizeof(jl_fielddesc32_t);
1010+
jl_fielddesc32_t *desc;
1011+
if (descsz < jl_page_size)
1012+
desc = (jl_fielddesc32_t*)alloca(descsz);
1013+
else
1014+
desc = (jl_fielddesc32_t*)malloc(descsz);
10101015
int haspadding = 0;
10111016
assert(st->name == jl_tuple_typename ||
10121017
st == jl_sym_type ||
@@ -1020,7 +1025,7 @@ void jl_compute_field_offsets(jl_datatype_t *st)
10201025
fsz = jl_datatype_size(ty);
10211026
// Should never happen
10221027
if (__unlikely(fsz > max_size))
1023-
jl_throw(jl_overflow_exception);
1028+
goto throw_ovf;
10241029
al = ((jl_datatype_t*)ty)->layout->alignment;
10251030
desc[i].isptr = 0;
10261031
if (((jl_datatype_t*)ty)->layout->haspadding)
@@ -1046,7 +1051,7 @@ void jl_compute_field_offsets(jl_datatype_t *st)
10461051
desc[i].offset = sz;
10471052
desc[i].size = fsz;
10481053
if (__unlikely(max_offset - sz < fsz))
1049-
jl_throw(jl_overflow_exception);
1054+
goto throw_ovf;
10501055
sz += fsz;
10511056
}
10521057
if (homogeneous && lastty!=NULL && jl_is_tuple_type(st)) {
@@ -1060,6 +1065,11 @@ void jl_compute_field_offsets(jl_datatype_t *st)
10601065
if (st->size > sz)
10611066
haspadding = 1;
10621067
st->layout = jl_get_layout(nfields, alignm, haspadding, desc);
1068+
if (descsz >= jl_page_size) free(desc);
1069+
return;
1070+
throw_ovf:
1071+
if (descsz >= jl_page_size) free(desc);
1072+
jl_throw(jl_overflow_exception);
10631073
}
10641074

10651075
extern int jl_boot_file_loaded;

test/core.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4600,3 +4600,13 @@ gVararg(a::fVararg(Int)) = length(a)
46004600
catch e
46014601
(e::ErrorException).msg
46024602
end == "generated function body is not pure. this likely means it contains a closure or comprehension."
4603+
4604+
# issue #10981, long argument lists
4605+
let a = fill(["sdf"], 2*10^6), temp_vcat(x...) = vcat(x...)
4606+
# we introduce a new function `temp_vcat` to make sure there is no existing
4607+
# method cache match, leading to a path that allocates a large tuple type.
4608+
b = temp_vcat(a...)
4609+
@test isa(b, Vector{String})
4610+
@test length(b) == 2*10^6
4611+
@test b[1] == b[end] == "sdf"
4612+
end

0 commit comments

Comments
 (0)