< prev index next >

src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp

Print this page




  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 #include "precompiled.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
  28 #include "gc_implementation/parallelScavenge/objectStartArray.hpp"
  29 #include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
  30 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
  31 #include "gc_implementation/parallelScavenge/psCompactionManager.inline.hpp"
  32 #include "gc_implementation/parallelScavenge/psOldGen.hpp"
  33 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp"



  34 #include "oops/objArrayKlass.inline.hpp"
  35 #include "oops/oop.inline.hpp"
  36 #include "runtime/atomic.inline.hpp"
  37 #include "utilities/stack.inline.hpp"
  38 
  39 PSOldGen*            ParCompactionManager::_old_gen = NULL;
  40 ParCompactionManager**  ParCompactionManager::_manager_array = NULL;
  41 
  42 RegionTaskQueue**              ParCompactionManager::_region_list = NULL;
  43 
  44 OopTaskQueueSet*     ParCompactionManager::_stack_array = NULL;
  45 ParCompactionManager::ObjArrayTaskQueueSet*
  46   ParCompactionManager::_objarray_queues = NULL;
  47 ObjectStartArray*    ParCompactionManager::_start_array = NULL;
  48 ParMarkBitMap*       ParCompactionManager::_mark_bitmap = NULL;
  49 RegionTaskQueueSet*  ParCompactionManager::_region_array = NULL;
  50 
  51 uint*                 ParCompactionManager::_recycled_stack_index = NULL;
  52 int                   ParCompactionManager::_recycled_top = -1;
  53 int                   ParCompactionManager::_recycled_bottom = -1;


 155   assert(action() != NotValid, "Action is not set");
 156   return (action() == ParCompactionManager::Copy) ||
 157          (action() == ParCompactionManager::CopyAndUpdate) ||
 158          (action() == ParCompactionManager::UpdateAndCopy);
 159 }
 160 
 161 void ParCompactionManager::region_list_push(uint list_index,
 162                                             size_t region_index) {
 163   region_list(list_index)->push(region_index);
 164 }
 165 
 166 void ParCompactionManager::verify_region_list_empty(uint list_index) {
 167   assert(region_list(list_index)->is_empty(), "Not empty");
 168 }
 169 
 170 ParCompactionManager*
 171 ParCompactionManager::gc_thread_compaction_manager(int index) {
 172   assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range");
 173   assert(_manager_array != NULL, "Sanity");
 174   return _manager_array[index];








































































































































 175 }
 176 
 177 void ParCompactionManager::follow_marking_stacks() {
 178   do {
 179     // Drain the overflow stack first, to allow stealing from the marking stack.
 180     oop obj;
 181     while (marking_stack()->pop_overflow(obj)) {
 182       follow_contents(obj);
 183     }
 184     while (marking_stack()->pop_local(obj)) {
 185       follow_contents(obj);
 186     }
 187 
 188     // Process ObjArrays one at a time to avoid marking stack bloat.
 189     ObjArrayTask task;
 190     if (_objarray_stack.pop_overflow(task) || _objarray_stack.pop_local(task)) {
 191       follow_contents((objArrayOop)task.obj(), task.index());
 192     }
 193   } while (!marking_stacks_empty());
 194 


  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 #include "precompiled.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
  28 #include "gc_implementation/parallelScavenge/objectStartArray.hpp"
  29 #include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
  30 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
  31 #include "gc_implementation/parallelScavenge/psCompactionManager.inline.hpp"
  32 #include "gc_implementation/parallelScavenge/psOldGen.hpp"
  33 #include "gc_implementation/parallelScavenge/psParallelCompact.inline.hpp"
  34 #include "memory/iterator.inline.hpp"
  35 #include "oops/instanceKlass.inline.hpp"
  36 #include "oops/instanceMirrorKlass.inline.hpp"
  37 #include "oops/objArrayKlass.inline.hpp"
  38 #include "oops/oop.inline.hpp"
  39 #include "runtime/atomic.inline.hpp"
  40 #include "utilities/stack.inline.hpp"
  41 
  42 PSOldGen*            ParCompactionManager::_old_gen = NULL;
  43 ParCompactionManager**  ParCompactionManager::_manager_array = NULL;
  44 
  45 RegionTaskQueue**              ParCompactionManager::_region_list = NULL;
  46 
  47 OopTaskQueueSet*     ParCompactionManager::_stack_array = NULL;
  48 ParCompactionManager::ObjArrayTaskQueueSet*
  49   ParCompactionManager::_objarray_queues = NULL;
  50 ObjectStartArray*    ParCompactionManager::_start_array = NULL;
  51 ParMarkBitMap*       ParCompactionManager::_mark_bitmap = NULL;
  52 RegionTaskQueueSet*  ParCompactionManager::_region_array = NULL;
  53 
  54 uint*                 ParCompactionManager::_recycled_stack_index = NULL;
  55 int                   ParCompactionManager::_recycled_top = -1;
  56 int                   ParCompactionManager::_recycled_bottom = -1;


 158   assert(action() != NotValid, "Action is not set");
 159   return (action() == ParCompactionManager::Copy) ||
 160          (action() == ParCompactionManager::CopyAndUpdate) ||
 161          (action() == ParCompactionManager::UpdateAndCopy);
 162 }
 163 
 164 void ParCompactionManager::region_list_push(uint list_index,
 165                                             size_t region_index) {
 166   region_list(list_index)->push(region_index);
 167 }
 168 
 169 void ParCompactionManager::verify_region_list_empty(uint list_index) {
 170   assert(region_list(list_index)->is_empty(), "Not empty");
 171 }
 172 
 173 ParCompactionManager*
 174 ParCompactionManager::gc_thread_compaction_manager(int index) {
 175   assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range");
 176   assert(_manager_array != NULL, "Sanity");
 177   return _manager_array[index];
 178 }
 179 
 180 void InstanceKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
 181   assert(obj != NULL, "can't follow the content of NULL object");
 182 
 183   PSParallelCompact::follow_klass(cm, obj->klass());
 184   // Only mark the header and let the scan of the meta-data mark
 185   // everything else.
 186 
 187   PSParallelCompact::MarkAndPushClosure cl(cm);
 188   InstanceKlass::oop_oop_iterate_oop_maps<true>(obj, &cl);
 189 }
 190 
 191 void InstanceMirrorKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
 192   InstanceKlass::oop_pc_follow_contents(obj, cm);
 193 
 194   // Follow the klass field in the mirror.
 195   Klass* klass = java_lang_Class::as_Klass(obj);
 196   if (klass != NULL) {
 197     // An anonymous class doesn't have its own class loader, so the call
 198     // to follow_klass will mark and push its java mirror instead of the
 199     // class loader. When handling the java mirror for an anonymous class
 200     // we need to make sure its class loader data is claimed, this is done
 201     // by calling follow_class_loader explicitly. For non-anonymous classes
 202     // the call to follow_class_loader is made when the class loader itself
 203     // is handled.
 204     if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
 205       PSParallelCompact::follow_class_loader(cm, klass->class_loader_data());
 206     } else {
 207       PSParallelCompact::follow_klass(cm, klass);
 208     }
 209   } else {
 210     // If klass is NULL then this a mirror for a primitive type.
 211     // We don't have to follow them, since they are handled as strong
 212     // roots in Universe::oops_do.
 213     assert(java_lang_Class::is_primitive(obj), "Sanity check");
 214   }
 215 
 216   PSParallelCompact::MarkAndPushClosure cl(cm);
 217   oop_oop_iterate_statics<true>(obj, &cl);
 218 }
 219 
 220 void InstanceClassLoaderKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
 221   InstanceKlass::oop_pc_follow_contents(obj, cm);
 222 
 223   ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
 224   if (loader_data != NULL) {
 225     PSParallelCompact::follow_class_loader(cm, loader_data);
 226   }
 227 }
 228 
 229 template <class T>
 230 static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj, ParCompactionManager* cm) {
 231   T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
 232   T heap_oop = oopDesc::load_heap_oop(referent_addr);
 233   debug_only(
 234     if(TraceReferenceGC && PrintGCDetails) {
 235       gclog_or_tty->print_cr("InstanceRefKlass::oop_pc_follow_contents " PTR_FORMAT, p2i(obj));
 236     }
 237   )
 238   if (!oopDesc::is_null(heap_oop)) {
 239     oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
 240     if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) &&
 241         PSParallelCompact::ref_processor()->discover_reference(obj, klass->reference_type())) {
 242       // reference already enqueued, referent will be traversed later
 243       klass->InstanceKlass::oop_pc_follow_contents(obj, cm);
 244       debug_only(
 245         if(TraceReferenceGC && PrintGCDetails) {
 246           gclog_or_tty->print_cr("       Non NULL enqueued " PTR_FORMAT, p2i(obj));
 247         }
 248       )
 249       return;
 250     } else {
 251       // treat referent as normal oop
 252       debug_only(
 253         if(TraceReferenceGC && PrintGCDetails) {
 254           gclog_or_tty->print_cr("       Non NULL normal " PTR_FORMAT, p2i(obj));
 255         }
 256       )
 257       PSParallelCompact::mark_and_push(cm, referent_addr);
 258     }
 259   }
 260   T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
 261   if (ReferenceProcessor::pending_list_uses_discovered_field()) {
 262     // Treat discovered as normal oop, if ref is not "active",
 263     // i.e. if next is non-NULL.
 264     T  next_oop = oopDesc::load_heap_oop(next_addr);
 265     if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
 266       T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
 267       debug_only(
 268         if(TraceReferenceGC && PrintGCDetails) {
 269           gclog_or_tty->print_cr("   Process discovered as normal "
 270                                  PTR_FORMAT, p2i(discovered_addr));
 271         }
 272       )
 273       PSParallelCompact::mark_and_push(cm, discovered_addr);
 274     }
 275   } else {
 276 #ifdef ASSERT
 277     // In the case of older JDKs which do not use the discovered
 278     // field for the pending list, an inactive ref (next != NULL)
 279     // must always have a NULL discovered field.
 280     T next = oopDesc::load_heap_oop(next_addr);
 281     oop discovered = java_lang_ref_Reference::discovered(obj);
 282     assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
 283            err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
 284                    p2i(obj)));
 285 #endif
 286   }
 287   PSParallelCompact::mark_and_push(cm, next_addr);
 288   klass->InstanceKlass::oop_pc_follow_contents(obj, cm);
 289 }
 290 
 291 
 292 void InstanceRefKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
 293   if (UseCompressedOops) {
 294     oop_pc_follow_contents_specialized<narrowOop>(this, obj, cm);
 295   } else {
 296     oop_pc_follow_contents_specialized<oop>(this, obj, cm);
 297   }
 298 }
 299 
 300 void ObjArrayKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
 301   PSParallelCompact::follow_klass(cm, this);
 302 
 303   if (UseCompressedOops) {
 304     oop_pc_follow_contents_specialized<narrowOop>(this, obj, 0, cm);
 305   } else {
 306     oop_pc_follow_contents_specialized<oop>(this, obj, 0, cm);
 307   }
 308 }
 309 
 310 void TypeArrayKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
 311   assert(obj->is_typeArray(),"must be a type array");
 312   // Performance tweak: We skip iterating over the klass pointer since we
 313   // know that Universe::TypeArrayKlass never moves.
 314 }
 315 
 316 void ParCompactionManager::follow_marking_stacks() {
 317   do {
 318     // Drain the overflow stack first, to allow stealing from the marking stack.
 319     oop obj;
 320     while (marking_stack()->pop_overflow(obj)) {
 321       follow_contents(obj);
 322     }
 323     while (marking_stack()->pop_local(obj)) {
 324       follow_contents(obj);
 325     }
 326 
 327     // Process ObjArrays one at a time to avoid marking stack bloat.
 328     ObjArrayTask task;
 329     if (_objarray_stack.pop_overflow(task) || _objarray_stack.pop_local(task)) {
 330       follow_contents((objArrayOop)task.obj(), task.index());
 331     }
 332   } while (!marking_stacks_empty());
 333 
< prev index next >