about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2011-03-11 13:44:13 -0800
committerGraydon Hoare <graydon@mozilla.com>2011-03-11 13:44:24 -0800
commitfc7cbe31f9639a1d37baf4a35df9719ad155aa2c (patch)
treef0c08ad3563d9f4527788193823b6d87feb4a7aa /src
parent2ef57287229218466f87ea99c20f9a16f889e1c7 (diff)
downloadrust-fc7cbe31f9639a1d37baf4a35df9719ad155aa2c.tar.gz
rust-fc7cbe31f9639a1d37baf4a35df9719ad155aa2c.zip
Switch rustboot from element-wise copying to take+drop+memcpy. Un-XFAIL size-and-align.rs for rustc.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile1
-rw-r--r--src/boot/be/abi.ml2
-rw-r--r--src/boot/me/semant.ml4
-rw-r--r--src/boot/me/trans.ml172
4 files changed, 77 insertions, 102 deletions
diff --git a/src/Makefile b/src/Makefile
index e8cf5d199e8..b0e2e9c7189 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -475,7 +475,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \
                         pred.rs \
                         preempt.rs \
                         rt-circular-buffer.rs \
-                        size-and-align.rs \
                         spawn-fn.rs \
                         spawn-module-qualified.rs \
                         spawn.rs \
diff --git a/src/boot/be/abi.ml b/src/boot/be/abi.ml
index 89e308bfab9..023e1e1df20 100644
--- a/src/boot/be/abi.ml
+++ b/src/boot/be/abi.ml
@@ -80,7 +80,7 @@ let general_code_alignment = 16;;
 let tydesc_field_first_param = 0;;
 let tydesc_field_size = 1;;
 let tydesc_field_align = 2;;
-let tydesc_field_copy_glue = 3;;
+let tydesc_field_take_glue = 3;;
 let tydesc_field_drop_glue = 4;;
 let tydesc_field_free_glue = 5;;
 let tydesc_field_sever_glue = 6;;
diff --git a/src/boot/me/semant.ml b/src/boot/me/semant.ml
index 3ce5eba2872..3419bb34698 100644
--- a/src/boot/me/semant.ml
+++ b/src/boot/me/semant.ml
@@ -20,7 +20,7 @@ type glue =
   | GLUE_yield
   | GLUE_exit_main_task
   | GLUE_exit_task
-  | GLUE_copy of Ast.ty           (* One-level copy.                    *)
+  | GLUE_take of Ast.ty           (* One-level refcounts++.             *)
   | GLUE_drop of Ast.ty           (* De-initialize local memory.        *)
   | GLUE_free of Ast.ty           (* Drop body + free() box ptr.        *)
   | GLUE_sever of Ast.ty          (* Null all box state slots.          *)
@@ -2776,7 +2776,7 @@ let glue_str (cx:ctxt) (g:glue) : string =
     | GLUE_yield -> "glue$yield"
     | GLUE_exit_main_task -> "glue$exit_main_task"
     | GLUE_exit_task -> "glue$exit_task"
-    | GLUE_copy ty -> "glue$copy$" ^ (ty_str cx ty)
+    | GLUE_take ty -> "glue$take$" ^ (ty_str cx ty)
     | GLUE_drop ty -> "glue$drop$" ^ (ty_str cx ty)
     | GLUE_free ty -> "glue$free$" ^ (ty_str cx ty)
     | GLUE_sever ty -> "glue$sever$" ^ (ty_str cx ty)
diff --git a/src/boot/me/trans.ml b/src/boot/me/trans.ml
index d6b470f9189..17dbe3ea263 100644
--- a/src/boot/me/trans.ml
+++ b/src/boot/me/trans.ml
@@ -1355,7 +1355,7 @@ let trans_visitor
                    Asm.WORD (word_ty_mach, Asm.IMM 0L);
                    Asm.WORD (word_ty_mach, Asm.IMM sz);
                    Asm.WORD (word_ty_mach, Asm.IMM align);
-                   fix (get_copy_glue t);
+                   fix (get_take_glue t);
                    fix (get_drop_glue t);
                    begin
                      match ty_mem_ctrl cx t with
@@ -2022,34 +2022,18 @@ let trans_visitor
       get_typed_mem_glue g fty inner
 
 
-  and get_copy_glue
+  and get_take_glue
       (ty:Ast.ty)
       : fixup =
     let ty = get_genericized_ty ty in
     let arg_ty_params_alias = 0 in
     let arg_src_alias = 1 in
-    let arg_initflag = 2 in
 
-    let g = GLUE_copy ty in
-    let inner (out_ptr:Il.cell) (args:Il.cell) =
-      let dst = deref out_ptr in
+    let g = GLUE_take ty in
+    let inner (_:Il.cell) (args:Il.cell) =
       let ty_params = deref (get_element_ptr args arg_ty_params_alias) in
       let src = deref (get_element_ptr args arg_src_alias) in
-
-      (* Translate copy code for the dst-initializing and
-       * dst-non-initializing cases and branch accordingly. *)
-      let initflag = get_element_ptr args arg_initflag in
-      let jmps = trans_compare_simple Il.JNE (Il.Cell initflag) one in
-
-        trans_copy_ty_full true ty_params true dst ty src ty;
-
-        let skip_noninit_jmp = mark() in
-          emit (Il.jmp Il.JMP Il.CodeNone);
-          List.iter patch jmps;
-
-          trans_copy_ty_full true ty_params false dst ty src ty;
-
-          patch skip_noninit_jmp;
+        trans_take_ty true ty_params src ty;
     in
     let ty_params_ptr = ty_params_covering ty in
     let fty =
@@ -2186,17 +2170,23 @@ let trans_visitor
               get_tydesc_params ty_params_cell elt_td_ptr_cell
             in
 
-            let initflag = Il.Reg (force_to_reg one) in
-
+              (* Take all *)
               copy_loop dst_buf src_buf (Il.Cell fill) (Il.Cell elt_sz)
                 begin
-                  fun dptr sptr ->
+                  fun _ sptr ->
                     trans_call_dynamic_glue
                       elt_td_ptr_cell
-                      Abi.tydesc_field_copy_glue
-                      (Some (deref dptr))
-                      [| ty_params_ptr; sptr; initflag |]
+                      Abi.tydesc_field_take_glue
                       None
+                      [| ty_params_ptr; sptr |]
+                      None;
+                end;
+
+              (* Memcpy all *)
+              copy_loop dst_buf src_buf (Il.Cell fill) one
+                begin
+                  fun dptr sptr ->
+                    mov (deref dptr) (Il.Cell (deref sptr))
                 end;
 
               (* Set the new vec's fill to the original vec's fill *)
@@ -3734,17 +3724,58 @@ let trans_visitor
       end
       tys
 
-  and trans_copy_ty
+  and trans_take_ty
+      (force_inline:bool)
       (ty_params:Il.cell)
-      (initializing:bool)
-      (dst:Il.cell) (dst_ty:Ast.ty)
-      (src:Il.cell) (src_ty:Ast.ty)
+      (v:Il.cell)
+      (ty:Ast.ty)
       : unit =
-    trans_copy_ty_full
-      false ty_params initializing dst dst_ty src src_ty
+    let ty = strip_mutable_or_constrained_ty ty in
+    match ty_mem_ctrl cx ty with
+        MEM_rc_opaque | MEM_gc | MEM_rc_struct -> incr_refcount v
+      | _ ->
+          begin
+            match ty with
+                Ast.TY_fn _
+              | Ast.TY_obj _ ->
+                  let binding =
+                    get_element_ptr v Abi.binding_field_bound_data
+                  in
+                  let null_jmp = null_check binding in
+                    incr_refcount binding;
+                    patch null_jmp
 
-  and trans_copy_ty_full
-      (force_inline:bool)
+              | Ast.TY_param (i, _) ->
+                  aliasing false v
+                    begin
+                      fun v ->
+                        let td = get_ty_param ty_params i in
+                        let ty_params_ptr = get_tydesc_params ty_params td in
+                          trans_call_dynamic_glue
+                            td Abi.tydesc_field_take_glue
+                            None
+                            [| ty_params_ptr; v; |]
+                            None
+                    end
+
+              | Ast.TY_rec _
+              | Ast.TY_tag _
+              | Ast.TY_tup _ ->
+                  if force_inline
+                  then
+                    iter_ty_parts ty_params v ty
+                      (trans_take_ty force_inline ty_params)
+                  else
+                    trans_call_static_glue
+                      (code_fixup_to_ptr_operand (get_take_glue ty))
+                      None
+                      [| alias ty_params; alias v; |]
+                      None
+
+              | _ -> ()
+          end
+
+  and trans_copy_ty
       (ty_params:Il.cell)
       (initializing:bool)
       (dst:Il.cell) (dst_ty:Ast.ty)
@@ -3789,7 +3820,7 @@ let trans_visitor
               | _ ->
                   (* Heavyweight copy: duplicate 1 level of the referent. *)
                   anno "heavy";
-                  trans_copy_ty_heavy force_inline ty_params initializing
+                  trans_copy_ty_heavy ty_params initializing
                     dst dst_ty src src_ty
         end
 
@@ -3821,7 +3852,6 @@ let trans_visitor
    *)
 
   and trans_copy_ty_heavy
-      (force_inline:bool)
       (ty_params:Il.cell)
       (initializing:bool)
       (dst:Il.cell) (dst_ty:Ast.ty)
@@ -3863,68 +3893,14 @@ let trans_visitor
                       (ty_sz cx ty)));
               mov dst (Il.Cell src)
 
-          | Ast.TY_param (i, _) ->
-              iflog
-                (fun _ -> annotate
-                   (Printf.sprintf "copy_ty: parametric copy %#d" i));
-              let initflag = Il.Reg (force_to_reg one) in
-              aliasing false src
-                begin
-                  fun src ->
-                    let td = get_ty_param ty_params i in
-                    let ty_params_ptr = get_tydesc_params ty_params td in
-                      trans_call_dynamic_glue
-                        td Abi.tydesc_field_copy_glue
-                        (Some dst)
-                        [| ty_params_ptr; src; initflag |]
-                        None
-                end
-
-          | Ast.TY_fn _
-          | Ast.TY_obj _ ->
-              begin
-                let src_item =
-                  get_element_ptr src Abi.binding_field_dispatch
-                in
-                let dst_item =
-                  get_element_ptr dst Abi.binding_field_dispatch
-                in
-                let src_binding =
-                  get_element_ptr src Abi.binding_field_bound_data
-                in
-                let dst_binding =
-                  get_element_ptr dst Abi.binding_field_bound_data
-                in
-                  mov dst_item (Il.Cell src_item);
-                  mov dst_binding zero;
-                  let null_jmp = null_check src_binding in
-                    (* Copy if we have a src binding. *)
-                    (* FIXME (issue #58): this is completely wrong, call
-                     * through to the binding's self-copy fptr. For now
-                     * this only works by accident.
-                     *)
-                    trans_copy_ty ty_params true
-                      dst_binding (Ast.TY_box Ast.TY_int)
-                      src_binding (Ast.TY_box Ast.TY_int);
-                    patch null_jmp
-              end
-
           | _ ->
-              if force_inline || should_inline_structure_helpers ty
-              then
-                iter_ty_parts_full ty_params dst src ty
-                  (fun dst src ty ->
-                     trans_copy_ty ty_params initializing
-                       dst ty src ty)
-              else
-                let initflag = Il.Reg (force_to_reg one) in
-                  trans_call_static_glue
-                    (code_fixup_to_ptr_operand (get_copy_glue ty))
-                    (Some dst)
-                    [| alias ty_params;
-                       alias src;
-                       initflag |]
-                    None
+              trans_take_ty false ty_params src ty;
+              if not initializing
+              then drop_ty ty_params dst ty;
+              let sz = ty_sz_with_ty_params ty_params ty in
+                copy_loop dst src sz (imm 1L)
+                  (fun dptr sptr ->
+                     mov (deref dptr) (Il.Cell (deref sptr)))
 
 
   and trans_copy