Skip to content

Commit c5a6b51

Browse files
committed
Update Cargo.lock and move size_and_align_of_dst back
1 parent c61531d commit c5a6b51

File tree

5 files changed

+132
-107
lines changed

5 files changed

+132
-107
lines changed

src/librustc_codegen_llvm/common.rs

Lines changed: 3 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212

1313
//! Code that is useful in various codegen modules.
1414
15-
use llvm::{self, ValueRef, ContextRef, TypeKind, True, False, Bool, OperandBundleDef};
15+
use llvm;
16+
use llvm::{ValueRef, ContextRef, TypeKind};
17+
use llvm::{True, False, Bool, OperandBundleDef};
1618
use rustc::hir::def_id::DefId;
1719
use rustc::middle::lang_items::LangItem;
1820
use abi;
@@ -27,8 +29,6 @@ use rustc::ty::{self, Ty, TyCtxt};
2729
use rustc::ty::layout::{HasDataLayout, LayoutOf};
2830
use rustc::hir;
2931

30-
use meth;
31-
3232
use libc::{c_uint, c_char};
3333
use std::iter;
3434

@@ -448,101 +448,3 @@ pub fn ty_fn_sig<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
448448
_ => bug!("unexpected type {:?} to ty_fn_sig", ty)
449449
}
450450
}
451-
452-
pub fn size_and_align_of_dst<'a, 'tcx>(bx: &Builder<'a, 'tcx>, t: Ty<'tcx>, info: ValueRef)
453-
-> (ValueRef, ValueRef) {
454-
debug!("calculate size of DST: {}; with lost info: {:?}",
455-
t, Value(info));
456-
if bx.cx.type_is_sized(t) {
457-
let (size, align) = bx.cx.size_and_align_of(t);
458-
debug!("size_and_align_of_dst t={} info={:?} size: {:?} align: {:?}",
459-
t, Value(info), size, align);
460-
let size = C_usize(bx.cx, size.bytes());
461-
let align = C_usize(bx.cx, align.abi());
462-
return (size, align);
463-
}
464-
assert!(!info.is_null());
465-
match t.sty {
466-
ty::TyDynamic(..) => {
467-
// load size/align from vtable
468-
(meth::SIZE.get_usize(bx, info), meth::ALIGN.get_usize(bx, info))
469-
}
470-
ty::TySlice(_) | ty::TyStr => {
471-
let unit = t.sequence_element_type(bx.tcx());
472-
// The info in this case is the length of the str, so the size is that
473-
// times the unit size.
474-
let (size, align) = bx.cx.size_and_align_of(unit);
475-
(bx.mul(info, C_usize(bx.cx, size.bytes())),
476-
C_usize(bx.cx, align.abi()))
477-
}
478-
_ => {
479-
let cx = bx.cx;
480-
// First get the size of all statically known fields.
481-
// Don't use size_of because it also rounds up to alignment, which we
482-
// want to avoid, as the unsized field's alignment could be smaller.
483-
assert!(!t.is_simd());
484-
let layout = cx.layout_of(t);
485-
debug!("DST {} layout: {:?}", t, layout);
486-
487-
let i = layout.fields.count() - 1;
488-
let sized_size = layout.fields.offset(i).bytes();
489-
let sized_align = layout.align.abi();
490-
debug!("DST {} statically sized prefix size: {} align: {}",
491-
t, sized_size, sized_align);
492-
let sized_size = C_usize(cx, sized_size);
493-
let sized_align = C_usize(cx, sized_align);
494-
495-
// Recurse to get the size of the dynamically sized field (must be
496-
// the last field).
497-
let field_ty = layout.field(cx, i).ty;
498-
let (unsized_size, mut unsized_align) = size_and_align_of_dst(bx, field_ty, info);
499-
500-
// FIXME (#26403, #27023): We should be adding padding
501-
// to `sized_size` (to accommodate the `unsized_align`
502-
// required of the unsized field that follows) before
503-
// summing it with `sized_size`. (Note that since #26403
504-
// is unfixed, we do not yet add the necessary padding
505-
// here. But this is where the add would go.)
506-
507-
// Return the sum of sizes and max of aligns.
508-
let size = bx.add(sized_size, unsized_size);
509-
510-
// Packed types ignore the alignment of their fields.
511-
if let ty::TyAdt(def, _) = t.sty {
512-
if def.repr.packed() {
513-
unsized_align = sized_align;
514-
}
515-
}
516-
517-
// Choose max of two known alignments (combined value must
518-
// be aligned according to more restrictive of the two).
519-
let align = match (const_to_opt_u128(sized_align, false),
520-
const_to_opt_u128(unsized_align, false)) {
521-
(Some(sized_align), Some(unsized_align)) => {
522-
// If both alignments are constant, (the sized_align should always be), then
523-
// pick the correct alignment statically.
524-
C_usize(cx, ::std::cmp::max(sized_align, unsized_align) as u64)
525-
}
526-
_ => bx.select(bx.icmp(llvm::IntUGT, sized_align, unsized_align),
527-
sized_align,
528-
unsized_align)
529-
};
530-
531-
// Issue #27023: must add any necessary padding to `size`
532-
// (to make it a multiple of `align`) before returning it.
533-
//
534-
// Namely, the returned size should be, in C notation:
535-
//
536-
// `size + ((size & (align-1)) ? align : 0)`
537-
//
538-
// emulated via the semi-standard fast bit trick:
539-
//
540-
// `(size + (align-1)) & -align`
541-
542-
let addend = bx.sub(align, C_usize(bx.cx, 1));
543-
let size = bx.and(bx.add(size, addend), bx.neg(align));
544-
545-
(size, align)
546-
}
547-
}
548-
}

src/librustc_codegen_llvm/glue.rs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//!
12+
//
13+
// Code relating to drop glue.
14+
15+
use std;
16+
17+
use builder::Builder;
18+
use common::*;
19+
use llvm::{ValueRef};
20+
use llvm;
21+
use meth;
22+
use rustc::ty::layout::LayoutOf;
23+
use rustc::ty::{self, Ty};
24+
use value::Value;
25+
26+
pub fn size_and_align_of_dst<'a, 'tcx>(bx: &Builder<'a, 'tcx>, t: Ty<'tcx>, info: ValueRef)
27+
-> (ValueRef, ValueRef) {
28+
debug!("calculate size of DST: {}; with lost info: {:?}",
29+
t, Value(info));
30+
if bx.cx.type_is_sized(t) {
31+
let (size, align) = bx.cx.size_and_align_of(t);
32+
debug!("size_and_align_of_dst t={} info={:?} size: {:?} align: {:?}",
33+
t, Value(info), size, align);
34+
let size = C_usize(bx.cx, size.bytes());
35+
let align = C_usize(bx.cx, align.abi());
36+
return (size, align);
37+
}
38+
assert!(!info.is_null());
39+
match t.sty {
40+
ty::TyDynamic(..) => {
41+
// load size/align from vtable
42+
(meth::SIZE.get_usize(bx, info), meth::ALIGN.get_usize(bx, info))
43+
}
44+
ty::TySlice(_) | ty::TyStr => {
45+
let unit = t.sequence_element_type(bx.tcx());
46+
// The info in this case is the length of the str, so the size is that
47+
// times the unit size.
48+
let (size, align) = bx.cx.size_and_align_of(unit);
49+
(bx.mul(info, C_usize(bx.cx, size.bytes())),
50+
C_usize(bx.cx, align.abi()))
51+
}
52+
_ => {
53+
let cx = bx.cx;
54+
// First get the size of all statically known fields.
55+
// Don't use size_of because it also rounds up to alignment, which we
56+
// want to avoid, as the unsized field's alignment could be smaller.
57+
assert!(!t.is_simd());
58+
let layout = cx.layout_of(t);
59+
debug!("DST {} layout: {:?}", t, layout);
60+
61+
let i = layout.fields.count() - 1;
62+
let sized_size = layout.fields.offset(i).bytes();
63+
let sized_align = layout.align.abi();
64+
debug!("DST {} statically sized prefix size: {} align: {}",
65+
t, sized_size, sized_align);
66+
let sized_size = C_usize(cx, sized_size);
67+
let sized_align = C_usize(cx, sized_align);
68+
69+
// Recurse to get the size of the dynamically sized field (must be
70+
// the last field).
71+
let field_ty = layout.field(cx, i).ty;
72+
let (unsized_size, mut unsized_align) = size_and_align_of_dst(bx, field_ty, info);
73+
74+
// FIXME (#26403, #27023): We should be adding padding
75+
// to `sized_size` (to accommodate the `unsized_align`
76+
// required of the unsized field that follows) before
77+
// summing it with `sized_size`. (Note that since #26403
78+
// is unfixed, we do not yet add the necessary padding
79+
// here. But this is where the add would go.)
80+
81+
// Return the sum of sizes and max of aligns.
82+
let size = bx.add(sized_size, unsized_size);
83+
84+
// Packed types ignore the alignment of their fields.
85+
if let ty::TyAdt(def, _) = t.sty {
86+
if def.repr.packed() {
87+
unsized_align = sized_align;
88+
}
89+
}
90+
91+
// Choose max of two known alignments (combined value must
92+
// be aligned according to more restrictive of the two).
93+
let align = match (const_to_opt_u128(sized_align, false),
94+
const_to_opt_u128(unsized_align, false)) {
95+
(Some(sized_align), Some(unsized_align)) => {
96+
// If both alignments are constant, (the sized_align should always be), then
97+
// pick the correct alignment statically.
98+
C_usize(cx, std::cmp::max(sized_align, unsized_align) as u64)
99+
}
100+
_ => bx.select(bx.icmp(llvm::IntUGT, sized_align, unsized_align),
101+
sized_align,
102+
unsized_align)
103+
};
104+
105+
// Issue #27023: must add any necessary padding to `size`
106+
// (to make it a multiple of `align`) before returning it.
107+
//
108+
// Namely, the returned size should be, in C notation:
109+
//
110+
// `size + ((size & (align-1)) ? align : 0)`
111+
//
112+
// emulated via the semi-standard fast bit trick:
113+
//
114+
// `(size + (align-1)) & -align`
115+
116+
let addend = bx.sub(align, C_usize(bx.cx, 1));
117+
let size = bx.and(bx.add(size, addend), bx.neg(align));
118+
119+
(size, align)
120+
}
121+
}
122+
}

src/librustc_codegen_llvm/intrinsic.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use mir::operand::{OperandRef, OperandValue};
1919
use base::*;
2020
use common::*;
2121
use declare;
22+
use glue;
2223
use type_::Type;
2324
use type_of::LayoutLlvmExt;
2425
use rustc::ty::{self, Ty};
@@ -145,7 +146,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
145146
let tp_ty = substs.type_at(0);
146147
if let OperandValue::Pair(_, meta) = args[0].val {
147148
let (llsize, _) =
148-
size_and_align_of_dst(bx, tp_ty, meta);
149+
glue::size_and_align_of_dst(bx, tp_ty, meta);
149150
llsize
150151
} else {
151152
C_usize(cx, cx.size_of(tp_ty).bytes())
@@ -159,7 +160,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
159160
let tp_ty = substs.type_at(0);
160161
if let OperandValue::Pair(_, meta) = args[0].val {
161162
let (_, llalign) =
162-
size_and_align_of_dst(bx, tp_ty, meta);
163+
glue::size_and_align_of_dst(bx, tp_ty, meta);
163164
llalign
164165
} else {
165166
C_usize(cx, cx.align_of(tp_ty).abi())

src/librustc_codegen_llvm/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ mod consts;
109109
mod context;
110110
mod debuginfo;
111111
mod declare;
112+
mod glue;
112113
mod intrinsic;
113114
mod llvm_util;
114115
mod metadata;

src/librustc_codegen_llvm/mir/place.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@ use rustc::mir::tcx::PlaceTy;
1616
use rustc_data_structures::indexed_vec::Idx;
1717
use base;
1818
use builder::Builder;
19-
use common::{
20-
CodegenCx, C_undef, C_usize, C_u8, C_u32, C_uint, C_null, C_uint_big,size_and_align_of_dst
21-
};
19+
use common::{CodegenCx, C_undef, C_usize, C_u8, C_u32, C_uint, C_null, C_uint_big};
2220
use consts;
2321
use type_of::LayoutLlvmExt;
2422
use type_::Type;
2523
use value::Value;
24+
use glue;
2625

2726
use std::ptr;
2827

@@ -223,7 +222,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
223222
let unaligned_offset = C_usize(cx, offset.bytes());
224223

225224
// Get the alignment of the field
226-
let (_, unsized_align) = size_and_align_of_dst(bx, field.ty, meta);
225+
let (_, unsized_align) = glue::size_and_align_of_dst(bx, field.ty, meta);
227226

228227
// Bump the unaligned offset up to the appropriate alignment using the
229228
// following expression:

0 commit comments

Comments
 (0)