@@ -21,6 +21,15 @@ use memory_manager_constants::*;
2121use tib_layout_constants:: * ;
2222use JikesRVM ;
2323
24+ /// Used as a parameter of `move_object` to specify where to move an object to.
25+ enum MoveTarget {
26+ /// Move an object to the address returned from `alloc_copy`.
27+ ToAddress ( Address ) ,
28+ /// Move an object to an `ObjectReference` pointing to an object previously computed from
29+ /// `get_reference_when_copied_to`.
30+ ToObject ( ObjectReference ) ,
31+ }
32+
2433/** Should we gather stats on hash code state transitions for address-based hashing? */
2534const HASH_STATS : bool = false ;
2635/** count number of Object.hashCode() operations */
@@ -131,7 +140,7 @@ impl ObjectModel<JikesRVM> for VMObjectModel {
131140
132141 let bytes = if copy {
133142 let bytes = Self :: bytes_required_when_copied ( from, rvm_type) ;
134- Self :: move_object ( unsafe { Address :: zero ( ) } , from , to , bytes, rvm_type) ;
143+ Self :: move_object ( from , MoveTarget :: ToObject ( to ) , bytes, rvm_type) ;
135144 bytes
136145 } else {
137146 Self :: bytes_used ( from, rvm_type)
@@ -156,7 +165,8 @@ impl ObjectModel<JikesRVM> for VMObjectModel {
156165 }
157166 }
158167
159- ObjectReference :: from_raw_address ( res + OBJECT_REF_OFFSET )
168+ debug_assert ! ( !res. is_zero( ) ) ;
169+ unsafe { ObjectReference :: from_raw_address_unchecked ( res + OBJECT_REF_OFFSET ) }
160170 }
161171
162172 fn get_current_size ( object : ObjectReference ) -> usize {
@@ -229,7 +239,8 @@ impl ObjectModel<JikesRVM> for VMObjectModel {
229239
230240 #[ inline( always) ]
231241 fn address_to_ref ( addr : Address ) -> ObjectReference {
232- ObjectReference :: from_raw_address ( addr + ( -TIB_OFFSET ) )
242+ debug_assert ! ( !addr. is_zero( ) ) ;
243+ unsafe { ObjectReference :: from_raw_address_unchecked ( addr + ( -TIB_OFFSET ) ) }
233244 }
234245
235246 fn dump_object ( _object : ObjectReference ) {
@@ -256,7 +267,7 @@ impl VMObjectModel {
256267 let offset = Self :: get_offset_for_alignment_class ( from, rvm_type) ;
257268 let region = copy_context. alloc_copy ( from, bytes, align, offset, copy) ;
258269
259- let to_obj = Self :: move_object ( region , from, ObjectReference :: NULL , bytes, rvm_type) ;
270+ let to_obj = Self :: move_object ( from, MoveTarget :: ToAddress ( region ) , bytes, rvm_type) ;
260271 copy_context. post_copy ( to_obj, bytes, copy) ;
261272 to_obj
262273 }
@@ -275,7 +286,7 @@ impl VMObjectModel {
275286 let offset = Self :: get_offset_for_alignment_array ( from, rvm_type) ;
276287 let region = copy_context. alloc_copy ( from, bytes, align, offset, copy) ;
277288
278- let to_obj = Self :: move_object ( region , from, ObjectReference :: NULL , bytes, rvm_type) ;
289+ let to_obj = Self :: move_object ( from, MoveTarget :: ToAddress ( region ) , bytes, rvm_type) ;
279290 copy_context. post_copy ( to_obj, bytes, copy) ;
280291 // XXX: Do not sync icache/dcache because we do not support PowerPC
281292 to_obj
@@ -371,16 +382,12 @@ impl VMObjectModel {
371382
372383 #[ inline( always) ]
373384 fn move_object (
374- immut_to_address : Address ,
375385 from_obj : ObjectReference ,
376- immut_to_obj : ObjectReference ,
386+ mut to : MoveTarget ,
377387 num_bytes : usize ,
378388 _rvm_type : Address ,
379389 ) -> ObjectReference {
380390 trace ! ( "VMObjectModel.move_object" ) ;
381- let mut to_address = immut_to_address;
382- let mut to_obj = immut_to_obj;
383- debug_assert ! ( to_address. is_zero( ) || to_obj. to_raw_address( ) . is_zero( ) ) ;
384391
385392 // Default values
386393 let mut copy_bytes = num_bytes;
@@ -399,8 +406,8 @@ impl VMObjectModel {
399406
400407 if !DYNAMIC_HASH_OFFSET {
401408 // The hashcode is the first word, so we copy to object one word higher
402- if to_obj . to_raw_address ( ) . is_zero ( ) {
403- to_address += HASHCODE_BYTES ;
409+ if let MoveTarget :: ToAddress ( ref mut addr ) = to {
410+ * addr += HASHCODE_BYTES ;
404411 }
405412 }
406413 } else if !DYNAMIC_HASH_OFFSET && hash_state == HASH_STATE_HASHED_AND_MOVED {
@@ -410,9 +417,18 @@ impl VMObjectModel {
410417 }
411418 }
412419
413- if !to_obj. to_raw_address ( ) . is_zero ( ) {
414- to_address = to_obj. to_raw_address ( ) + ( -obj_ref_offset) ;
415- }
420+ let ( to_address, to_obj) = match to {
421+ MoveTarget :: ToAddress ( addr) => {
422+ let obj =
423+ unsafe { ObjectReference :: from_raw_address_unchecked ( addr + obj_ref_offset) } ;
424+ ( addr, obj)
425+ }
426+ MoveTarget :: ToObject ( obj) => {
427+ let addr = obj. to_raw_address ( ) + ( -obj_ref_offset) ;
428+ debug_assert ! ( obj. to_raw_address( ) == addr + obj_ref_offset) ;
429+ ( addr, obj)
430+ }
431+ } ;
416432
417433 // Low memory word of source object
418434 let from_address = from_obj. to_raw_address ( ) + ( -obj_ref_offset) ;
@@ -422,12 +438,6 @@ impl VMObjectModel {
422438 Self :: aligned_32_copy ( to_address, from_address, copy_bytes) ;
423439 }
424440
425- if to_obj. is_null ( ) {
426- to_obj = ObjectReference :: from_raw_address ( to_address + obj_ref_offset) ;
427- } else {
428- debug_assert ! ( to_obj. to_raw_address( ) == to_address + obj_ref_offset) ;
429- }
430-
431441 // Do we need to copy the hash code?
432442 if hash_state == HASH_STATE_HASHED {
433443 unsafe {
0 commit comments