--- old/src/hotspot/share/gc/z/zRootsIterator.cpp 2020-06-24 11:28:31.073112762 +0200 +++ new/src/hotspot/share/gc/z/zRootsIterator.cpp 2020-06-24 11:28:30.905109461 +0200 @@ -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 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 @@ } 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 @@ 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::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); } --- old/src/hotspot/share/gc/z/zRootsIterator.hpp 2020-06-24 11:28:31.385118894 +0200 +++ new/src/hotspot/share/gc/z/zRootsIterator.hpp 2020-06-24 11:28:31.229115828 +0200 @@ -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 ZOopStorageIterator; +typedef OopStorageSetStrongParState ZOopStorageSetIterator; template class ZSerialOopsDo { @@ -134,16 +136,13 @@ 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 _jni_handles; - ZParallelOopsDo _vm_handles; + ZParallelOopsDo _oop_storage_set; ZParallelOopsDo _class_loader_data_graph; public: --- /dev/null 2020-06-11 14:40:13.671999880 +0200 +++ new/src/hotspot/share/gc/shared/oopStorageSetParState.hpp 2020-06-24 11:28:31.541121958 +0200 @@ -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 +class OopStorageSetStrongParState { + typedef OopStorage::ParState ParStateType; + typedef ValueObjArray ParStateArray; + + ParStateArray _par_states; + +public: + OopStorageSetStrongParState(); + + template + void oops_do(Closure* cl); +}; + +#endif // SHARE_GC_SHARED_OOPSTORAGESETPARSTATE_HPP --- /dev/null 2020-06-11 14:40:13.671999880 +0200 +++ new/src/hotspot/share/gc/shared/oopStorageSetParState.inline.hpp 2020-06-24 11:28:31.865128326 +0200 @@ -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 +OopStorageSetStrongParState::OopStorageSetStrongParState() : + _par_states(OopStorageSet::strong_iterator()) { +} + +template +template +void OopStorageSetStrongParState::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 --- /dev/null 2020-06-11 14:40:13.671999880 +0200 +++ new/src/hotspot/share/utilities/valueObjArray.hpp 2020-06-24 11:28:32.197134850 +0200 @@ -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 +class ValueObjBlock { + typedef ValueObjBlock Next; + + Type _instance; + Next _next; + +public: + template + ValueObjBlock(Generator g, Type** save_to) : + _instance(*g), + _next(++g, save_to + 1) { + *save_to = &_instance; + } +}; + +// Specialization for the recursion base case. +template +class ValueObjBlock { +public: + template + ValueObjBlock(Generator, Type**) {} +}; + +// Maps an array of size Count over stamped-out instances of Type. +template +struct ValueObjArray { + Type* _ptrs[Count]; + ValueObjBlock _block; + + template + 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 --- /dev/null 2020-06-11 14:40:13.671999880 +0200 +++ new/test/hotspot/gtest/utilities/test_valueObjArray.cpp 2020-06-24 11:28:32.481140430 +0200 @@ -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 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 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'); +}