diff --git a/src/codegen.cpp b/src/codegen.cpp index 6d4ecc63e5ca1..a7d24b1b8340b 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6378,8 +6378,9 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_ jl_value_t *val = expr; if (jl_is_quotenode(expr)) val = jl_fieldref_noalloc(expr, 0); - if (jl_is_method(ctx.linfo->def.method)) // toplevel exprs are already rooted - val = jl_ensure_rooted(ctx, val); + // Toplevel exprs are rooted but because codegen assumes this is constant, it removes the write barriers for this code. + // This means we have to globally root the value here. (The other option would be to change how we optimize toplevel code) + val = jl_ensure_rooted(ctx, val); return mark_julia_const(ctx, val); } diff --git a/test/gc.jl b/test/gc.jl index f924f4952cfb0..e46ff0ed73fd9 100644 --- a/test/gc.jl +++ b/test/gc.jl @@ -72,3 +72,17 @@ end @testset "Base.GC docstrings" begin @test isempty(Docs.undocumented_names(GC)) end + +#testset doesn't work here because this needs to run in top level +#Check that we ensure objects in toplevel exprs are rooted +global dims54422 = [] # allocate the Binding +GC.gc(); GC.gc(); # force the binding to be old +GC.enable(false); # prevent new objects from being old +@eval begin + Base.Experimental.@force_compile # use the compiler + dims54422 = $([]) + nothing +end +GC.enable(true); GC.gc(false) # incremental collection +@test typeof(dims54422) == Vector{Any} +@test isempty(dims54422)