From f029e3cfb48f0799853e775f8871a30be8de2948 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 20 Feb 2020 17:38:24 -0500 Subject: [PATCH] codegen: fix memory type issue causing lost gc roots When using memory to contain GC roots, you must be VERY careful never to access that typed-memory through a different type of pointer (in this case, accessing it as an i8 in the memcpy). --- src/ccall.cpp | 7 +------ src/cgutils.cpp | 8 +------- src/intrinsics.cpp | 16 +++++++++++++--- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/ccall.cpp b/src/ccall.cpp index 18a20cf4ee339..54b0ccd42c216 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -513,12 +513,7 @@ static Value *julia_to_native( // pass the address of an alloca'd thing, not a box // since those are immutable. Value *slot = emit_static_alloca(ctx, to); - if (!jvinfo.ispointer()) { - tbaa_decorate(jvinfo.tbaa, ctx.builder.CreateStore(emit_unbox(ctx, to, jvinfo, jlto), slot)); - } - else { - emit_memcpy(ctx, slot, jvinfo.tbaa, jvinfo, jl_datatype_size(jlto), julia_alignment(jlto)); - } + emit_unbox(ctx, to, jvinfo, jlto, slot, jvinfo.tbaa, julia_alignment(jlto)); return slot; } diff --git a/src/cgutils.cpp b/src/cgutils.cpp index c7a03edb91a9f..adf7bececf7d2 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -2091,13 +2091,7 @@ static void init_bits_value(jl_codectx_t &ctx, Value *newv, Value *v, MDNode *tb static void init_bits_cgval(jl_codectx_t &ctx, Value *newv, const jl_cgval_t& v, MDNode *tbaa) { - // newv should already be tagged - if (v.ispointer()) { - emit_memcpy(ctx, newv, tbaa, v, jl_datatype_size(v.typ), sizeof(void*)); - } - else { - init_bits_value(ctx, newv, v.V, tbaa); - } + emit_unbox(ctx, julia_type_to_llvm(v.typ), v, v.typ, newv, tbaa); } static jl_value_t *static_constant_instance(Constant *constant, jl_value_t *jt) diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index 9e97d6b010026..e92b67152e975 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -367,7 +367,7 @@ static Value *emit_unbox(jl_codectx_t &ctx, Type *to, const jl_cgval_t &x, jl_va unsigned alignment = julia_alignment(jt); Type *ptype = to->getPointerTo(); - if (dest) { + if (dest && CountTrackedPointers(to).count == 0) { emit_memcpy(ctx, dest, tbaa_dest, p, x.tbaa, jl_datatype_size(jt), alignment, false); return NULL; } @@ -385,12 +385,22 @@ static Value *emit_unbox(jl_codectx_t &ctx, Type *to, const jl_cgval_t &x, jl_va (to->isFloatingPointTy() || to->isIntegerTy() || to->isPointerTy()) && DL.getTypeSizeInBits(AllocType) == DL.getTypeSizeInBits(to)) { Instruction *load = ctx.builder.CreateAlignedLoad(p, alignment); - return emit_unboxed_coercion(ctx, to, tbaa_decorate(x.tbaa, load)); + Value *unboxed = emit_unboxed_coercion(ctx, to, tbaa_decorate(x.tbaa, load)); + if (dest) { + tbaa_decorate(tbaa_dest, ctx.builder.CreateStore(unboxed, dest)); + return NULL; + } + return unboxed; } } p = maybe_bitcast(ctx, p, ptype); Instruction *load = ctx.builder.CreateAlignedLoad(p, alignment); - return tbaa_decorate(x.tbaa, load); + Value *unboxed = tbaa_decorate(x.tbaa, load); + if (dest) { + tbaa_decorate(tbaa_dest, ctx.builder.CreateStore(unboxed, dest)); + return NULL; + } + return unboxed; } }