rustc: Put all boxes into addrspace 1

This commit is contained in:
Brian Anderson 2012-05-07 14:27:43 -07:00
parent 0e43e8ccc8
commit b99038c2bf
5 changed files with 61 additions and 8 deletions

View file

@ -1034,7 +1034,15 @@ fn type_to_str_inner(names: type_names, outer0: [TypeRef], ty: TypeRef) ->
ret "*\\" + int::str(n as int); 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)); type_to_str_inner(names, outer, llvm::LLVMGetElementType(ty));
} }
13 { ret "Vector"; } 13 { ret "Vector"; }

View file

@ -436,7 +436,9 @@ fn compile_submatch(bcx: block, m: match, vals: [ValueRef],
// Unbox in case of a box field // Unbox in case of a box field
if any_box_pat(m, col) { if any_box_pat(m, col) {
let box = Load(bcx, val); 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] compile_submatch(bcx, enter_box(dm, m, col, val), [unboxed]
+ vals_left, chk, exits); + vals_left, chk, exits);
ret; ret;

View file

@ -88,6 +88,7 @@ resource icx_popper(ccx: @crate_ctxt) {
impl ccx_icx for @crate_ctxt { impl ccx_icx for @crate_ctxt {
fn insn_ctxt(s: str) -> icx_popper { fn insn_ctxt(s: str) -> icx_popper {
#debug("new insn_ctxt: %s", s);
if (self.sess.opts.count_llvm_insns) { if (self.sess.opts.count_llvm_insns) {
*self.stats.llvm_insn_ctxt += [s]; *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 _icx = bcx.insn_ctxt("trans_malloc_boxed");
let mut ti = none; let mut ti = none;
let box = malloc_boxed_raw(bcx, t, ti); 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}; 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 t = expr_ty(cx, base);
let val = alt check ty::get(t).struct { let val = alt check ty::get(t).struct {
ty::ty_box(_) { 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(_, _, _) { ty::ty_res(_, _, _) {
GEPi(sub.bcx, sub.val, [0u, 1u]) 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 { 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 } }; let must_bind = alt c.env { self_env(_, _, _) { true } _ { false } };
if must_bind { if must_bind {

View file

@ -642,12 +642,17 @@ fn T_box(cx: @crate_ctxt, t: TypeRef) -> TypeRef {
ret T_struct(T_box_header_fields(cx) + [t]); 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 { fn T_opaque_box(cx: @crate_ctxt) -> TypeRef {
ret T_box(cx, T_i8()); ret T_box(cx, T_i8());
} }
fn T_opaque_box_ptr(cx: @crate_ctxt) -> TypeRef { 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 { fn T_port(cx: @crate_ctxt, _t: TypeRef) -> TypeRef {

View file

@ -11,6 +11,7 @@ export type_of;
export type_of_explicit_args; export type_of_explicit_args;
export type_of_fn_from_ty; export type_of_fn_from_ty;
export type_of_fn; export type_of_fn;
export type_of_non_gc_box;
fn type_of_explicit_args(cx: @crate_ctxt, inputs: [ty::arg]) -> [TypeRef] { fn type_of_explicit_args(cx: @crate_ctxt, inputs: [ty::arg]) -> [TypeRef] {
vec::map(inputs) {|arg| 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)) 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 { fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
assert !ty::type_has_vars(t); 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_estr(ty::vstore_uniq) |
ty::ty_str { T_ptr(T_vec(cx, T_i8())) } ty::ty_str { T_ptr(T_vec(cx, T_i8())) }
ty::ty_enum(did, _) { type_of_enum(cx, did, t) } 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_evec(mt, ty::vstore_box) |
ty::ty_box(mt) { T_ptr(T_box(cx, type_of(cx, mt.ty))) } ty::ty_box(mt) { T_box_ptr(T_box(cx, type_of(cx, mt.ty))) }
ty::ty_opaque_box { T_ptr(T_box(cx, T_i8())) } 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_uniq(mt) { T_ptr(type_of(cx, mt.ty)) }
ty::ty_evec(mt, ty::vstore_uniq) | ty::ty_evec(mt, ty::vstore_uniq) |
ty::ty_vec(mt) { T_ptr(T_vec(cx, type_of(cx, mt.ty))) } ty::ty_vec(mt) { T_ptr(T_vec(cx, type_of(cx, mt.ty))) }