@@ -31,6 +31,13 @@ pub(crate) const HASH_BITS_SPEC: SideMetadataSpec = SideMetadataSpec {
31
31
log_bytes_in_region : LOG_MIN_OBJECT_SIZE as usize ,
32
32
} ;
33
33
34
+ #[ cfg( feature = "record_moved_objects" ) ]
35
+ use std:: { sync:: Mutex , collections:: HashMap } ;
36
+ #[ cfg( feature = "record_moved_objects" ) ]
37
+ lazy_static ! {
38
+ static ref COPIED_OBJECTS : Mutex <HashMap <usize , String >> = Mutex :: new( HashMap :: new( ) ) ;
39
+ }
40
+
34
41
pub ( crate ) const MARKING_METADATA_SPEC : VMLocalMarkBitSpec =
35
42
VMLocalMarkBitSpec :: side_after ( LOS_METADATA_SPEC . as_spec ( ) ) ;
36
43
@@ -187,6 +194,12 @@ impl ObjectModel<JuliaVM> for VMObjectModel {
187
194
}
188
195
}
189
196
197
+ #[ cfg( feature = "record_moved_objects" ) ]
198
+ {
199
+ let mut map = COPIED_OBJECTS . lock ( ) . unwrap ( ) ;
200
+ map. insert ( from. to_raw_address ( ) . as_usize ( ) , unsafe { crate :: julia_scanning:: get_julia_object_type ( from. to_raw_address ( ) ) } ) ;
201
+ }
202
+
190
203
// zero from_obj (for debugging purposes)
191
204
#[ cfg( debug_assertions) ]
192
205
{
@@ -297,6 +310,35 @@ pub fn is_object_in_nonmoving(object: &ObjectReference) -> bool {
297
310
&& ( * object) . to_raw_address ( ) . as_usize ( ) < 0xa00_0000_0000
298
311
}
299
312
313
+ // If an object has its type tag bits set as 'smalltag', but those bits are not recognizable,
314
+ // very possibly the object is corrupted. This function asserts this case.
315
+ pub fn assert_generic_datatype ( obj : Address ) {
316
+ unsafe {
317
+ let vtag = mmtk_jl_typetagof ( obj) ;
318
+ let vt = vtag. to_ptr :: < jl_datatype_t > ( ) ;
319
+ let type_tag = mmtk_jl_typetagof ( vtag) ;
320
+
321
+ if type_tag. as_usize ( ) != ( ( jl_small_typeof_tags_jl_datatype_tag as usize ) << 4 )
322
+ || ( * vt) . smalltag ( ) != 0
323
+ {
324
+ #[ cfg( feature = "record_moved_objects" ) ]
325
+ let old_type = {
326
+ let not_moved = "not moved" . to_string ( ) ;
327
+ { let map = COPIED_OBJECTS . lock ( ) . unwrap ( ) ; map. get ( & obj. as_usize ( ) ) . unwrap_or ( & not_moved) . to_string ( ) }
328
+ } ;
329
+ #[ cfg( not( feature = "record_moved_objects" ) ) ]
330
+ let old_type = "not recorded (need record_moved_objects)" . to_string ( ) ;
331
+ panic ! (
332
+ "GC error (probable corruption) - !jl_is_datatype(vt) = {}; vt->smalltag = {}, vt = {:?}, it was = {}" ,
333
+ vt as usize != ( ( jl_small_typeof_tags_jl_datatype_tag as usize ) << 4 ) ,
334
+ ( * ( vtag. to_ptr:: <jl_datatype_t>( ) ) ) . smalltag( ) != 0 ,
335
+ vt,
336
+ old_type
337
+ ) ;
338
+ }
339
+ }
340
+ }
341
+
300
342
/// This function uses mutable static variables and requires unsafe annotation
301
343
302
344
#[ inline( always) ]
@@ -353,19 +395,7 @@ pub unsafe fn get_so_object_size(object: ObjectReference, hash_size: usize) -> u
353
395
return llt_align ( with_header_size ( dtsz) , 16 ) ;
354
396
}
355
397
} else {
356
- let vt = vtag. to_ptr :: < jl_datatype_t > ( ) ;
357
- let type_tag = mmtk_jl_typetagof ( vtag) ;
358
-
359
- if type_tag. as_usize ( ) != ( ( jl_small_typeof_tags_jl_datatype_tag as usize ) << 4 )
360
- || ( * vt) . smalltag ( ) != 0
361
- {
362
- panic ! (
363
- "GC error (probable corruption) - !jl_is_datatype(vt) = {}; vt->smalltag = {}, vt = {:?}" ,
364
- type_tag. as_usize( ) != ( ( jl_small_typeof_tags_jl_datatype_tag as usize ) << 4 ) ,
365
- ( * ( vtag. to_ptr:: <jl_datatype_t>( ) ) ) . smalltag( ) != 0 ,
366
- vt
367
- ) ;
368
- }
398
+ assert_generic_datatype ( obj_address) ;
369
399
}
370
400
371
401
let obj_type = mmtk_jl_typeof ( obj_address) ;
0 commit comments