7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25
26 #include "gc/shenandoah/shenandoahAsserts.hpp"
27 #include "gc/shenandoah/shenandoahForwarding.hpp"
28 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
29 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
30 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
31 #include "gc/shenandoah/shenandoahUtils.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "runtime/os.hpp"
35 #include "utilities/vmError.hpp"
36
37 void print_raw_memory(ShenandoahMessageBuffer &msg, void* loc) {
38 // Be extra safe. Only access data that is guaranteed to be safe:
39 // should be in heap, in known committed region, within that region.
40
41 ShenandoahHeap* heap = ShenandoahHeap::heap();
42 if (!heap->is_in_reserved(loc)) return;
43
44 ShenandoahHeapRegion* r = heap->heap_region_containing(loc);
45 if (r != nullptr && r->is_committed()) {
46 address start = MAX2((address) r->bottom(), (address) loc - 32);
47 address end = MIN2((address) r->end(), (address) loc + 128);
328 "Mirrored array class should point to Metaspace",
329 file, line);
330 }
331 }
332 }
333
334 void ShenandoahAsserts::assert_in_correct_region(void* interior_loc, oop obj, const char* file, int line) {
335 assert_correct(interior_loc, obj, file, line);
336
337 ShenandoahHeap* heap = ShenandoahHeap::heap();
338 ShenandoahHeapRegion* r = heap->heap_region_containing(obj);
339 if (!r->is_active()) {
340 print_failure(_safe_unknown, obj, interior_loc, nullptr, "Shenandoah assert_in_correct_region failed",
341 "Object must reside in active region",
342 file, line);
343 }
344
345 size_t alloc_size = obj->size();
346 HeapWord* obj_end = cast_from_oop<HeapWord*>(obj) + alloc_size;
347
348 if (ShenandoahHeapRegion::requires_humongous(alloc_size)) {
349 size_t idx = r->index();
350 size_t end_idx = heap->heap_region_index_containing(obj_end - 1);
351 for (size_t i = idx; i < end_idx; i++) {
352 ShenandoahHeapRegion* chain_reg = heap->get_region(i);
353 if (i == idx && !chain_reg->is_humongous_start()) {
354 print_failure(_safe_unknown, obj, interior_loc, nullptr, "Shenandoah assert_in_correct_region failed",
355 "Object must reside in humongous start",
356 file, line);
357 }
358 if (i != idx && !chain_reg->is_humongous_continuation()) {
359 print_failure(_safe_oop, obj, interior_loc, nullptr, "Shenandoah assert_in_correct_region failed",
360 "Humongous continuation should be of proper size",
361 file, line);
362 }
363 }
364 } else {
365 if (obj_end > r->top()) {
366 print_failure(_safe_unknown, obj, interior_loc, nullptr, "Shenandoah assert_in_correct_region failed",
367 "Object end should be within the active area of the region",
368 file, line);
556 }
557 }
558
559 ShenandoahMessageBuffer msg("Must be either control thread, or vm thread");
560 if (at_safepoint) {
561 msg.append(" at a safepoint");
562 }
563 report_vm_error(file, line, msg.buffer());
564 }
565
566 bool ShenandoahAsserts::extract_klass_safely(oop obj, narrowKlass& nk, const Klass*& k) {
567 nk = 0;
568 k = nullptr;
569
570 if (!os::is_readable_pointer(obj)) {
571 return false;
572 }
573
574 if (UseCompactObjectHeaders) { // look in forwardee
575 markWord mark = obj->mark();
576 if (mark.is_marked()) {
577 oop fwd = cast_to_oop(mark.clear_lock_bits().to_pointer());
578 if (!os::is_readable_pointer(fwd)) {
579 return false;
580 }
581 mark = fwd->mark();
582 }
583 nk = mark.narrow_klass();
584 } else {
585 nk = obj->narrow_klass();
586 }
587 if (!CompressedKlassPointers::is_valid_narrow_klass_id(nk)) {
588 return false;
589 }
590 k = CompressedKlassPointers::decode_not_null_without_asserts(nk);
591
592 return k != nullptr;
593 }
|
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25
26 #include "gc/shenandoah/shenandoahAsserts.hpp"
27 #include "gc/shenandoah/shenandoahForwarding.inline.hpp"
28 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
29 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
30 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
31 #include "gc/shenandoah/shenandoahUtils.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "runtime/os.hpp"
35 #include "utilities/vmError.hpp"
36
37 void print_raw_memory(ShenandoahMessageBuffer &msg, void* loc) {
38 // Be extra safe. Only access data that is guaranteed to be safe:
39 // should be in heap, in known committed region, within that region.
40
41 ShenandoahHeap* heap = ShenandoahHeap::heap();
42 if (!heap->is_in_reserved(loc)) return;
43
44 ShenandoahHeapRegion* r = heap->heap_region_containing(loc);
45 if (r != nullptr && r->is_committed()) {
46 address start = MAX2((address) r->bottom(), (address) loc - 32);
47 address end = MIN2((address) r->end(), (address) loc + 128);
328 "Mirrored array class should point to Metaspace",
329 file, line);
330 }
331 }
332 }
333
334 void ShenandoahAsserts::assert_in_correct_region(void* interior_loc, oop obj, const char* file, int line) {
335 assert_correct(interior_loc, obj, file, line);
336
337 ShenandoahHeap* heap = ShenandoahHeap::heap();
338 ShenandoahHeapRegion* r = heap->heap_region_containing(obj);
339 if (!r->is_active()) {
340 print_failure(_safe_unknown, obj, interior_loc, nullptr, "Shenandoah assert_in_correct_region failed",
341 "Object must reside in active region",
342 file, line);
343 }
344
345 size_t alloc_size = obj->size();
346 HeapWord* obj_end = cast_from_oop<HeapWord*>(obj) + alloc_size;
347
348 // Mirror the allocator's humongous classification. A fresh object whose base
349 // size could grow by one word for an injected identity hash-code is allocated
350 // as humongous up front (see ShenandoahFreeSet::allocate), so verification must
351 // reserve the same headroom while the object is still unexpanded. Once expanded,
352 // obj->size() already includes the hash word and is final, so no headroom is
353 // added -- and requires_humongous() then yields the same answer the allocator
354 // reached on the unexpanded base size.
355 const bool may_expand_for_hash = UseCompactObjectHeaders && !obj->mark().is_expanded();
356 if (ShenandoahHeapRegion::requires_humongous(alloc_size, may_expand_for_hash)) {
357 size_t idx = r->index();
358 size_t end_idx = heap->heap_region_index_containing(obj_end - 1);
359 for (size_t i = idx; i < end_idx; i++) {
360 ShenandoahHeapRegion* chain_reg = heap->get_region(i);
361 if (i == idx && !chain_reg->is_humongous_start()) {
362 print_failure(_safe_unknown, obj, interior_loc, nullptr, "Shenandoah assert_in_correct_region failed",
363 "Object must reside in humongous start",
364 file, line);
365 }
366 if (i != idx && !chain_reg->is_humongous_continuation()) {
367 print_failure(_safe_oop, obj, interior_loc, nullptr, "Shenandoah assert_in_correct_region failed",
368 "Humongous continuation should be of proper size",
369 file, line);
370 }
371 }
372 } else {
373 if (obj_end > r->top()) {
374 print_failure(_safe_unknown, obj, interior_loc, nullptr, "Shenandoah assert_in_correct_region failed",
375 "Object end should be within the active area of the region",
376 file, line);
564 }
565 }
566
567 ShenandoahMessageBuffer msg("Must be either control thread, or vm thread");
568 if (at_safepoint) {
569 msg.append(" at a safepoint");
570 }
571 report_vm_error(file, line, msg.buffer());
572 }
573
574 bool ShenandoahAsserts::extract_klass_safely(oop obj, narrowKlass& nk, const Klass*& k) {
575 nk = 0;
576 k = nullptr;
577
578 if (!os::is_readable_pointer(obj)) {
579 return false;
580 }
581
582 if (UseCompactObjectHeaders) { // look in forwardee
583 markWord mark = obj->mark();
584 if (ShenandoahForwarding::has_forwardee(mark)) {
585 oop fwd = cast_to_oop(mark.clear_lock_bits().to_pointer());
586 if (!os::is_readable_pointer(fwd)) {
587 return false;
588 }
589 mark = fwd->mark();
590 }
591 nk = mark.narrow_klass();
592 } else {
593 nk = obj->narrow_klass();
594 }
595 if (!CompressedKlassPointers::is_valid_narrow_klass_id(nk)) {
596 return false;
597 }
598 k = CompressedKlassPointers::decode_not_null_without_asserts(nk);
599
600 return k != nullptr;
601 }
|