src/share/vm/memory/sharedHeap.cpp
Print this page
rev 4735 : 8015237: Parallelize string table scanning during strong root processing
Summary: Parallelize the scanning of the intern string table by having each GC worker claim a given number of buckets.
Reviewed-by:
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
@@ -44,11 +44,10 @@
SH_PS_ObjectSynchronizer_oops_do,
SH_PS_FlatProfiler_oops_do,
SH_PS_Management_oops_do,
SH_PS_SystemDictionary_oops_do,
SH_PS_jvmti_oops_do,
- SH_PS_StringTable_oops_do,
SH_PS_CodeCache_oops_do,
// Leave this one last.
SH_PS_NumElements
};
@@ -124,10 +123,12 @@
SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* outer, bool activate)
: MarkScope(activate)
{
if (_active) {
outer->change_strong_roots_parity();
+ // Zero the claimed high water mark in the StringTable
+ StringTable::clear_par_claimed_index();
}
}
SharedHeap::StrongRootsScope::~StrongRootsScope() {
// nothing particular
@@ -136,11 +137,12 @@
void SharedHeap::process_strong_roots(bool activate_scope,
bool is_scavenging,
ScanningOption so,
OopClosure* roots,
CodeBlobClosure* code_roots,
- KlassClosure* klass_closure) {
+ KlassClosure* klass_closure,
+ uint worker_id) {
StrongRootsScope srs(this, activate_scope);
// General strong roots.
assert(_strong_roots_parity != 0, "must have called prologue code");
// _n_termination for _process_strong_tasks should be set up stream
@@ -151,18 +153,20 @@
Universe::oops_do(roots);
}
// Global (strong) JNI handles
if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
JNIHandles::oops_do(roots);
+
// All threads execute this; the individual threads are task groups.
CLDToOopClosure roots_from_clds(roots);
CLDToOopClosure* roots_from_clds_p = (is_scavenging ? NULL : &roots_from_clds);
- if (ParallelGCThreads > 0) {
+ if (CollectedHeap::use_parallel_gc_threads()) {
Threads::possibly_parallel_oops_do(roots, roots_from_clds_p ,code_roots);
} else {
Threads::oops_do(roots, roots_from_clds_p, code_roots);
}
+
if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do))
ObjectSynchronizer::oops_do(roots);
if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do))
FlatProfiler::oops_do(roots);
if (!_process_strong_tasks->is_task_claimed(SH_PS_Management_oops_do))
@@ -180,12 +184,17 @@
} else {
fatal("We should always have selected either SO_AllClasses or SO_SystemClasses");
}
}
- if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
+ // All threads execute the following. A specific chunk of buckets
+ // from the StringTable are the individual tasks.
if (so & SO_Strings) {
+ if (CollectedHeap::use_parallel_gc_threads()) {
+ StringTable::possibly_parallel_oops_do(roots, worker_id);
+ } else {
+ assert(worker_id == 0, "only worker 0 for serial work");
StringTable::oops_do(roots);
}
}
if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {