add ability to report statistics about how borrowck is being used
This commit is contained in:
parent
9b7d9a9a1b
commit
668285b9c8
4 changed files with 64 additions and 17 deletions
|
@ -28,7 +28,7 @@ const ppregions: uint = 1u;
|
|||
const time_passes: uint = 2u;
|
||||
const count_llvm_insns: uint = 4u;
|
||||
const time_llvm_passes: uint = 8u;
|
||||
const stats: uint = 16u;
|
||||
const trans_stats: uint = 16u;
|
||||
const no_asm_comments: uint = 32u;
|
||||
const no_verify: uint = 64u;
|
||||
const trace: uint = 128u;
|
||||
|
@ -36,6 +36,7 @@ const trace: uint = 128u;
|
|||
// It should be removed
|
||||
const no_rt: uint = 256u;
|
||||
const coherence: uint = 512u;
|
||||
const borrowck_stats: uint = 1024u;
|
||||
|
||||
fn debugging_opts_map() -> ~[(str, str, uint)] {
|
||||
~[("ppregions", "prettyprint regions with \
|
||||
|
@ -49,7 +50,8 @@ fn debugging_opts_map() -> ~[(str, str, uint)] {
|
|||
("no-verify", "skip LLVM verification", no_verify),
|
||||
("trace", "emit trace logs", trace),
|
||||
("no-rt", "do not link to the runtime", no_rt),
|
||||
("coherence", "perform coherence checking", coherence)
|
||||
("coherence", "perform coherence checking", coherence),
|
||||
("borrowck-stats", "gather borrowck statistics", borrowck_stats)
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -160,11 +162,12 @@ impl session for session {
|
|||
fn time_passes() -> bool { self.debugging_opt(time_passes) }
|
||||
fn count_llvm_insns() -> bool { self.debugging_opt(count_llvm_insns) }
|
||||
fn time_llvm_passes() -> bool { self.debugging_opt(time_llvm_passes) }
|
||||
fn stats() -> bool { self.debugging_opt(stats) }
|
||||
fn trans_stats() -> bool { self.debugging_opt(trans_stats) }
|
||||
fn no_asm_comments() -> bool { self.debugging_opt(no_asm_comments) }
|
||||
fn no_verify() -> bool { self.debugging_opt(no_verify) }
|
||||
fn trace() -> bool { self.debugging_opt(trace) }
|
||||
fn coherence() -> bool { self.debugging_opt(coherence) }
|
||||
fn borrowck_stats() -> bool { self.debugging_opt(borrowck_stats) }
|
||||
}
|
||||
|
||||
/// Some reasonable defaults
|
||||
|
|
|
@ -175,11 +175,37 @@ fn check_crate(tcx: ty::ctxt,
|
|||
last_use_map: last_use_map,
|
||||
binding_map: int_hash(),
|
||||
root_map: root_map(),
|
||||
mutbl_map: int_hash()};
|
||||
mutbl_map: int_hash(),
|
||||
mut loaned_paths_same: 0,
|
||||
mut loaned_paths_imm: 0,
|
||||
mut stable_paths: 0,
|
||||
mut req_pure_paths: 0,
|
||||
mut guaranteed_paths: 0};
|
||||
|
||||
let req_maps = gather_loans::gather_loans(bccx, crate);
|
||||
check_loans::check_loans(bccx, req_maps, crate);
|
||||
|
||||
if tcx.sess.borrowck_stats() {
|
||||
io::println("--- borrowck stats ---");
|
||||
io::println(#fmt["paths requiring guarantees: %u",
|
||||
bccx.guaranteed_paths]);
|
||||
io::println(#fmt["paths requiring loans : %s",
|
||||
make_stat(bccx, bccx.loaned_paths_same)]);
|
||||
io::println(#fmt["paths requiring imm loans : %s",
|
||||
make_stat(bccx, bccx.loaned_paths_imm)]);
|
||||
io::println(#fmt["stable paths : %s",
|
||||
make_stat(bccx, bccx.stable_paths)]);
|
||||
io::println(#fmt["paths requiring purity : %s",
|
||||
make_stat(bccx, bccx.req_pure_paths)]);
|
||||
}
|
||||
|
||||
ret (bccx.root_map, bccx.mutbl_map);
|
||||
|
||||
fn make_stat(bccx: borrowck_ctxt, stat: uint) -> str {
|
||||
let stat_f = stat as float;
|
||||
let total = bccx.guaranteed_paths as float;
|
||||
#fmt["%u (%.0f%%)", stat , stat_f * 100f / total]
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -190,7 +216,14 @@ type borrowck_ctxt = @{tcx: ty::ctxt,
|
|||
last_use_map: liveness::last_use_map,
|
||||
binding_map: binding_map,
|
||||
root_map: root_map,
|
||||
mutbl_map: mutbl_map};
|
||||
mutbl_map: mutbl_map,
|
||||
|
||||
// Statistics:
|
||||
mut loaned_paths_same: uint,
|
||||
mut loaned_paths_imm: uint,
|
||||
mut stable_paths: uint,
|
||||
mut req_pure_paths: uint,
|
||||
mut guaranteed_paths: uint};
|
||||
|
||||
// a map mapping id's of expressions of gc'd type (@T, @[], etc) where
|
||||
// the box needs to be kept live to the id of the scope for which they
|
||||
|
|
|
@ -172,6 +172,8 @@ impl methods for gather_loan_ctxt {
|
|||
req_mutbl: ast::mutability,
|
||||
scope_r: ty::region) {
|
||||
|
||||
self.bccx.guaranteed_paths += 1;
|
||||
|
||||
#debug["guarantee_valid(cmt=%s, req_mutbl=%s, scope_r=%s)",
|
||||
self.bccx.cmt_to_repr(cmt),
|
||||
self.bccx.mut_to_str(req_mutbl),
|
||||
|
@ -179,20 +181,27 @@ impl methods for gather_loan_ctxt {
|
|||
let _i = indenter();
|
||||
|
||||
alt cmt.lp {
|
||||
// If this expression is a loanable path, we MUST take out a loan.
|
||||
// This is somewhat non-obvious. You might think, for example, that
|
||||
// if we have an immutable local variable `x` whose value is being
|
||||
// borrowed, we could rely on `x` not to change. This is not so,
|
||||
// however, because even immutable locals can be moved. So we take
|
||||
// out a loan on `x`, guaranteeing that it remains immutable for the
|
||||
// duration of the reference: if there is an attempt to move it
|
||||
// within that scope, the loan will be detected and an error will be
|
||||
// reported.
|
||||
// If this expression is a loanable path, we MUST take out a
|
||||
// loan. This is somewhat non-obvious. You might think,
|
||||
// for example, that if we have an immutable local variable
|
||||
// `x` whose value is being borrowed, we could rely on `x`
|
||||
// not to change. This is not so, however, because even
|
||||
// immutable locals can be moved. So we take out a loan on
|
||||
// `x`, guaranteeing that it remains immutable for the
|
||||
// duration of the reference: if there is an attempt to move
|
||||
// it within that scope, the loan will be detected and an
|
||||
// error will be reported.
|
||||
some(_) {
|
||||
alt scope_r {
|
||||
ty::re_scope(scope_id) {
|
||||
let loans = self.bccx.loan(cmt, req_mutbl);
|
||||
self.add_loans(scope_id, loans);
|
||||
|
||||
if req_mutbl == m_imm && cmt.mutbl != m_imm {
|
||||
self.bccx.loaned_paths_imm += 1;
|
||||
} else {
|
||||
self.bccx.loaned_paths_same += 1;
|
||||
}
|
||||
}
|
||||
_ {
|
||||
self.bccx.span_err(
|
||||
|
@ -225,6 +234,7 @@ impl methods for gather_loan_ctxt {
|
|||
// we were able guarantee the validity of the ptr,
|
||||
// perhaps by rooting or because it is immutably
|
||||
// rooted. good.
|
||||
self.bccx.stable_paths += 1;
|
||||
}
|
||||
err(e) {
|
||||
// not able to guarantee the validity of the ptr.
|
||||
|
@ -235,6 +245,7 @@ impl methods for gather_loan_ctxt {
|
|||
alt opt_scope_id {
|
||||
some(scope_id) {
|
||||
self.req_maps.pure_map.insert(scope_id, e);
|
||||
self.bccx.req_pure_paths += 1;
|
||||
}
|
||||
none {
|
||||
// otherwise, fine, I give up.
|
||||
|
|
|
@ -551,7 +551,7 @@ fn make_generic_glue(ccx: @crate_ctxt, t: ty::t, llfn: ValueRef,
|
|||
helper: glue_helper, name: str)
|
||||
-> ValueRef {
|
||||
let _icx = ccx.insn_ctxt("make_generic_glue");
|
||||
if !ccx.sess.stats() {
|
||||
if !ccx.sess.trans_stats() {
|
||||
ret make_generic_glue_inner(ccx, t, llfn, helper);
|
||||
}
|
||||
|
||||
|
@ -4550,7 +4550,7 @@ fn trans_fn(ccx: @crate_ctxt,
|
|||
ty_self: self_arg,
|
||||
param_substs: option<param_substs>,
|
||||
id: ast::node_id) {
|
||||
let do_time = ccx.sess.stats();
|
||||
let do_time = ccx.sess.trans_stats();
|
||||
let start = if do_time { time::get_time() }
|
||||
else { {sec: 0i64, nsec: 0i32} };
|
||||
let _icx = ccx.insn_ctxt("trans_fn");
|
||||
|
@ -5591,7 +5591,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
|
|||
|
||||
// Translate the metadata.
|
||||
write_metadata(ccx, crate);
|
||||
if ccx.sess.stats() {
|
||||
if ccx.sess.trans_stats() {
|
||||
io::println("--- trans stats ---");
|
||||
io::println(#fmt("n_static_tydescs: %u",
|
||||
ccx.stats.n_static_tydescs));
|
||||
|
|
Loading…
Reference in a new issue