@@ -122,13 +122,38 @@ class PSStripeShadowCardTable {
122
122
const uint _card_shift;
123
123
const uint _card_size;
124
124
CardValue _table[PSCardTable::num_cards_in_stripe];
125
- const CardValue* _table_base;
125
+ uintptr_t _table_base;
126
+
127
+ // Avoid UB pointer operations by using integers internally.
128
+
129
+ static_assert (sizeof (uintptr_t ) == sizeof (CardValue*), " simplifying assumption" );
130
+ static_assert (sizeof (CardValue) == 1 , " simplifying assumption" );
131
+
132
+ static uintptr_t iaddr (const void * p) {
133
+ return reinterpret_cast <uintptr_t >(p);
134
+ }
135
+
136
+ uintptr_t compute_table_base (HeapWord* start) const {
137
+ uintptr_t offset = iaddr (start) >> _card_shift;
138
+ return iaddr (_table) - offset;
139
+ }
140
+
141
+ void verify_card_inclusive (const CardValue* card) const {
142
+ assert (iaddr (card) >= iaddr (_table), " out of bounds" );
143
+ assert (iaddr (card) <= (iaddr (_table) + sizeof (_table)), " out of bounds" );
144
+ }
145
+
146
+ void verify_card_exclusive (const CardValue* card) const {
147
+ assert (iaddr (card) >= iaddr (_table), " out of bounds" );
148
+ assert (iaddr (card) < (iaddr (_table) + sizeof (_table)), " out of bounds" );
149
+ }
126
150
127
151
public:
128
152
PSStripeShadowCardTable (PSCardTable* pst, HeapWord* const start, HeapWord* const end) :
129
153
_card_shift (CardTable::card_shift()),
130
154
_card_size (CardTable::card_size()),
131
- _table_base (_table - (uintptr_t (start) >> _card_shift)) {
155
+ _table_base (compute_table_base(start))
156
+ {
132
157
size_t stripe_byte_size = pointer_delta (end, start) * HeapWordSize;
133
158
size_t copy_length = align_up (stripe_byte_size, _card_size) >> _card_shift;
134
159
// The end of the last stripe may not be card aligned as it is equal to old
@@ -143,20 +168,24 @@ class PSStripeShadowCardTable {
143
168
}
144
169
145
170
HeapWord* addr_for (const CardValue* const card) {
146
- assert (card >= _table && card <= &_table[PSCardTable::num_cards_in_stripe], " out of bounds" );
147
- return (HeapWord*) ((card - _table_base) << _card_shift);
171
+ verify_card_inclusive (card);
172
+ uintptr_t addr = (iaddr (card) - _table_base) << _card_shift;
173
+ return reinterpret_cast <HeapWord*>(addr);
148
174
}
149
175
150
176
const CardValue* card_for (HeapWord* addr) {
151
- return &_table_base[uintptr_t (addr) >> _card_shift];
177
+ uintptr_t icard = _table_base + (iaddr (addr) >> _card_shift);
178
+ const CardValue* card = reinterpret_cast <const CardValue*>(icard);
179
+ verify_card_inclusive (card);
180
+ return card;
152
181
}
153
182
154
183
bool is_dirty (const CardValue* const card) {
155
184
return !is_clean (card);
156
185
}
157
186
158
187
bool is_clean (const CardValue* const card) {
159
- assert (card >= _table && card < &_table[PSCardTable::num_cards_in_stripe], " out of bounds " );
188
+ verify_card_exclusive (card);
160
189
return *card == PSCardTable::clean_card_val ();
161
190
}
162
191
0 commit comments