about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPiotr Czarnecki <pioczarn@gmail.com>2016-02-08 11:53:06 +0100
committerPiotr Czarnecki <pioczarn@gmail.com>2016-02-08 11:53:06 +0100
commita9ab8096ba4445f6495684b85a7c9b34fd94049c (patch)
tree9f07f0e6104017dc9b519d233277c123fc3ea649
parent06266eb3bdd22e590e3a778d019d8b71b61567a6 (diff)
downloadrust-a9ab8096ba4445f6495684b85a7c9b34fd94049c.tar.gz
rust-a9ab8096ba4445f6495684b85a7c9b34fd94049c.zip
Refactor storage of `LandingPad`s
-rw-r--r--src/librustc_trans/trans/base.rs3
-rw-r--r--src/librustc_trans/trans/build.rs9
-rw-r--r--src/librustc_trans/trans/cleanup.rs10
-rw-r--r--src/librustc_trans/trans/common.rs28
-rw-r--r--src/librustc_trans/trans/mir/block.rs25
-rw-r--r--src/librustc_trans/trans/mir/mod.rs11
-rw-r--r--src/librustc_trans/trans/mir/rvalue.rs6
7 files changed, 58 insertions, 34 deletions
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index bcca4963781..57e69a0efa9 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -988,7 +988,7 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
 }
 
 pub fn avoid_invoke(bcx: Block) -> bool {
-    bcx.sess().no_landing_pads() || bcx.lpad.borrow().is_some()
+    bcx.sess().no_landing_pads() || bcx.lpad().is_some()
 }
 
 pub fn need_invoke(bcx: Block) -> bool {
@@ -1616,6 +1616,7 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
         param_substs: param_substs,
         span: sp,
         block_arena: block_arena,
+        lpad_arena: TypedArena::new(),
         ccx: ccx,
         debug_context: debug_context,
         scopes: RefCell::new(Vec::new()),
diff --git a/src/librustc_trans/trans/build.rs b/src/librustc_trans/trans/build.rs
index e501855b5d5..ce541c8d411 100644
--- a/src/librustc_trans/trans/build.rs
+++ b/src/librustc_trans/trans/build.rs
@@ -150,8 +150,7 @@ pub fn Invoke(cx: Block,
            cx.val_to_string(fn_),
            args.iter().map(|a| cx.val_to_string(*a)).collect::<Vec<String>>().join(", "));
     debug_loc.apply(cx.fcx);
-    let lpad = cx.lpad.borrow();
-    let bundle = lpad.as_ref().and_then(|b| b.bundle());
+    let bundle = cx.lpad().and_then(|b| b.bundle());
     B(cx).invoke(fn_, args, then, catch, bundle, attributes)
 }
 
@@ -916,8 +915,7 @@ pub fn Call(cx: Block,
         return _UndefReturn(cx, fn_);
     }
     debug_loc.apply(cx.fcx);
-    let lpad = cx.lpad.borrow();
-    let bundle = lpad.as_ref().and_then(|b| b.bundle());
+    let bundle = cx.lpad.get().and_then(|b| b.bundle());
     B(cx).call(fn_, args, bundle, attributes)
 }
 
@@ -932,8 +930,7 @@ pub fn CallWithConv(cx: Block,
         return _UndefReturn(cx, fn_);
     }
     debug_loc.apply(cx.fcx);
-    let lpad = cx.lpad.borrow();
-    let bundle = lpad.as_ref().and_then(|b| b.bundle());
+    let bundle = cx.lpad.get().and_then(|b| b.bundle());
     B(cx).call_with_conv(fn_, args, conv, bundle, attributes)
 }
 
diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs
index 7c98868dfe7..1b69784c096 100644
--- a/src/librustc_trans/trans/cleanup.rs
+++ b/src/librustc_trans/trans/cleanup.rs
@@ -740,7 +740,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
                     UnwindExit(val) => {
                         // Generate a block that will resume unwinding to the
                         // calling function
-                        let bcx = self.new_block("resume", None);
+                        let bcx = self.new_block("resume", None, None);
                         match val {
                             UnwindKind::LandingPad => {
                                 let addr = self.landingpad_alloca.get()
@@ -830,7 +830,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
                 let name = scope.block_name("clean");
                 debug!("generating cleanups for {}", name);
 
-                let bcx_in = self.new_block(&name[..], None);
+                let bcx_in = self.new_block(&name[..], None, None);
                 let exit_label = label.start(bcx_in);
                 let mut bcx_out = bcx_in;
                 let len = scope.cleanups.len();
@@ -873,7 +873,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
                 Some(llbb) => return llbb,
                 None => {
                     let name = last_scope.block_name("unwind");
-                    pad_bcx = self.new_block(&name[..], None);
+                    pad_bcx = self.new_block(&name[..], None, None);
                     last_scope.cached_landing_pad = Some(pad_bcx.llbb);
                 }
             }
@@ -1054,11 +1054,11 @@ impl EarlyExitLabel {
         match *self {
             UnwindExit(UnwindKind::CleanupPad(..)) => {
                 let pad = build::CleanupPad(bcx, None, &[]);
-                *bcx.lpad.borrow_mut() = Some(LandingPad::msvc(pad));
+                bcx.lpad.set(Some(bcx.fcx.lpad_arena.alloc(LandingPad::msvc(pad))));
                 UnwindExit(UnwindKind::CleanupPad(pad))
             }
             UnwindExit(UnwindKind::LandingPad) => {
-                *bcx.lpad.borrow_mut() = Some(LandingPad::gnu());
+                bcx.lpad.set(Some(bcx.fcx.lpad_arena.alloc(LandingPad::gnu())));
                 *self
             }
             label => label,
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index a23d879bba9..20c48357719 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -367,6 +367,9 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
     // The arena that blocks are allocated from.
     pub block_arena: &'a TypedArena<BlockS<'a, 'tcx>>,
 
+    // The arena that landing pads are allocated from.
+    pub lpad_arena: TypedArena<LandingPad>,
+
     // This function's enclosing crate context.
     pub ccx: &'a CrateContext<'a, 'tcx>,
 
@@ -431,14 +434,19 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
 
     pub fn new_block(&'a self,
                      name: &str,
-                     opt_node_id: Option<ast::NodeId>)
+                     opt_node_id: Option<ast::NodeId>,
+                     landing_pad: Option<LandingPad>)
                      -> Block<'a, 'tcx> {
         unsafe {
             let name = CString::new(name).unwrap();
             let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
                                                            self.llfn,
                                                            name.as_ptr());
-            BlockS::new(llbb, opt_node_id, self)
+            let block = BlockS::new(llbb, opt_node_id, self);
+            if let Some(landing_pad) = landing_pad {
+                block.lpad.set(Some(self.lpad_arena.alloc(landing_pad)));
+            }
+            block
         }
     }
 
@@ -446,13 +454,13 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
                         name: &str,
                         node_id: ast::NodeId)
                         -> Block<'a, 'tcx> {
-        self.new_block(name, Some(node_id))
+        self.new_block(name, Some(node_id), None)
     }
 
     pub fn new_temp_block(&'a self,
                           name: &str)
                           -> Block<'a, 'tcx> {
-        self.new_block(name, None)
+        self.new_block(name, None, None)
     }
 
     pub fn join_blocks(&'a self,
@@ -584,7 +592,7 @@ pub struct BlockS<'blk, 'tcx: 'blk> {
 
     // If this block part of a landing pad, then this is `Some` indicating what
     // kind of landing pad its in, otherwise this is none.
-    pub lpad: RefCell<Option<LandingPad>>,
+    pub lpad: Cell<Option<&'blk LandingPad>>,
 
     // AST node-id associated with this block, if any. Used for
     // debugging purposes only.
@@ -606,7 +614,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
             llbb: llbb,
             terminated: Cell::new(false),
             unreachable: Cell::new(false),
-            lpad: RefCell::new(None),
+            lpad: Cell::new(None),
             opt_node_id: opt_node_id,
             fcx: fcx
         })
@@ -623,6 +631,10 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
     }
     pub fn sess(&self) -> &'blk Session { self.fcx.ccx.sess() }
 
+    pub fn lpad(&self) -> Option<&'blk LandingPad> {
+        self.lpad.get()
+    }
+
     pub fn mir(&self) -> &'blk Mir<'tcx> {
         self.fcx.mir()
     }
@@ -747,6 +759,10 @@ impl<'blk, 'tcx> BlockAndBuilder<'blk, 'tcx> {
         self.bcx.llbb
     }
 
+    pub fn lpad(&self) -> Option<&'blk LandingPad> {
+        self.bcx.lpad()
+    }
+
     pub fn mir(&self) -> &'blk Mir<'tcx> {
         self.bcx.mir()
     }
diff --git a/src/librustc_trans/trans/mir/block.rs b/src/librustc_trans/trans/mir/block.rs
index 113970d2fc1..6c1a5ac74d0 100644
--- a/src/librustc_trans/trans/mir/block.rs
+++ b/src/librustc_trans/trans/mir/block.rs
@@ -119,13 +119,16 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                 if let Some(unwind) = unwind {
                     let uwbcx = self.bcx(unwind);
                     let unwind = self.make_landing_pad(uwbcx);
+                    let bundle = bcx.lpad().and_then(|b| b.bundle());
                     bcx.invoke(drop_fn,
                                &[llvalue],
                                self.llblock(target),
                                unwind.llbb(),
+                               bundle,
                                None);
                 } else {
-                    bcx.call(drop_fn, &[llvalue], None);
+                    let bundle = bcx.lpad().and_then(|b| b.bundle());
+                    bcx.call(drop_fn, &[llvalue], bundle, None);
                     bcx.br(self.llblock(target));
                 }
             }
@@ -187,24 +190,28 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                         let cleanup = self.bcx(cleanup);
                         let landingpad = self.make_landing_pad(cleanup);
                         let unreachable_blk = self.unreachable_block();
+                        let bundle = bcx.lpad().and_then(|b| b.bundle());
                         bcx.invoke(callee.immediate(),
                                    &llargs[..],
                                    unreachable_blk.llbb,
                                    landingpad.llbb(),
+                                   bundle,
                                    Some(attrs));
                     },
                     (false, false, &Some(cleanup), &Some((_, success))) => {
                         let cleanup = self.bcx(cleanup);
                         let landingpad = self.make_landing_pad(cleanup);
                         let (target, postinvoke) = if must_copy_dest {
-                            (bcx.fcx().new_block("", None), Some(self.bcx(success)))
+                            (bcx.fcx().new_block("", None, None).build(), Some(self.bcx(success)))
                         } else {
                             (self.bcx(success), None)
                         };
+                        let bundle = bcx.lpad().and_then(|b| b.bundle());
                         let invokeret = bcx.invoke(callee.immediate(),
                                                    &llargs[..],
                                                    target.llbb(),
                                                    landingpad.llbb(),
+                                                   bundle,
                                                    Some(attrs));
                         if let Some(postinvoketarget) = postinvoke {
                             // We translate the copy into a temporary block. The temporary block is
@@ -240,7 +247,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                         }
                     },
                     (false, _, _, &None) => {
-                        bcx.call(callee.immediate(), &llargs[..], Some(attrs));
+                        let bundle = bcx.lpad().and_then(|b| b.bundle());
+                        bcx.call(callee.immediate(), &llargs[..], bundle, Some(attrs));
                         bcx.unreachable();
                     }
                     (false, _, _, &Some((_, target))) => {
@@ -301,12 +309,11 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                         cleanup: BlockAndBuilder<'bcx, 'tcx>)
                         -> BlockAndBuilder<'bcx, 'tcx>
     {
+        let cleanup_llbb = cleanup.llbb();
         let bcx = cleanup.map_block(|cleanup| {
-            cleanup.fcx.new_block("cleanup", None)
+            // FIXME(#30941) this doesn't handle msvc-style exceptions
+            cleanup.fcx.new_block("cleanup", None, Some(LandingPad::gnu()))
         });
-        // FIXME(#30941) this doesn't handle msvc-style exceptions
-        *bcx.lpad.borrow_mut() = Some(LandingPad::gnu());
-        let bcx = bcx.build();
         let ccx = bcx.ccx();
         let llpersonality = bcx.fcx().eh_personality();
         let llretty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)], false);
@@ -314,13 +321,13 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
         bcx.set_cleanup(llretval);
         let slot = self.get_personality_slot(&bcx);
         bcx.store(llretval, slot);
-        bcx.br(cleanup.llbb());
+        bcx.br(cleanup_llbb);
         bcx
     }
 
     fn unreachable_block(&mut self) -> Block<'bcx, 'tcx> {
         self.unreachable_block.unwrap_or_else(|| {
-            let bl = self.fcx.new_block("unreachable", None);
+            let bl = self.fcx.new_block("unreachable", None, None);
             bl.build().unreachable();
             self.unreachable_block = Some(bl);
             bl
diff --git a/src/librustc_trans/trans/mir/mod.rs b/src/librustc_trans/trans/mir/mod.rs
index 289faf4c136..e93c920d9a3 100644
--- a/src/librustc_trans/trans/mir/mod.rs
+++ b/src/librustc_trans/trans/mir/mod.rs
@@ -114,12 +114,13 @@ pub fn trans_mir<'bcx, 'tcx>(bcx: BlockAndBuilder<'bcx, 'tcx>) {
     let block_bcxs: Vec<Block<'bcx,'tcx>> =
         mir_blocks.iter()
                   .map(|&bb|{
-                      let bcx = fcx.new_block(&format!("{:?}", bb), None);
                       // FIXME(#30941) this doesn't handle msvc-style exceptions
-                      if mir.basic_block_data(bb).is_cleanup {
-                          *bcx.lpad.borrow_mut() = Some(LandingPad::gnu())
-                      }
-                      bcx
+                      let lpad = if mir.basic_block_data(bb).is_cleanup {
+                          Some(LandingPad::gnu())
+                      } else {
+                          None
+                      };
+                      fcx.new_block(&format!("{:?}", bb), None, lpad)
                   })
                   .collect();
 
diff --git a/src/librustc_trans/trans/mir/rvalue.rs b/src/librustc_trans/trans/mir/rvalue.rs
index 6ef5d53ce87..5debb76aa6c 100644
--- a/src/librustc_trans/trans/mir/rvalue.rs
+++ b/src/librustc_trans/trans/mir/rvalue.rs
@@ -497,10 +497,12 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                     if input_ty == tcx.types.f32 {
                         let lllhs = bcx.fpext(lhs, f64t);
                         let llrhs = bcx.fpext(rhs, f64t);
-                        let llres = bcx.call(llfn, &[lllhs, llrhs], None);
+                        let bundle = bcx.lpad().and_then(|b| b.bundle());
+                        let llres = bcx.call(llfn, &[lllhs, llrhs], bundle, None);
                         bcx.fptrunc(llres, Type::f32(bcx.ccx()))
                     } else {
-                        bcx.call(llfn, &[lhs, rhs], None)
+                        let bundle = bcx.lpad().and_then(|b| b.bundle());
+                        bcx.call(llfn, &[lhs, rhs], bundle, None)
                     }
                 } else {
                     bcx.frem(lhs, rhs)