Skip to content

Commit

Permalink
Auto merge of #59749 - petrochenkov:upspan, r=<try>
Browse files Browse the repository at this point in the history
[do not merge] Measure upper limit for performance of 32 bit `Span`

What would happen if span interner accesses were cheap and didn't require any synchronization?

r? @ghost
  • Loading branch information
bors committed Apr 11, 2019
2 parents 3de0106 + 955ca4c commit d806815
Show file tree
Hide file tree
Showing 18 changed files with 25 additions and 201 deletions.
2 changes: 1 addition & 1 deletion src/librustc_data_structures/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ impl<T> Once<T> {
}

#[derive(Debug)]
pub struct Lock<T>(InnerLock<T>);
pub struct Lock<T>(pub InnerLock<T>);

impl<T> Lock<T> {
#[inline(always)]
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,7 @@ impl Tester for Collector {
)
}),
});
self.tests.clear();
}

fn get_line(&self) -> usize {
Expand Down
13 changes: 12 additions & 1 deletion src/libsyntax/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,18 @@ pub fn with_globals<F, R>(f: F) -> R
{
let globals = Globals::new();
GLOBALS.set(&globals, || {
syntax_pos::GLOBALS.set(&globals.syntax_pos_globals, f)
syntax_pos::GLOBALS.set(&globals.syntax_pos_globals, || unsafe {
let init_backdoor = syntax_pos::SPAN_INTERNER_BACKDOOR.is_null();
if init_backdoor {
syntax_pos::SPAN_INTERNER_BACKDOOR =
globals.syntax_pos_globals.span_interner.0.as_ptr();
}
let res = f();
if init_backdoor {
syntax_pos::SPAN_INTERNER_BACKDOOR = std::ptr::null_mut();
}
res
})
})
}

Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax_pos/hygiene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,17 @@ pub fn clear_markings() {
}

impl SyntaxContext {
#[inline]
pub const fn empty() -> Self {
SyntaxContext(0)
}

#[inline]
crate fn as_u32(self) -> u32 {
self.0
}

#[inline]
crate fn from_u32(raw: u32) -> SyntaxContext {
SyntaxContext(raw)
}
Expand Down
5 changes: 3 additions & 2 deletions src/libsyntax_pos/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#![feature(rustc_attrs)]
#![feature(specialization)]
#![feature(step_trait)]
#![feature(stmt_expr_attributes)]

use serialize::{Encodable, Decodable, Encoder, Decoder};

Expand All @@ -29,7 +30,7 @@ pub mod hygiene;
pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnFormat, CompilerDesugaringKind};

mod span_encoding;
pub use span_encoding::{Span, DUMMY_SP};
pub use span_encoding::{Span, DUMMY_SP, SPAN_INTERNER_BACKDOOR};

pub mod symbol;

Expand All @@ -48,7 +49,7 @@ use std::path::PathBuf;

pub struct Globals {
symbol_interner: Lock<symbol::Interner>,
span_interner: Lock<span_encoding::SpanInterner>,
pub span_interner: Lock<span_encoding::SpanInterner>,
hygiene_data: Lock<hygiene::HygieneData>,
}

Expand Down
40 changes: 5 additions & 35 deletions src/libsyntax_pos/span_encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,19 @@
// The encoding format for inline spans were obtained by optimizing over crates in rustc/libstd.
// See https://internals.rust-lang.org/t/rfc-compiler-refactoring-spans/1357/28

use crate::GLOBALS;
use crate::{BytePos, SpanData};
use crate::hygiene::SyntaxContext;

use rustc_data_structures::fx::FxHashMap;
use std::hash::{Hash, Hasher};

/// A compressed span.
/// Contains either fields of `SpanData` inline if they are small, or index into span interner.
/// The primary goal of `Span` is to be as small as possible and fit into other structures
/// (that's why it uses `packed` as well). Decoding speed is the second priority.
/// See `SpanData` for the info on span fields in decoded representation.
#[repr(packed)]
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct Span(u32);

impl Copy for Span {}
impl Clone for Span {
#[inline]
fn clone(&self) -> Span {
*self
}
}
impl PartialEq for Span {
#[inline]
fn eq(&self, other: &Span) -> bool {
let a = self.0;
let b = other.0;
a == b
}
}
impl Eq for Span {}
impl Hash for Span {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
let a = self.0;
a.hash(state)
}
}

/// Dummy span, both position and length are zero, syntax context is zero as well.
/// This span is kept inline and encoded with format 0.
pub const DUMMY_SP: Span = Span(0);
Expand Down Expand Up @@ -98,7 +72,7 @@ fn encode(sd: &SpanData) -> Span {
(base << INLINE_OFFSETS[BASE_INDEX]) | (len << INLINE_OFFSETS[LEN_INDEX]) |
(ctxt << INLINE_OFFSETS[CTXT_INDEX]) | TAG_INLINE
} else {
let index = with_span_interner(|interner| interner.intern(sd));
let index = unsafe { (*SPAN_INTERNER_BACKDOOR).intern(sd) };
(index << INTERNED_INDEX_OFFSET) | TAG_INTERNED
};
Span(val)
Expand All @@ -109,7 +83,7 @@ fn decode(span: Span) -> SpanData {
let val = span.0;

// Extract a field at position `pos` having size `size`.
let extract = |pos: u32, size: u32| {
let extract = #[inline] |pos: u32, size: u32| {
let mask = ((!0u32) as u64 >> (32 - size)) as u32; // Can't shift u32 by 32
(val >> pos) & mask
};
Expand All @@ -120,7 +94,7 @@ fn decode(span: Span) -> SpanData {
extract(INLINE_OFFSETS[CTXT_INDEX], INLINE_SIZES[CTXT_INDEX]),
)} else {
let index = extract(INTERNED_INDEX_OFFSET, INTERNED_INDEX_SIZE);
return with_span_interner(|interner| *interner.get(index));
return unsafe { *(*SPAN_INTERNER_BACKDOOR).get(index) };
};
SpanData { lo: BytePos(base), hi: BytePos(base + len), ctxt: SyntaxContext::from_u32(ctxt) }
}
Expand Down Expand Up @@ -149,8 +123,4 @@ impl SpanInterner {
}
}

// If an interner exists, return it. Otherwise, prepare a fresh one.
#[inline]
fn with_span_interner<T, F: FnOnce(&mut SpanInterner) -> T>(f: F) -> T {
GLOBALS.with(|globals| f(&mut *globals.span_interner.lock()))
}
pub static mut SPAN_INTERNER_BACKDOOR: *mut SpanInterner = std::ptr::null_mut();
7 changes: 0 additions & 7 deletions src/test/run-make-fulldeps/issue-22131/Makefile

This file was deleted.

5 changes: 0 additions & 5 deletions src/test/run-make-fulldeps/issue-22131/foo.rs

This file was deleted.

8 changes: 0 additions & 8 deletions src/test/run-make-fulldeps/rustdoc-error-lines/Makefile

This file was deleted.

11 changes: 0 additions & 11 deletions src/test/run-make-fulldeps/rustdoc-error-lines/input.rs

This file was deleted.

20 changes: 0 additions & 20 deletions src/test/rustdoc-ui/failed-doctest-output.rs

This file was deleted.

35 changes: 0 additions & 35 deletions src/test/rustdoc-ui/failed-doctest-output.stdout

This file was deleted.

21 changes: 0 additions & 21 deletions src/test/rustdoc/doc-cfg-target-feature.rs

This file was deleted.

11 changes: 0 additions & 11 deletions src/test/rustdoc/force-target-feature.rs

This file was deleted.

8 changes: 0 additions & 8 deletions src/test/rustdoc/issue-38219.rs

This file was deleted.

9 changes: 0 additions & 9 deletions src/test/rustdoc/no-run-still-checks-lints.rs

This file was deleted.

9 changes: 0 additions & 9 deletions src/test/rustdoc/test_option_check/bar.rs

This file was deleted.

18 changes: 0 additions & 18 deletions src/test/rustdoc/test_option_check/test.rs

This file was deleted.

0 comments on commit d806815

Please sign in to comment.