From b99038c2bf02a24501320783feb5b1f6c5763d73 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 7 May 2012 14:27:43 -0700 Subject: [PATCH] rustc: Put all boxes into addrspace 1 --- src/rustc/lib/llvm.rs | 10 +++++++++- src/rustc/middle/trans/alt.rs | 4 +++- src/rustc/middle/trans/base.rs | 23 +++++++++++++++++++++-- src/rustc/middle/trans/common.rs | 7 ++++++- src/rustc/middle/trans/type_of.rs | 25 ++++++++++++++++++++++--- 5 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/rustc/lib/llvm.rs b/src/rustc/lib/llvm.rs index 97e439f235b..f984b0de63a 100644 --- a/src/rustc/lib/llvm.rs +++ b/src/rustc/lib/llvm.rs @@ -1034,7 +1034,15 @@ fn type_to_str_inner(names: type_names, outer0: [TypeRef], ty: TypeRef) -> ret "*\\" + int::str(n as int); } } - ret "*" + + let addrstr = { + let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint; + if addrspace == 0u { + "" + } else { + #fmt("addrspace(%u)", addrspace) + } + }; + ret addrstr + "*" + type_to_str_inner(names, outer, llvm::LLVMGetElementType(ty)); } 13 { ret "Vector"; } diff --git a/src/rustc/middle/trans/alt.rs b/src/rustc/middle/trans/alt.rs index 3dae38d9496..08543d0f535 100644 --- a/src/rustc/middle/trans/alt.rs +++ b/src/rustc/middle/trans/alt.rs @@ -436,7 +436,9 @@ fn compile_submatch(bcx: block, m: match, vals: [ValueRef], // Unbox in case of a box field if any_box_pat(m, col) { let box = Load(bcx, val); - let unboxed = GEPi(bcx, box, [0u, abi::box_field_body]); + let box_ty = node_id_type(bcx, pat_id); + let box_no_addrspace = non_gc_box_cast(bcx, box, box_ty); + let unboxed = GEPi(bcx, box_no_addrspace, [0u, abi::box_field_body]); compile_submatch(bcx, enter_box(dm, m, col, val), [unboxed] + vals_left, chk, exits); ret; diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 6c1b81a371d..f79cba16510 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -88,6 +88,7 @@ resource icx_popper(ccx: @crate_ctxt) { impl ccx_icx for @crate_ctxt { fn insn_ctxt(s: str) -> icx_popper { + #debug("new insn_ctxt: %s", s); if (self.sess.opts.count_llvm_insns) { *self.stats.llvm_insn_ctxt += [s]; } @@ -356,7 +357,9 @@ fn malloc_boxed(bcx: block, t: ty::t) -> {box: ValueRef, body: ValueRef} { let _icx = bcx.insn_ctxt("trans_malloc_boxed"); let mut ti = none; let box = malloc_boxed_raw(bcx, t, ti); - let body = GEPi(bcx, box, [0u, abi::box_field_body]); + let box_no_addrspace = non_gc_box_cast( + bcx, box, ty::mk_imm_box(bcx.tcx(), t)); + let body = GEPi(bcx, box_no_addrspace, [0u, abi::box_field_body]); ret {box: box, body: body}; } @@ -2399,7 +2402,8 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result { let t = expr_ty(cx, base); let val = alt check ty::get(t).struct { ty::ty_box(_) { - GEPi(sub.bcx, sub.val, [0u, abi::box_field_body]) + let non_gc_val = non_gc_box_cast(sub.bcx, sub.val, t); + GEPi(sub.bcx, non_gc_val, [0u, abi::box_field_body]) } ty::ty_res(_, _, _) { GEPi(sub.bcx, sub.val, [0u, 1u]) @@ -2417,6 +2421,21 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result { } } +#[doc = " +Get the type of a box in the default address space. + +Shared box pointers live in address space 1 so the GC strategy can find them. +Before taking a pointer to the inside of a box it should be cast into address +space 0. Otherwise the resulting (non-box) pointer will be in the wrong +address space and thus be the wrong type. +"] +fn non_gc_box_cast(cx: block, val: ValueRef, t: ty::t) -> ValueRef { + #debug("non_gc_box_cast"); + add_comment(cx, "non_gc_box_cast"); + let non_gc_t = type_of_non_gc_box(cx.ccx(), t); + PointerCast(cx, val, non_gc_t) +} + fn lval_maybe_callee_to_lval(c: lval_maybe_callee, ty: ty::t) -> lval_result { let must_bind = alt c.env { self_env(_, _, _) { true } _ { false } }; if must_bind { diff --git a/src/rustc/middle/trans/common.rs b/src/rustc/middle/trans/common.rs index d71773a138d..412bacbda1d 100644 --- a/src/rustc/middle/trans/common.rs +++ b/src/rustc/middle/trans/common.rs @@ -642,12 +642,17 @@ fn T_box(cx: @crate_ctxt, t: TypeRef) -> TypeRef { ret T_struct(T_box_header_fields(cx) + [t]); } +fn T_box_ptr(t: TypeRef) -> TypeRef { + const box_addrspace: uint = 1u; + ret llvm::LLVMPointerType(t, box_addrspace as c_uint); +} + fn T_opaque_box(cx: @crate_ctxt) -> TypeRef { ret T_box(cx, T_i8()); } fn T_opaque_box_ptr(cx: @crate_ctxt) -> TypeRef { - ret T_ptr(T_opaque_box(cx)); + ret T_box_ptr(T_opaque_box(cx)); } fn T_port(cx: @crate_ctxt, _t: TypeRef) -> TypeRef { diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs index 6d1c4a8b430..b20f5bc368a 100644 --- a/src/rustc/middle/trans/type_of.rs +++ b/src/rustc/middle/trans/type_of.rs @@ -11,6 +11,7 @@ export type_of; export type_of_explicit_args; export type_of_fn_from_ty; export type_of_fn; +export type_of_non_gc_box; fn type_of_explicit_args(cx: @crate_ctxt, inputs: [ty::arg]) -> [TypeRef] { vec::map(inputs) {|arg| @@ -42,6 +43,24 @@ fn type_of_fn_from_ty(cx: @crate_ctxt, fty: ty::t) -> TypeRef { type_of_fn(cx, ty::ty_fn_args(fty), ty::ty_fn_ret(fty)) } +fn type_of_non_gc_box(cx: @crate_ctxt, t: ty::t) -> TypeRef { + assert !ty::type_has_vars(t); + + let t_norm = ty::normalize_ty(cx.tcx, t); + if t != t_norm { + type_of_non_gc_box(cx, t_norm) + } else { + alt ty::get(t).struct { + ty::ty_box(mt) { + T_ptr(T_box(cx, type_of(cx, mt.ty))) + } + _ { + cx.sess.bug("non-box in type_of_non_gc_box"); + } + } + } +} + fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef { assert !ty::type_has_vars(t); @@ -68,10 +87,10 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef { ty::ty_estr(ty::vstore_uniq) | ty::ty_str { T_ptr(T_vec(cx, T_i8())) } ty::ty_enum(did, _) { type_of_enum(cx, did, t) } - ty::ty_estr(ty::vstore_box) { T_ptr(T_box(cx, T_i8())) } + ty::ty_estr(ty::vstore_box) { T_box_ptr(T_box(cx, T_i8())) } ty::ty_evec(mt, ty::vstore_box) | - ty::ty_box(mt) { T_ptr(T_box(cx, type_of(cx, mt.ty))) } - ty::ty_opaque_box { T_ptr(T_box(cx, T_i8())) } + ty::ty_box(mt) { T_box_ptr(T_box(cx, type_of(cx, mt.ty))) } + ty::ty_opaque_box { T_box_ptr(T_box(cx, T_i8())) } ty::ty_uniq(mt) { T_ptr(type_of(cx, mt.ty)) } ty::ty_evec(mt, ty::vstore_uniq) | ty::ty_vec(mt) { T_ptr(T_vec(cx, type_of(cx, mt.ty))) }