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

Wed, 24 Apr 2013 20:13:37 +0200

author
stefank
date
Wed, 24 Apr 2013 20:13:37 +0200
changeset 5018
b06ac540229e
parent 4037
da91efe96a93
child 5202
47bdfb3d010f
permissions
-rw-r--r--

8013132: Add a flag to turn off the output of the verbose verification code
Reviewed-by: johnc, brutisso

     1 /*
     2  * Copyright (c) 2002, 2012, 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   if (oopDesc::is_null(heap_oop)) return false;
    43   oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
    44   return PSScavenge::is_obj_in_young((HeapWord*)obj);
    45 }
    47 template <class T>
    48 inline bool PSScavenge::should_scavenge(T* p, MutableSpace* to_space) {
    49   if (should_scavenge(p)) {
    50     oop obj = oopDesc::load_decode_heap_oop_not_null(p);
    51     // Skip objects copied to to_space since the scavenge started.
    52     HeapWord* const addr = (HeapWord*)obj;
    53     return addr < to_space_top_before_gc() || addr >= to_space->end();
    54   }
    55   return false;
    56 }
    58 template <class T>
    59 inline bool PSScavenge::should_scavenge(T* p, bool check_to_space) {
    60   if (check_to_space) {
    61     ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
    62     return should_scavenge(p, heap->young_gen()->to_space());
    63   }
    64   return should_scavenge(p);
    65 }
    67 // Attempt to "claim" oop at p via CAS, push the new obj if successful
    68 // This version tests the oop* to make sure it is within the heap before
    69 // attempting marking.
    70 template <class T, bool promote_immediately>
    71 inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm,
    72                                                    T*                  p) {
    73   assert(should_scavenge(p, true), "revisiting object?");
    75   oop o = oopDesc::load_decode_heap_oop_not_null(p);
    76   oop new_obj = o->is_forwarded()
    77         ? o->forwardee()
    78         : pm->copy_to_survivor_space<promote_immediately>(o);
    80 #ifndef PRODUCT
    81   // This code must come after the CAS test, or it will print incorrect
    82   // information.
    83   if (TraceScavenge &&  o->is_forwarded()) {
    84     gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
    85        "forwarding",
    86        new_obj->klass()->internal_name(), o, new_obj, new_obj->size());
    87   }
    88 #endif
    90   oopDesc::encode_store_heap_oop_not_null(p, new_obj);
    92   // We cannot mark without test, as some code passes us pointers
    93   // that are outside the heap. These pointers are either from roots
    94   // or from metadata.
    95   if ((!PSScavenge::is_obj_in_young((HeapWord*)p)) &&
    96       Universe::heap()->is_in_reserved(p)) {
    97     if (PSScavenge::is_obj_in_young((HeapWord*)new_obj)) {
    98       card_table()->inline_write_ref_field_gc(p, new_obj);
    99     }
   100   }
   101 }
   103 template<bool promote_immediately>
   104 class PSRootsClosure: public OopClosure {
   105  private:
   106   PSPromotionManager* _promotion_manager;
   108  protected:
   109   template <class T> void do_oop_work(T *p) {
   110     if (PSScavenge::should_scavenge(p)) {
   111       // We never card mark roots, maybe call a func without test?
   112       PSScavenge::copy_and_push_safe_barrier<T, promote_immediately>(_promotion_manager, p);
   113     }
   114   }
   115  public:
   116   PSRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }
   117   void do_oop(oop* p)       { PSRootsClosure::do_oop_work(p); }
   118   void do_oop(narrowOop* p) { PSRootsClosure::do_oop_work(p); }
   119 };
   121 typedef PSRootsClosure</*promote_immediately=*/false> PSScavengeRootsClosure;
   122 typedef PSRootsClosure</*promote_immediately=*/true> PSPromoteRootsClosure;
   124 // Scavenges a single oop in a Klass.
   125 class PSScavengeFromKlassClosure: public OopClosure {
   126  private:
   127   PSPromotionManager* _pm;
   128   // Used to redirty a scanned klass if it has oops
   129   // pointing to the young generation after being scanned.
   130   Klass*             _scanned_klass;
   131  public:
   132   PSScavengeFromKlassClosure(PSPromotionManager* pm) : _pm(pm), _scanned_klass(NULL) { }
   133   void do_oop(narrowOop* p) { ShouldNotReachHere(); }
   134   void do_oop(oop* p)       {
   135     ParallelScavengeHeap* psh = ParallelScavengeHeap::heap();
   136     assert(!psh->is_in_reserved(p), "GC barrier needed");
   137     if (PSScavenge::should_scavenge(p)) {
   138       assert(!Universe::heap()->is_in_reserved(p), "Not from meta-data?");
   139       assert(PSScavenge::should_scavenge(p, true), "revisiting object?");
   141       oop o = *p;
   142       oop new_obj;
   143       if (o->is_forwarded()) {
   144         new_obj = o->forwardee();
   145       } else {
   146         new_obj = _pm->copy_to_survivor_space</*promote_immediately=*/false>(o);
   147       }
   148       oopDesc::encode_store_heap_oop_not_null(p, new_obj);
   150       if (PSScavenge::is_obj_in_young((HeapWord*)new_obj)) {
   151         do_klass_barrier();
   152       }
   153     }
   154   }
   156   void set_scanned_klass(Klass* klass) {
   157     assert(_scanned_klass == NULL || klass == NULL, "Should always only handling one klass at a time");
   158     _scanned_klass = klass;
   159   }
   161  private:
   162   void do_klass_barrier() {
   163     assert(_scanned_klass != NULL, "Should not be called without having a scanned klass");
   164     _scanned_klass->record_modified_oops();
   165   }
   167 };
   169 // Scavenges the oop in a Klass.
   170 class PSScavengeKlassClosure: public KlassClosure {
   171  private:
   172   PSScavengeFromKlassClosure _oop_closure;
   173  protected:
   174  public:
   175   PSScavengeKlassClosure(PSPromotionManager* pm) : _oop_closure(pm) { }
   176   void do_klass(Klass* klass) {
   177     // If the klass has not been dirtied we know that there's
   178     // no references into  the young gen and we can skip it.
   180 #ifndef PRODUCT
   181     if (TraceScavenge) {
   182       ResourceMark rm;
   183       gclog_or_tty->print_cr("PSScavengeKlassClosure::do_klass %p, %s, dirty: %s",
   184                              klass,
   185                              klass->external_name(),
   186                              klass->has_modified_oops() ? "true" : "false");
   187     }
   188 #endif
   190     if (klass->has_modified_oops()) {
   191       // Clean the klass since we're going to scavenge all the metadata.
   192       klass->clear_modified_oops();
   194       // Setup the promotion manager to redirty this klass
   195       // if references are left in the young gen.
   196       _oop_closure.set_scanned_klass(klass);
   198       klass->oops_do(&_oop_closure);
   200       _oop_closure.set_scanned_klass(NULL);
   201     }
   202   }
   203 };
   205 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSSCAVENGE_INLINE_HPP

mercurial