@@ -54,26 +54,38 @@ use crate::util::ObjectReference;
5454use crate :: vm:: object_model:: ObjectModel ;
5555use crate :: vm:: VMBinding ;
5656
57- /// A VO bit is required per min-object-size aligned address, rather than per object, and can only exist as side metadata.
58- pub ( crate ) const VO_BIT_SIDE_METADATA_SPEC : SideMetadataSpec =
59- crate :: util:: metadata:: side_metadata:: spec_defs:: VO_BIT ;
57+ cfg_if:: cfg_if! {
58+ if #[ cfg( feature = "vo_bit_access" ) ] {
59+ /// A VO bit is required per min-object-size aligned address, rather than per object, and can only exist as side metadata.
60+ /// This is only publicly available when the feature "vo_bit_access" is enabled.
61+ /// Check the comments on "vo_bit_access" in `Cargo.toml` before use. Use at your own risk.
62+ pub const VO_BIT_SIDE_METADATA_SPEC : SideMetadataSpec =
63+ crate :: util:: metadata:: side_metadata:: spec_defs:: VO_BIT ;
64+ } else {
65+ /// A VO bit is required per min-object-size aligned address, rather than per object, and can only exist as side metadata.
66+ pub ( crate ) const VO_BIT_SIDE_METADATA_SPEC : SideMetadataSpec =
67+ crate :: util:: metadata:: side_metadata:: spec_defs:: VO_BIT ;
68+ }
69+ }
6070
71+ /// The base address for VO bit side metadata on 64 bits platforms.
72+ #[ cfg( target_pointer_width = "64" ) ]
6173pub const VO_BIT_SIDE_METADATA_ADDR : Address = VO_BIT_SIDE_METADATA_SPEC . get_absolute_offset ( ) ;
6274
6375/// Atomically set the VO bit for an object.
64- pub fn set_vo_bit ( object : ObjectReference ) {
76+ pub ( crate ) fn set_vo_bit ( object : ObjectReference ) {
6577 debug_assert ! ( !is_vo_bit_set( object) , "{:x}: VO bit already set" , object) ;
6678 VO_BIT_SIDE_METADATA_SPEC . store_atomic :: < u8 > ( object. to_raw_address ( ) , 1 , Ordering :: SeqCst ) ;
6779}
6880
6981/// Atomically unset the VO bit for an object.
70- pub fn unset_vo_bit ( object : ObjectReference ) {
82+ pub ( crate ) fn unset_vo_bit ( object : ObjectReference ) {
7183 debug_assert ! ( is_vo_bit_set( object) , "{:x}: VO bit not set" , object) ;
7284 VO_BIT_SIDE_METADATA_SPEC . store_atomic :: < u8 > ( object. to_raw_address ( ) , 0 , Ordering :: SeqCst ) ;
7385}
7486
7587/// Atomically unset the VO bit for an object, regardless whether the bit is set or not.
76- pub fn unset_vo_bit_nocheck ( object : ObjectReference ) {
88+ pub ( crate ) fn unset_vo_bit_nocheck ( object : ObjectReference ) {
7789 VO_BIT_SIDE_METADATA_SPEC . store_atomic :: < u8 > ( object. to_raw_address ( ) , 0 , Ordering :: SeqCst ) ;
7890}
7991
@@ -83,21 +95,21 @@ pub fn unset_vo_bit_nocheck(object: ObjectReference) {
8395/// # Safety
8496///
8597/// This is unsafe: check the comment on `side_metadata::store`
86- pub unsafe fn unset_vo_bit_unsafe ( object : ObjectReference ) {
98+ pub ( crate ) unsafe fn unset_vo_bit_unsafe ( object : ObjectReference ) {
8799 debug_assert ! ( is_vo_bit_set( object) , "{:x}: VO bit not set" , object) ;
88100 VO_BIT_SIDE_METADATA_SPEC . store :: < u8 > ( object. to_raw_address ( ) , 0 ) ;
89101}
90102
91103/// Check if the VO bit is set for an object.
92- pub fn is_vo_bit_set ( object : ObjectReference ) -> bool {
104+ pub ( crate ) fn is_vo_bit_set ( object : ObjectReference ) -> bool {
93105 VO_BIT_SIDE_METADATA_SPEC . load_atomic :: < u8 > ( object. to_raw_address ( ) , Ordering :: SeqCst ) == 1
94106}
95107
96108/// Check if an address can be turned directly into an object reference using the VO bit.
97109/// If so, return `Some(object)`. Otherwise return `None`.
98110///
99111/// The `address` must be word-aligned.
100- pub fn is_vo_bit_set_for_addr ( address : Address ) -> Option < ObjectReference > {
112+ pub ( crate ) fn is_vo_bit_set_for_addr ( address : Address ) -> Option < ObjectReference > {
101113 is_vo_bit_set_inner :: < true > ( address)
102114}
103115
@@ -110,7 +122,7 @@ pub fn is_vo_bit_set_for_addr(address: Address) -> Option<ObjectReference> {
110122/// # Safety
111123///
112124/// This is unsafe: check the comment on `side_metadata::load`
113- pub unsafe fn is_vo_bit_set_unsafe ( address : Address ) -> Option < ObjectReference > {
125+ pub ( crate ) unsafe fn is_vo_bit_set_unsafe ( address : Address ) -> Option < ObjectReference > {
114126 is_vo_bit_set_inner :: < false > ( address)
115127}
116128
@@ -135,7 +147,7 @@ fn is_vo_bit_set_inner<const ATOMIC: bool>(addr: Address) -> Option<ObjectRefere
135147}
136148
137149/// Bulk zero the VO bit.
138- pub fn bzero_vo_bit ( start : Address , size : usize ) {
150+ pub ( crate ) fn bzero_vo_bit ( start : Address , size : usize ) {
139151 VO_BIT_SIDE_METADATA_SPEC . bzero_metadata ( start, size) ;
140152}
141153
@@ -145,7 +157,7 @@ pub fn bzero_vo_bit(start: Address, size: usize) {
145157/// As an alternative, this function copies the mark bits metadata to VO bits.
146158/// The caller needs to ensure the mark bits are set exactly wherever VO bits need to be set before
147159/// calling this function.
148- pub fn bcopy_vo_bit_from_mark_bit < VM : VMBinding > ( start : Address , size : usize ) {
160+ pub ( crate ) fn bcopy_vo_bit_from_mark_bit < VM : VMBinding > ( start : Address , size : usize ) {
149161 let mark_bit_spec = VM :: VMObjectModel :: LOCAL_MARK_BIT_SPEC ;
150162 debug_assert ! (
151163 mark_bit_spec. is_on_side( ) ,
@@ -158,19 +170,19 @@ pub fn bcopy_vo_bit_from_mark_bit<VM: VMBinding>(start: Address, size: usize) {
158170use crate :: util:: constants:: { LOG_BITS_IN_BYTE , LOG_BYTES_IN_ADDRESS } ;
159171
160172/// How many data memory bytes does 1 word in the VO bit side metadata represents?
161- pub const VO_BIT_WORD_TO_REGION : usize = 1
173+ pub ( crate ) const VO_BIT_WORD_TO_REGION : usize = 1
162174 << ( VO_BIT_SIDE_METADATA_SPEC . log_bytes_in_region
163175 + LOG_BITS_IN_BYTE as usize
164176 + LOG_BYTES_IN_ADDRESS as usize
165177 - VO_BIT_SIDE_METADATA_SPEC . log_num_of_bits ) ;
166178
167179/// Bulk check if a VO bit word. Return true if there is any bit set in the word.
168- pub fn get_raw_vo_bit_word ( addr : Address ) -> usize {
180+ pub ( crate ) fn get_raw_vo_bit_word ( addr : Address ) -> usize {
169181 unsafe { VO_BIT_SIDE_METADATA_SPEC . load_raw_word ( addr) }
170182}
171183
172184/// Find the base reference to the object from a potential internal pointer.
173- pub fn find_object_from_internal_pointer < VM : VMBinding > (
185+ pub ( crate ) fn find_object_from_internal_pointer < VM : VMBinding > (
174186 start : Address ,
175187 search_limit_bytes : usize ,
176188) -> Option < ObjectReference > {
@@ -203,7 +215,7 @@ fn is_internal_ptr<VM: VMBinding>(obj: ObjectReference, internal_ptr: Address) -
203215}
204216
205217/// Check if the address could be an internal pointer based on where VO bit is set.
206- pub fn is_internal_ptr_from_vo_bit < VM : VMBinding > (
218+ pub ( crate ) fn is_internal_ptr_from_vo_bit < VM : VMBinding > (
207219 vo_addr : Address ,
208220 internal_ptr : Address ,
209221) -> Option < ObjectReference > {
@@ -219,6 +231,6 @@ pub fn is_internal_ptr_from_vo_bit<VM: VMBinding>(
219231///
220232/// # Safety
221233/// The caller needs to make sure that no one is modifying VO bit.
222- pub unsafe fn is_vo_addr ( addr : Address ) -> bool {
234+ pub ( crate ) unsafe fn is_vo_addr ( addr : Address ) -> bool {
223235 VO_BIT_SIDE_METADATA_SPEC . load :: < u8 > ( addr) != 0
224236}
0 commit comments