about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--mk/llvm.mk2
-rw-r--r--src/librustc/back/link.rs173
-rw-r--r--src/librustc/back/upcall.rs20
-rw-r--r--src/librustc/driver/driver.rs7
-rw-r--r--src/librustc/driver/session.rs51
-rw-r--r--src/librustc/lib.rs4
-rw-r--r--src/librustc/lib/llvm.rs12
-rw-r--r--src/librustc/middle/trans/base.rs62
-rw-r--r--src/librustc/middle/trans/expr.rs8
-rw-r--r--src/librustc/middle/trans/macros.rs22
-rw-r--r--src/librustc/middle/trans/write_guard.rs7
m---------src/llvm0
-rw-r--r--src/rt/rust_upcall.c3
-rw-r--r--src/rustllvm/PassWrapper.cpp1
-rw-r--r--src/rustllvm/RustWrapper.cpp278
-rw-r--r--src/rustllvm/llvm-auto-clean-trigger2
-rw-r--r--src/rustllvm/rustllvm.def.in3
17 files changed, 74 insertions, 581 deletions
diff --git a/mk/llvm.mk b/mk/llvm.mk
index efaa109c29e..42b1a551805 100644
--- a/mk/llvm.mk
+++ b/mk/llvm.mk
@@ -37,7 +37,9 @@ endif
 # dependencies. In these cases, commit a change that touches
 # the stamp in the source dir.
 $$(LLVM_STAMP_$(1)): $(S)src/rustllvm/llvm-auto-clean-trigger
+	@$$(call E, make: cleaning llvm)
 	$(Q)$(MAKE) clean-llvm
+	@$$(call E, make: done cleaning llvm)
 	touch $$@
 
 endef
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index 1c4b15f42e9..1cb10d59e59 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -82,111 +82,8 @@ pub fn WriteOutputFile(
     }
 }
 
-pub mod jit {
-
-    use back::link::llvm_err;
-    use driver::session::Session;
-    use lib::llvm::llvm;
-    use lib::llvm::{ModuleRef, ContextRef, ExecutionEngineRef};
-
-    use std::c_str::ToCStr;
-    use std::cast;
-    use std::local_data;
-    use std::unstable::intrinsics;
-
-    struct LLVMJITData {
-        ee: ExecutionEngineRef,
-        llcx: ContextRef
-    }
-
-    pub trait Engine {}
-    impl Engine for LLVMJITData {}
-
-    impl Drop for LLVMJITData {
-        fn drop(&mut self) {
-            unsafe {
-                llvm::LLVMDisposeExecutionEngine(self.ee);
-                llvm::LLVMContextDispose(self.llcx);
-            }
-        }
-    }
-
-    pub fn exec(sess: Session,
-                c: ContextRef,
-                m: ModuleRef,
-                stacks: bool) {
-        unsafe {
-            let manager = llvm::LLVMRustPrepareJIT(intrinsics::morestack_addr());
-
-            // We need to tell JIT where to resolve all linked
-            // symbols from. The equivalent of -lstd, -lcore, etc.
-            // By default the JIT will resolve symbols from the extra and
-            // core linked into rustc. We don't want that,
-            // incase the user wants to use an older extra library.
-
-            // We custom-build a JIT execution engine via some rust wrappers
-            // first. This wrappers takes ownership of the module passed in.
-            let ee = llvm::LLVMRustBuildJIT(manager, m, stacks);
-            if ee.is_null() {
-                llvm::LLVMContextDispose(c);
-                llvm_err(sess, ~"Could not create the JIT");
-            }
-
-            // Next, we need to get a handle on the _rust_main function by
-            // looking up it's corresponding ValueRef and then requesting that
-            // the execution engine compiles the function.
-            let fun = "_rust_main".with_c_str(|entry| {
-                llvm::LLVMGetNamedFunction(m, entry)
-            });
-            if fun.is_null() {
-                llvm::LLVMDisposeExecutionEngine(ee);
-                llvm::LLVMContextDispose(c);
-                llvm_err(sess, ~"Could not find _rust_main in the JIT");
-            }
-
-            // Finally, once we have the pointer to the code, we can do some
-            // closure magic here to turn it straight into a callable rust
-            // closure
-            let code = llvm::LLVMGetPointerToGlobal(ee, fun);
-            assert!(!code.is_null());
-            let func: extern "Rust" fn() = cast::transmute(code);
-            func();
-
-            // Currently there is no method of re-using the executing engine
-            // from LLVM in another call to the JIT. While this kinda defeats
-            // the purpose of having a JIT in the first place, there isn't
-            // actually much code currently which would re-use data between
-            // different invocations of this. Additionally, the compilation
-            // model currently isn't designed to support this scenario.
-            //
-            // We can't destroy the engine/context immediately here, however,
-            // because of annihilation. The JIT code contains drop glue for any
-            // types defined in the crate we just ran, and if any of those boxes
-            // are going to be dropped during annihilation, the drop glue must
-            // be run. Hence, we need to transfer ownership of this jit engine
-            // to the caller of this function. To be convenient for now, we
-            // shove it into TLS and have someone else remove it later on.
-            let data = ~LLVMJITData { ee: ee, llcx: c };
-            set_engine(data as ~Engine);
-        }
-    }
-
-    // The stage1 compiler won't work, but that doesn't really matter. TLS
-    // changed only very recently to allow storage of owned values.
-    local_data_key!(engine_key: ~Engine)
-
-    fn set_engine(engine: ~Engine) {
-        local_data::set(engine_key, engine)
-    }
-
-    pub fn consume_engine() -> Option<~Engine> {
-        local_data::pop(engine_key)
-    }
-}
-
 pub mod write {
 
-    use back::link::jit;
     use back::link::{WriteOutputFile, output_type};
     use back::link::{output_type_assembly, output_type_bitcode};
     use back::link::{output_type_exe, output_type_llvm_assembly};
@@ -307,48 +204,38 @@ pub mod write {
                 })
             }
 
-            if sess.opts.jit {
-                // If we are using JIT, go ahead and create and execute the
-                // engine now. JIT execution takes ownership of the module and
-                // context, so don't dispose
-                jit::exec(sess, llcx, llmod, true);
-            } else {
-                // Create a codegen-specific pass manager to emit the actual
-                // assembly or object files. This may not end up getting used,
-                // but we make it anyway for good measure.
-                let cpm = llvm::LLVMCreatePassManager();
-                llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
-                llvm::LLVMRustAddLibraryInfo(cpm, llmod);
-
-                match output_type {
-                    output_type_none => {}
-                    output_type_bitcode => {
-                        output.with_c_str(|buf| {
-                            llvm::LLVMWriteBitcodeToFile(llmod, buf);
-                        })
-                    }
-                    output_type_llvm_assembly => {
-                        output.with_c_str(|output| {
-                            llvm::LLVMRustPrintModule(cpm, llmod, output)
-                        })
-                    }
-                    output_type_assembly => {
-                        WriteOutputFile(sess, tm, cpm, llmod, output, lib::llvm::AssemblyFile);
-                    }
-                    output_type_exe | output_type_object => {
-                        WriteOutputFile(sess, tm, cpm, llmod, output, lib::llvm::ObjectFile);
-                    }
+            // Create a codegen-specific pass manager to emit the actual
+            // assembly or object files. This may not end up getting used,
+            // but we make it anyway for good measure.
+            let cpm = llvm::LLVMCreatePassManager();
+            llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
+            llvm::LLVMRustAddLibraryInfo(cpm, llmod);
+
+            match output_type {
+                output_type_none => {}
+                output_type_bitcode => {
+                    output.with_c_str(|buf| {
+                        llvm::LLVMWriteBitcodeToFile(llmod, buf);
+                    })
+                }
+                output_type_llvm_assembly => {
+                    output.with_c_str(|output| {
+                        llvm::LLVMRustPrintModule(cpm, llmod, output)
+                    })
+                }
+                output_type_assembly => {
+                    WriteOutputFile(sess, tm, cpm, llmod, output, lib::llvm::AssemblyFile);
+                }
+                output_type_exe | output_type_object => {
+                    WriteOutputFile(sess, tm, cpm, llmod, output, lib::llvm::ObjectFile);
                 }
-
-                llvm::LLVMDisposePassManager(cpm);
             }
 
+            llvm::LLVMDisposePassManager(cpm);
+
             llvm::LLVMRustDisposeTargetMachine(tm);
-            // the jit takes ownership of these two items
-            if !sess.opts.jit {
-                llvm::LLVMDisposeModule(llmod);
-                llvm::LLVMContextDispose(llcx);
-            }
+            llvm::LLVMDisposeModule(llmod);
+            llvm::LLVMContextDispose(llcx);
             if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
         }
     }
@@ -711,8 +598,8 @@ pub fn sanitize(s: &str) -> ~str {
             ',' => result.push_str("$C$"),
 
             // '.' doesn't occur in types and functions, so reuse it
-            // for ':'
-            ':' => result.push_char('.'),
+            // for ':' and '-'
+            '-' | ':' => result.push_char('.'),
 
             // These are legal symbols
             'a' .. 'z'
diff --git a/src/librustc/back/upcall.rs b/src/librustc/back/upcall.rs
index 0ad53c4d49c..730ceba12c7 100644
--- a/src/librustc/back/upcall.rs
+++ b/src/librustc/back/upcall.rs
@@ -15,22 +15,10 @@ use middle::trans::type_::Type;
 use lib::llvm::{ModuleRef, ValueRef};
 
 pub struct Upcalls {
-    trace: ValueRef,
     rust_personality: ValueRef,
-    reset_stack_limit: ValueRef
 }
 
 macro_rules! upcall (
-    (fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
-        let fn_ty = Type::func([ $($arg),* ], &$ret);
-        base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty)
-    });
-    (nothrow fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
-        let fn_ty = Type::func([ $($arg),* ], &$ret);
-        let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
-        base::set_no_unwind(decl);
-        decl
-    });
     (nothrow fn $name:ident -> $ret:expr) => ({
         let fn_ty = Type::func([], &$ret);
         let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
@@ -39,13 +27,9 @@ macro_rules! upcall (
     })
 )
 
-pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls {
-    let opaque_ptr = Type::i8().ptr_to();
-    let int_ty = Type::int(targ_cfg.arch);
-
+pub fn declare_upcalls(_targ_cfg: @session::config,
+                       llmod: ModuleRef) -> @Upcalls {
     @Upcalls {
-        trace: upcall!(fn trace(opaque_ptr, opaque_ptr, int_ty) -> Type::void()),
         rust_personality: upcall!(nothrow fn rust_personality -> Type::i32()),
-        reset_stack_limit: upcall!(nothrow fn reset_stack_limit -> Type::void())
     }
 }
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index 4559a1230bd..63d6c60d269 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -419,11 +419,6 @@ pub fn stop_after_phase_5(sess: Session) -> bool {
         debug!("not building executable, returning early from compile_input");
         return true;
     }
-
-    if sess.opts.jit {
-        debug!("running JIT, returning early from compile_input");
-        return true;
-    }
     return false;
 }
 
@@ -751,7 +746,6 @@ pub fn build_session_options(binary: @str,
         } else { No }
     };
     let gc = debugging_opts & session::gc != 0;
-    let jit = debugging_opts & session::jit != 0;
     let extra_debuginfo = debugging_opts & session::extra_debug_info != 0;
     let debuginfo = debugging_opts & session::debug_info != 0 ||
         extra_debuginfo;
@@ -802,7 +796,6 @@ pub fn build_session_options(binary: @str,
         extra_debuginfo: extra_debuginfo,
         lint_opts: lint_opts,
         save_temps: save_temps,
-        jit: jit,
         output_type: output_type,
         addl_lib_search_paths: @mut addl_lib_search_paths,
         ar: ar,
diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs
index e45ea533f79..6a4755344ef 100644
--- a/src/librustc/driver/session.rs
+++ b/src/librustc/driver/session.rs
@@ -44,30 +44,28 @@ pub static time_llvm_passes:        uint = 1 <<  3;
 pub static trans_stats:             uint = 1 <<  4;
 pub static asm_comments:            uint = 1 <<  5;
 pub static no_verify:               uint = 1 <<  6;
-pub static trace:                   uint = 1 <<  7;
-pub static coherence:               uint = 1 <<  8;
-pub static borrowck_stats:          uint = 1 <<  9;
-pub static borrowck_note_pure:      uint = 1 << 10;
-pub static borrowck_note_loan:      uint = 1 << 11;
-pub static no_landing_pads:         uint = 1 << 12;
-pub static debug_llvm:              uint = 1 << 13;
-pub static count_type_sizes:        uint = 1 << 14;
-pub static meta_stats:              uint = 1 << 15;
-pub static no_opt:                  uint = 1 << 16;
-pub static gc:                      uint = 1 << 17;
-pub static jit:                     uint = 1 << 18;
-pub static debug_info:              uint = 1 << 19;
-pub static extra_debug_info:        uint = 1 << 20;
-pub static print_link_args:         uint = 1 << 21;
-pub static no_debug_borrows:        uint = 1 << 22;
-pub static lint_llvm:               uint = 1 << 23;
-pub static print_llvm_passes:       uint = 1 << 24;
-pub static no_vectorize_loops:      uint = 1 << 25;
-pub static no_vectorize_slp:        uint = 1 << 26;
-pub static no_prepopulate_passes:   uint = 1 << 27;
-pub static use_softfp:              uint = 1 << 28;
-pub static gen_crate_map:           uint = 1 << 29;
-pub static prefer_dynamic:          uint = 1 << 30;
+pub static coherence:               uint = 1 <<  7;
+pub static borrowck_stats:          uint = 1 <<  8;
+pub static borrowck_note_pure:      uint = 1 <<  9;
+pub static borrowck_note_loan:      uint = 1 << 10;
+pub static no_landing_pads:         uint = 1 << 11;
+pub static debug_llvm:              uint = 1 << 12;
+pub static count_type_sizes:        uint = 1 << 13;
+pub static meta_stats:              uint = 1 << 14;
+pub static no_opt:                  uint = 1 << 15;
+pub static gc:                      uint = 1 << 16;
+pub static debug_info:              uint = 1 << 17;
+pub static extra_debug_info:        uint = 1 << 18;
+pub static print_link_args:         uint = 1 << 19;
+pub static no_debug_borrows:        uint = 1 << 20;
+pub static lint_llvm:               uint = 1 << 21;
+pub static print_llvm_passes:       uint = 1 << 22;
+pub static no_vectorize_loops:      uint = 1 << 23;
+pub static no_vectorize_slp:        uint = 1 << 24;
+pub static no_prepopulate_passes:   uint = 1 << 25;
+pub static use_softfp:              uint = 1 << 26;
+pub static gen_crate_map:           uint = 1 << 27;
+pub static prefer_dynamic:          uint = 1 << 28;
 
 pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] {
     ~[("verbose", "in general, enable more debug printouts", verbose),
@@ -79,7 +77,6 @@ pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] {
      ("trans-stats", "gather trans statistics", trans_stats),
      ("asm-comments", "generate comments into the assembly (may change behavior)", asm_comments),
      ("no-verify", "skip LLVM verification", no_verify),
-     ("trace", "emit trace logs", trace),
      ("coherence", "perform coherence checking", coherence),
      ("borrowck-stats", "gather borrowck statistics",  borrowck_stats),
      ("borrowck-note-pure", "note where purity is req'd",
@@ -95,7 +92,6 @@ pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] {
      ("no-opt", "do not optimize, even if -O is passed", no_opt),
      ("print-link-args", "Print the arguments passed to the linker", print_link_args),
      ("gc", "Garbage collect shared data (experimental)", gc),
-     ("jit", "Execute using JIT (experimental)", jit),
      ("extra-debug-info", "Extra debugging info (experimental)",
       extra_debug_info),
      ("debug-info", "Produce debug info (experimental)", debug_info),
@@ -146,7 +142,6 @@ pub struct options {
     extra_debuginfo: bool,
     lint_opts: ~[(lint::lint, lint::level)],
     save_temps: bool,
-    jit: bool,
     output_type: back::link::output_type,
     addl_lib_search_paths: @mut HashSet<Path>, // This is mutable for rustpkg, which
                                                // updates search paths based on the
@@ -311,7 +306,6 @@ impl Session_ {
     pub fn asm_comments(&self) -> bool { self.debugging_opt(asm_comments) }
     pub fn no_verify(&self) -> bool { self.debugging_opt(no_verify) }
     pub fn lint_llvm(&self) -> bool { self.debugging_opt(lint_llvm) }
-    pub fn trace(&self) -> bool { self.debugging_opt(trace) }
     pub fn coherence(&self) -> bool { self.debugging_opt(coherence) }
     pub fn borrowck_stats(&self) -> bool { self.debugging_opt(borrowck_stats) }
     pub fn borrowck_note_pure(&self) -> bool {
@@ -370,7 +364,6 @@ pub fn basic_options() -> @options {
         extra_debuginfo: false,
         lint_opts: ~[],
         save_temps: false,
-        jit: false,
         output_type: link::output_type_exe,
         addl_lib_search_paths: @mut HashSet::new(),
         ar: None,
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 438dc03b766..166e1414f6e 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -363,10 +363,6 @@ pub fn monitor(f: proc(@diagnostic::Emitter)) {
         let _finally = finally { ch: ch };
 
         f(demitter);
-
-        // Due reasons explain in #7732, if there was a jit execution context it
-        // must be consumed and passed along to our parent task.
-        back::link::jit::consume_engine()
     }) {
         result::Ok(_) => { /* fallthrough */ }
         result::Err(_) => {
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
index a856c069971..1e1444babf2 100644
--- a/src/librustc/lib/llvm.rs
+++ b/src/librustc/lib/llvm.rs
@@ -1441,18 +1441,6 @@ pub mod llvm {
             call. */
         pub fn LLVMRustGetLastError() -> *c_char;
 
-        /** Prepare the JIT. Returns a memory manager that can load crates. */
-        pub fn LLVMRustPrepareJIT(__morestack: *()) -> *();
-
-        /** Load a crate into the memory manager. */
-        pub fn LLVMRustLoadCrate(MM: *(), Filename: *c_char) -> bool;
-
-        /** Execute the JIT engine. */
-        pub fn LLVMRustBuildJIT(MM: *(),
-                                M: ModuleRef,
-                                EnableSegmentedStacks: bool)
-                                -> ExecutionEngineRef;
-
         /// Print the pass timings since static dtors aren't picking them up.
         pub fn LLVMRustPrintPassTimings();
 
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index d4586fc5990..72b9fc83c4a 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -1018,11 +1018,6 @@ pub fn get_landing_pad(bcx: @mut Block) -> BasicBlockRef {
     // The landing pad block is a cleanup
     SetCleanup(pad_bcx, llretval);
 
-    // Because we may have unwound across a stack boundary, we must call into
-    // the runtime to figure out which stack segment we are on and place the
-    // stack limit back into the TLS.
-    Call(pad_bcx, bcx.ccx().upcalls.reset_stack_limit, [], []);
-
     // We store the retval in a function-central alloca, so that calls to
     // Resume can find it.
     match bcx.fcx.personality {
@@ -1097,28 +1092,6 @@ pub fn load_if_immediate(cx: @mut Block, v: ValueRef, t: ty::t) -> ValueRef {
     return v;
 }
 
-pub fn trans_trace(bcx: @mut Block, sp_opt: Option<Span>, trace_str: @str) {
-    if !bcx.sess().trace() { return; }
-    let _icx = push_ctxt("trans_trace");
-    add_comment(bcx, trace_str);
-    let V_trace_str = C_cstr(bcx.ccx(), trace_str);
-    let (V_filename, V_line) = match sp_opt {
-      Some(sp) => {
-        let sess = bcx.sess();
-        let loc = sess.parse_sess.cm.lookup_char_pos(sp.lo);
-        (C_cstr(bcx.ccx(), loc.file.name), loc.line as int)
-      }
-      None => {
-        (C_cstr(bcx.ccx(), @"<runtime>"), 0)
-      }
-    };
-    let ccx = bcx.ccx();
-    let V_trace_str = PointerCast(bcx, V_trace_str, Type::i8p());
-    let V_filename = PointerCast(bcx, V_filename, Type::i8p());
-    let args = ~[V_trace_str, V_filename, C_int(ccx, V_line)];
-    Call(bcx, ccx.upcalls.trace, args, []);
-}
-
 pub fn ignore_lhs(_bcx: @mut Block, local: &ast::Local) -> bool {
     match local.pat.node {
         ast::PatWild => true, _ => false
@@ -1313,12 +1286,6 @@ pub fn cleanup_and_leave(bcx: @mut Block,
     loop {
         debug!("cleanup_and_leave: leaving {}", cur.to_str());
 
-        if bcx.sess().trace() {
-            trans_trace(
-                bcx, None,
-                (format!("cleanup_and_leave({})", cur.to_str())).to_managed());
-        }
-
         let mut cur_scope = cur.scope;
         loop {
             cur_scope = match cur_scope {
@@ -1387,12 +1354,6 @@ pub fn cleanup_block(bcx: @mut Block, upto: Option<BasicBlockRef>) -> @mut Block
     loop {
         debug!("cleanup_block: {}", cur.to_str());
 
-        if bcx.sess().trace() {
-            trans_trace(
-                bcx, None,
-                (format!("cleanup_block({})", cur.to_str())).to_managed());
-        }
-
         let mut cur_scope = cur.scope;
         loop {
             cur_scope = match cur_scope {
@@ -2961,6 +2922,11 @@ pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint) {
     return (map, keys.len())
 }
 
+pub fn symname(sess: session::Session, name: &str,
+               hash: &str, vers: &str) -> ~str {
+    let elt = path_name(sess.ident_of(name));
+    link::exported_name(sess, ~[elt], hash, vers)
+}
 
 pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
                       llmod: ModuleRef) -> ValueRef {
@@ -2969,13 +2935,14 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
     let mut n_subcrates = 1;
     let cstore = sess.cstore;
     while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; }
-    let mapname = if *sess.building_library && !sess.gen_crate_map() {
-        format!("{}_{}_{}", mapmeta.name, mapmeta.vers, mapmeta.extras_hash)
+    let is_top = !*sess.building_library || sess.gen_crate_map();
+    let sym_name = if is_top {
+        ~"_rust_crate_map_toplevel"
     } else {
-        ~"toplevel"
+        symname(sess, "_rust_crate_map_" + mapmeta.name, mapmeta.extras_hash,
+                mapmeta.vers)
     };
 
-    let sym_name = ~"_rust_crate_map_" + mapname;
     let slicetype = Type::struct_([int_type, int_type], false);
     let maptype = Type::struct_([
         Type::i32(),        // version
@@ -2990,7 +2957,7 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
     });
     // On windows we'd like to export the toplevel cratemap
     // such that we can find it from libstd.
-    if targ_cfg.os == OsWin32 && "toplevel" == mapname {
+    if targ_cfg.os == OsWin32 && is_top {
         lib::llvm::SetLinkage(map, lib::llvm::DLLExportLinkage);
     } else {
         lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
@@ -3005,10 +2972,9 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) {
     let cstore = ccx.sess.cstore;
     while cstore::have_crate_data(cstore, i) {
         let cdata = cstore::get_crate_data(cstore, i);
-        let nm = format!("_rust_crate_map_{}_{}_{}",
-                      cdata.name,
-                      cstore::get_crate_vers(cstore, i),
-                      cstore::get_crate_hash(cstore, i));
+        let nm = symname(ccx.sess, format!("_rust_crate_map_{}", cdata.name),
+                         cstore::get_crate_hash(cstore, i),
+                         cstore::get_crate_vers(cstore, i));
         let cr = nm.with_c_str(|buf| {
             unsafe {
                 llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 09218b53424..2c3a9e040c9 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -567,8 +567,6 @@ fn trans_to_datum_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock {
 fn trans_rvalue_datum_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock {
     let _icx = push_ctxt("trans_rvalue_datum_unadjusted");
 
-    trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr)));
-
     match expr.node {
         ast::ExprPath(_) | ast::ExprSelf => {
             return trans_def_datum_unadjusted(bcx, expr, bcx.def(expr.id));
@@ -625,8 +623,6 @@ fn trans_rvalue_stmt_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> @mut Block
         return bcx;
     }
 
-    trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr)));
-
     match expr.node {
         ast::ExprBreak(label_opt) => {
             return controlflow::trans_break(bcx, label_opt);
@@ -676,8 +672,6 @@ fn trans_rvalue_dps_unadjusted(bcx: @mut Block, expr: &ast::Expr,
     let _icx = push_ctxt("trans_rvalue_dps_unadjusted");
     let tcx = bcx.tcx();
 
-    trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr)));
-
     match expr.node {
         ast::ExprParen(e) => {
             return trans_rvalue_dps_unadjusted(bcx, e, dest);
@@ -895,8 +889,6 @@ fn trans_lvalue_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock {
     debug!("trans_lvalue(expr={})", bcx.expr_to_str(expr));
     let _indenter = indenter();
 
-    trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr)));
-
     return match expr.node {
         ast::ExprParen(e) => {
             trans_lvalue_unadjusted(bcx, e)
diff --git a/src/librustc/middle/trans/macros.rs b/src/librustc/middle/trans/macros.rs
index 43cc66c5568..938484fd44c 100644
--- a/src/librustc/middle/trans/macros.rs
+++ b/src/librustc/middle/trans/macros.rs
@@ -29,25 +29,3 @@ macro_rules! unpack_result(
         }
     )
 )
-
-macro_rules! trace_span(
-    ($bcx: ident, $sp: expr, $str: expr) => (
-        {
-            let bcx = $bcx;
-            if bcx.sess().trace() {
-                trans_trace(bcx, Some($sp), $str);
-            }
-        }
-    )
-)
-
-macro_rules! trace(
-    ($bcx: ident, $str: expr) => (
-        {
-            let bcx = $bcx;
-            if bcx.sess().trace() {
-                trans_trace(bcx, None, $str);
-            }
-        }
-    )
-)
diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs
index 577e0a28105..2da2da80fdd 100644
--- a/src/librustc/middle/trans/write_guard.rs
+++ b/src/librustc/middle/trans/write_guard.rs
@@ -114,13 +114,6 @@ fn root(datum: &Datum,
     debug!("write_guard::root(root_key={:?}, root_info={:?}, datum={:?})",
            root_key, root_info, datum.to_str(bcx.ccx()));
 
-    if bcx.sess().trace() {
-        trans_trace(
-            bcx, None,
-            (format!("preserving until end of scope {}",
-                  root_info.scope)).to_managed());
-    }
-
     // First, root the datum. Note that we must zero this value,
     // because sometimes we root on one path but not another.
     // See e.g. #4904.
diff --git a/src/llvm b/src/llvm
-Subproject c9ffab392a39eb85f2f15ffc8d41e8c4f4397b8
+Subproject eac6ff795c40778683e42b0c6ab6f6adaceb391
diff --git a/src/rt/rust_upcall.c b/src/rt/rust_upcall.c
index 9740fdea82c..18b71fbb179 100644
--- a/src/rt/rust_upcall.c
+++ b/src/rt/rust_upcall.c
@@ -51,7 +51,7 @@ struct s_rust_personality_args {
     struct _Unwind_Context *context;
 };
 
-void
+static void
 upcall_s_rust_personality(struct s_rust_personality_args *args) {
     args->retval = PERSONALITY_FUNC(args->version,
                                     args->actions,
@@ -78,6 +78,7 @@ upcall_rust_personality(int version,
     return args.retval;
 }
 
+// NOTE: remove after stage0
 // Landing pads need to call this to insert the
 // correct limit into TLS.
 // NB: This must run on the Rust stack because it
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 8d0b447fa4a..0ae8991b2e7 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -81,7 +81,6 @@ LLVMRustCreateTargetMachine(const char *triple,
     TargetOptions Options;
     Options.NoFramePointerElim = true;
     Options.EnableSegmentedStacks = EnableSegmentedStacks;
-    Options.FixedStackSegmentSize = 2 * 1024 * 1024; // XXX: This is too big.
     Options.FloatABIType =
          (Trip.getEnvironment() == Triple::GNUEABIHF) ? FloatABI::Hard :
                                                         FloatABI::Default;
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 0a148d334ab..484cded3147 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -34,282 +34,6 @@ extern "C" const char *LLVMRustGetLastError(void) {
   return LLVMRustError;
 }
 
-// Custom memory manager for MCJITting. It needs special features
-// that the generic JIT memory manager doesn't entail. Based on
-// code from LLI, change where needed for Rust.
-class RustMCJITMemoryManager : public JITMemoryManager {
-public:
-  SmallVector<sys::MemoryBlock, 16> AllocatedDataMem;
-  SmallVector<sys::MemoryBlock, 16> AllocatedCodeMem;
-  SmallVector<sys::MemoryBlock, 16> FreeCodeMem;
-  void* __morestack;
-  DenseSet<DynamicLibrary*> crates;
-
-  RustMCJITMemoryManager(void* sym) : __morestack(sym) { }
-  ~RustMCJITMemoryManager();
-
-  bool loadCrate(const char*, std::string*);
-
-  virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
-                                       unsigned SectionID);
-
-  virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
-                                       unsigned SectionID, bool isReadOnly);
-  bool finalizeMemory(std::string *ErrMsg) { return false; }
-
-  virtual bool applyPermissions(std::string *Str);
-
-  virtual void *getPointerToNamedFunction(const std::string &Name,
-                                          bool AbortOnFailure = true);
-
-  // Invalidate instruction cache for code sections. Some platforms with
-  // separate data cache and instruction cache require explicit cache flush,
-  // otherwise JIT code manipulations (like resolved relocations) will get to
-  // the data cache but not to the instruction cache.
-  virtual void invalidateInstructionCache();
-
-  // The MCJITMemoryManager doesn't use the following functions, so we don't
-  // need implement them.
-  virtual void setMemoryWritable() {
-    llvm_unreachable("Unimplemented call");
-  }
-  virtual void setMemoryExecutable() {
-    llvm_unreachable("Unimplemented call");
-  }
-  virtual void setPoisonMemory(bool poison) {
-    llvm_unreachable("Unimplemented call");
-  }
-  virtual void AllocateGOT() {
-    llvm_unreachable("Unimplemented call");
-  }
-  virtual uint8_t *getGOTBase() const {
-    llvm_unreachable("Unimplemented call");
-    return 0;
-  }
-  virtual uint8_t *startFunctionBody(const Function *F,
-                                     uintptr_t &ActualSize){
-    llvm_unreachable("Unimplemented call");
-    return 0;
-  }
-  virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
-                                unsigned Alignment) {
-    llvm_unreachable("Unimplemented call");
-    return 0;
-  }
-  virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
-                               uint8_t *FunctionEnd) {
-    llvm_unreachable("Unimplemented call");
-  }
-  virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
-    llvm_unreachable("Unimplemented call");
-    return 0;
-  }
-  virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
-    llvm_unreachable("Unimplemented call");
-    return 0;
-  }
-  virtual void deallocateFunctionBody(void *Body) {
-    llvm_unreachable("Unimplemented call");
-  }
-  virtual uint8_t* startExceptionTable(const Function* F,
-                                       uintptr_t &ActualSize) {
-    llvm_unreachable("Unimplemented call");
-    return 0;
-  }
-  virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
-                                 uint8_t *TableEnd, uint8_t* FrameRegister) {
-    llvm_unreachable("Unimplemented call");
-  }
-  virtual void deallocateExceptionTable(void *ET) {
-    llvm_unreachable("Unimplemented call");
-  }
-};
-
-bool RustMCJITMemoryManager::loadCrate(const char* file, std::string* err) {
-  DynamicLibrary crate = DynamicLibrary::getPermanentLibrary(file,
-                                                             err);
-
-  if(crate.isValid()) {
-    crates.insert(&crate);
-
-    return true;
-  }
-
-  return false;
-}
-
-uint8_t *RustMCJITMemoryManager::allocateDataSection(uintptr_t Size,
-                                                     unsigned Alignment,
-                                                     unsigned SectionID,
-                                                     bool isReadOnly) {
-  if (!Alignment)
-    Alignment = 16;
-  uint8_t *Addr = (uint8_t*)calloc((Size + Alignment - 1)/Alignment, Alignment);
-  AllocatedDataMem.push_back(sys::MemoryBlock(Addr, Size));
-  return Addr;
-}
-
-bool RustMCJITMemoryManager::applyPermissions(std::string *Str) {
-    // Empty.
-    return true;
-}
-
-uint8_t *RustMCJITMemoryManager::allocateCodeSection(uintptr_t Size,
-                                                     unsigned Alignment,
-                                                     unsigned SectionID) {
-  if (!Alignment)
-    Alignment = 16;
-  unsigned NeedAllocate = Alignment * ((Size + Alignment - 1)/Alignment + 1);
-  uintptr_t Addr = 0;
-  // Look in the list of free code memory regions and use a block there if one
-  // is available.
-  for (int i = 0, e = FreeCodeMem.size(); i != e; ++i) {
-    sys::MemoryBlock &MB = FreeCodeMem[i];
-    if (MB.size() >= NeedAllocate) {
-      Addr = (uintptr_t)MB.base();
-      uintptr_t EndOfBlock = Addr + MB.size();
-      // Align the address.
-      Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
-      // Store cutted free memory block.
-      FreeCodeMem[i] = sys::MemoryBlock((void*)(Addr + Size),
-                                        EndOfBlock - Addr - Size);
-      return (uint8_t*)Addr;
-    }
-  }
-
-  // No pre-allocated free block was large enough. Allocate a new memory region.
-  sys::MemoryBlock MB = sys::Memory::AllocateRWX(NeedAllocate, 0, 0);
-
-  AllocatedCodeMem.push_back(MB);
-  Addr = (uintptr_t)MB.base();
-  uintptr_t EndOfBlock = Addr + MB.size();
-  // Align the address.
-  Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
-  // The AllocateRWX may allocate much more memory than we need. In this case,
-  // we store the unused memory as a free memory block.
-  unsigned FreeSize = EndOfBlock-Addr-Size;
-  if (FreeSize > 16)
-    FreeCodeMem.push_back(sys::MemoryBlock((void*)(Addr + Size), FreeSize));
-
-  // Return aligned address
-  return (uint8_t*)Addr;
-}
-
-void RustMCJITMemoryManager::invalidateInstructionCache() {
-  for (int i = 0, e = AllocatedCodeMem.size(); i != e; ++i)
-    sys::Memory::InvalidateInstructionCache(AllocatedCodeMem[i].base(),
-                                            AllocatedCodeMem[i].size());
-}
-
-void *RustMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name,
-                                                       bool AbortOnFailure) {
-#ifdef __linux__
-  // Force the following functions to be linked in to anything that uses the
-  // JIT. This is a hack designed to work around the all-too-clever Glibc
-  // strategy of making these functions work differently when inlined vs. when
-  // not inlined, and hiding their real definitions in a separate archive file
-  // that the dynamic linker can't see. For more info, search for
-  // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274.
-  if (Name == "stat") return (void*)(intptr_t)&stat;
-  if (Name == "fstat") return (void*)(intptr_t)&fstat;
-  if (Name == "lstat") return (void*)(intptr_t)&lstat;
-  if (Name == "stat64") return (void*)(intptr_t)&stat64;
-  if (Name == "fstat64") return (void*)(intptr_t)&fstat64;
-  if (Name == "lstat64") return (void*)(intptr_t)&lstat64;
-  if (Name == "atexit") return (void*)(intptr_t)&atexit;
-  if (Name == "mknod") return (void*)(intptr_t)&mknod;
-#endif
-
-  if (Name == "__morestack" || Name == "___morestack") return &__morestack;
-
-  const char *NameStr = Name.c_str();
-
-  // Look through loaded crates and main for symbols.
-
-  void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
-  if (Ptr) return Ptr;
-
-  // If it wasn't found and if it starts with an underscore ('_') character,
-  // try again without the underscore.
-  if (NameStr[0] == '_') {
-    Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1);
-    if (Ptr) return Ptr;
-  }
-
-  if (AbortOnFailure)
-    report_fatal_error("Program used external function '" + Name +
-                      "' which could not be resolved!");
-  return 0;
-}
-
-RustMCJITMemoryManager::~RustMCJITMemoryManager() {
-  for (unsigned i = 0, e = AllocatedCodeMem.size(); i != e; ++i)
-    sys::Memory::ReleaseRWX(AllocatedCodeMem[i]);
-  for (unsigned i = 0, e = AllocatedDataMem.size(); i != e; ++i)
-    free(AllocatedDataMem[i].base());
-}
-
-extern "C" void*
-LLVMRustPrepareJIT(void* __morestack) {
-  // An execution engine will take ownership of this later
-  // and clean it up for us.
-
-  return (void*) new RustMCJITMemoryManager(__morestack);
-}
-
-extern "C" bool
-LLVMRustLoadCrate(void* mem, const char* crate) {
-  RustMCJITMemoryManager* manager = (RustMCJITMemoryManager*) mem;
-  std::string Err;
-
-  assert(manager);
-
-  if(!manager->loadCrate(crate, &Err)) {
-    LLVMRustError = Err.c_str();
-    return false;
-  }
-
-  return true;
-}
-
-extern "C" LLVMExecutionEngineRef
-LLVMRustBuildJIT(void* mem,
-                 LLVMModuleRef M,
-                 bool EnableSegmentedStacks) {
-
-  InitializeNativeTarget();
-  InitializeNativeTargetAsmPrinter();
-  InitializeNativeTargetAsmParser();
-
-  std::string Err;
-  TargetOptions Options;
-  Options.JITEmitDebugInfo = true;
-  Options.NoFramePointerElim = true;
-  Options.EnableSegmentedStacks = EnableSegmentedStacks;
-  RustMCJITMemoryManager* MM = (RustMCJITMemoryManager*) mem;
-  assert(MM);
-
-  ExecutionEngine* EE = EngineBuilder(unwrap(M))
-    .setErrorStr(&Err)
-    .setTargetOptions(Options)
-    .setJITMemoryManager(MM)
-    .setUseMCJIT(true)
-    .setAllocateGVsWithCode(false)
-    .create();
-
-  if(!EE || Err != "") {
-    LLVMRustError = Err.c_str();
-    // The EngineBuilder only takes ownership of these two structures if the
-    // create() call is successful, but here it wasn't successful.
-    LLVMDisposeModule(M);
-    delete MM;
-    return NULL;
-  }
-
-  MM->invalidateInstructionCache();
-  return wrap(EE);
-}
-
 extern "C" void
 LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) {
     unwrap(M)->setTargetTriple(Triple::normalize(triple));
@@ -566,7 +290,7 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateStructType(
         unwrapDI<DIType>(DerivedFrom),
         unwrapDI<DIArray>(Elements),
         RunTimeLang,
-        unwrapDI<MDNode*>(VTableHolder),
+        unwrapDI<DIType>(VTableHolder),
         UniqueId));
 }
 
diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger
index 01a5eaefa89..bae0ad8fbc6 100644
--- a/src/rustllvm/llvm-auto-clean-trigger
+++ b/src/rustllvm/llvm-auto-clean-trigger
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2013-09-23
+2013-12-05
diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in
index 069f29e909d..d8ec1c86840 100644
--- a/src/rustllvm/rustllvm.def.in
+++ b/src/rustllvm/rustllvm.def.in
@@ -3,9 +3,6 @@ LLVMRustWriteOutputFile
 LLVMRustGetLastError
 LLVMRustConstSmallInt
 LLVMRustConstInt
-LLVMRustLoadCrate
-LLVMRustPrepareJIT
-LLVMRustBuildJIT
 LLVMRustPrintPassTimings
 LLVMRustStartMultithreading
 LLVMCreateObjectFile