0N/A/*
3198N/A * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A * or visit www.oracle.com if you need additional information or have any
1472N/A * questions.
0N/A *
0N/A */
0N/A
1879N/A#include "precompiled.hpp"
1879N/A#include "classfile/systemDictionary.hpp"
1879N/A#include "code/codeCache.hpp"
1879N/A#include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
1879N/A#include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
1879N/A#include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
1879N/A#include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
1879N/A#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
2226N/A#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
1879N/A#include "gc_implementation/parallelScavenge/psTasks.hpp"
1879N/A#include "memory/iterator.hpp"
1879N/A#include "memory/universe.hpp"
1879N/A#include "oops/oop.inline.hpp"
1879N/A#include "oops/oop.psgc.inline.hpp"
1879N/A#include "runtime/fprofiler.hpp"
1879N/A#include "runtime/thread.hpp"
1879N/A#include "runtime/vmThread.hpp"
1879N/A#include "services/management.hpp"
1879N/A#include "utilities/taskqueue.hpp"
0N/A
0N/A//
0N/A// ScavengeRootsTask
0N/A//
0N/A
0N/Avoid ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
0N/A assert(Universe::heap()->is_gc_active(), "called outside gc");
0N/A
0N/A PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
0N/A PSScavengeRootsClosure roots_closure(pm);
3198N/A PSPromoteRootsClosure roots_to_old_closure(pm);
0N/A
0N/A switch (_root_type) {
0N/A case universe:
0N/A Universe::oops_do(&roots_closure);
0N/A break;
0N/A
0N/A case jni_handles:
0N/A JNIHandles::oops_do(&roots_closure);
0N/A break;
0N/A
0N/A case threads:
0N/A {
0N/A ResourceMark rm;
989N/A Threads::oops_do(&roots_closure, NULL);
0N/A }
0N/A break;
0N/A
0N/A case object_synchronizer:
0N/A ObjectSynchronizer::oops_do(&roots_closure);
0N/A break;
0N/A
0N/A case flat_profiler:
0N/A FlatProfiler::oops_do(&roots_closure);
0N/A break;
0N/A
0N/A case system_dictionary:
0N/A SystemDictionary::oops_do(&roots_closure);
0N/A break;
0N/A
0N/A case management:
0N/A Management::oops_do(&roots_closure);
0N/A break;
0N/A
0N/A case jvmti:
0N/A JvmtiExport::oops_do(&roots_closure);
0N/A break;
0N/A
989N/A
989N/A case code_cache:
989N/A {
3198N/A CodeBlobToOopClosure each_scavengable_code_blob(&roots_to_old_closure, /*do_marking=*/ true);
989N/A CodeCache::scavenge_root_nmethods_do(&each_scavengable_code_blob);
989N/A }
989N/A break;
989N/A
0N/A default:
0N/A fatal("Unknown root type");
0N/A }
0N/A
0N/A // Do the real work
0N/A pm->drain_stacks(false);
0N/A}
0N/A
0N/A//
0N/A// ThreadRootsTask
0N/A//
0N/A
0N/Avoid ThreadRootsTask::do_it(GCTaskManager* manager, uint which) {
0N/A assert(Universe::heap()->is_gc_active(), "called outside gc");
0N/A
0N/A PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
0N/A PSScavengeRootsClosure roots_closure(pm);
989N/A CodeBlobToOopClosure roots_in_blobs(&roots_closure, /*do_marking=*/ true);
0N/A
0N/A if (_java_thread != NULL)
989N/A _java_thread->oops_do(&roots_closure, &roots_in_blobs);
0N/A
0N/A if (_vm_thread != NULL)
989N/A _vm_thread->oops_do(&roots_closure, &roots_in_blobs);
0N/A
0N/A // Do the real work
0N/A pm->drain_stacks(false);
0N/A}
0N/A
0N/A//
0N/A// StealTask
0N/A//
0N/A
0N/AStealTask::StealTask(ParallelTaskTerminator* t) :
0N/A _terminator(t) {}
0N/A
0N/Avoid StealTask::do_it(GCTaskManager* manager, uint which) {
0N/A assert(Universe::heap()->is_gc_active(), "called outside gc");
0N/A
0N/A PSPromotionManager* pm =
0N/A PSPromotionManager::gc_thread_promotion_manager(which);
0N/A pm->drain_stacks(true);
0N/A guarantee(pm->stacks_empty(),
0N/A "stacks should be empty at this point");
0N/A
0N/A int random_seed = 17;
1626N/A while(true) {
1626N/A StarTask p;
1626N/A if (PSPromotionManager::steal_depth(which, &random_seed, p)) {
1626N/A TASKQUEUE_STATS_ONLY(pm->record_steal(p));
1626N/A pm->process_popped_location_depth(p);
1626N/A pm->drain_stacks_depth(true);
1626N/A } else {
1626N/A if (terminator()->offer_termination()) {
1626N/A break;
0N/A }
0N/A }
0N/A }
113N/A guarantee(pm->stacks_empty(), "stacks should be empty at this point");
0N/A}
0N/A
0N/A//
0N/A// SerialOldToYoungRootsTask
0N/A//
0N/A
0N/Avoid SerialOldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
0N/A assert(_gen != NULL, "Sanity");
0N/A assert(_gen->object_space()->contains(_gen_top) || _gen_top == _gen->object_space()->top(), "Sanity");
0N/A
0N/A {
0N/A PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
0N/A
0N/A assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
0N/A CardTableExtension* card_table = (CardTableExtension *)Universe::heap()->barrier_set();
0N/A // FIX ME! Assert that card_table is the type we believe it to be.
0N/A
0N/A card_table->scavenge_contents(_gen->start_array(),
0N/A _gen->object_space(),
0N/A _gen_top,
0N/A pm);
0N/A
0N/A // Do the real work
0N/A pm->drain_stacks(false);
0N/A }
0N/A}
0N/A
0N/A//
0N/A// OldToYoungRootsTask
0N/A//
0N/A
0N/Avoid OldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
0N/A assert(_gen != NULL, "Sanity");
0N/A assert(_gen->object_space()->contains(_gen_top) || _gen_top == _gen->object_space()->top(), "Sanity");
0N/A assert(_stripe_number < ParallelGCThreads, "Sanity");
0N/A
0N/A {
0N/A PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
0N/A
0N/A assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
0N/A CardTableExtension* card_table = (CardTableExtension *)Universe::heap()->barrier_set();
0N/A // FIX ME! Assert that card_table is the type we believe it to be.
0N/A
0N/A card_table->scavenge_contents_parallel(_gen->start_array(),
0N/A _gen->object_space(),
0N/A _gen_top,
0N/A pm,
2941N/A _stripe_number,
2941N/A _stripe_total);
0N/A
0N/A // Do the real work
0N/A pm->drain_stacks(false);
0N/A }
0N/A}