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

Thu, 22 Sep 2011 10:57:37 -0700

author
johnc
date
Thu, 22 Sep 2011 10:57:37 -0700
changeset 3175
4dfb2df418f2
parent 3115
c2bf0120ee5d
child 3294
bca17e38de00
permissions
-rw-r--r--

6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp

duke@435 1 /*
trims@2708 2 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #include "precompiled.hpp"
stefank@2314 26 #include "classfile/systemDictionary.hpp"
stefank@2314 27 #include "code/codeCache.hpp"
stefank@2314 28 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
stefank@2314 29 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
stefank@2314 30 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
stefank@2314 31 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
stefank@2314 32 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
jcoomes@2661 33 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
stefank@2314 34 #include "gc_implementation/parallelScavenge/psTasks.hpp"
stefank@2314 35 #include "memory/iterator.hpp"
stefank@2314 36 #include "memory/universe.hpp"
stefank@2314 37 #include "oops/oop.inline.hpp"
stefank@2314 38 #include "oops/oop.psgc.inline.hpp"
stefank@2314 39 #include "runtime/fprofiler.hpp"
stefank@2314 40 #include "runtime/thread.hpp"
stefank@2314 41 #include "runtime/vmThread.hpp"
stefank@2314 42 #include "services/management.hpp"
stefank@2314 43 #include "utilities/taskqueue.hpp"
duke@435 44
duke@435 45 //
duke@435 46 // ScavengeRootsTask
duke@435 47 //
duke@435 48
duke@435 49 void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
duke@435 50 assert(Universe::heap()->is_gc_active(), "called outside gc");
duke@435 51
duke@435 52 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
duke@435 53 PSScavengeRootsClosure roots_closure(pm);
duke@435 54
duke@435 55 switch (_root_type) {
duke@435 56 case universe:
duke@435 57 Universe::oops_do(&roots_closure);
duke@435 58 break;
duke@435 59
duke@435 60 case jni_handles:
duke@435 61 JNIHandles::oops_do(&roots_closure);
duke@435 62 break;
duke@435 63
duke@435 64 case threads:
duke@435 65 {
duke@435 66 ResourceMark rm;
jrose@1424 67 Threads::oops_do(&roots_closure, NULL);
duke@435 68 }
duke@435 69 break;
duke@435 70
duke@435 71 case object_synchronizer:
duke@435 72 ObjectSynchronizer::oops_do(&roots_closure);
duke@435 73 break;
duke@435 74
duke@435 75 case flat_profiler:
duke@435 76 FlatProfiler::oops_do(&roots_closure);
duke@435 77 break;
duke@435 78
duke@435 79 case system_dictionary:
duke@435 80 SystemDictionary::oops_do(&roots_closure);
duke@435 81 break;
duke@435 82
duke@435 83 case management:
duke@435 84 Management::oops_do(&roots_closure);
duke@435 85 break;
duke@435 86
duke@435 87 case jvmti:
duke@435 88 JvmtiExport::oops_do(&roots_closure);
duke@435 89 break;
duke@435 90
jrose@1424 91
jrose@1424 92 case code_cache:
jrose@1424 93 {
jrose@1424 94 CodeBlobToOopClosure each_scavengable_code_blob(&roots_closure, /*do_marking=*/ true);
jrose@1424 95 CodeCache::scavenge_root_nmethods_do(&each_scavengable_code_blob);
jrose@1424 96 }
jrose@1424 97 break;
jrose@1424 98
duke@435 99 default:
duke@435 100 fatal("Unknown root type");
duke@435 101 }
duke@435 102
duke@435 103 // Do the real work
duke@435 104 pm->drain_stacks(false);
duke@435 105 }
duke@435 106
duke@435 107 //
duke@435 108 // ThreadRootsTask
duke@435 109 //
duke@435 110
duke@435 111 void ThreadRootsTask::do_it(GCTaskManager* manager, uint which) {
duke@435 112 assert(Universe::heap()->is_gc_active(), "called outside gc");
duke@435 113
duke@435 114 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
duke@435 115 PSScavengeRootsClosure roots_closure(pm);
jrose@1424 116 CodeBlobToOopClosure roots_in_blobs(&roots_closure, /*do_marking=*/ true);
duke@435 117
duke@435 118 if (_java_thread != NULL)
jrose@1424 119 _java_thread->oops_do(&roots_closure, &roots_in_blobs);
duke@435 120
duke@435 121 if (_vm_thread != NULL)
jrose@1424 122 _vm_thread->oops_do(&roots_closure, &roots_in_blobs);
duke@435 123
duke@435 124 // Do the real work
duke@435 125 pm->drain_stacks(false);
duke@435 126 }
duke@435 127
duke@435 128 //
duke@435 129 // StealTask
duke@435 130 //
duke@435 131
duke@435 132 StealTask::StealTask(ParallelTaskTerminator* t) :
duke@435 133 _terminator(t) {}
duke@435 134
duke@435 135 void StealTask::do_it(GCTaskManager* manager, uint which) {
duke@435 136 assert(Universe::heap()->is_gc_active(), "called outside gc");
duke@435 137
duke@435 138 PSPromotionManager* pm =
duke@435 139 PSPromotionManager::gc_thread_promotion_manager(which);
duke@435 140 pm->drain_stacks(true);
duke@435 141 guarantee(pm->stacks_empty(),
duke@435 142 "stacks should be empty at this point");
duke@435 143
duke@435 144 int random_seed = 17;
tonyp@2061 145 while(true) {
tonyp@2061 146 StarTask p;
tonyp@2061 147 if (PSPromotionManager::steal_depth(which, &random_seed, p)) {
tonyp@2061 148 TASKQUEUE_STATS_ONLY(pm->record_steal(p));
tonyp@2061 149 pm->process_popped_location_depth(p);
tonyp@2061 150 pm->drain_stacks_depth(true);
tonyp@2061 151 } else {
tonyp@2061 152 if (terminator()->offer_termination()) {
tonyp@2061 153 break;
duke@435 154 }
duke@435 155 }
duke@435 156 }
coleenp@548 157 guarantee(pm->stacks_empty(), "stacks should be empty at this point");
duke@435 158 }
duke@435 159
duke@435 160 //
duke@435 161 // SerialOldToYoungRootsTask
duke@435 162 //
duke@435 163
duke@435 164 void SerialOldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
duke@435 165 assert(_gen != NULL, "Sanity");
duke@435 166 assert(_gen->object_space()->contains(_gen_top) || _gen_top == _gen->object_space()->top(), "Sanity");
duke@435 167
duke@435 168 {
duke@435 169 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
duke@435 170
duke@435 171 assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
duke@435 172 CardTableExtension* card_table = (CardTableExtension *)Universe::heap()->barrier_set();
duke@435 173 // FIX ME! Assert that card_table is the type we believe it to be.
duke@435 174
duke@435 175 card_table->scavenge_contents(_gen->start_array(),
duke@435 176 _gen->object_space(),
duke@435 177 _gen_top,
duke@435 178 pm);
duke@435 179
duke@435 180 // Do the real work
duke@435 181 pm->drain_stacks(false);
duke@435 182 }
duke@435 183 }
duke@435 184
duke@435 185 //
duke@435 186 // OldToYoungRootsTask
duke@435 187 //
duke@435 188
duke@435 189 void OldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
duke@435 190 assert(_gen != NULL, "Sanity");
duke@435 191 assert(_gen->object_space()->contains(_gen_top) || _gen_top == _gen->object_space()->top(), "Sanity");
duke@435 192 assert(_stripe_number < ParallelGCThreads, "Sanity");
duke@435 193
duke@435 194 {
duke@435 195 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
duke@435 196
duke@435 197 assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
duke@435 198 CardTableExtension* card_table = (CardTableExtension *)Universe::heap()->barrier_set();
duke@435 199 // FIX ME! Assert that card_table is the type we believe it to be.
duke@435 200
duke@435 201 card_table->scavenge_contents_parallel(_gen->start_array(),
duke@435 202 _gen->object_space(),
duke@435 203 _gen_top,
duke@435 204 pm,
duke@435 205 _stripe_number);
duke@435 206
duke@435 207 // Do the real work
duke@435 208 pm->drain_stacks(false);
duke@435 209 }
duke@435 210 }

mercurial