@@ -537,6 +537,9 @@ pub struct Actor
537537 // Message queue receiver endpoint
538538 queue_rx : mpsc:: Receiver < Message > ,
539539
540+ // Hash map used for garbage collection
541+ dst_map : HashMap :: < Value , Value > ,
542+
540543 // Cache of actor ids to message queue endpoints
541544 actor_map : HashMap < u64 , ActorTx > ,
542545
@@ -578,6 +581,7 @@ impl Actor
578581 msg_alloc,
579582 queue_rx,
580583 globals,
584+ dst_map : HashMap :: default ( ) ,
581585 actor_map : HashMap :: default ( ) ,
582586 stack : Vec :: default ( ) ,
583587 frames : Vec :: default ( ) ,
@@ -827,38 +831,37 @@ impl Actor
827831 fn try_copy (
828832 actor : & mut Actor ,
829833 dst_alloc : & mut Alloc ,
830- dst_map : & mut HashMap < Value , Value > ,
831834 extra_roots : & mut [ & mut Value ] ,
832835 ) -> Result < ( ) , ( ) >
833836 {
834837 // Copy the global variables
835838 for val in & mut actor. globals {
836- deepcopy ( * val, dst_alloc, dst_map) ?;
839+ deepcopy ( * val, dst_alloc, & mut actor . dst_map ) ?;
837840 }
838841
839842 // Copy values on the stack
840843 for val in & mut actor. stack {
841- deepcopy ( * val, dst_alloc, dst_map) ?;
844+ deepcopy ( * val, dst_alloc, & mut actor . dst_map ) ?;
842845 }
843846
844847 // Copy closures in the stack frames
845848 for frame in & mut actor. frames {
846- deepcopy ( frame. fun , dst_alloc, dst_map) ?;
849+ deepcopy ( frame. fun , dst_alloc, & mut actor . dst_map ) ?;
847850 }
848851
849852 // Copy heap values referenced in instructions
850853 for insn in & mut actor. insns {
851854 match insn {
852855 Insn :: push { val } => {
853- deepcopy ( * val, dst_alloc, dst_map) ?;
856+ deepcopy ( * val, dst_alloc, & mut actor . dst_map ) ?;
854857 }
855858
856859 // Instructions referencing name strings
857860 Insn :: get_field { field : s, .. } |
858861 Insn :: set_field { field : s, .. } |
859862 Insn :: call_method { name : s, .. } |
860863 Insn :: call_method_pc { name : s, .. } => {
861- deepcopy ( Value :: String ( * s) , dst_alloc, dst_map) ?;
864+ deepcopy ( Value :: String ( * s) , dst_alloc, & mut actor . dst_map ) ?;
862865 }
863866
864867 _ => { }
@@ -867,16 +870,16 @@ impl Actor
867870
868871 // Copy extra roots supplied by the user
869872 for val in extra_roots {
870- deepcopy ( * * val, dst_alloc, dst_map) ?;
873+ deepcopy ( * * val, dst_alloc, & mut actor . dst_map ) ?;
871874 }
872875
873876 println ! (
874877 "GC copied {} values, {} bytes free" ,
875- thousands_sep( dst_map. len( ) ) ,
878+ thousands_sep( actor . dst_map. len( ) ) ,
876879 thousands_sep( dst_alloc. bytes_free( ) ) ,
877880 ) ;
878881
879- remap ( dst_map) ;
882+ remap ( & mut actor . dst_map ) ;
880883
881884 Ok ( ( ) )
882885 }
@@ -899,15 +902,12 @@ impl Actor
899902 // Create a new allocator to copy the data into
900903 let mut dst_alloc = Alloc :: with_size ( new_mem_size) ;
901904
902- // Hash map for remapping copied values
903- let mut dst_map = HashMap :: < Value , Value > :: default ( ) ;
904-
905905 loop {
906906 // Clear the value map
907- dst_map. clear ( ) ;
907+ self . dst_map . clear ( ) ;
908908
909909 // Try to copy all objects into the new allocator
910- let copy_fail = try_copy ( self , & mut dst_alloc, & mut dst_map , extra_roots) . is_err ( ) ;
910+ let copy_fail = try_copy ( self , & mut dst_alloc, extra_roots) . is_err ( ) ;
911911
912912 // If there is not enough free memory after copying
913913 let min_free_bytes = std:: cmp:: max ( self . alloc . mem_size ( ) / 5 , bytes_needed) ;
@@ -940,32 +940,32 @@ impl Actor
940940
941941 // Remap the global variables
942942 for val in & mut self . globals {
943- * val = get_new_val ( * val, & dst_map) ;
943+ * val = get_new_val ( * val, & self . dst_map ) ;
944944 }
945945
946946 // Remap values on the stack
947947 for val in & mut self . stack {
948- * val = get_new_val ( * val, & dst_map) ;
948+ * val = get_new_val ( * val, & self . dst_map ) ;
949949 }
950950
951951 // Remap closures in the stack frames
952952 for frame in & mut self . frames {
953- frame. fun = get_new_val ( frame. fun , & dst_map) ;
953+ frame. fun = get_new_val ( frame. fun , & self . dst_map ) ;
954954 }
955955
956956 // Remap heap values referenced in instructions
957957 for insn in & mut self . insns {
958958 match insn {
959959 Insn :: push { val } => {
960- * val = get_new_val ( * val, & dst_map) ;
960+ * val = get_new_val ( * val, & self . dst_map ) ;
961961 }
962962
963963 // Instructions referencing name strings
964964 Insn :: get_field { field : s, .. } |
965965 Insn :: set_field { field : s, .. } |
966966 Insn :: call_method { name : s, .. } |
967967 Insn :: call_method_pc { name : s, .. } => {
968- match get_new_val ( Value :: String ( * s) , & dst_map) {
968+ match get_new_val ( Value :: String ( * s) , & self . dst_map ) {
969969 Value :: String ( new_s) => * s = new_s,
970970 _ => panic ! ( ) ,
971971 }
@@ -977,7 +977,7 @@ impl Actor
977977
978978 // Remap extra roots supplied by the user
979979 for val in extra_roots {
980- * * val = get_new_val ( * * val, & dst_map) ;
980+ * * val = get_new_val ( * * val, & self . dst_map ) ;
981981 }
982982
983983 // Drop and replace the old allocator
0 commit comments