@@ -54,26 +54,38 @@ use crate::util::ObjectReference;
54
54
use crate :: vm:: object_model:: ObjectModel ;
55
55
use crate :: vm:: VMBinding ;
56
56
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
+ }
60
70
71
+ /// The base address for VO bit side metadata on 64 bits platforms.
72
+ #[ cfg( target_pointer_width = "64" ) ]
61
73
pub const VO_BIT_SIDE_METADATA_ADDR : Address = VO_BIT_SIDE_METADATA_SPEC . get_absolute_offset ( ) ;
62
74
63
75
/// 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 ) {
65
77
debug_assert ! ( !is_vo_bit_set( object) , "{:x}: VO bit already set" , object) ;
66
78
VO_BIT_SIDE_METADATA_SPEC . store_atomic :: < u8 > ( object. to_raw_address ( ) , 1 , Ordering :: SeqCst ) ;
67
79
}
68
80
69
81
/// 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 ) {
71
83
debug_assert ! ( is_vo_bit_set( object) , "{:x}: VO bit not set" , object) ;
72
84
VO_BIT_SIDE_METADATA_SPEC . store_atomic :: < u8 > ( object. to_raw_address ( ) , 0 , Ordering :: SeqCst ) ;
73
85
}
74
86
75
87
/// 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 ) {
77
89
VO_BIT_SIDE_METADATA_SPEC . store_atomic :: < u8 > ( object. to_raw_address ( ) , 0 , Ordering :: SeqCst ) ;
78
90
}
79
91
@@ -83,21 +95,21 @@ pub fn unset_vo_bit_nocheck(object: ObjectReference) {
83
95
/// # Safety
84
96
///
85
97
/// 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 ) {
87
99
debug_assert ! ( is_vo_bit_set( object) , "{:x}: VO bit not set" , object) ;
88
100
VO_BIT_SIDE_METADATA_SPEC . store :: < u8 > ( object. to_raw_address ( ) , 0 ) ;
89
101
}
90
102
91
103
/// 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 {
93
105
VO_BIT_SIDE_METADATA_SPEC . load_atomic :: < u8 > ( object. to_raw_address ( ) , Ordering :: SeqCst ) == 1
94
106
}
95
107
96
108
/// Check if an address can be turned directly into an object reference using the VO bit.
97
109
/// If so, return `Some(object)`. Otherwise return `None`.
98
110
///
99
111
/// 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 > {
101
113
is_vo_bit_set_inner :: < true > ( address)
102
114
}
103
115
@@ -110,7 +122,7 @@ pub fn is_vo_bit_set_for_addr(address: Address) -> Option<ObjectReference> {
110
122
/// # Safety
111
123
///
112
124
/// 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 > {
114
126
is_vo_bit_set_inner :: < false > ( address)
115
127
}
116
128
@@ -135,7 +147,7 @@ fn is_vo_bit_set_inner<const ATOMIC: bool>(addr: Address) -> Option<ObjectRefere
135
147
}
136
148
137
149
/// 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 ) {
139
151
VO_BIT_SIDE_METADATA_SPEC . bzero_metadata ( start, size) ;
140
152
}
141
153
@@ -145,7 +157,7 @@ pub fn bzero_vo_bit(start: Address, size: usize) {
145
157
/// As an alternative, this function copies the mark bits metadata to VO bits.
146
158
/// The caller needs to ensure the mark bits are set exactly wherever VO bits need to be set before
147
159
/// 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 ) {
149
161
let mark_bit_spec = VM :: VMObjectModel :: LOCAL_MARK_BIT_SPEC ;
150
162
debug_assert ! (
151
163
mark_bit_spec. is_on_side( ) ,
@@ -158,19 +170,19 @@ pub fn bcopy_vo_bit_from_mark_bit<VM: VMBinding>(start: Address, size: usize) {
158
170
use crate :: util:: constants:: { LOG_BITS_IN_BYTE , LOG_BYTES_IN_ADDRESS } ;
159
171
160
172
/// 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
162
174
<< ( VO_BIT_SIDE_METADATA_SPEC . log_bytes_in_region
163
175
+ LOG_BITS_IN_BYTE as usize
164
176
+ LOG_BYTES_IN_ADDRESS as usize
165
177
- VO_BIT_SIDE_METADATA_SPEC . log_num_of_bits ) ;
166
178
167
179
/// 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 {
169
181
unsafe { VO_BIT_SIDE_METADATA_SPEC . load_raw_word ( addr) }
170
182
}
171
183
172
184
/// 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 > (
174
186
start : Address ,
175
187
search_limit_bytes : usize ,
176
188
) -> Option < ObjectReference > {
@@ -203,7 +215,7 @@ fn is_internal_ptr<VM: VMBinding>(obj: ObjectReference, internal_ptr: Address) -
203
215
}
204
216
205
217
/// 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 > (
207
219
vo_addr : Address ,
208
220
internal_ptr : Address ,
209
221
) -> Option < ObjectReference > {
@@ -219,6 +231,6 @@ pub fn is_internal_ptr_from_vo_bit<VM: VMBinding>(
219
231
///
220
232
/// # Safety
221
233
/// 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 {
223
235
VO_BIT_SIDE_METADATA_SPEC . load :: < u8 > ( addr) != 0
224
236
}
0 commit comments