Skip to content

Commit b9f0165

Browse files
committed
Store dst_map on the actor to avoid reallocation and growth overhead
1 parent 477feea commit b9f0165

1 file changed

Lines changed: 20 additions & 20 deletions

File tree

src/vm.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)