diff options
Diffstat (limited to 'gc/mmtk/src/object_model.rs')
| -rw-r--r-- | gc/mmtk/src/object_model.rs | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/gc/mmtk/src/object_model.rs b/gc/mmtk/src/object_model.rs index abeef1f2b9..d673ca11a0 100644 --- a/gc/mmtk/src/object_model.rs +++ b/gc/mmtk/src/object_model.rs @@ -1,8 +1,15 @@ -use crate::abi::{RubyObjectAccess, OBJREF_OFFSET}; -use crate::{abi, Ruby}; +use std::ptr::copy_nonoverlapping; + +use crate::abi; +use crate::abi::RubyObjectAccess; +use crate::abi::MIN_OBJ_ALIGN; +use crate::abi::OBJREF_OFFSET; +use crate::Ruby; use mmtk::util::constants::BITS_IN_BYTE; -use mmtk::util::copy::{CopySemantics, GCWorkerCopyContext}; -use mmtk::util::{Address, ObjectReference}; +use mmtk::util::copy::CopySemantics; +use mmtk::util::copy::GCWorkerCopyContext; +use mmtk::util::Address; +use mmtk::util::ObjectReference; use mmtk::vm::*; pub struct VMObjectModel {} @@ -36,13 +43,39 @@ impl ObjectModel<Ruby> for VMObjectModel { const NEED_VO_BITS_DURING_TRACING: bool = true; fn copy( - _from: ObjectReference, - _semantics: CopySemantics, - _copy_context: &mut GCWorkerCopyContext<Ruby>, + from: ObjectReference, + semantics: CopySemantics, + copy_context: &mut GCWorkerCopyContext<Ruby>, ) -> ObjectReference { - unimplemented!( - "Copying GC not currently supported" - ) + let from_acc = RubyObjectAccess::from_objref(from); + let from_start = from_acc.obj_start(); + let object_size = from_acc.object_size(); + let to_start = copy_context.alloc_copy(from, object_size, MIN_OBJ_ALIGN, 0, semantics); + debug_assert!(!to_start.is_zero()); + let to_payload = to_start.add(OBJREF_OFFSET); + unsafe { + copy_nonoverlapping::<u8>(from_start.to_ptr(), to_start.to_mut_ptr(), object_size); + } + let to_obj = unsafe { ObjectReference::from_raw_address_unchecked(to_payload) }; + copy_context.post_copy(to_obj, object_size, semantics); + trace!("Copied object from {} to {}", from, to_obj); + + (crate::binding().upcalls().move_obj_during_marking)(from, to_obj); + + #[cfg(feature = "clear_old_copy")] + { + trace!( + "Clearing old copy {} ({}-{})", + from, + from_start, + from_start + object_size + ); + // For debug purpose, we clear the old copy so that if the Ruby VM reads from the old + // copy again, it will likely result in an error. + unsafe { std::ptr::write_bytes::<u8>(from_start.to_mut_ptr(), 0, object_size) } + } + + to_obj } fn copy_to(_from: ObjectReference, _to: ObjectReference, _region: Address) -> Address { |
