diff --git a/Cargo.toml b/Cargo.toml index 22233eb428..e9b8a17dcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -231,6 +231,12 @@ no_mmap_annotation = [] # only be used if you understand how VO bit works internally. Use at your own risk. vo_bit_access = [] +# When a pointer points to the end of an object, it is not pointing inside an object and is usually not considered as an internal pointer. +# However, some languages may have 0-size fields such as unit (). +# When such fields appear as the last field of an object, an internal pointer to it would point directly to the end of the object, +# and still needs to be considered as an internal pointer. +object_end_internal_pointer = [] + # Do not modify the following line - ci-common.sh matches it # -- Mutally exclusive features -- # Only one feature from each group can be provided. Otherwise build will fail. diff --git a/src/util/metadata/vo_bit/mod.rs b/src/util/metadata/vo_bit/mod.rs index b5794e4075..4d4d52ca62 100644 --- a/src/util/metadata/vo_bit/mod.rs +++ b/src/util/metadata/vo_bit/mod.rs @@ -211,7 +211,11 @@ pub(crate) fn get_object_ref_for_vo_addr(vo_addr: Address) -> ObjectReference { fn is_internal_ptr(obj: ObjectReference, internal_ptr: Address) -> bool { let obj_start = obj.to_object_start::(); let obj_size = VM::VMObjectModel::get_current_size(obj); - internal_ptr < obj_start + obj_size + if cfg!(feature = "object_end_internal_pointer") { + internal_ptr <= obj_start + obj_size + } else { + internal_ptr < obj_start + obj_size + } } /// Check if the address could be an internal pointer based on where VO bit is set.