src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp

Thu, 26 Sep 2013 10:25:02 -0400

author
hseigel
date
Thu, 26 Sep 2013 10:25:02 -0400
changeset 5784
190899198332
parent 5202
47bdfb3d010f
child 6680
78bbf4d43a14
permissions
-rw-r--r--

7195622: CheckUnhandledOops has limited usefulness now
Summary: Enable CHECK_UNHANDLED_OOPS in fastdebug builds across all supported platforms.
Reviewed-by: coleenp, hseigel, dholmes, stefank, twisti, ihse, rdurbin
Contributed-by: lois.foltan@oracle.com

     1 /*
     2  * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     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  */
    25 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSSCAVENGE_INLINE_HPP
    26 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSSCAVENGE_INLINE_HPP
    28 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
    29 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
    30 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
    31 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
    32 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
    33 #include "memory/iterator.hpp"
    35 inline void PSScavenge::save_to_space_top_before_gc() {
    36   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
    37   _to_space_top_before_gc = heap->young_gen()->to_space()->top();
    38 }
    40 template <class T> inline bool PSScavenge::should_scavenge(T* p) {
    41   T heap_oop = oopDesc::load_heap_oop(p);
    42   return PSScavenge::is_obj_in_young(heap_oop);
    43 }
    45 template <class T>
    46 inline bool PSScavenge::should_scavenge(T* p, MutableSpace* to_space) {
    47   if (should_scavenge(p)) {
    48     oop obj = oopDesc::load_decode_heap_oop_not_null(p);
    49     // Skip objects copied to to_space since the scavenge started.
    50     HeapWord* const addr = (HeapWord*)obj;
    51     return addr < to_space_top_before_gc() || addr >= to_space->end();
    52   }
    53   return false;
    54 }
    56 template <class T>
    57 inline bool PSScavenge::should_scavenge(T* p, bool check_to_space) {
    58   if (check_to_space) {
    59     ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
    60     return should_scavenge(p, heap->young_gen()->to_space());
    61   }
    62   return should_scavenge(p);
    63 }
    65 // Attempt to "claim" oop at p via CAS, push the new obj if successful
    66 // This version tests the oop* to make sure it is within the heap before
    67 // attempting marking.
    68 template <class T, bool promote_immediately>
    69 inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm,
    70                                                    T*                  p) {
    71   assert(should_scavenge(p, true), "revisiting object?");
    73   oop o = oopDesc::load_decode_heap_oop_not_null(p);
    74   oop new_obj = o->is_forwarded()
    75         ? o->forwardee()
    76         : pm->copy_to_survivor_space<promote_immediately>(o);
    78 #ifndef PRODUCT
    79   // This code must come after the CAS test, or it will print incorrect
    80   // information.
    81   if (TraceScavenge &&  o->is_forwarded()) {
    82     gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
    83        "forwarding",
    84        new_obj->klass()->internal_name(), (void *)o, (void *)new_obj, new_obj->size());
    85   }
    86 #endif
    88   oopDesc::encode_store_heap_oop_not_null(p, new_obj);
    90   // We cannot mark without test, as some code passes us pointers
    91   // that are outside the heap. These pointers are either from roots
    92   // or from metadata.
    93   if ((!PSScavenge::is_obj_in_young((HeapWord*)p)) &&
    94       Universe::heap()->is_in_reserved(p)) {
    95     if (PSScavenge::is_obj_in_young(new_obj)) {
    96       card_table()->inline_write_ref_field_gc(p, new_obj);
    97     }
    98   }
    99 }
   101 template<bool promote_immediately>
   102 class PSRootsClosure: public OopClosure {
   103  private:
   104   PSPromotionManager* _promotion_manager;
   106  protected:
   107   template <class T> void do_oop_work(T *p) {
   108     if (PSScavenge::should_scavenge(p)) {
   109       // We never card mark roots, maybe call a func without test?
   110       PSScavenge::copy_and_push_safe_barrier<T, promote_immediately>(_promotion_manager, p);
   111     }
   112   }
   113  public:
   114   PSRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }
   115   void do_oop(oop* p)       { PSRootsClosure::do_oop_work(p); }
   116   void do_oop(narrowOop* p) { PSRootsClosure::do_oop_work(p); }
   117 };
   119 typedef PSRootsClosure</*promote_immediately=*/false> PSScavengeRootsClosure;
   120 typedef PSRootsClosure</*promote_immediately=*/true> PSPromoteRootsClosure;
   122 // Scavenges a single oop in a Klass.
   123 class PSScavengeFromKlassClosure: public OopClosure {
   124  private:
   125   PSPromotionManager* _pm;
   126   // Used to redirty a scanned klass if it has oops
   127   // pointing to the young generation after being scanned.
   128   Klass*             _scanned_klass;
   129  public:
   130   PSScavengeFromKlassClosure(PSPromotionManager* pm) : _pm(pm), _scanned_klass(NULL) { }
   131   void do_oop(narrowOop* p) { ShouldNotReachHere(); }
   132   void do_oop(oop* p)       {
   133     ParallelScavengeHeap* psh = ParallelScavengeHeap::heap();
   134     assert(!psh->is_in_reserved(p), "GC barrier needed");
   135     if (PSScavenge::should_scavenge(p)) {
   136       assert(!Universe::heap()->is_in_reserved(p), "Not from meta-data?");
   137       assert(PSScavenge::should_scavenge(p, true), "revisiting object?");
   139       oop o = *p;
   140       oop new_obj;
   141       if (o->is_forwarded()) {
   142         new_obj = o->forwardee();
   143       } else {
   144         new_obj = _pm->copy_to_survivor_space</*promote_immediately=*/false>(o);
   145       }
   146       oopDesc::encode_store_heap_oop_not_null(p, new_obj);
   148       if (PSScavenge::is_obj_in_young(new_obj)) {
   149         do_klass_barrier();
   150       }
   151     }
   152   }
   154   void set_scanned_klass(Klass* klass) {
   155     assert(_scanned_klass == NULL || klass == NULL, "Should always only handling one klass at a time");
   156     _scanned_klass = klass;
   157   }
   159  private:
   160   void do_klass_barrier() {
   161     assert(_scanned_klass != NULL, "Should not be called without having a scanned klass");
   162     _scanned_klass->record_modified_oops();
   163   }
   165 };
   167 // Scavenges the oop in a Klass.
   168 class PSScavengeKlassClosure: public KlassClosure {
   169  private:
   170   PSScavengeFromKlassClosure _oop_closure;
   171  protected:
   172  public:
   173   PSScavengeKlassClosure(PSPromotionManager* pm) : _oop_closure(pm) { }
   174   void do_klass(Klass* klass) {
   175     // If the klass has not been dirtied we know that there's
   176     // no references into  the young gen and we can skip it.
   178 #ifndef PRODUCT
   179     if (TraceScavenge) {
   180       ResourceMark rm;
   181       gclog_or_tty->print_cr("PSScavengeKlassClosure::do_klass %p, %s, dirty: %s",
   182                              klass,
   183                              klass->external_name(),
   184                              klass->has_modified_oops() ? "true" : "false");
   185     }
   186 #endif
   188     if (klass->has_modified_oops()) {
   189       // Clean the klass since we're going to scavenge all the metadata.
   190       klass->clear_modified_oops();
   192       // Setup the promotion manager to redirty this klass
   193       // if references are left in the young gen.
   194       _oop_closure.set_scanned_klass(klass);
   196       klass->oops_do(&_oop_closure);
   198       _oop_closure.set_scanned_klass(NULL);
   199     }
   200   }
   201 };
   203 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSSCAVENGE_INLINE_HPP

mercurial