}
// LLVM doesn't like types that don't fit in the address space
-fn ensure_struct_fits_in_address_space(ccx: &CrateContext,
- fields: &[Type],
- packed: bool,
- scapegoat: ty::t) {
+fn ensure_struct_fits_in_address_space<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
+ fields: &[Type],
+ packed: bool,
+ scapegoat: Ty<'tcx>) {
let mut offset = 0;
for &llty in fields.iter() {
- // Invariant: offset < ccx.max_obj_size() <= 1<<61
+ // Invariant: offset < ccx.obj_size_bound() <= 1<<61
if !packed {
let type_align = machine::llalign_of_min(ccx, llty);
offset = roundup(offset, type_align);
&self.local.trait_cache
}
- pub fn max_obj_size(&self) -> u64 {
- 1<<31 /* FIXME #18069: select based on architecture */
+ /// Return exclusive upper bound on object size.
+ ///
+ /// The theoretical maximum object size is defined as the maximum positive `int` value. This
+ /// ensures that the `offset` semantics remain well-defined by allowing it to correctly index
+ /// every address within an object along with one byte past the end, along with allowing `int`
+ /// to store the difference between any two pointers into an object.
+ ///
+ /// The upper bound on 64-bit currently needs to be lower because LLVM uses a 64-bit integer to
+ /// represent object size in bits. It would need to be 1 << 61 to account for this, but is
+ /// currently conservatively bounded to 1 << 47 as that is enough to cover the current usable
+ /// address space on 64-bit ARMv8 and x86_64.
+ pub fn obj_size_bound(&self) -> u64 {
+ match self.sess().target.target.target_word_size[] {
+ "32" => 1 << 31,
+ "64" => 1 << 47,
+ _ => unreachable!() // error handled by config::build_target_config
+ }
}
- pub fn report_overbig_object(&self, obj: ty::t) -> ! {
+ pub fn report_overbig_object(&self, obj: Ty<'tcx>) -> ! {
self.sess().fatal(
format!("the type `{}` is too big for the current architecture",
obj.repr(self.tcx())).as_slice())
use syntax::ast;
// LLVM doesn't like objects that are too big. Issue #17913
-fn ensure_array_fits_in_address_space(ccx: &CrateContext,
- llet: Type,
- size: machine::llsize,
- scapegoat: ty::t) {
+fn ensure_array_fits_in_address_space<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
+ llet: Type,
+ size: machine::llsize,
+ scapegoat: Ty<'tcx>) {
let esz = machine::llsize_of_alloc(ccx, llet);
match esz.checked_mul(size) {
- Some(n) if n < ccx.max_obj_size() => {}
+ Some(n) if n < ccx.obj_size_bound() => {}
_ => { ccx.report_overbig_object(scapegoat) }
}
}