From 89a85e45c5e29f4b465b01ac0afa3986b19ababf Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Sat, 21 Dec 2013 15:47:08 -0800 Subject: [PATCH] librustc: De-`@mut` `ScopeInfo::cleanups` --- src/librustc/middle/trans/base.rs | 28 ++++---- src/librustc/middle/trans/common.rs | 107 +++++++++++++++++----------- 2 files changed, 81 insertions(+), 54 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index fd1c1872df7d..ecd6258bf0f9 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -971,7 +971,8 @@ pub fn need_invoke(bcx: @Block) -> bool { loop { cur_scope = match cur_scope { Some(inf) => { - for cleanup in inf.cleanups.iter() { + let cleanups = inf.cleanups.borrow(); + for cleanup in cleanups.get().iter() { match *cleanup { clean(_, cleanup_type) | clean_temp(_, _, cleanup_type) => { if cleanup_type == normal_exit_and_unwind { @@ -1221,7 +1222,7 @@ pub fn simple_block_scope(parent: Option<@mut ScopeInfo>, parent: parent, loop_break: None, loop_label: None, - cleanups: ~[], + cleanups: RefCell::new(~[]), cleanup_paths: ~[], landing_pad: None, node_info: node_info, @@ -1251,7 +1252,7 @@ pub fn loop_scope_block(bcx: @Block, parent: None, loop_break: Some(loop_break), loop_label: loop_label, - cleanups: ~[], + cleanups: RefCell::new(~[]), cleanup_paths: ~[], landing_pad: None, node_info: opt_node_info, @@ -1334,7 +1335,8 @@ pub fn cleanup_and_leave(bcx: @Block, { let r = (*inf).cleanup_paths.rev_iter().find(|cp| cp.target == leave); for cp in r.iter() { - if cp.size == inf.cleanups.len() { + let cleanups = inf.cleanups.borrow(); + if cp.size == cleanups.get().len() { Br(bcx, cp.dest); return; } @@ -1345,12 +1347,13 @@ pub fn cleanup_and_leave(bcx: @Block, } let sub_cx = sub_block(bcx, "cleanup"); Br(bcx, sub_cx.llbb); + let cleanups = inf.cleanups.borrow(); inf.cleanup_paths.push(cleanup_path { target: leave, - size: inf.cleanups.len(), + size: cleanups.get().len(), dest: sub_cx.llbb }); - (sub_cx, dest, inf.cleanups.tailn(skip).to_owned()) + (sub_cx, dest, cleanups.get().tailn(skip).to_owned()) }; bcx = trans_block_cleanups_(sub_cx, inf_cleanups, @@ -1394,8 +1397,11 @@ pub fn cleanup_block(bcx: @Block, upto: Option) -> @Block{ let mut cur_scope = cur.scope.get(); loop { cur_scope = match cur_scope { - Some (inf) => { - bcx = trans_block_cleanups_(bcx, inf.cleanups.to_owned(), false); + Some(inf) => { + let cleanups = inf.cleanups.borrow(); + bcx = trans_block_cleanups_(bcx, + cleanups.get().to_owned(), + false); inf.parent } None => break @@ -1443,7 +1449,7 @@ pub fn with_scope(bcx: @Block, let scope = simple_block_scope(bcx.scope.get(), opt_node_info); bcx.scope.set(Some(scope)); let ret = f(bcx); - let ret = trans_block_cleanups_(ret, (scope.cleanups).clone(), false); + let ret = trans_block_cleanups_(ret, scope.cleanups.get(), false); bcx.scope.set(scope.parent); ret } @@ -1458,9 +1464,7 @@ pub fn with_scope_result(bcx: @Block, let scope = simple_block_scope(bcx.scope.get(), opt_node_info); bcx.scope.set(Some(scope)); let Result { bcx: out_bcx, val } = f(bcx); - let out_bcx = trans_block_cleanups_(out_bcx, - (scope.cleanups).clone(), - false); + let out_bcx = trans_block_cleanups_(out_bcx, scope.cleanups.get(), false); bcx.scope.set(scope.parent); rslt(out_bcx, val) diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index d7705b918070..9e25756fc497 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -457,11 +457,14 @@ pub fn add_clean(bcx: @Block, val: ValueRef, t: ty::t) { let cleanup_type = cleanup_type(bcx.tcx(), t); in_scope_cx(bcx, None, |scope_info| { - scope_info.cleanups.push(clean(@TypeDroppingCleanupFunction { - val: val, - t: t, - } as @CleanupFunction, - cleanup_type)); + { + let mut cleanups = scope_info.cleanups.borrow_mut(); + cleanups.get().push(clean(@TypeDroppingCleanupFunction { + val: val, + t: t, + } as @CleanupFunction, + cleanup_type)); + } grow_scope_clean(scope_info); }) } @@ -473,12 +476,15 @@ pub fn add_clean_temp_immediate(cx: @Block, val: ValueRef, ty: ty::t) { ty.repr(cx.tcx())); let cleanup_type = cleanup_type(cx.tcx(), ty); in_scope_cx(cx, None, |scope_info| { - scope_info.cleanups.push(clean_temp(val, - @ImmediateTypeDroppingCleanupFunction { - val: val, - t: ty, - } as @CleanupFunction, - cleanup_type)); + { + let mut cleanups = scope_info.cleanups.borrow_mut(); + cleanups.get().push(clean_temp(val, + @ImmediateTypeDroppingCleanupFunction { + val: val, + t: ty, + } as @CleanupFunction, + cleanup_type)); + } grow_scope_clean(scope_info); }) } @@ -502,12 +508,15 @@ pub fn add_clean_temp_mem_in_scope_(bcx: @Block, scope_id: Option, t.repr(bcx.tcx())); let cleanup_type = cleanup_type(bcx.tcx(), t); in_scope_cx(bcx, scope_id, |scope_info| { - scope_info.cleanups.push(clean_temp(val, - @TypeDroppingCleanupFunction { - val: val, - t: t, - } as @CleanupFunction, - cleanup_type)); + { + let mut cleanups = scope_info.cleanups.borrow_mut(); + cleanups.get().push(clean_temp(val, + @TypeDroppingCleanupFunction { + val: val, + t: t, + } as @CleanupFunction, + cleanup_type)); + } grow_scope_clean(scope_info); }) } @@ -531,16 +540,19 @@ pub fn add_clean_return_to_mut(bcx: @Block, bcx.val_to_str(frozen_val_ref), bcx.val_to_str(bits_val_ref)); in_scope_cx(bcx, Some(scope_id), |scope_info| { - scope_info.cleanups.push(clean_temp( - frozen_val_ref, - @WriteGuardReleasingCleanupFunction { - root_key: root_key, - frozen_val_ref: frozen_val_ref, - bits_val_ref: bits_val_ref, - filename_val: filename_val, - line_val: line_val, - } as @CleanupFunction, - normal_exit_only)); + { + let mut cleanups = scope_info.cleanups.borrow_mut(); + cleanups.get().push(clean_temp( + frozen_val_ref, + @WriteGuardReleasingCleanupFunction { + root_key: root_key, + frozen_val_ref: frozen_val_ref, + bits_val_ref: bits_val_ref, + filename_val: filename_val, + line_val: line_val, + } as @CleanupFunction, + normal_exit_only)); + } grow_scope_clean(scope_info); }) } @@ -558,9 +570,12 @@ pub fn add_clean_free(cx: @Block, ptr: ValueRef, heap: heap) { } }; in_scope_cx(cx, None, |scope_info| { - scope_info.cleanups.push(clean_temp(ptr, - free_fn, - normal_exit_and_unwind)); + { + let mut cleanups = scope_info.cleanups.borrow_mut(); + cleanups.get().push(clean_temp(ptr, + free_fn, + normal_exit_and_unwind)); + } grow_scope_clean(scope_info); }) } @@ -571,16 +586,23 @@ pub fn add_clean_free(cx: @Block, ptr: ValueRef, heap: heap) { // drop glue checks whether it is zero. pub fn revoke_clean(cx: @Block, val: ValueRef) { in_scope_cx(cx, None, |scope_info| { - let cleanup_pos = scope_info.cleanups.iter().position( - |cu| match *cu { - clean_temp(v, _, _) if v == val => true, - _ => false - }); + let cleanup_pos = { + let mut cleanups = scope_info.cleanups.borrow_mut(); + cleanups.get().iter().position(|cu| { + match *cu { + clean_temp(v, _, _) if v == val => true, + _ => false + } + }) + }; for i in cleanup_pos.iter() { - scope_info.cleanups = - vec::append(scope_info.cleanups.slice(0u, *i).to_owned(), - scope_info.cleanups.slice(*i + 1u, - scope_info.cleanups.len())); + let new_cleanups = { + let cleanups = scope_info.cleanups.borrow(); + vec::append(cleanups.get().slice(0u, *i).to_owned(), + cleanups.get().slice(*i + 1u, cleanups.get() + .len())) + }; + scope_info.cleanups.set(new_cleanups); shrink_scope_clean(scope_info, *i); } }) @@ -589,7 +611,7 @@ pub fn revoke_clean(cx: @Block, val: ValueRef) { pub fn block_cleanups(bcx: &Block) -> ~[cleanup] { match bcx.scope.get() { None => ~[], - Some(inf) => inf.cleanups.clone(), + Some(inf) => inf.cleanups.get(), } } @@ -600,7 +622,7 @@ pub struct ScopeInfo { // A list of functions that must be run at when leaving this // block, cleaning up any variables that were introduced in the // block. - cleanups: ~[cleanup], + cleanups: RefCell<~[cleanup]>, // Existing cleanup paths that may be reused, indexed by destination and // cleared when the set of cleanups changes. cleanup_paths: ~[cleanup_path], @@ -612,7 +634,8 @@ pub struct ScopeInfo { impl ScopeInfo { pub fn empty_cleanups(&mut self) -> bool { - self.cleanups.is_empty() + let cleanups = self.cleanups.borrow(); + cleanups.get().is_empty() } }