1 /*
2 * Copyright (c) 2017, 2021, Red Hat, Inc. All rights reserved.
3 * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
4 * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 *
7 * This code is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 only, as
9 * published by the Free Software Foundation.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
132 }
133
134 bool in_generation(oop obj) {
135 if (_generation == nullptr) {
136 return true;
137 }
138
139 ShenandoahHeapRegion* region = _heap->heap_region_containing(obj);
140 return _generation->contains(region);
141 }
142
143 void verify_oop(oop obj) {
144 // Perform consistency checks with gradually decreasing safety level. This guarantees
145 // that failure report would not try to touch something that was not yet verified to be
146 // safe to process.
147
148 check(ShenandoahAsserts::_safe_unknown, obj, _heap->is_in_reserved(obj),
149 "oop must be in heap bounds");
150 check(ShenandoahAsserts::_safe_unknown, obj, is_object_aligned(obj),
151 "oop must be aligned");
152
153 ShenandoahHeapRegion *obj_reg = _heap->heap_region_containing(obj);
154 Klass* obj_klass = ShenandoahForwarding::klass(obj);
155
156 // Verify that obj is not in dead space:
157 {
158 // Do this before touching obj->size()
159 check(ShenandoahAsserts::_safe_unknown, obj, obj_klass != nullptr,
160 "Object klass pointer should not be null");
161 check(ShenandoahAsserts::_safe_unknown, obj, Metaspace::contains(obj_klass),
162 "Object klass pointer must go to metaspace");
163
164 HeapWord *obj_addr = cast_from_oop<HeapWord*>(obj);
165 check(ShenandoahAsserts::_safe_unknown, obj, obj_addr < obj_reg->top(),
166 "Object start should be within the region");
167
168 if (!obj_reg->is_humongous()) {
169 check(ShenandoahAsserts::_safe_unknown, obj, (obj_addr + ShenandoahForwarding::size(obj)) <= obj_reg->top(),
170 "Object end should be within the region");
171 } else {
172 size_t humongous_start = obj_reg->index();
173 size_t humongous_end = humongous_start + (ShenandoahForwarding::size(obj) >> ShenandoahHeapRegion::region_size_words_shift());
174 for (size_t idx = humongous_start + 1; idx < humongous_end; idx++) {
175 check(ShenandoahAsserts::_safe_unknown, obj, _heap->get_region(idx)->is_humongous_continuation(),
176 "Humongous object is in continuation that fits it");
177 }
178 }
179
180 // ------------ obj is safe at this point --------------
227 "Forwardee should be in active region");
228
229 // Verify that forwardee is not in the dead space:
230 check(ShenandoahAsserts::_safe_oop, obj, !fwd_reg->is_humongous(),
231 "Should have no humongous forwardees");
232
233 HeapWord *fwd_addr = cast_from_oop<HeapWord *>(fwd);
234 check(ShenandoahAsserts::_safe_oop, obj, fwd_addr < fwd_reg->top(),
235 "Forwardee start should be within the region");
236 check(ShenandoahAsserts::_safe_oop, obj, (fwd_addr + ShenandoahForwarding::size(fwd)) <= fwd_reg->top(),
237 "Forwardee end should be within the region");
238
239 oop fwd2 = ShenandoahForwarding::get_forwardee_raw_unchecked(fwd);
240 check(ShenandoahAsserts::_safe_oop, obj, (fwd == fwd2),
241 "Double forwarding");
242 } else {
243 fwd_reg = obj_reg;
244 }
245
246 // Do additional checks for special objects: their fields can hold metadata as well.
247 // We want to check class loading/unloading did not corrupt them.
248
249 if (obj_klass == vmClasses::Class_klass()) {
250 Metadata* klass = obj->metadata_field(java_lang_Class::klass_offset());
251 check(ShenandoahAsserts::_safe_oop, obj,
252 klass == nullptr || Metaspace::contains(klass),
253 "Instance class mirror should point to Metaspace");
254
255 Metadata* array_klass = obj->metadata_field(java_lang_Class::array_klass_offset());
256 check(ShenandoahAsserts::_safe_oop, obj,
257 array_klass == nullptr || Metaspace::contains(array_klass),
258 "Array class mirror should point to Metaspace");
259 }
260
261 // ------------ obj and fwd are safe at this point --------------
262 switch (_options._verify_marked) {
263 case ShenandoahVerifier::_verify_marked_disable:
264 // skip
265 break;
266 case ShenandoahVerifier::_verify_marked_incomplete:
267 check(ShenandoahAsserts::_safe_all, obj, _heap->marking_context()->is_marked(obj),
268 "Must be marked in incomplete bitmap");
269 break;
270 case ShenandoahVerifier::_verify_marked_complete:
271 check(ShenandoahAsserts::_safe_all, obj, _heap->gc_generation()->complete_marking_context()->is_marked(obj),
272 "Must be marked in complete bitmap");
273 break;
274 case ShenandoahVerifier::_verify_marked_complete_except_references:
275 case ShenandoahVerifier::_verify_marked_complete_satb_empty:
276 check(ShenandoahAsserts::_safe_all, obj, _heap->gc_generation()->complete_marking_context()->is_marked(obj),
277 "Must be marked in complete bitmap, except j.l.r.Reference referents");
278 break;
|
1 /*
2 * Copyright (c) 2017, 2025, Red Hat, Inc. All rights reserved.
3 * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
4 * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 *
7 * This code is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 only, as
9 * published by the Free Software Foundation.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
132 }
133
134 bool in_generation(oop obj) {
135 if (_generation == nullptr) {
136 return true;
137 }
138
139 ShenandoahHeapRegion* region = _heap->heap_region_containing(obj);
140 return _generation->contains(region);
141 }
142
143 void verify_oop(oop obj) {
144 // Perform consistency checks with gradually decreasing safety level. This guarantees
145 // that failure report would not try to touch something that was not yet verified to be
146 // safe to process.
147
148 check(ShenandoahAsserts::_safe_unknown, obj, _heap->is_in_reserved(obj),
149 "oop must be in heap bounds");
150 check(ShenandoahAsserts::_safe_unknown, obj, is_object_aligned(obj),
151 "oop must be aligned");
152 check(ShenandoahAsserts::_safe_unknown, obj, os::is_readable_pointer(obj),
153 "oop must be accessible");
154
155 ShenandoahHeapRegion *obj_reg = _heap->heap_region_containing(obj);
156
157 narrowKlass nk = 0;
158 const Klass* obj_klass = nullptr;
159 const bool klass_valid = ShenandoahAsserts::extract_klass_safely(obj, nk, obj_klass);
160
161 check(ShenandoahAsserts::_safe_unknown, obj, klass_valid,
162 "Object klass pointer unreadable or invalid");
163
164 // Verify that obj is not in dead space:
165 {
166 // Do this before touching obj->size()
167 check(ShenandoahAsserts::_safe_unknown, obj, Metaspace::contains(obj_klass),
168 "Object klass pointer must go to metaspace");
169
170 HeapWord *obj_addr = cast_from_oop<HeapWord*>(obj);
171 check(ShenandoahAsserts::_safe_unknown, obj, obj_addr < obj_reg->top(),
172 "Object start should be within the region");
173
174 if (!obj_reg->is_humongous()) {
175 check(ShenandoahAsserts::_safe_unknown, obj, (obj_addr + ShenandoahForwarding::size(obj)) <= obj_reg->top(),
176 "Object end should be within the region");
177 } else {
178 size_t humongous_start = obj_reg->index();
179 size_t humongous_end = humongous_start + (ShenandoahForwarding::size(obj) >> ShenandoahHeapRegion::region_size_words_shift());
180 for (size_t idx = humongous_start + 1; idx < humongous_end; idx++) {
181 check(ShenandoahAsserts::_safe_unknown, obj, _heap->get_region(idx)->is_humongous_continuation(),
182 "Humongous object is in continuation that fits it");
183 }
184 }
185
186 // ------------ obj is safe at this point --------------
233 "Forwardee should be in active region");
234
235 // Verify that forwardee is not in the dead space:
236 check(ShenandoahAsserts::_safe_oop, obj, !fwd_reg->is_humongous(),
237 "Should have no humongous forwardees");
238
239 HeapWord *fwd_addr = cast_from_oop<HeapWord *>(fwd);
240 check(ShenandoahAsserts::_safe_oop, obj, fwd_addr < fwd_reg->top(),
241 "Forwardee start should be within the region");
242 check(ShenandoahAsserts::_safe_oop, obj, (fwd_addr + ShenandoahForwarding::size(fwd)) <= fwd_reg->top(),
243 "Forwardee end should be within the region");
244
245 oop fwd2 = ShenandoahForwarding::get_forwardee_raw_unchecked(fwd);
246 check(ShenandoahAsserts::_safe_oop, obj, (fwd == fwd2),
247 "Double forwarding");
248 } else {
249 fwd_reg = obj_reg;
250 }
251
252 // Do additional checks for special objects: their fields can hold metadata as well.
253 // We want to check class loading/unloading did not corrupt them. We can only reasonably
254 // trust the forwarded objects, as the from-space object can have the klasses effectively
255 // dead.
256
257 if (obj_klass == vmClasses::Class_klass()) {
258 const Metadata* klass = fwd->metadata_field(java_lang_Class::klass_offset());
259 check(ShenandoahAsserts::_safe_oop, obj,
260 klass == nullptr || Metaspace::contains(klass),
261 "Mirrored instance class should point to Metaspace");
262
263 const Metadata* array_klass = obj->metadata_field(java_lang_Class::array_klass_offset());
264 check(ShenandoahAsserts::_safe_oop, obj,
265 array_klass == nullptr || Metaspace::contains(array_klass),
266 "Mirrored array class should point to Metaspace");
267 }
268
269 // ------------ obj and fwd are safe at this point --------------
270 switch (_options._verify_marked) {
271 case ShenandoahVerifier::_verify_marked_disable:
272 // skip
273 break;
274 case ShenandoahVerifier::_verify_marked_incomplete:
275 check(ShenandoahAsserts::_safe_all, obj, _heap->marking_context()->is_marked(obj),
276 "Must be marked in incomplete bitmap");
277 break;
278 case ShenandoahVerifier::_verify_marked_complete:
279 check(ShenandoahAsserts::_safe_all, obj, _heap->gc_generation()->complete_marking_context()->is_marked(obj),
280 "Must be marked in complete bitmap");
281 break;
282 case ShenandoahVerifier::_verify_marked_complete_except_references:
283 case ShenandoahVerifier::_verify_marked_complete_satb_empty:
284 check(ShenandoahAsserts::_safe_all, obj, _heap->gc_generation()->complete_marking_context()->is_marked(obj),
285 "Must be marked in complete bitmap, except j.l.r.Reference referents");
286 break;
|