aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-10-08 23:32:18 -0700
committerGraydon Hoare <[email protected]>2010-10-08 23:32:18 -0700
commit39f51b31dfe917bf2bbe3f12bed5431160966625 (patch)
tree0e122ab268dcd0c7062fc849adf5df8b3283cfb6 /src
parentAdd quad-counting system. (diff)
downloadrust-39f51b31dfe917bf2bbe3f12bed5431160966625.tar.xz
rust-39f51b31dfe917bf2bbe3f12bed5431160966625.zip
Quad counters are revealing. Move drops out-of-line, cut 200kb from rustc.
Diffstat (limited to 'src')
-rw-r--r--src/boot/me/trans.ml271
1 files changed, 168 insertions, 103 deletions
diff --git a/src/boot/me/trans.ml b/src/boot/me/trans.ml
index 68d0aac6..d4579211 100644
--- a/src/boot/me/trans.ml
+++ b/src/boot/me/trans.ml
@@ -280,6 +280,18 @@ let trans_visitor
string_of_name (path_to_name cx.ctxt_curr_path)
in
+ let should_inline_structure_helpers t =
+ let n = 2 in
+ match t with
+ Ast.TY_tag ttag ->
+ get_n_tag_tups cx ttag > n
+ | Ast.TY_rec elts ->
+ Array.length elts > 3
+ | Ast.TY_tup elts ->
+ Array.length elts > 3
+ | _ -> false
+ in
+
let based (reg:Il.reg) : Il.mem =
Il.RegIn (reg, None)
in
@@ -361,7 +373,9 @@ let trans_visitor
in
let get_element_ptr =
- Il.get_element_ptr word_bits abi.Abi.abi_str_of_hardreg
+ Session.time_inner "trans GEP" cx.ctxt_sess
+ (fun _ ->
+ Il.get_element_ptr word_bits abi.Abi.abi_str_of_hardreg)
in
let get_variant_ptr (mem_cell:Il.cell) (i:int) : Il.cell =
@@ -383,10 +397,12 @@ let trans_visitor
word_at (fp_imm frame_crate_ptr)
and crate_rel_to_ptr (rel:Il.operand) (rty:Il.referent_ty) : Il.cell =
- let cell = next_vreg_cell (Il.AddrTy rty) in
- mov cell (Il.Cell (curr_crate_ptr()));
- add_to cell rel;
- cell
+ (in_quad_category "crate_rel -> ptr"
+ (fun _ ->
+ let cell = next_vreg_cell (Il.AddrTy rty) in
+ mov cell (Il.Cell (curr_crate_ptr()));
+ add_to cell rel;
+ cell))
(*
* Note: alias *requires* its cell to be in memory already, and should
@@ -648,11 +664,11 @@ let trans_visitor
(fun _ -> fold_ty cx fold t)
in
- let rec calculate_sz (ty_params:Il.cell) (size:size) : Il.operand =
+ let rec calculate_sz_full (ty_params:Il.cell) (size:size) : Il.operand =
iflog (fun _ -> annotate
(Printf.sprintf "calculating size %s"
(string_of_size size)));
- let sub_sz = calculate_sz ty_params in
+ let sub_sz = calculate_sz_full ty_params in
match htab_search (emitter_size_cache()) size with
Some op ->
iflog (fun _ -> annotate
@@ -754,6 +770,9 @@ let trans_visitor
htab_put (emitter_size_cache()) size res;
res
+ and calculate_sz c s =
+ in_quad_category "size calc"
+ (fun _ -> calculate_sz_full c s)
and calculate_sz_in_current_frame (size:size) : Il.operand =
calculate_sz (get_ty_params_of_current_frame()) size
@@ -1222,7 +1241,8 @@ let trans_visitor
(initializing:bool)
(lv:Ast.lval)
: (Il.cell * Ast.ty) =
- trans_lval_full initializing lv
+ in_quad_category "lval"
+ (fun _ -> trans_lval_full initializing lv)
and trans_lval_init (lv:Ast.lval) : (Il.cell * Ast.ty) =
trans_lval_maybe_init true lv
@@ -1582,10 +1602,13 @@ let trans_visitor
let framesz = SIZE_fixup_mem_sz spill in
push_new_emitter_with_vregs None;
iflog (fun _ -> annotate "prologue");
- abi.Abi.abi_emit_fn_prologue (emitter())
- framesz callsz nabi_rust (upcall_fixup "upcall_grow_task")
- false cx.ctxt_sess.Session.sess_minimal;
- write_frame_info_ptrs None;
+ in_native_quad_category "prologue"
+ (fun _ ->
+ abi.Abi.abi_emit_fn_prologue (emitter())
+ framesz callsz nabi_rust (upcall_fixup "upcall_grow_task")
+ false cx.ctxt_sess.Session.sess_minimal);
+ (in_quad_category "prologue"
+ (fun _ -> write_frame_info_ptrs None));
(* FIXME: not clear why, but checking interrupt in glue context
* causes many.rs to crash when run on a sufficiently large number
* of tasks; possibly a weird interaction with growing? *)
@@ -1740,7 +1763,7 @@ let trans_visitor
let callsz = SIZE_fixed (word_n n_outgoing_args) in
trans_glue_frame_entry callsz spill false
- and get_mem_glue (g:glue) (inner:Il.mem -> unit) : fixup =
+ and get_mem_glue_full (g:glue) (inner:Il.mem -> unit) : fixup =
match htab_search cx.ctxt_glue_code g with
Some code -> code.code_fixup
| None ->
@@ -1766,6 +1789,9 @@ let trans_visitor
fix
end
+ and get_mem_glue g i =
+ in_quad_category "mem glue" (fun _ -> get_mem_glue_full g i)
+
and get_typed_mem_glue
(g:glue)
(fty:Ast.ty)
@@ -1822,7 +1848,7 @@ let trans_visitor
let cell = get_element_ptr args 1 in
note_drop_step ty "in drop-glue, dropping";
trace_word cx.ctxt_sess.Session.sess_trace_drop cell;
- drop_ty ty_params (deref cell) ty;
+ drop_ty_full true ty_params (deref cell) ty;
note_drop_step ty "drop-glue complete";
in
let ty_params_ptr = ty_params_covering ty in
@@ -3080,7 +3106,14 @@ let trans_visitor
iter_ty_parts_full ty_params cell cell ty
(fun _ src_cell ty -> f src_cell ty)
- and drop_ty
+ and drop_ty tp c t =
+ (in_quad_category "drop" (fun _ -> drop_ty_normal tp c t))
+
+ and drop_ty_normal tp c t =
+ drop_ty_full false tp c t
+
+ and drop_ty_full
+ (force_inline:bool)
(ty_params:Il.cell)
(cell:Il.cell)
(ty:Ast.ty)
@@ -3088,11 +3121,15 @@ let trans_visitor
let mctrl = ty_mem_ctrl cx ty in
let ty = strip_mutable_or_constrained_ty ty in
+ let call_out_of_line _ =
+ trans_call_simple_static_glue (get_drop_glue ty)
+ ty_params [| alias cell |] None;
+ in
match ty with
Ast.TY_fn _
- | Ast.TY_obj _ ->
+ | Ast.TY_obj _ when force_inline ->
note_drop_step ty "drop_ty: obj/fn path";
let box_ptr =
get_element_ptr cell Abi.binding_field_bound_data
@@ -3148,8 +3185,11 @@ let trans_visitor
patch null_jmp;
note_drop_step ty "drop_ty: done obj path";
+ | Ast.TY_fn _
+ | Ast.TY_obj _ ->
+ call_out_of_line()
- | Ast.TY_param (i, _) ->
+ | Ast.TY_param (i, _) ->
note_drop_step ty "drop_ty: parametric-ty path";
aliasing false cell
begin
@@ -3163,51 +3203,61 @@ let trans_visitor
end;
note_drop_step ty "drop_ty: done parametric-ty path";
- | _ ->
- match mctrl with
- MEM_gc
- | MEM_rc_opaque
- | MEM_rc_struct ->
+ | _ ->
+ match mctrl with
+ MEM_gc
+ | MEM_rc_opaque
+ | MEM_rc_struct when force_inline ->
- note_drop_step ty "drop_ty: box-drop path";
+ note_drop_step ty "drop_ty: box-drop path";
- let _ = check_box_rty cell in
- let null_jmp = null_check cell in
- let j = drop_refcount_and_cmp cell in
+ let _ = check_box_rty cell in
+ let null_jmp = null_check cell in
+ let j = drop_refcount_and_cmp cell in
- (* FIXME (issue #25): check to see that the box has
- * further box members; if it doesn't we can elide the
- * call to the glue function. *)
+ (* FIXME (issue #25): check to see that the box has
+ * further box members; if it doesn't we can elide the
+ * call to the glue function. *)
- trans_call_simple_static_glue
- (get_free_glue ty (mctrl = MEM_gc))
- ty_params
- [| cell |]
- None;
+ trans_call_simple_static_glue
+ (get_free_glue ty (mctrl = MEM_gc))
+ ty_params
+ [| cell |]
+ None;
+
+ (* Null the slot out to prevent double-free if the frame
+ * unwinds. *)
+ mov cell zero;
+ patch j;
+ patch null_jmp;
+ note_drop_step ty "drop_ty: done box-drop path";
+
+ | MEM_gc
+ | MEM_rc_opaque
+ | MEM_rc_struct ->
+ call_out_of_line()
+
+ | MEM_interior
+ when type_points_to_heap cx ty ||
+ (n_used_type_params cx ty > 0) ->
+ begin
+ note_drop_step ty
+ "drop_ty possibly-heap-referencing path";
+ if force_inline || should_inline_structure_helpers ty
+ then iter_ty_parts ty_params cell ty
+ (drop_ty ty_params)
+ else
+ call_out_of_line();
- (* Null the slot out to prevent double-free if the frame
- * unwinds.
- *)
- mov cell zero;
- patch j;
- patch null_jmp;
- note_drop_step ty "drop_ty: done box-drop path";
-
- | MEM_interior
- when type_points_to_heap cx ty ||
- (n_used_type_params cx ty > 0) ->
- note_drop_step ty "drop_ty possibly-heap-referencing path";
- iter_ty_parts ty_params cell ty
- (drop_ty ty_params);
- note_drop_step ty
- "drop_ty: done possibly-heap-referencing path";
-
- | MEM_interior ->
- note_drop_step ty "drop_ty: no-op simple-interior path";
- (* Interior allocation of all-interior value not caught above:
- * nothing to do.
- *)
- ()
+ note_drop_step ty
+ "drop_ty: done possibly-heap-referencing path";
+ end
+
+ | MEM_interior ->
+ note_drop_step ty "drop_ty: no-op simple-interior path";
+ (* Interior allocation of all-interior value not caught
+ * above: nothing to do. *)
+ ()
and sever_ty
(ty_params:Il.cell)
@@ -3414,42 +3464,54 @@ let trans_visitor
* the null case (i.e. fall-through means not null).
*)
and null_check (cell:Il.cell) : quad_idx =
- emit (Il.cmp (Il.Cell cell) zero);
- let j = mark() in
- emit (Il.jmp Il.JE Il.CodeNone);
- j
+ in_quad_category "null check"
+ begin
+ fun _ ->
+ emit (Il.cmp (Il.Cell cell) zero);
+ let j = mark() in
+ emit (Il.jmp Il.JE Il.CodeNone);
+ j
+ end
(* Returns a mark for a jmp that must be patched to the continuation of
* the non-zero refcount case (i.e. fall-through means zero refcount).
*)
and drop_refcount_and_cmp (boxed:Il.cell) : quad_idx =
- iflog (fun _ -> annotate "drop refcount and maybe free");
- let rc = box_rc_cell boxed in
- if cx.ctxt_sess.Session.sess_trace_gc ||
- cx.ctxt_sess.Session.sess_trace_drop
- then
+ in_quad_category "drop refcnt + free"
begin
- trace_str true "refcount--";
- trace_word true boxed;
- trace_word true rc
- end;
- emit (Il.binary Il.SUB rc (Il.Cell rc) one);
- emit (Il.cmp (Il.Cell rc) zero);
- let j = mark () in
- emit (Il.jmp Il.JNE Il.CodeNone);
- j
+ fun _ ->
+ iflog (fun _ -> annotate "drop refcount and maybe free");
+ let rc = box_rc_cell boxed in
+ if cx.ctxt_sess.Session.sess_trace_gc ||
+ cx.ctxt_sess.Session.sess_trace_drop
+ then
+ begin
+ trace_str true "refcount--";
+ trace_word true boxed;
+ trace_word true rc
+ end;
+ emit (Il.binary Il.SUB rc (Il.Cell rc) one);
+ emit (Il.cmp (Il.Cell rc) zero);
+ let j = mark () in
+ emit (Il.jmp Il.JNE Il.CodeNone);
+ j
+ end
and incr_refcount (boxed:Il.cell) : unit =
- let rc = box_rc_cell boxed in
- if cx.ctxt_sess.Session.sess_trace_gc ||
- cx.ctxt_sess.Session.sess_trace_drop
- then
- begin
- trace_str true "refcount++";
- trace_word true boxed;
- trace_word true rc
- end;
- add_to rc one
+ in_quad_category "incr refcnt"
+ begin
+ fun _ ->
+ let rc = box_rc_cell boxed in
+ if cx.ctxt_sess.Session.sess_trace_gc ||
+ cx.ctxt_sess.Session.sess_trace_drop
+ then
+ begin
+ trace_str true "refcount++";
+ trace_word true boxed;
+ trace_word true rc
+ end;
+ add_to rc one
+ end
and drop_slot
(ty_params:Il.cell)
@@ -3615,24 +3677,27 @@ let trans_visitor
(cell_str dst) (cell_str src);
end;
assert (simplified_ty src_ty = simplified_ty dst_ty);
- match (ty_mem_ctrl cx src_ty, ty_mem_ctrl cx dst_ty) with
-
- | (MEM_rc_opaque, MEM_rc_opaque)
- | (MEM_gc, MEM_gc)
- | (MEM_rc_struct, MEM_rc_struct) ->
- (* Lightweight copy: twiddle refcounts, move pointer. *)
- anno "refcounted light";
- incr_refcount src;
- if not initializing
- then
- drop_ty ty_params dst dst_ty;
- mov dst (Il.Cell src)
+ in_quad_category "copy"
+ begin
+ fun _ ->
+ match (ty_mem_ctrl cx src_ty, ty_mem_ctrl cx dst_ty) with
+ (MEM_rc_opaque, MEM_rc_opaque)
+ | (MEM_gc, MEM_gc)
+ | (MEM_rc_struct, MEM_rc_struct) ->
+ (* Lightweight copy: twiddle refcounts, move pointer. *)
+ anno "refcounted light";
+ incr_refcount src;
+ if not initializing
+ then
+ drop_ty ty_params dst dst_ty;
+ mov dst (Il.Cell src)
- | _ ->
- (* Heavyweight copy: duplicate 1 level of the referent. *)
- anno "heavy";
- trans_copy_ty_heavy ty_params initializing
- dst dst_ty src src_ty
+ | _ ->
+ (* Heavyweight copy: duplicate 1 level of the referent. *)
+ anno "heavy";
+ trans_copy_ty_heavy ty_params initializing
+ dst dst_ty src src_ty
+ end
(* NB: heavyweight copying here does not mean "producing a deep
* clone of the entire data tree rooted at the src operand". It means
@@ -6084,7 +6149,7 @@ let fixup_assigning_visitor
let visit_crate_pre c =
enter_file_for c.id;
- inner.Walk.visit_crate_pre c
+ inner.Walk.visit_crate_pre c;
in
{ inner with