diff --git a/src/hotspot/share/oops/klassMode.cpp b/src/hotspot/share/oops/klassMode.cpp new file mode 100644 index 0000000000000..75cb34510e716 --- /dev/null +++ b/src/hotspot/share/oops/klassMode.cpp @@ -0,0 +1,39 @@ +/* + * Copyright Amazon.com Inc. 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 "oops/klassMode.hpp" + +KlassMode::Mode KlassMode::_klass_mode = KlassMode::Undefined; + +void KlassMode::init_klass_mode() { + assert(_klass_mode == Undefined, "KlassMode initialized twice"); + if (UseCompactObjectHeaders) { + _klass_mode = Compact; + } else if (UseCompressedClassPointers) { + _klass_mode = Compressed; + } else { + _klass_mode = Uncompressed; + } +} \ No newline at end of file diff --git a/src/hotspot/share/oops/klassMode.hpp b/src/hotspot/share/oops/klassMode.hpp new file mode 100644 index 0000000000000..23550b9a078f8 --- /dev/null +++ b/src/hotspot/share/oops/klassMode.hpp @@ -0,0 +1,74 @@ +/* + * Copyright Amazon.com Inc. 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_OOPS_KLASSMODE_HPP +#define SHARE_OOPS_KLASSMODE_HPP + +/* + * This class helps to avoid loading more than one flag when + * accessing the Klass* in oopDesc::klass(). This is important + * on some performance critical paths where the Klass* is + * accessed frequently, especially by GC oop iterators. + * + * Instead of doing: + * if (UseCompactObjectHeaders) { // Load first flag + * .. + * } else if (UseCompressedClassPointers) { // Load second flag + * .. + * } else { + * .. + * } + * + * we can do: + * switch (KlassMode::klass_mode()) { + * case Compact: + * .. + * case Compressed: + * .. + * case Uncompressed: + * .. + * } + */ +class KlassMode { +public: + enum Mode { + // +UseCompactObjectHeaders (implies +UseCompressedClassPointers) + Compact, + // +UseCompressedClassPointers (-UseCompactObjectHeaders) + Compressed, + // -UseCompressedClassPointers (-UseCompactObjectHeaders) + Uncompressed, + // Not yet initialized + Undefined + }; + +private: + static Mode _klass_mode; + +public: + static void init_klass_mode(); + static inline Mode klass_mode(); +}; + +#endif // SHARE_OOPS_KLASSMODE_HPP diff --git a/src/hotspot/share/oops/klassMode.inline.hpp b/src/hotspot/share/oops/klassMode.inline.hpp new file mode 100644 index 0000000000000..393cd3b647d23 --- /dev/null +++ b/src/hotspot/share/oops/klassMode.inline.hpp @@ -0,0 +1,48 @@ +/* + * Copyright Amazon.com Inc. 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_OOPS_KLASSMODE_INLINE_HPP +#define SHARE_OOPS_KLASSMODE_INLINE_HPP + +#include "oops/klassMode.hpp" + +inline KlassMode::Mode KlassMode::klass_mode() { +#ifdef ASSERT + assert(_klass_mode != Undefined, "KlassMode not yet initialized"); + if (UseCompactObjectHeaders) { + assert(_klass_mode == Compact, "Klass mode does not match flags"); + } else if (UseCompressedClassPointers) { + assert(_klass_mode == Compressed, "Klass mode does not match flags"); + } else { + assert(_klass_mode == Uncompressed, "Klass mode does not match flags"); + } +#endif +#ifdef _LP64 + return _klass_mode; +#else + return Uncompressed; +#endif +} + +#endif // SHARE_OOPS_KLASSMODE_INLINE_HPP diff --git a/src/hotspot/share/oops/oop.inline.hpp b/src/hotspot/share/oops/oop.inline.hpp index 098e6bfa90f45..5f459e9ac1934 100644 --- a/src/hotspot/share/oops/oop.inline.hpp +++ b/src/hotspot/share/oops/oop.inline.hpp @@ -34,6 +34,7 @@ #include "oops/arrayOop.hpp" #include "oops/compressedKlass.inline.hpp" #include "oops/instanceKlass.hpp" +#include "oops/klassMode.inline.hpp" #include "oops/markWord.inline.hpp" #include "oops/oopsHierarchy.hpp" #include "runtime/atomic.hpp" @@ -95,43 +96,48 @@ void oopDesc::init_mark() { } Klass* oopDesc::klass() const { - if (UseCompactObjectHeaders) { - return mark().klass(); - } else if (UseCompressedClassPointers) { - return CompressedKlassPointers::decode_not_null(_metadata._compressed_klass); - } else { - return _metadata._klass; + switch (KlassMode::klass_mode()) { + case KlassMode::Compact: + return mark().klass(); + case KlassMode::Compressed: + return CompressedKlassPointers::decode_not_null(_metadata._compressed_klass); + default: + return _metadata._klass; } } Klass* oopDesc::klass_or_null() const { - if (UseCompactObjectHeaders) { - return mark().klass_or_null(); - } else if (UseCompressedClassPointers) { - return CompressedKlassPointers::decode(_metadata._compressed_klass); - } else { - return _metadata._klass; + switch (KlassMode::klass_mode()) { + case KlassMode::Compact: + return mark().klass_or_null(); + case KlassMode::Compressed: + return CompressedKlassPointers::decode(_metadata._compressed_klass); + default: + return _metadata._klass; } } Klass* oopDesc::klass_or_null_acquire() const { - if (UseCompactObjectHeaders) { - return mark_acquire().klass(); - } else if (UseCompressedClassPointers) { - narrowKlass narrow_klass = Atomic::load_acquire(&_metadata._compressed_klass); - return CompressedKlassPointers::decode(narrow_klass); - } else { - return Atomic::load_acquire(&_metadata._klass); + switch (KlassMode::klass_mode()) { + case KlassMode::Compact: + return mark_acquire().klass(); + case KlassMode::Compressed: { + narrowKlass narrow_klass = Atomic::load_acquire(&_metadata._compressed_klass); + return CompressedKlassPointers::decode(narrow_klass); + } + default: + return Atomic::load_acquire(&_metadata._klass); } } Klass* oopDesc::klass_without_asserts() const { - if (UseCompactObjectHeaders) { - return mark().klass_without_asserts(); - } else if (UseCompressedClassPointers) { - return CompressedKlassPointers::decode_without_asserts(_metadata._compressed_klass); - } else { - return _metadata._klass; + switch (KlassMode::klass_mode()) { + case KlassMode::Compact: + return mark().klass_without_asserts(); + case KlassMode::Compressed: + return CompressedKlassPointers::decode_without_asserts(_metadata._compressed_klass); + default: + return _metadata._klass; } } diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 3aa7ab5e84ef0..a0585eb69466c 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -46,6 +46,7 @@ #include "nmt/nmtCommon.hpp" #include "oops/compressedKlass.hpp" #include "oops/instanceKlass.hpp" +#include "oops/klassMode.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiAgentList.hpp" #include "prims/jvmtiExport.hpp" @@ -3670,6 +3671,7 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) { if (UseCompactObjectHeaders && !UseCompressedClassPointers) { FLAG_SET_DEFAULT(UseCompressedClassPointers, true); } + KlassMode::init_klass_mode(); #endif return JNI_OK;