< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp

Print this page

   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;
< prev index next >