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

Fri, 16 Jul 2010 21:33:21 -0700

author
jcoomes
date
Fri, 16 Jul 2010 21:33:21 -0700
changeset 2020
a93a9eda13f7
parent 1993
b2a00dd3117c
child 2191
894b1d7c7e01
permissions
-rw-r--r--

6962947: shared TaskQueue statistics
Reviewed-by: tonyp, ysr

     1 /*
     2  * Copyright (c) 2005, 2010, 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 #include "incls/_precompiled.incl"
    26 #include "incls/_psCompactionManager.cpp.incl"
    28 PSOldGen*            ParCompactionManager::_old_gen = NULL;
    29 ParCompactionManager**  ParCompactionManager::_manager_array = NULL;
    30 OopTaskQueueSet*     ParCompactionManager::_stack_array = NULL;
    31 ParCompactionManager::ObjArrayTaskQueueSet*
    32   ParCompactionManager::_objarray_queues = NULL;
    33 ObjectStartArray*    ParCompactionManager::_start_array = NULL;
    34 ParMarkBitMap*       ParCompactionManager::_mark_bitmap = NULL;
    35 RegionTaskQueueSet*  ParCompactionManager::_region_array = NULL;
    37 ParCompactionManager::ParCompactionManager() :
    38     _action(CopyAndUpdate) {
    40   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
    41   assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
    43   _old_gen = heap->old_gen();
    44   _start_array = old_gen()->start_array();
    46   marking_stack()->initialize();
    47   _objarray_stack.initialize();
    48   region_stack()->initialize();
    50   // Note that _revisit_klass_stack is allocated out of the
    51   // C heap (as opposed to out of ResourceArena).
    52   int size =
    53     (SystemDictionary::number_of_classes() * 2) * 2 / ParallelGCThreads;
    54   _revisit_klass_stack = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(size, true);
    55   // From some experiments (#klass/k)^2 for k = 10 seems a better fit, but this will
    56   // have to do for now until we are able to investigate a more optimal setting.
    57   _revisit_mdo_stack = new (ResourceObj::C_HEAP) GrowableArray<DataLayout*>(size*2, true);
    58 }
    60 ParCompactionManager::~ParCompactionManager() {
    61   delete _revisit_klass_stack;
    62   delete _revisit_mdo_stack;
    63   // _manager_array and _stack_array are statics
    64   // shared with all instances of ParCompactionManager
    65   // should not be deallocated.
    66 }
    68 void ParCompactionManager::initialize(ParMarkBitMap* mbm) {
    69   assert(PSParallelCompact::gc_task_manager() != NULL,
    70     "Needed for initialization");
    72   _mark_bitmap = mbm;
    74   uint parallel_gc_threads = PSParallelCompact::gc_task_manager()->workers();
    76   assert(_manager_array == NULL, "Attempt to initialize twice");
    77   _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1 );
    78   guarantee(_manager_array != NULL, "Could not allocate manager_array");
    80   _stack_array = new OopTaskQueueSet(parallel_gc_threads);
    81   guarantee(_stack_array != NULL, "Could not allocate stack_array");
    82   _objarray_queues = new ObjArrayTaskQueueSet(parallel_gc_threads);
    83   guarantee(_objarray_queues != NULL, "Could not allocate objarray_queues");
    84   _region_array = new RegionTaskQueueSet(parallel_gc_threads);
    85   guarantee(_region_array != NULL, "Could not allocate region_array");
    87   // Create and register the ParCompactionManager(s) for the worker threads.
    88   for(uint i=0; i<parallel_gc_threads; i++) {
    89     _manager_array[i] = new ParCompactionManager();
    90     guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager");
    91     stack_array()->register_queue(i, _manager_array[i]->marking_stack());
    92     _objarray_queues->register_queue(i, &_manager_array[i]->_objarray_stack);
    93     region_array()->register_queue(i, _manager_array[i]->region_stack());
    94   }
    96   // The VMThread gets its own ParCompactionManager, which is not available
    97   // for work stealing.
    98   _manager_array[parallel_gc_threads] = new ParCompactionManager();
    99   guarantee(_manager_array[parallel_gc_threads] != NULL,
   100     "Could not create ParCompactionManager");
   101   assert(PSParallelCompact::gc_task_manager()->workers() != 0,
   102     "Not initialized?");
   103 }
   105 bool ParCompactionManager::should_update() {
   106   assert(action() != NotValid, "Action is not set");
   107   return (action() == ParCompactionManager::Update) ||
   108          (action() == ParCompactionManager::CopyAndUpdate) ||
   109          (action() == ParCompactionManager::UpdateAndCopy);
   110 }
   112 bool ParCompactionManager::should_copy() {
   113   assert(action() != NotValid, "Action is not set");
   114   return (action() == ParCompactionManager::Copy) ||
   115          (action() == ParCompactionManager::CopyAndUpdate) ||
   116          (action() == ParCompactionManager::UpdateAndCopy);
   117 }
   119 bool ParCompactionManager::should_verify_only() {
   120   assert(action() != NotValid, "Action is not set");
   121   return action() == ParCompactionManager::VerifyUpdate;
   122 }
   124 bool ParCompactionManager::should_reset_only() {
   125   assert(action() != NotValid, "Action is not set");
   126   return action() == ParCompactionManager::ResetObjects;
   127 }
   129 ParCompactionManager*
   130 ParCompactionManager::gc_thread_compaction_manager(int index) {
   131   assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range");
   132   assert(_manager_array != NULL, "Sanity");
   133   return _manager_array[index];
   134 }
   136 void ParCompactionManager::reset() {
   137   for(uint i=0; i<ParallelGCThreads+1; i++) {
   138     manager_array(i)->revisit_klass_stack()->clear();
   139     manager_array(i)->revisit_mdo_stack()->clear();
   140   }
   141 }
   143 void ParCompactionManager::follow_marking_stacks() {
   144   do {
   145     // Drain the overflow stack first, to allow stealing from the marking stack.
   146     oop obj;
   147     while (marking_stack()->pop_overflow(obj)) {
   148       obj->follow_contents(this);
   149     }
   150     while (marking_stack()->pop_local(obj)) {
   151       obj->follow_contents(this);
   152     }
   154     // Process ObjArrays one at a time to avoid marking stack bloat.
   155     ObjArrayTask task;
   156     if (_objarray_stack.pop_overflow(task)) {
   157       objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
   158       k->oop_follow_contents(this, task.obj(), task.index());
   159     } else if (_objarray_stack.pop_local(task)) {
   160       objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
   161       k->oop_follow_contents(this, task.obj(), task.index());
   162     }
   163   } while (!marking_stacks_empty());
   165   assert(marking_stacks_empty(), "Sanity");
   166 }
   168 void ParCompactionManager::drain_region_stacks() {
   169   do {
   170     // Drain overflow stack first so other threads can steal.
   171     size_t region_index;
   172     while (region_stack()->pop_overflow(region_index)) {
   173       PSParallelCompact::fill_and_update_region(this, region_index);
   174     }
   176     while (region_stack()->pop_local(region_index)) {
   177       PSParallelCompact::fill_and_update_region(this, region_index);
   178     }
   179   } while (!region_stack()->is_empty());
   180 }
   182 #ifdef ASSERT
   183 bool ParCompactionManager::stacks_have_been_allocated() {
   184   return (revisit_klass_stack()->data_addr() != NULL &&
   185           revisit_mdo_stack()->data_addr() != NULL);
   186 }
   187 #endif

mercurial