Skip to content

Commit

Permalink
Remove Rc from the interner.
Browse files Browse the repository at this point in the history
  • Loading branch information
jseyfried committed Nov 21, 2016
1 parent 36c8f6b commit cc74068
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 51 deletions.
8 changes: 0 additions & 8 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1355,11 +1355,3 @@ pub fn build_output_filenames(input: &Input,
}
}
}

// For use by the `rusti` project (https://github.com/murarth/rusti).
pub fn reset_thread_local_state() {
// These may be left in an incoherent state after a previous compile.
syntax::ext::hygiene::reset_hygiene_data();
// `clear_interner` can be used to free memory, but it does not restore the initial state.
symbol::reset_interner();
}
39 changes: 14 additions & 25 deletions src/librustc_trans/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ use std::ffi::CString;
use std::fmt::Write;
use std::path::Path;
use std::ptr;
use std::rc::Rc;
use syntax::ast;
use syntax::symbol::{Interner, InternedString};
use syntax_pos::{self, Span};
Expand Down Expand Up @@ -116,9 +115,8 @@ impl<'tcx> TypeMap<'tcx> {
unique_type_id: UniqueTypeId,
metadata: DIType) {
if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id);
bug!("Type metadata for unique id '{}' is already in the TypeMap!",
&unique_type_id_str[..]);
self.get_unique_type_id_as_string(unique_type_id));
}
}

Expand All @@ -132,7 +130,7 @@ impl<'tcx> TypeMap<'tcx> {

// Get the string representation of a UniqueTypeId. This method will fail if
// the id is unknown.
fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> Rc<str> {
fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
let UniqueTypeId(interner_key) = unique_type_id;
self.unique_id_interner.get(interner_key)
}
Expand Down Expand Up @@ -181,7 +179,7 @@ impl<'tcx> TypeMap<'tcx> {
-> UniqueTypeId {
let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
let enum_variant_type_id = format!("{}::{}",
&self.get_unique_type_id_as_string(enum_type_id),
self.get_unique_type_id_as_string(enum_type_id),
variant_name);
let interner_key = self.unique_id_interner.intern(&enum_variant_type_id);
UniqueTypeId(interner_key)
Expand Down Expand Up @@ -622,29 +620,25 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
Some(metadata) => metadata,
None => {
let unique_type_id_str =
type_map.get_unique_type_id_as_string(unique_type_id);
span_bug!(usage_site_span,
"Expected type metadata for unique \
type id '{}' to already be in \
the debuginfo::TypeMap but it \
was not. (Ty = {})",
&unique_type_id_str[..],
type_map.get_unique_type_id_as_string(unique_type_id),
t);
}
};

match type_map.find_metadata_for_type(t) {
Some(metadata) => {
if metadata != metadata_for_uid {
let unique_type_id_str =
type_map.get_unique_type_id_as_string(unique_type_id);
span_bug!(usage_site_span,
"Mismatch between Ty and \
UniqueTypeId maps in \
debuginfo::TypeMap. \
UniqueTypeId={}, Ty={}",
&unique_type_id_str[..],
type_map.get_unique_type_id_as_string(unique_type_id),
t);
}
}
Expand Down Expand Up @@ -1525,13 +1519,10 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let enum_llvm_type = type_of::type_of(cx, enum_type);
let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);

let unique_type_id_str = debug_context(cx)
.type_map
.borrow()
.get_unique_type_id_as_string(unique_type_id);

let enum_name = CString::new(enum_name).unwrap();
let unique_type_id_str = CString::new(unique_type_id_str.as_bytes()).unwrap();
let unique_type_id_str = CString::new(
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
).unwrap();
let enum_metadata = unsafe {
llvm::LLVMRustDIBuilderCreateUnionType(
DIB(cx),
Expand Down Expand Up @@ -1668,11 +1659,10 @@ fn create_struct_stub(cx: &CrateContext,
-> DICompositeType {
let (struct_size, struct_align) = size_and_align_of(cx, struct_llvm_type);

let unique_type_id_str = debug_context(cx).type_map
.borrow()
.get_unique_type_id_as_string(unique_type_id);
let name = CString::new(struct_type_name).unwrap();
let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
let unique_type_id = CString::new(
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
).unwrap();
let metadata_stub = unsafe {
// LLVMRustDIBuilderCreateStructType() wants an empty array. A null
// pointer will lead to hard to trace and debug LLVM assertions
Expand Down Expand Up @@ -1706,11 +1696,10 @@ fn create_union_stub(cx: &CrateContext,
-> DICompositeType {
let (union_size, union_align) = size_and_align_of(cx, union_llvm_type);

let unique_type_id_str = debug_context(cx).type_map
.borrow()
.get_unique_type_id_as_string(unique_type_id);
let name = CString::new(union_type_name).unwrap();
let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
let unique_type_id = CString::new(
debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
).unwrap();
let metadata_stub = unsafe {
// LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
// pointer will lead to hard to trace and debug LLVM assertions
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#![feature(associated_consts)]
#![feature(const_fn)]
#![feature(libc)]
#![feature(optin_builtin_traits)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(str_escape)]
Expand Down
39 changes: 21 additions & 18 deletions src/libsyntax/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ use serialize::{Decodable, Decoder, Encodable, Encoder};
use std::cell::RefCell;
use std::collections::HashMap;
use std::fmt;
use std::rc::Rc;

/// A symbol is an interned or gensymed string.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Symbol(u32);

// The interner in thread-local, so `Symbol` shouldn't move between threads.
impl !Send for Symbol { }

impl Symbol {
/// Maps a string to its interned representation.
pub fn intern(string: &str) -> Self {
Expand All @@ -34,7 +36,11 @@ impl Symbol {
}

pub fn as_str(self) -> InternedString {
with_interner(|interner| InternedString { string: interner.get(self) })
with_interner(|interner| unsafe {
InternedString {
string: ::std::mem::transmute::<&str, &str>(interner.get(self))
}
})
}

pub fn as_u32(self) -> u32 {
Expand Down Expand Up @@ -74,8 +80,8 @@ impl<'a> PartialEq<&'a str> for Symbol {

#[derive(Default)]
pub struct Interner {
names: HashMap<Rc<str>, Symbol>,
strings: Vec<Rc<str>>,
names: HashMap<Box<str>, Symbol>,
strings: Vec<Box<str>>,
}

impl Interner {
Expand All @@ -97,7 +103,7 @@ impl Interner {
}

let name = Symbol(self.strings.len() as u32);
let string = Rc::__from_str(string);
let string = string.to_string().into_boxed_str();
self.strings.push(string.clone());
self.names.insert(string, name);
name
Expand All @@ -106,12 +112,12 @@ impl Interner {
fn gensym(&mut self, string: &str) -> Symbol {
let gensym = Symbol(self.strings.len() as u32);
// leave out of `names` to avoid colliding
self.strings.push(Rc::__from_str(string));
self.strings.push(string.to_string().into_boxed_str());
gensym
}

pub fn get(&self, name: Symbol) -> Rc<str> {
self.strings[name.0 as usize].clone()
pub fn get(&self, name: Symbol) -> &str {
&self.strings[name.0 as usize]
}
}

Expand Down Expand Up @@ -225,11 +231,6 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
INTERNER.with(|interner| f(&mut *interner.borrow_mut()))
}

/// Reset the ident interner to its initial state.
pub fn reset_interner() {
with_interner(|interner| *interner = Interner::fresh());
}

/// Represents a string stored in the thread-local interner. Because the
/// interner lives for the life of the thread, this can be safely treated as an
/// immortal string, as long as it never crosses between threads.
Expand All @@ -241,23 +242,25 @@ pub fn reset_interner() {
/// somehow.
#[derive(Clone, PartialEq, Hash, PartialOrd, Eq, Ord)]
pub struct InternedString {
string: Rc<str>,
string: &'static str,
}

impl !Send for InternedString { }

impl ::std::ops::Deref for InternedString {
type Target = str;
fn deref(&self) -> &str { &self.string }
fn deref(&self) -> &str { self.string }
}

impl fmt::Debug for InternedString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&self.string, f)
fmt::Debug::fmt(self.string, f)
}
}

impl fmt::Display for InternedString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.string, f)
fmt::Display::fmt(self.string, f)
}
}

Expand All @@ -269,7 +272,7 @@ impl Decodable for InternedString {

impl Encodable for InternedString {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_str(&self.string)
s.emit_str(self.string)
}
}

Expand Down

0 comments on commit cc74068

Please sign in to comment.