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

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,211 @@
     1.4 +/*
     1.5 + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#include "precompiled.hpp"
    1.29 +#include "classfile/systemDictionary.hpp"
    1.30 +#include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
    1.31 +#include "gc_implementation/parallelScavenge/objectStartArray.hpp"
    1.32 +#include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
    1.33 +#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
    1.34 +#include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
    1.35 +#include "gc_implementation/parallelScavenge/psOldGen.hpp"
    1.36 +#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
    1.37 +#include "oops/objArrayKlass.inline.hpp"
    1.38 +#include "oops/oop.inline.hpp"
    1.39 +#include "oops/oop.pcgc.inline.hpp"
    1.40 +#include "utilities/stack.inline.hpp"
    1.41 +
    1.42 +PSOldGen*            ParCompactionManager::_old_gen = NULL;
    1.43 +ParCompactionManager**  ParCompactionManager::_manager_array = NULL;
    1.44 +
    1.45 +RegionTaskQueue**              ParCompactionManager::_region_list = NULL;
    1.46 +
    1.47 +OopTaskQueueSet*     ParCompactionManager::_stack_array = NULL;
    1.48 +ParCompactionManager::ObjArrayTaskQueueSet*
    1.49 +  ParCompactionManager::_objarray_queues = NULL;
    1.50 +ObjectStartArray*    ParCompactionManager::_start_array = NULL;
    1.51 +ParMarkBitMap*       ParCompactionManager::_mark_bitmap = NULL;
    1.52 +RegionTaskQueueSet*  ParCompactionManager::_region_array = NULL;
    1.53 +
    1.54 +uint*                 ParCompactionManager::_recycled_stack_index = NULL;
    1.55 +int                   ParCompactionManager::_recycled_top = -1;
    1.56 +int                   ParCompactionManager::_recycled_bottom = -1;
    1.57 +
    1.58 +ParCompactionManager::ParCompactionManager() :
    1.59 +    _action(CopyAndUpdate),
    1.60 +    _region_stack(NULL),
    1.61 +    _region_stack_index((uint)max_uintx) {
    1.62 +
    1.63 +  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
    1.64 +  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
    1.65 +
    1.66 +  _old_gen = heap->old_gen();
    1.67 +  _start_array = old_gen()->start_array();
    1.68 +
    1.69 +  marking_stack()->initialize();
    1.70 +  _objarray_stack.initialize();
    1.71 +}
    1.72 +
    1.73 +ParCompactionManager::~ParCompactionManager() {
    1.74 +  delete _recycled_stack_index;
    1.75 +}
    1.76 +
    1.77 +void ParCompactionManager::initialize(ParMarkBitMap* mbm) {
    1.78 +  assert(PSParallelCompact::gc_task_manager() != NULL,
    1.79 +    "Needed for initialization");
    1.80 +
    1.81 +  _mark_bitmap = mbm;
    1.82 +
    1.83 +  uint parallel_gc_threads = PSParallelCompact::gc_task_manager()->workers();
    1.84 +
    1.85 +  assert(_manager_array == NULL, "Attempt to initialize twice");
    1.86 +  _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1, mtGC);
    1.87 +  guarantee(_manager_array != NULL, "Could not allocate manager_array");
    1.88 +
    1.89 +  _region_list = NEW_C_HEAP_ARRAY(RegionTaskQueue*,
    1.90 +                         parallel_gc_threads+1, mtGC);
    1.91 +  guarantee(_region_list != NULL, "Could not initialize promotion manager");
    1.92 +
    1.93 +  _recycled_stack_index = NEW_C_HEAP_ARRAY(uint, parallel_gc_threads, mtGC);
    1.94 +
    1.95 +  // parallel_gc-threads + 1 to be consistent with the number of
    1.96 +  // compaction managers.
    1.97 +  for(uint i=0; i<parallel_gc_threads + 1; i++) {
    1.98 +    _region_list[i] = new RegionTaskQueue();
    1.99 +    region_list(i)->initialize();
   1.100 +  }
   1.101 +
   1.102 +  _stack_array = new OopTaskQueueSet(parallel_gc_threads);
   1.103 +  guarantee(_stack_array != NULL, "Could not allocate stack_array");
   1.104 +  _objarray_queues = new ObjArrayTaskQueueSet(parallel_gc_threads);
   1.105 +  guarantee(_objarray_queues != NULL, "Could not allocate objarray_queues");
   1.106 +  _region_array = new RegionTaskQueueSet(parallel_gc_threads);
   1.107 +  guarantee(_region_array != NULL, "Could not allocate region_array");
   1.108 +
   1.109 +  // Create and register the ParCompactionManager(s) for the worker threads.
   1.110 +  for(uint i=0; i<parallel_gc_threads; i++) {
   1.111 +    _manager_array[i] = new ParCompactionManager();
   1.112 +    guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager");
   1.113 +    stack_array()->register_queue(i, _manager_array[i]->marking_stack());
   1.114 +    _objarray_queues->register_queue(i, &_manager_array[i]->_objarray_stack);
   1.115 +    region_array()->register_queue(i, region_list(i));
   1.116 +  }
   1.117 +
   1.118 +  // The VMThread gets its own ParCompactionManager, which is not available
   1.119 +  // for work stealing.
   1.120 +  _manager_array[parallel_gc_threads] = new ParCompactionManager();
   1.121 +  guarantee(_manager_array[parallel_gc_threads] != NULL,
   1.122 +    "Could not create ParCompactionManager");
   1.123 +  assert(PSParallelCompact::gc_task_manager()->workers() != 0,
   1.124 +    "Not initialized?");
   1.125 +}
   1.126 +
   1.127 +int ParCompactionManager::pop_recycled_stack_index() {
   1.128 +  assert(_recycled_bottom <= _recycled_top, "list is empty");
   1.129 +  // Get the next available index
   1.130 +  if (_recycled_bottom < _recycled_top) {
   1.131 +    uint cur, next, last;
   1.132 +    do {
   1.133 +      cur = _recycled_bottom;
   1.134 +      next = cur + 1;
   1.135 +      last = Atomic::cmpxchg(next, &_recycled_bottom, cur);
   1.136 +    } while (cur != last);
   1.137 +    return _recycled_stack_index[next];
   1.138 +  } else {
   1.139 +    return -1;
   1.140 +  }
   1.141 +}
   1.142 +
   1.143 +void ParCompactionManager::push_recycled_stack_index(uint v) {
   1.144 +  // Get the next available index
   1.145 +  int cur = Atomic::add(1, &_recycled_top);
   1.146 +  _recycled_stack_index[cur] = v;
   1.147 +  assert(_recycled_bottom <= _recycled_top, "list top and bottom are wrong");
   1.148 +}
   1.149 +
   1.150 +bool ParCompactionManager::should_update() {
   1.151 +  assert(action() != NotValid, "Action is not set");
   1.152 +  return (action() == ParCompactionManager::Update) ||
   1.153 +         (action() == ParCompactionManager::CopyAndUpdate) ||
   1.154 +         (action() == ParCompactionManager::UpdateAndCopy);
   1.155 +}
   1.156 +
   1.157 +bool ParCompactionManager::should_copy() {
   1.158 +  assert(action() != NotValid, "Action is not set");
   1.159 +  return (action() == ParCompactionManager::Copy) ||
   1.160 +         (action() == ParCompactionManager::CopyAndUpdate) ||
   1.161 +         (action() == ParCompactionManager::UpdateAndCopy);
   1.162 +}
   1.163 +
   1.164 +void ParCompactionManager::region_list_push(uint list_index,
   1.165 +                                            size_t region_index) {
   1.166 +  region_list(list_index)->push(region_index);
   1.167 +}
   1.168 +
   1.169 +void ParCompactionManager::verify_region_list_empty(uint list_index) {
   1.170 +  assert(region_list(list_index)->is_empty(), "Not empty");
   1.171 +}
   1.172 +
   1.173 +ParCompactionManager*
   1.174 +ParCompactionManager::gc_thread_compaction_manager(int index) {
   1.175 +  assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range");
   1.176 +  assert(_manager_array != NULL, "Sanity");
   1.177 +  return _manager_array[index];
   1.178 +}
   1.179 +
   1.180 +void ParCompactionManager::follow_marking_stacks() {
   1.181 +  do {
   1.182 +    // Drain the overflow stack first, to allow stealing from the marking stack.
   1.183 +    oop obj;
   1.184 +    while (marking_stack()->pop_overflow(obj)) {
   1.185 +      obj->follow_contents(this);
   1.186 +    }
   1.187 +    while (marking_stack()->pop_local(obj)) {
   1.188 +      obj->follow_contents(this);
   1.189 +    }
   1.190 +
   1.191 +    // Process ObjArrays one at a time to avoid marking stack bloat.
   1.192 +    ObjArrayTask task;
   1.193 +    if (_objarray_stack.pop_overflow(task) || _objarray_stack.pop_local(task)) {
   1.194 +      ObjArrayKlass* k = (ObjArrayKlass*)task.obj()->klass();
   1.195 +      k->oop_follow_contents(this, task.obj(), task.index());
   1.196 +    }
   1.197 +  } while (!marking_stacks_empty());
   1.198 +
   1.199 +  assert(marking_stacks_empty(), "Sanity");
   1.200 +}
   1.201 +
   1.202 +void ParCompactionManager::drain_region_stacks() {
   1.203 +  do {
   1.204 +    // Drain overflow stack first so other threads can steal.
   1.205 +    size_t region_index;
   1.206 +    while (region_stack()->pop_overflow(region_index)) {
   1.207 +      PSParallelCompact::fill_and_update_region(this, region_index);
   1.208 +    }
   1.209 +
   1.210 +    while (region_stack()->pop_local(region_index)) {
   1.211 +      PSParallelCompact::fill_and_update_region(this, region_index);
   1.212 +    }
   1.213 +  } while (!region_stack()->is_empty());
   1.214 +}

mercurial