From 30cb8bd97d5bf7ce1d047ce98f0c5f7b7fbea2e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 30 Jul 2013 08:22:32 +0200 Subject: [PATCH] Allow early release of rvalues in assignments The rvalues in assignments might be temporaries (like function return values) that could be freed immediately after the assignment is done. But currently, they live to the end of the enclosing scope. For managed box, this currently means that there is an extra ref count that keeps the value alive. This leads to a huge memory usage peak in the expansion phase of compilation with rustc, because all intermediate expansion results are kept alive till the end of phase 2, instead of being freed immediately after their last "usable" ref is dropped. As a stop-gap solution, we can add a scope around the assignment during translation, which means that the temporary value is dropped right away. It's only a stop-gap solution because once we switch from refcounting to garbage collection, it won't help anymore and the code should switch to either RC or ~ for Crate data, but for now this reduces the peak memory usage when compiling librustc by about 100MB on my x86_64 Linux box. --- src/librustc/middle/trans/expr.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index c038ca710aa4f..7d496903774e7 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -525,12 +525,11 @@ fn trans_rvalue_stmt_unadjusted(bcx: @mut Block, expr: @ast::expr) -> @mut Block return controlflow::trans_loop(bcx, body, opt_label); } ast::expr_assign(dst, src) => { - let src_datum = unpack_datum!( - bcx, trans_to_datum(bcx, src)); - let dst_datum = unpack_datum!( - bcx, trans_lvalue(bcx, dst)); - return src_datum.store_to_datum( - bcx, DROP_EXISTING, dst_datum); + let dst_datum = unpack_datum!(bcx, trans_lvalue(bcx, dst)); + return do with_scope(bcx, None, "assign") |mut bcx| { + let src_datum = unpack_datum!(bcx, trans_to_datum(bcx, src)); + src_datum.store_to_datum(bcx, DROP_EXISTING, dst_datum) + } } ast::expr_assign_op(callee_id, op, dst, src) => { return trans_assign_op(bcx, expr, callee_id, op, dst, src);