1 /*
   2  * Copyright (c) 2007, 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  */
  24 
  25 template <class T> inline void ParScanWeakRefClosure::do_oop_work(T* p) {
  26   assert (!oopDesc::is_null(*p), "null weak reference?");
  27   oop obj = oopDesc::load_decode_heap_oop_not_null(p);
  28   // weak references are sometimes scanned twice; must check
  29   // that to-space doesn't already contain this object
  30   if ((HeapWord*)obj < _boundary && !_g->to()->is_in_reserved(obj)) {
  31     // we need to ensure that it is copied (see comment in
  32     // ParScanClosure::do_oop_work).
  33     klassOop objK = obj->klass();
  34     markOop m = obj->mark();
  35     oop new_obj;
  36     if (m->is_marked()) { // Contains forwarding pointer.
  37       new_obj = ParNewGeneration::real_forwardee(obj);
  38     } else {
  39       size_t obj_sz = obj->size_given_klass(objK->klass_part());
  40       new_obj = ((ParNewGeneration*)_g)->copy_to_survivor_space(_par_scan_state,
  41                                                                 obj, obj_sz, m);
  42     }
  43     oopDesc::encode_store_heap_oop_not_null(p, new_obj);
  44   }
  45 }
  46 
  47 inline void ParScanWeakRefClosure::do_oop_nv(oop* p)       { ParScanWeakRefClosure::do_oop_work(p); }
  48 inline void ParScanWeakRefClosure::do_oop_nv(narrowOop* p) { ParScanWeakRefClosure::do_oop_work(p); }
  49 
  50 template <class T> inline void ParScanClosure::par_do_barrier(T* p) {
  51   assert(generation()->is_in_reserved(p), "expected ref in generation");
  52   assert(!oopDesc::is_null(*p), "expected non-null object");
  53   oop obj = oopDesc::load_decode_heap_oop_not_null(p);
  54   // If p points to a younger generation, mark the card.
  55   if ((HeapWord*)obj < gen_boundary()) {
  56     rs()->write_ref_field_gc_par(p, obj);
  57   }
  58 }
  59 
  60 template <class T>
  61 inline void ParScanClosure::do_oop_work(T* p,
  62                                         bool gc_barrier,
  63                                         bool root_scan) {
  64   assert((!Universe::heap()->is_in_reserved(p) ||
  65           generation()->is_in_reserved(p))
  66          && (generation()->level() == 0 || gc_barrier),
  67          "The gen must be right, and we must be doing the barrier "
  68          "in older generations.");
  69   T heap_oop = oopDesc::load_heap_oop(p);
  70   if (!oopDesc::is_null(heap_oop)) {
  71     oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
  72     if ((HeapWord*)obj < _boundary) {
  73       assert(!_g->to()->is_in_reserved(obj), "Scanning field twice?");
  74       // OK, we need to ensure that it is copied.
  75       // We read the klass and mark in this order, so that we can reliably
  76       // get the size of the object: if the mark we read is not a
  77       // forwarding pointer, then the klass is valid: the klass is only
  78       // overwritten with an overflow next pointer after the object is
  79       // forwarded.
  80       klassOop objK = obj->klass();
  81       markOop m = obj->mark();
  82       oop new_obj;
  83       if (m->is_marked()) { // Contains forwarding pointer.
  84         new_obj = ParNewGeneration::real_forwardee(obj);
  85         oopDesc::encode_store_heap_oop_not_null(p, new_obj);
  86       } else {
  87         size_t obj_sz = obj->size_given_klass(objK->klass_part());
  88         new_obj = _g->copy_to_survivor_space(_par_scan_state, obj, obj_sz, m);
  89         oopDesc::encode_store_heap_oop_not_null(p, new_obj);
  90         if (root_scan) {
  91           // This may have pushed an object.  If we have a root
  92           // category with a lot of roots, can't let the queue get too
  93           // full:
  94           (void)_par_scan_state->trim_queues(10 * ParallelGCThreads);
  95         }
  96       }
  97       if (gc_barrier) {
  98         // Now call parent closure
  99         par_do_barrier(p);
 100       }
 101     }
 102   }
 103 }
 104 
 105 inline void ParScanWithBarrierClosure::do_oop_nv(oop* p)       { ParScanClosure::do_oop_work(p, true, false); }
 106 inline void ParScanWithBarrierClosure::do_oop_nv(narrowOop* p) { ParScanClosure::do_oop_work(p, true, false); }
 107 
 108 inline void ParScanWithoutBarrierClosure::do_oop_nv(oop* p)       { ParScanClosure::do_oop_work(p, false, false); }
 109 inline void ParScanWithoutBarrierClosure::do_oop_nv(narrowOop* p) { ParScanClosure::do_oop_work(p, false, false); }