Skip to content

Commit 9cc8384

Browse files
---
yaml --- r: 69076 b: refs/heads/auto c: 976d7a5 h: refs/heads/master v: v3
1 parent e6caba5 commit 9cc8384

File tree

9 files changed

+301
-66
lines changed

9 files changed

+301
-66
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0
1414
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
1515
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1616
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
17-
refs/heads/auto: 91ebfbb9592a2262c62c684a5a2431111c987b1e
17+
refs/heads/auto: 976d7a53cbb35d2f7814d2d13dcc55a304d5e7a7
1818
refs/heads/servo: af82457af293e2a842ba6b7759b70288da276167
1919
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c

branches/auto/src/librustc/lib/llvm.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,6 +1635,14 @@ pub mod llvm {
16351635
#[fast_ffi]
16361636
pub unsafe fn LLVMABIAlignmentOfType(TD: TargetDataRef,
16371637
Ty: TypeRef) -> c_uint;
1638+
1639+
/** Computes the byte offset of the indexed struct element for a target. */
1640+
#[fast_ffi]
1641+
pub unsafe fn LLVMOffsetOfElement(TD: TargetDataRef,
1642+
StructTy: TypeRef,
1643+
Element: c_uint)
1644+
-> c_ulonglong;
1645+
16381646
/**
16391647
* Returns the minimum alignment of a type when part of a call frame.
16401648
*/

branches/auto/src/librustc/middle/trans/debuginfo.rs

Lines changed: 175 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use lib::llvm::debuginfo::*;
4949
use middle::trans::common::*;
5050
use middle::trans::machine;
5151
use middle::trans::type_of;
52+
use middle::trans::type_::Type;
5253
use middle::trans;
5354
use middle::ty;
5455
use util::ppaux::ty_to_str;
@@ -65,6 +66,8 @@ use syntax::codemap::span;
6566
use syntax::{ast, codemap, ast_util, ast_map};
6667
use syntax::parse::token;
6768

69+
70+
6871
static DW_LANG_RUST: int = 0x9000;
6972

7073
static AutoVariableTag: int = 256;
@@ -594,17 +597,102 @@ fn create_struct(cx: &mut CrateContext, struct_type: ty::t, fields: ~[ty::field]
594597
-> DICompositeType {
595598
debug!("create_struct: %?", ty::get(struct_type));
596599

600+
let struct_name = ty_to_str(cx.tcx, struct_type);
601+
let struct_llvm_type = type_of::type_of(cx, struct_type);
602+
603+
let field_llvm_types = fields.map(|field| type_of::type_of(cx, field.mt.ty));
604+
let field_names = fields.map(|field| cx.sess.str_of(field.ident).to_owned());
605+
let field_types_metadata = fields.map(|field| create_ty(cx, field.mt.ty, span));
606+
607+
return create_composite_type(
608+
cx,
609+
struct_llvm_type,
610+
struct_name,
611+
field_llvm_types,
612+
field_names,
613+
field_types_metadata,
614+
span);
615+
}
616+
617+
fn create_tuple(cx: &mut CrateContext,
618+
tuple_type: ty::t,
619+
component_types: &[ty::t],
620+
span: span)
621+
-> DICompositeType {
622+
623+
let tuple_name = (cx.sess.str_of((dbg_cx(cx).names)("tuple"))).to_owned();
624+
let tuple_llvm_type = type_of::type_of(cx, tuple_type);
625+
// Create a vec of empty strings. A vec::build_n() function would be nice for this.
626+
let mut component_names : ~[~str] = vec::with_capacity(component_types.len());
627+
component_names.grow_fn(component_types.len(), |_| ~"");
628+
629+
let component_llvm_types = component_types.map(|it| type_of::type_of(cx, *it));
630+
let component_types_metadata = component_types.map(|it| create_ty(cx, *it, span));
631+
632+
return create_composite_type(
633+
cx,
634+
tuple_llvm_type,
635+
tuple_name,
636+
component_llvm_types,
637+
component_names,
638+
component_types_metadata,
639+
span);
640+
}
641+
642+
fn create_composite_type(cx: &mut CrateContext,
643+
composite_llvm_type: Type,
644+
composite_type_name: &str,
645+
member_llvm_types: &[Type],
646+
member_names: &[~str],
647+
member_type_metadata: &[DIType],
648+
span: span)
649+
-> DICompositeType {
650+
597651
let loc = span_start(cx, span);
598-
let file_md = create_file(cx, loc.file.name);
652+
let file_metadata = create_file(cx, loc.file.name);
653+
654+
let composite_size = machine::llsize_of_alloc(cx, composite_llvm_type);
655+
let composite_align = machine::llalign_of_min(cx, composite_llvm_type);
656+
657+
let member_metadata = create_DIArray(
658+
DIB(cx),
659+
// transform the ty::t array of components into an array of DIEs
660+
do vec::mapi(member_llvm_types) |i, member_llvm_type| {
661+
let member_size = machine::llsize_of_alloc(cx, *member_llvm_type);
662+
let member_align = machine::llalign_of_min(cx, *member_llvm_type);
663+
let member_offset = machine::llelement_offset(cx, composite_llvm_type, i);
664+
let member_name : &str = member_names[i];
665+
666+
do member_name.as_c_str |member_name| { unsafe {
667+
llvm::LLVMDIBuilderCreateMemberType(
668+
DIB(cx),
669+
file_metadata,
670+
member_name,
671+
file_metadata,
672+
loc.line as c_uint,
673+
bytes_to_bits(member_size),
674+
bytes_to_bits(member_align),
675+
bytes_to_bits(member_offset),
676+
0,
677+
member_type_metadata[i])
678+
}}
679+
});
599680

600-
let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, struct_type), file_md, loc.line);
601-
for fields.iter().advance |field| {
602-
let field_t = field.mt.ty;
603-
let ty_md = create_ty(cx, field_t, span);
604-
let (size, align) = size_and_align_of(cx, field_t);
605-
scx.add_member(cx.sess.str_of(field.ident), loc.line, size, align, ty_md);
606-
}
607-
return scx.finalize();
681+
return do composite_type_name.as_c_str |name| { unsafe {
682+
llvm::LLVMDIBuilderCreateStructType(
683+
DIB(cx),
684+
file_metadata,
685+
name,
686+
file_metadata,
687+
loc.line as c_uint,
688+
bytes_to_bits(composite_size),
689+
bytes_to_bits(composite_align),
690+
0,
691+
ptr::null(),
692+
member_metadata,
693+
0,
694+
ptr::null())
695+
}};
608696
}
609697

610698
// returns (void* type as a ValueRef, size in bytes, align in bytes)
@@ -639,30 +727,83 @@ fn create_tuple(cx: &mut CrateContext, tuple_type: ty::t, elements: &[ty::t], sp
639727
return scx.finalize();
640728
}
641729

642-
fn create_boxed_type(cx: &mut CrateContext, contents: ty::t,
643-
span: span, boxed: DIType) -> DICompositeType {
644-
debug!("create_boxed_type: %?", ty::get(contents));
645-
646-
let loc = span_start(cx, span);
647-
let file_md = create_file(cx, loc.file.name);
648-
let int_t = ty::mk_int();
649-
let refcount_type = create_basic_type(cx, int_t, span);
650-
let name = ty_to_str(cx.tcx, contents);
651-
652-
let mut scx = StructContext::new(cx, fmt!("box<%s>", name), file_md, 0);
653-
scx.add_member("refcnt", 0, sys::size_of::<uint>(),
654-
sys::min_align_of::<uint>(), refcount_type);
655-
// the tydesc and other pointers should be irrelevant to the
656-
// debugger, so treat them as void* types
657-
let (vp, vpsize, vpalign) = voidptr(cx);
658-
scx.add_member("tydesc", 0, vpsize, vpalign, vp);
659-
scx.add_member("prev", 0, vpsize, vpalign, vp);
660-
scx.add_member("next", 0, vpsize, vpalign, vp);
661-
let (size, align) = size_and_align_of(cx, contents);
662-
scx.add_member("boxed", 0, size, align, boxed);
663-
return scx.finalize();
730+
fn create_boxed_type(cx: &mut CrateContext,
731+
content_type: ty::t,
732+
span: span)
733+
-> DICompositeType {
734+
735+
debug!("create_boxed_type: %?", ty::get(content_type));
736+
737+
let content_llvm_type = type_of::type_of(cx, content_type);
738+
let content_type_metadata = create_ty(cx, content_type, span);
739+
740+
let box_llvm_type = Type::box(cx, &content_llvm_type);
741+
let member_llvm_types = box_llvm_type.field_types();
742+
let member_names = [~"refcnt", ~"tydesc", ~"prev", ~"next", ~"val"];
743+
744+
assert!(box_layout_is_as_expected(cx, member_llvm_types, content_llvm_type));
745+
746+
let int_type = ty::mk_int();
747+
let nil_pointer_type = ty::mk_nil_ptr(cx.tcx);
748+
749+
let member_types_metadata = [
750+
create_ty(cx, int_type, span),
751+
create_ty(cx, nil_pointer_type, span),
752+
create_ty(cx, nil_pointer_type, span),
753+
create_ty(cx, nil_pointer_type, span),
754+
content_type_metadata
755+
];
756+
757+
return create_composite_type(
758+
cx,
759+
box_llvm_type,
760+
"box name",
761+
member_llvm_types,
762+
member_names,
763+
member_types_metadata,
764+
span);
765+
766+
fn box_layout_is_as_expected(cx: &CrateContext,
767+
member_types: &[Type],
768+
content_type: Type)
769+
-> bool {
770+
return member_types[0] == cx.int_type
771+
&& member_types[1] == cx.tydesc_type.ptr_to()
772+
&& member_types[2] == Type::i8().ptr_to()
773+
&& member_types[3] == Type::i8().ptr_to()
774+
&& member_types[4] == content_type;
775+
}
664776
}
665777

778+
// fn create_boxed_type(cx: &mut CrateContext,
779+
// contents: ty::t,
780+
// span: span,
781+
// boxed: DIType)
782+
// -> DICompositeType {
783+
784+
// debug!("create_boxed_type: %?", ty::get(contents));
785+
786+
// let loc = span_start(cx, span);
787+
// let file_md = create_file(cx, loc.file.name);
788+
// let int_t = ty::mk_int();
789+
// let refcount_type = create_basic_type(cx, int_t, span);
790+
// let name = ty_to_str(cx.tcx, contents);
791+
792+
// let mut scx = StructContext::new(cx, fmt!("box<%s>", name), file_md, 0);
793+
// scx.add_member("refcnt", 0, sys::size_of::<uint>(),
794+
// sys::min_align_of::<uint>(), refcount_type);
795+
// // the tydesc and other pointers should be irrelevant to the
796+
// // debugger, so treat them as void* types
797+
// let (vp, vpsize, vpalign) = voidptr(cx);
798+
// scx.add_member("tydesc", 0, vpsize, vpalign, vp);
799+
// scx.add_member("prev", 0, vpsize, vpalign, vp);
800+
// scx.add_member("next", 0, vpsize, vpalign, vp);
801+
// let (size, align) = size_and_align_of(cx, contents);
802+
// scx.add_member("val", 0, size, align, boxed);
803+
// return scx.finalize();
804+
// }
805+
806+
666807
fn create_fixed_vec(cx: &mut CrateContext, _vec_t: ty::t, elem_t: ty::t,
667808
len: uint, span: span) -> DIType {
668809
debug!("create_fixed_vec: %?", ty::get(_vec_t));
@@ -840,9 +981,8 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
840981
create_unimpl_ty(cx, t)
841982
}
842983
ty::ty_box(ref mt) | ty::ty_uniq(ref mt) => {
843-
let boxed = create_ty(cx, mt.ty, span);
844-
let box_md = create_boxed_type(cx, mt.ty, span, boxed);
845-
create_pointer_type(cx, t, span, box_md)
984+
let box_metadata = create_boxed_type(cx, mt.ty, span);
985+
create_pointer_type(cx, t, span, box_metadata)
846986
},
847987
ty::ty_evec(ref mt, ref vstore) => {
848988
match *vstore {
@@ -858,10 +998,7 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
858998
}
859999
}
8601000
},
861-
ty::ty_ptr(ref mt) => {
862-
let pointee = create_ty(cx, mt.ty, span);
863-
create_pointer_type(cx, t, span, pointee)
864-
},
1001+
ty::ty_ptr(ref mt) |
8651002
ty::ty_rptr(_, ref mt) => {
8661003
let pointee = create_ty(cx, mt.ty, span);
8671004
create_pointer_type(cx, t, span, pointee)

branches/auto/src/librustc/middle/trans/machine.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,48 @@ pub fn llalign_of(cx: &CrateContext, ty: Type) -> ValueRef {
113113
llvm::LLVMAlignOf(ty.to_ref()), cx.int_type.to_ref(), False);
114114
}
115115
}
116+
117+
pub fn llelement_offset(cx: &CrateContext, struct_ty: Type, element: uint) -> uint {
118+
unsafe {
119+
return llvm::LLVMOffsetOfElement(cx.td.lltd, struct_ty.to_ref(), element as u32) as uint;
120+
}
121+
}
122+
123+
// Computes the size of the data part of an enum.
124+
pub fn static_size_of_enum(cx: &mut CrateContext, t: ty::t) -> uint {
125+
if cx.enum_sizes.contains_key(&t) {
126+
return cx.enum_sizes.get_copy(&t);
127+
}
128+
129+
debug!("static_size_of_enum %s", ty_to_str(cx.tcx, t));
130+
131+
match ty::get(t).sty {
132+
ty::ty_enum(tid, ref substs) => {
133+
// Compute max(variant sizes).
134+
let mut max_size = 0;
135+
let variants = ty::enum_variants(cx.tcx, tid);
136+
for variants.iter().advance |variant| {
137+
if variant.args.len() == 0 {
138+
loop;
139+
}
140+
141+
let lltypes = variant.args.map(|&variant_arg| {
142+
let substituted = ty::subst(cx.tcx, substs, variant_arg);
143+
type_of::sizing_type_of(cx, substituted)
144+
});
145+
146+
debug!("static_size_of_enum: variant %s type %s",
147+
cx.tcx.sess.str_of(variant.name),
148+
cx.tn.type_to_str(Type::struct_(lltypes, false)));
149+
150+
let this_size = llsize_of_real(cx, Type::struct_(lltypes, false));
151+
if max_size < this_size {
152+
max_size = this_size;
153+
}
154+
}
155+
cx.enum_sizes.insert(t, max_size);
156+
return max_size;
157+
}
158+
_ => cx.sess.bug("static_size_of_enum called on non-enum")
159+
}
160+
}

branches/auto/src/rt/memory_region.cpp

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,6 @@ void *memory_region::get_data(alloc_header *ptr) {
3434
return (void*)((char *)ptr + HEADER_SIZE);
3535
}
3636

37-
inline void memory_region::maybe_print_backtrace(const alloc_header *header) const {
38-
# if RUSTRT_TRACK_ALLOCATIONS >= 3
39-
if (_detailed_leaks) {
40-
backtrace_symbols_fd(header->bt + 1, header->btframes - 1, 2);
41-
}
42-
# endif
43-
}
44-
4537
memory_region::memory_region(bool synchronized,
4638
bool detailed_leaks,
4739
bool poison_on_free) :
@@ -182,7 +174,13 @@ memory_region::~memory_region() {
182174
header->tag,
183175
(uintptr_t) get_data(header));
184176
++leak_count;
185-
maybe_print_backtrace(header);
177+
178+
# if RUSTRT_TRACK_ALLOCATIONS >= 3
179+
if (_detailed_leaks) {
180+
backtrace_symbols_fd(header->bt + 1,
181+
header->btframes - 1, 2);
182+
}
183+
# endif
186184
}
187185
}
188186
assert(leak_count == _live_allocations);
@@ -205,16 +203,9 @@ memory_region::release_alloc(void *mem) {
205203

206204
# if RUSTRT_TRACK_ALLOCATIONS >= 2
207205
if (_synchronized) { _lock.lock(); }
208-
if (((size_t) alloc->index) >= _allocation_list.size()) {
209-
printf("free: ptr 0x%" PRIxPTR " (%s) index %d is beyond allocation_list of size %zu\n",
210-
(uintptr_t) get_data(alloc), alloc->tag, alloc->index, _allocation_list.size());
211-
maybe_print_backtrace(alloc);
212-
assert(false && "index beyond allocation_list");
213-
}
214206
if (_allocation_list[alloc->index] != alloc) {
215207
printf("free: ptr 0x%" PRIxPTR " (%s) is not in allocation_list\n",
216208
(uintptr_t) get_data(alloc), alloc->tag);
217-
maybe_print_backtrace(alloc);
218209
assert(false && "not in allocation_list");
219210
}
220211
else {

branches/auto/src/rt/memory_region.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@ class memory_region {
6969
void release_alloc(void *mem);
7070
void claim_alloc(void *mem);
7171

72-
void maybe_print_backtrace(const alloc_header *) const;
73-
7472
private:
7573
// private and undefined to disable copying
7674
memory_region(const memory_region& rhs);

0 commit comments

Comments
 (0)