Skip to content

Commit f21154f

Browse files
gbaraldigiordano
authored andcommitted
Root globals in toplevel exprs (#54433)
This fixes #54422, the code here assumes that top level exprs are always rooted, but I don't see that referenced anywhere else, or guaranteed, so conservatively always root objects that show up in code.
1 parent c5ab7c9 commit f21154f

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

src/codegen.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5457,8 +5457,9 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_
54575457
jl_value_t *val = expr;
54585458
if (jl_is_quotenode(expr))
54595459
val = jl_fieldref_noalloc(expr, 0);
5460-
if (jl_is_method(ctx.linfo->def.method)) // toplevel exprs are already rooted
5461-
val = jl_ensure_rooted(ctx, val);
5460+
// Toplevel exprs are rooted but because codegen assumes this is constant, it removes the write barriers for this code.
5461+
// This means we have to globally root the value here. (The other option would be to change how we optimize toplevel code)
5462+
val = jl_ensure_rooted(ctx, val);
54625463
return mark_julia_const(ctx, val);
54635464
}
54645465

test/gc.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,17 @@ end
2727
run_gctest("gc/objarray.jl")
2828
run_gctest("gc/chunks.jl")
2929
end
30+
31+
#testset doesn't work here because this needs to run in top level
32+
#Check that we ensure objects in toplevel exprs are rooted
33+
global dims54422 = [] # allocate the Binding
34+
GC.gc(); GC.gc(); # force the binding to be old
35+
GC.enable(false); # prevent new objects from being old
36+
@eval begin
37+
Base.Experimental.@force_compile # use the compiler
38+
dims54422 = $([])
39+
nothing
40+
end
41+
GC.enable(true); GC.gc(false) # incremental collection
42+
@test typeof(dims54422) == Vector{Any}
43+
@test isempty(dims54422)

0 commit comments

Comments
 (0)