@@ -21,6 +21,15 @@ use memory_manager_constants::*;
21
21
use tib_layout_constants:: * ;
22
22
use JikesRVM ;
23
23
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
+
24
33
/** Should we gather stats on hash code state transitions for address-based hashing? */
25
34
const HASH_STATS : bool = false ;
26
35
/** count number of Object.hashCode() operations */
@@ -131,7 +140,7 @@ impl ObjectModel<JikesRVM> for VMObjectModel {
131
140
132
141
let bytes = if copy {
133
142
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) ;
135
144
bytes
136
145
} else {
137
146
Self :: bytes_used ( from, rvm_type)
@@ -156,7 +165,8 @@ impl ObjectModel<JikesRVM> for VMObjectModel {
156
165
}
157
166
}
158
167
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 ) }
160
170
}
161
171
162
172
fn get_current_size ( object : ObjectReference ) -> usize {
@@ -229,7 +239,8 @@ impl ObjectModel<JikesRVM> for VMObjectModel {
229
239
230
240
#[ inline( always) ]
231
241
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 ) ) }
233
244
}
234
245
235
246
fn dump_object ( _object : ObjectReference ) {
@@ -256,7 +267,7 @@ impl VMObjectModel {
256
267
let offset = Self :: get_offset_for_alignment_class ( from, rvm_type) ;
257
268
let region = copy_context. alloc_copy ( from, bytes, align, offset, copy) ;
258
269
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) ;
260
271
copy_context. post_copy ( to_obj, bytes, copy) ;
261
272
to_obj
262
273
}
@@ -275,7 +286,7 @@ impl VMObjectModel {
275
286
let offset = Self :: get_offset_for_alignment_array ( from, rvm_type) ;
276
287
let region = copy_context. alloc_copy ( from, bytes, align, offset, copy) ;
277
288
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) ;
279
290
copy_context. post_copy ( to_obj, bytes, copy) ;
280
291
// XXX: Do not sync icache/dcache because we do not support PowerPC
281
292
to_obj
@@ -371,16 +382,12 @@ impl VMObjectModel {
371
382
372
383
#[ inline( always) ]
373
384
fn move_object (
374
- immut_to_address : Address ,
375
385
from_obj : ObjectReference ,
376
- immut_to_obj : ObjectReference ,
386
+ mut to : MoveTarget ,
377
387
num_bytes : usize ,
378
388
_rvm_type : Address ,
379
389
) -> ObjectReference {
380
390
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( ) ) ;
384
391
385
392
// Default values
386
393
let mut copy_bytes = num_bytes;
@@ -399,8 +406,8 @@ impl VMObjectModel {
399
406
400
407
if !DYNAMIC_HASH_OFFSET {
401
408
// 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 ;
404
411
}
405
412
}
406
413
} else if !DYNAMIC_HASH_OFFSET && hash_state == HASH_STATE_HASHED_AND_MOVED {
@@ -410,9 +417,18 @@ impl VMObjectModel {
410
417
}
411
418
}
412
419
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
+ } ;
416
432
417
433
// Low memory word of source object
418
434
let from_address = from_obj. to_raw_address ( ) + ( -obj_ref_offset) ;
@@ -422,12 +438,6 @@ impl VMObjectModel {
422
438
Self :: aligned_32_copy ( to_address, from_address, copy_bytes) ;
423
439
}
424
440
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
-
431
441
// Do we need to copy the hash code?
432
442
if hash_state == HASH_STATE_HASHED {
433
443
unsafe {
0 commit comments