Skip to content

Commit

Permalink
Auto merge of #60030 - Centril:rollup-3d0t24t, r=Centril
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - #59128 (Emit ansi color codes in the `rendered` field of json diagnostics)
 - #59646 (const fn: Improve wording)
 - #59986 (Miri: refactor new allocation tagging)
 - #60003 (LLD is not supported on Darwin)
 - #60018 (Miri now supports entropy, but is still slow)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Apr 17, 2019
2 parents e4e032a + eb958e1 commit efe2f32
Show file tree
Hide file tree
Showing 33 changed files with 444 additions and 426 deletions.
6 changes: 4 additions & 2 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,10 @@ impl Step for Llvm {
.define("LLVM_DEFAULT_TARGET_TRIPLE", target);

if builder.config.llvm_thin_lto && !emscripten {
cfg.define("LLVM_ENABLE_LTO", "Thin")
.define("LLVM_ENABLE_LLD", "ON");
cfg.define("LLVM_ENABLE_LTO", "Thin");
if !target.contains("apple") {
cfg.define("LLVM_ENABLE_LLD", "ON");
}
}

// By default, LLVM will automatically find OCaml and, if it finds it,
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/tests/binary_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ fn assert_covariance() {
//
// Destructors must be called exactly once per element.
#[test]
#[cfg(not(miri))] // Miri does not support panics nor entropy
#[cfg(not(miri))] // Miri does not support catching panics
fn panic_safe() {
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);

Expand Down
21 changes: 15 additions & 6 deletions src/liballoc/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ fn test_reverse() {
}

#[test]
#[cfg(not(miri))] // Miri does not support entropy
#[cfg(not(miri))] // Miri is too slow
fn test_sort() {
let mut rng = thread_rng();

Expand Down Expand Up @@ -466,10 +466,19 @@ fn test_sort() {
}

#[test]
#[cfg(not(miri))] // Miri does not support entropy
fn test_sort_stability() {
for len in (2..25).chain(500..510) {
for _ in 0..10 {
#[cfg(not(miri))] // Miri is too slow
let large_range = 500..510;
#[cfg(not(miri))] // Miri is too slow
let rounds = 10;

#[cfg(miri)]
let large_range = 0..0; // empty range
#[cfg(miri)]
let rounds = 1;

for len in (2..25).chain(large_range) {
for _ in 0..rounds {
let mut counts = [0; 10];

// create a vector like [(6, 1), (5, 1), (6, 2), ...],
Expand Down Expand Up @@ -1397,7 +1406,7 @@ fn test_box_slice_clone() {
#[test]
#[allow(unused_must_use)] // here, we care about the side effects of `.clone()`
#[cfg_attr(target_os = "emscripten", ignore)]
#[cfg(not(miri))] // Miri does not support threads nor entropy
#[cfg(not(miri))] // Miri does not support threads
fn test_box_slice_clone_panics() {
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
Expand Down Expand Up @@ -1589,7 +1598,7 @@ thread_local!(static SILENCE_PANIC: Cell<bool> = Cell::new(false));

#[test]
#[cfg_attr(target_os = "emscripten", ignore)] // no threads
#[cfg(not(miri))] // Miri does not support threads nor entropy
#[cfg(not(miri))] // Miri does not support threads
fn panic_safe() {
let prev = panic::take_hook();
panic::set_hook(Box::new(move |info| {
Expand Down
17 changes: 13 additions & 4 deletions src/libcore/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1024,22 +1024,31 @@ fn test_rotate_right() {

#[test]
#[cfg(not(target_arch = "wasm32"))]
#[cfg(not(miri))] // Miri does not support entropy
fn sort_unstable() {
use core::cmp::Ordering::{Equal, Greater, Less};
use core::slice::heapsort;
use rand::{FromEntropy, Rng, rngs::SmallRng, seq::SliceRandom};

#[cfg(not(miri))] // Miri is too slow
let large_range = 500..510;
#[cfg(not(miri))] // Miri is too slow
let rounds = 100;

#[cfg(miri)]
let large_range = 0..0; // empty range
#[cfg(miri)]
let rounds = 1;

let mut v = [0; 600];
let mut tmp = [0; 600];
let mut rng = SmallRng::from_entropy();

for len in (2..25).chain(500..510) {
for len in (2..25).chain(large_range) {
let v = &mut v[0..len];
let tmp = &mut tmp[0..len];

for &modulus in &[5, 10, 100, 1000] {
for _ in 0..100 {
for _ in 0..rounds {
for i in 0..len {
v[i] = rng.gen::<i32>() % modulus;
}
Expand Down Expand Up @@ -1095,7 +1104,7 @@ fn sort_unstable() {

#[test]
#[cfg(not(target_arch = "wasm32"))]
#[cfg(not(miri))] // Miri does not support entropy
#[cfg(not(miri))] // Miri is too slow
fn partition_at_index() {
use core::cmp::Ordering::{Equal, Greater, Less};
use rand::rngs::SmallRng;
Expand Down
73 changes: 20 additions & 53 deletions src/librustc/mir/interpret/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,10 @@ pub struct Allocation<Tag=(),Extra=()> {
}


pub trait AllocationExtra<Tag, MemoryExtra>: ::std::fmt::Debug + Clone {
/// Hook to initialize the extra data when an allocation gets created.
fn memory_allocated(
_size: Size,
_memory_extra: &MemoryExtra
) -> Self;
pub trait AllocationExtra<Tag>: ::std::fmt::Debug + Clone {
// There is no constructor in here because the constructor's type depends
// on `MemoryKind`, and making things sufficiently generic leads to painful
// inference failure.

/// Hook for performing extra checks on a memory read access.
///
Expand Down Expand Up @@ -88,15 +86,8 @@ pub trait AllocationExtra<Tag, MemoryExtra>: ::std::fmt::Debug + Clone {
}
}

impl AllocationExtra<(), ()> for () {
#[inline(always)]
fn memory_allocated(
_size: Size,
_memory_extra: &()
) -> Self {
()
}
}
// For Tag=() and no extra state, we have is a trivial implementation.
impl AllocationExtra<()> for () { }

impl<Tag, Extra> Allocation<Tag, Extra> {
/// Creates a read-only allocation initialized by the given bytes
Expand Down Expand Up @@ -159,23 +150,21 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
}

/// Byte accessors
impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
/// The last argument controls whether we error out when there are undefined
/// or pointer bytes. You should never call this, call `get_bytes` or
/// `get_bytes_with_undef_and_ptr` instead,
///
/// This function also guarantees that the resulting pointer will remain stable
/// even when new allocations are pushed to the `HashMap`. `copy_repeatedly` relies
/// on that.
fn get_bytes_internal<MemoryExtra>(
fn get_bytes_internal(
&self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
size: Size,
check_defined_and_ptr: bool,
) -> EvalResult<'tcx, &[u8]>
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
where Extra: AllocationExtra<Tag, MemoryExtra>
{
self.check_bounds(cx, ptr, size)?;

Expand All @@ -196,43 +185,37 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
}

#[inline]
pub fn get_bytes<MemoryExtra>(
pub fn get_bytes(
&self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
size: Size,
) -> EvalResult<'tcx, &[u8]>
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
where Extra: AllocationExtra<Tag, MemoryExtra>
{
self.get_bytes_internal(cx, ptr, size, true)
}

/// It is the caller's responsibility to handle undefined and pointer bytes.
/// However, this still checks that there are no relocations on the *edges*.
#[inline]
pub fn get_bytes_with_undef_and_ptr<MemoryExtra>(
pub fn get_bytes_with_undef_and_ptr(
&self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
size: Size,
) -> EvalResult<'tcx, &[u8]>
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
where Extra: AllocationExtra<Tag, MemoryExtra>
{
self.get_bytes_internal(cx, ptr, size, false)
}

/// Just calling this already marks everything as defined and removes relocations,
/// so be sure to actually put data there!
pub fn get_bytes_mut<MemoryExtra>(
pub fn get_bytes_mut(
&mut self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
size: Size,
) -> EvalResult<'tcx, &mut [u8]>
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
where Extra: AllocationExtra<Tag, MemoryExtra>
{
assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`");
self.check_bounds(cx, ptr, size)?;
Expand All @@ -250,16 +233,14 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
}

/// Reading and writing
impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
/// Reads bytes until a `0` is encountered. Will error if the end of the allocation is reached
/// before a `0` is found.
pub fn read_c_str<MemoryExtra>(
pub fn read_c_str(
&self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
) -> EvalResult<'tcx, &[u8]>
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
where Extra: AllocationExtra<Tag, MemoryExtra>
{
assert_eq!(ptr.offset.bytes() as usize as u64, ptr.offset.bytes());
let offset = ptr.offset.bytes() as usize;
Expand All @@ -278,15 +259,13 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
/// Validates that `ptr.offset` and `ptr.offset + size` do not point to the middle of a
/// relocation. If `allow_ptr_and_undef` is `false`, also enforces that the memory in the
/// given range contains neither relocations nor undef bytes.
pub fn check_bytes<MemoryExtra>(
pub fn check_bytes(
&self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
size: Size,
allow_ptr_and_undef: bool,
) -> EvalResult<'tcx>
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
where Extra: AllocationExtra<Tag, MemoryExtra>
{
// Check bounds and relocations on the edges
self.get_bytes_with_undef_and_ptr(cx, ptr, size)?;
Expand All @@ -301,30 +280,26 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
/// Writes `src` to the memory starting at `ptr.offset`.
///
/// Will do bounds checks on the allocation.
pub fn write_bytes<MemoryExtra>(
pub fn write_bytes(
&mut self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
src: &[u8],
) -> EvalResult<'tcx>
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
where Extra: AllocationExtra<Tag, MemoryExtra>
{
let bytes = self.get_bytes_mut(cx, ptr, Size::from_bytes(src.len() as u64))?;
bytes.clone_from_slice(src);
Ok(())
}

/// Sets `count` bytes starting at `ptr.offset` with `val`. Basically `memset`.
pub fn write_repeat<MemoryExtra>(
pub fn write_repeat(
&mut self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
val: u8,
count: Size
) -> EvalResult<'tcx>
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
where Extra: AllocationExtra<Tag, MemoryExtra>
{
let bytes = self.get_bytes_mut(cx, ptr, count)?;
for b in bytes {
Expand All @@ -341,14 +316,12 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
/// being valid for ZSTs
///
/// Note: This function does not do *any* alignment checks, you need to do these before calling
pub fn read_scalar<MemoryExtra>(
pub fn read_scalar(
&self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
size: Size
) -> EvalResult<'tcx, ScalarMaybeUndef<Tag>>
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
where Extra: AllocationExtra<Tag, MemoryExtra>
{
// get_bytes_unchecked tests relocation edges
let bytes = self.get_bytes_with_undef_and_ptr(cx, ptr, size)?;
Expand Down Expand Up @@ -379,13 +352,11 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
}

/// Note: This function does not do *any* alignment checks, you need to do these before calling
pub fn read_ptr_sized<MemoryExtra>(
pub fn read_ptr_sized(
&self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
) -> EvalResult<'tcx, ScalarMaybeUndef<Tag>>
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
where Extra: AllocationExtra<Tag, MemoryExtra>
{
self.read_scalar(cx, ptr, cx.data_layout().pointer_size)
}
Expand All @@ -398,15 +369,13 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
/// being valid for ZSTs
///
/// Note: This function does not do *any* alignment checks, you need to do these before calling
pub fn write_scalar<MemoryExtra>(
pub fn write_scalar(
&mut self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
val: ScalarMaybeUndef<Tag>,
type_size: Size,
) -> EvalResult<'tcx>
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
where Extra: AllocationExtra<Tag, MemoryExtra>
{
let val = match val {
ScalarMaybeUndef::Scalar(scalar) => scalar,
Expand Down Expand Up @@ -446,14 +415,12 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
}

/// Note: This function does not do *any* alignment checks, you need to do these before calling
pub fn write_ptr_sized<MemoryExtra>(
pub fn write_ptr_sized(
&mut self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
val: ScalarMaybeUndef<Tag>
) -> EvalResult<'tcx>
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
where Extra: AllocationExtra<Tag, MemoryExtra>
{
let ptr_size = cx.data_layout().pointer_size;
self.write_scalar(cx, ptr.into(), val, ptr_size)
Expand Down
8 changes: 7 additions & 1 deletion src/librustc/mir/interpret/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,17 @@ impl<'tcx> Pointer<()> {
Pointer { alloc_id, offset, tag: () }
}

#[inline(always)]
pub fn with_tag<Tag>(self, tag: Tag) -> Pointer<Tag>
{
Pointer::new_with_tag(self.alloc_id, self.offset, tag)
}

#[inline(always)]
pub fn with_default_tag<Tag>(self) -> Pointer<Tag>
where Tag: Default
{
Pointer::new_with_tag(self.alloc_id, self.offset, Default::default())
self.with_tag(Tag::default())
}
}

Expand Down
Loading

0 comments on commit efe2f32

Please sign in to comment.