8248132: ZGC: Unify handling of all OopStorage instances in root processing
Reviewed-by: pliden, kbarrett, tschatzl
This commit is contained in:
parent
a1f02d13e5
commit
156f6174ed
46
src/hotspot/share/gc/shared/oopStorageSetParState.hpp
Normal file
46
src/hotspot/share/gc/shared/oopStorageSetParState.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_GC_SHARED_OOPSTORAGESETPARSTATE_HPP
|
||||
#define SHARE_GC_SHARED_OOPSTORAGESETPARSTATE_HPP
|
||||
|
||||
#include "gc/shared/oopStorageParState.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "utilities/valueObjArray.hpp"
|
||||
|
||||
template <bool concurrent, bool is_const>
|
||||
class OopStorageSetStrongParState {
|
||||
typedef OopStorage::ParState<concurrent, is_const> ParStateType;
|
||||
typedef ValueObjArray<ParStateType, OopStorageSet::strong_count> ParStateArray;
|
||||
|
||||
ParStateArray _par_states;
|
||||
|
||||
public:
|
||||
OopStorageSetStrongParState();
|
||||
|
||||
template <typename Closure>
|
||||
void oops_do(Closure* cl);
|
||||
};
|
||||
|
||||
#endif // SHARE_GC_SHARED_OOPSTORAGESETPARSTATE_HPP
|
46
src/hotspot/share/gc/shared/oopStorageSetParState.inline.hpp
Normal file
46
src/hotspot/share/gc/shared/oopStorageSetParState.inline.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_GC_SHARED_OOPSTORAGESETPARSTATE_INLINE_HPP
|
||||
#define SHARE_GC_SHARED_OOPSTORAGESETPARSTATE_INLINE_HPP
|
||||
|
||||
#include "gc/shared/oopStorageParState.inline.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "gc/shared/oopStorageSetParState.hpp"
|
||||
|
||||
template <bool concurrent, bool is_const>
|
||||
OopStorageSetStrongParState<concurrent, is_const>::OopStorageSetStrongParState() :
|
||||
_par_states(OopStorageSet::strong_iterator()) {
|
||||
}
|
||||
|
||||
template <bool concurrent, bool is_const>
|
||||
template <typename Closure>
|
||||
void OopStorageSetStrongParState<concurrent, is_const>::oops_do(Closure* cl) {
|
||||
for (int i = 0; i < _par_states.count(); i++) {
|
||||
_par_states.at(i)->oops_do(cl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // SHARE_GC_SHARED_OOPSTORAGESETPARSTATE_INLINE_HPP
|
@ -30,7 +30,7 @@
|
||||
#include "gc/shared/barrierSetNMethod.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "gc/shared/oopStorageParState.inline.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "gc/shared/oopStorageSetParState.inline.hpp"
|
||||
#include "gc/shared/suspendibleThreadSet.hpp"
|
||||
#include "gc/z/zBarrierSetNMethod.hpp"
|
||||
#include "gc/z/zGlobals.hpp"
|
||||
@ -70,8 +70,7 @@ static const ZStatSubPhase ZSubPhasePauseRootsCodeCache("Pause Roots CodeCache")
|
||||
static const ZStatSubPhase ZSubPhaseConcurrentRootsSetup("Concurrent Roots Setup");
|
||||
static const ZStatSubPhase ZSubPhaseConcurrentRoots("Concurrent Roots");
|
||||
static const ZStatSubPhase ZSubPhaseConcurrentRootsTeardown("Concurrent Roots Teardown");
|
||||
static const ZStatSubPhase ZSubPhaseConcurrentRootsJNIHandles("Concurrent Roots JNIHandles");
|
||||
static const ZStatSubPhase ZSubPhaseConcurrentRootsVMHandles("Concurrent Roots VMHandles");
|
||||
static const ZStatSubPhase ZSubPhaseConcurrentRootsOopStorageSet("Concurrent Roots OopStorageSet");
|
||||
static const ZStatSubPhase ZSubPhaseConcurrentRootsClassLoaderDataGraph("Concurrent Roots ClassLoaderDataGraph");
|
||||
|
||||
static const ZStatSubPhase ZSubPhasePauseWeakRootsSetup("Pause Weak Roots Setup");
|
||||
@ -286,11 +285,9 @@ void ZRootsIterator::oops_do(ZRootsIteratorClosure* cl) {
|
||||
}
|
||||
|
||||
ZConcurrentRootsIterator::ZConcurrentRootsIterator(int cld_claim) :
|
||||
_jni_handles_iter(OopStorageSet::jni_global()),
|
||||
_vm_handles_iter(OopStorageSet::vm_global()),
|
||||
_oop_storage_set_iter(),
|
||||
_cld_claim(cld_claim),
|
||||
_jni_handles(this),
|
||||
_vm_handles(this),
|
||||
_oop_storage_set(this),
|
||||
_class_loader_data_graph(this) {
|
||||
ZStatTimer timer(ZSubPhaseConcurrentRootsSetup);
|
||||
ClassLoaderDataGraph::clear_claimed_marks(cld_claim);
|
||||
@ -300,14 +297,9 @@ ZConcurrentRootsIterator::~ZConcurrentRootsIterator() {
|
||||
ZStatTimer timer(ZSubPhaseConcurrentRootsTeardown);
|
||||
}
|
||||
|
||||
void ZConcurrentRootsIterator::do_jni_handles(ZRootsIteratorClosure* cl) {
|
||||
ZStatTimer timer(ZSubPhaseConcurrentRootsJNIHandles);
|
||||
_jni_handles_iter.oops_do(cl);
|
||||
}
|
||||
|
||||
void ZConcurrentRootsIterator::do_vm_handles(ZRootsIteratorClosure* cl) {
|
||||
ZStatTimer timer(ZSubPhaseConcurrentRootsVMHandles);
|
||||
_vm_handles_iter.oops_do(cl);
|
||||
void ZConcurrentRootsIterator::do_oop_storage_set(ZRootsIteratorClosure* cl) {
|
||||
ZStatTimer timer(ZSubPhaseConcurrentRootsOopStorageSet);
|
||||
_oop_storage_set_iter.oops_do(cl);
|
||||
}
|
||||
|
||||
void ZConcurrentRootsIterator::do_class_loader_data_graph(ZRootsIteratorClosure* cl) {
|
||||
@ -318,8 +310,7 @@ void ZConcurrentRootsIterator::do_class_loader_data_graph(ZRootsIteratorClosure*
|
||||
|
||||
void ZConcurrentRootsIterator::oops_do(ZRootsIteratorClosure* cl) {
|
||||
ZStatTimer timer(ZSubPhaseConcurrentRoots);
|
||||
_jni_handles.oops_do(cl);
|
||||
_vm_handles.oops_do(cl),
|
||||
_oop_storage_set.oops_do(cl);
|
||||
_class_loader_data_graph.oops_do(cl);
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#define SHARE_GC_Z_ZROOTSITERATOR_HPP
|
||||
|
||||
#include "gc/shared/oopStorageParState.hpp"
|
||||
#include "gc/shared/oopStorageSetParState.hpp"
|
||||
#include "gc/shared/suspendibleThreadSet.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
@ -35,6 +36,7 @@
|
||||
class ZRootsIteratorClosure;
|
||||
|
||||
typedef OopStorage::ParState<true /* concurrent */, false /* is_const */> ZOopStorageIterator;
|
||||
typedef OopStorageSetStrongParState<true /* concurrent */, false /* is_const */> ZOopStorageSetIterator;
|
||||
|
||||
template <typename T, void (T::*F)(ZRootsIteratorClosure*)>
|
||||
class ZSerialOopsDo {
|
||||
@ -134,16 +136,13 @@ public:
|
||||
|
||||
class ZConcurrentRootsIterator {
|
||||
private:
|
||||
ZOopStorageIterator _jni_handles_iter;
|
||||
ZOopStorageIterator _vm_handles_iter;
|
||||
const int _cld_claim;
|
||||
ZOopStorageSetIterator _oop_storage_set_iter;
|
||||
const int _cld_claim;
|
||||
|
||||
void do_jni_handles(ZRootsIteratorClosure* cl);
|
||||
void do_vm_handles(ZRootsIteratorClosure* cl);
|
||||
void do_oop_storage_set(ZRootsIteratorClosure* cl);
|
||||
void do_class_loader_data_graph(ZRootsIteratorClosure* cl);
|
||||
|
||||
ZParallelOopsDo<ZConcurrentRootsIterator, &ZConcurrentRootsIterator::do_jni_handles> _jni_handles;
|
||||
ZParallelOopsDo<ZConcurrentRootsIterator, &ZConcurrentRootsIterator::do_vm_handles> _vm_handles;
|
||||
ZParallelOopsDo<ZConcurrentRootsIterator, &ZConcurrentRootsIterator::do_oop_storage_set> _oop_storage_set;
|
||||
ZParallelOopsDo<ZConcurrentRootsIterator, &ZConcurrentRootsIterator::do_class_loader_data_graph> _class_loader_data_graph;
|
||||
|
||||
public:
|
||||
|
74
src/hotspot/share/utilities/valueObjArray.hpp
Normal file
74
src/hotspot/share/utilities/valueObjArray.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_UTILITIES_VALUEOBJARRAY_HPP
|
||||
#define SHARE_UTILITIES_VALUEOBJARRAY_HPP
|
||||
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
// Stamps out Count instances of Type using a recursive template.
|
||||
template <typename Type, int Count>
|
||||
class ValueObjBlock {
|
||||
typedef ValueObjBlock<Type, Count - 1> Next;
|
||||
|
||||
Type _instance;
|
||||
Next _next;
|
||||
|
||||
public:
|
||||
template <typename Generator>
|
||||
ValueObjBlock(Generator g, Type** save_to) :
|
||||
_instance(*g),
|
||||
_next(++g, save_to + 1) {
|
||||
*save_to = &_instance;
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for the recursion base case.
|
||||
template <typename Type>
|
||||
class ValueObjBlock<Type, 0> {
|
||||
public:
|
||||
template <typename Generator>
|
||||
ValueObjBlock(Generator, Type**) {}
|
||||
};
|
||||
|
||||
// Maps an array of size Count over stamped-out instances of Type.
|
||||
template <typename Type, int Count>
|
||||
struct ValueObjArray {
|
||||
Type* _ptrs[Count];
|
||||
ValueObjBlock<Type, Count> _block;
|
||||
|
||||
template <typename Generator>
|
||||
ValueObjArray(Generator g) : _ptrs(), _block(g, _ptrs) {}
|
||||
|
||||
Type* at(int index) const {
|
||||
assert(0 <= index && index < Count, "index out-of-bounds: %d", index);
|
||||
return _ptrs[index];
|
||||
}
|
||||
|
||||
static int count() {
|
||||
return Count;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SHARE_UTILITIES_VALUEOBJARRAY_HPP
|
98
test/hotspot/gtest/utilities/test_valueObjArray.cpp
Normal file
98
test/hotspot/gtest/utilities/test_valueObjArray.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "utilities/valueObjArray.hpp"
|
||||
#include "unittest.hpp"
|
||||
|
||||
class ValueObjArrayTest : public ::testing::Test {
|
||||
protected:
|
||||
class IntGenerator {
|
||||
int _current;
|
||||
|
||||
public:
|
||||
IntGenerator() : _current(0) {}
|
||||
int operator*() const {
|
||||
return _current;
|
||||
}
|
||||
IntGenerator operator++() {
|
||||
++_current;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct Struct {
|
||||
int _value;
|
||||
const char* _string;
|
||||
};
|
||||
|
||||
class StructGenerator {
|
||||
int _current;
|
||||
|
||||
static const char* str(int i) {
|
||||
const char* array[] = {
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3"};
|
||||
return array[i];
|
||||
}
|
||||
|
||||
public:
|
||||
StructGenerator() : _current(0) {}
|
||||
Struct operator*() const {
|
||||
assert(_current < 4, "precondition");
|
||||
Struct s = { _current, str(_current)};
|
||||
return s;
|
||||
}
|
||||
StructGenerator operator++() {
|
||||
++_current;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
TEST_F(ValueObjArrayTest, primitive) {
|
||||
ValueObjArrayTest::IntGenerator g;
|
||||
ValueObjArray<int, 4> array(g);
|
||||
ASSERT_EQ(array.count(), 4);
|
||||
ASSERT_EQ(*array.at(0), 0);
|
||||
ASSERT_EQ(*array.at(1), 1);
|
||||
ASSERT_EQ(*array.at(2), 2);
|
||||
ASSERT_EQ(*array.at(3), 3);
|
||||
}
|
||||
|
||||
TEST_F(ValueObjArrayTest, struct) {
|
||||
ValueObjArrayTest::StructGenerator g;
|
||||
ValueObjArray<Struct, 4> array(g);
|
||||
ASSERT_EQ(array.count(), 4);
|
||||
ASSERT_EQ(array.at(0)->_value, 0);
|
||||
ASSERT_EQ(array.at(1)->_value, 1);
|
||||
ASSERT_EQ(array.at(2)->_value, 2);
|
||||
ASSERT_EQ(array.at(3)->_value, 3);
|
||||
ASSERT_EQ(array.at(0)->_string[0], '0');
|
||||
ASSERT_EQ(array.at(1)->_string[0], '1');
|
||||
ASSERT_EQ(array.at(2)->_string[0], '2');
|
||||
ASSERT_EQ(array.at(3)->_string[0], '3');
|
||||
}
|
Loading…
Reference in New Issue
Block a user