diff --git a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp index 82f5f994c52..fdfab3ab562 100644 --- a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp @@ -28,6 +28,7 @@ #include "jvmci/jvmciRuntime.hpp" #include "jvmci/jvmciCompilerToVM.hpp" #include "jvmci/jvmciJavaClasses.hpp" +#include "oops/compressedKlass.hpp" #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/jniHandles.hpp" diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index ffe8698b9b5..e3df32ed602 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -45,6 +45,7 @@ #include "memory/universe.hpp" #include "nativeInst_aarch64.hpp" #include "oops/accessDecorators.hpp" +#include "oops/compressedKlass.inline.hpp" #include "oops/compressedOops.inline.hpp" #include "oops/klass.inline.hpp" #include "runtime/continuation.hpp" diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index 6b45be8ce43..ada0891a5de 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -30,6 +30,7 @@ #include "code/vmreg.hpp" #include "metaprogramming/enableIf.hpp" #include "oops/compressedOops.hpp" +#include "oops/compressedKlass.hpp" #include "runtime/vm_version.hpp" #include "utilities/powerOfTwo.hpp" diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp index 686f2c9d48e..4e7d5cde8a5 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp @@ -32,6 +32,8 @@ #include "interpreter/interpreter.hpp" #include "memory/resourceArea.hpp" #include "nativeInst_ppc.hpp" +#include "oops/compressedKlass.inline.hpp" +#include "oops/compressedOops.inline.hpp" #include "oops/klass.inline.hpp" #include "oops/methodData.hpp" #include "prims/methodHandles.hpp" diff --git a/src/hotspot/cpu/riscv/jvmciCodeInstaller_riscv.cpp b/src/hotspot/cpu/riscv/jvmciCodeInstaller_riscv.cpp index 6b0fc486f89..a7160bd7241 100644 --- a/src/hotspot/cpu/riscv/jvmciCodeInstaller_riscv.cpp +++ b/src/hotspot/cpu/riscv/jvmciCodeInstaller_riscv.cpp @@ -29,6 +29,7 @@ #include "jvmci/jvmciRuntime.hpp" #include "jvmci/jvmciCompilerToVM.hpp" #include "jvmci/jvmciJavaClasses.hpp" +#include "oops/compressedKlass.hpp" #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/jniHandles.hpp" diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index da2b9236c9b..e0a216ab4a7 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -39,6 +39,7 @@ #include "memory/universe.hpp" #include "nativeInst_riscv.hpp" #include "oops/accessDecorators.hpp" +#include "oops/compressedKlass.inline.hpp" #include "oops/compressedOops.inline.hpp" #include "oops/klass.inline.hpp" #include "oops/oop.hpp" diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index 8055510e6c3..08dc39cd41e 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -35,6 +35,7 @@ #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/accessDecorators.hpp" +#include "oops/compressedKlass.inline.hpp" #include "oops/compressedOops.inline.hpp" #include "oops/klass.inline.hpp" #include "prims/methodHandles.hpp" diff --git a/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp b/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp index 1404617e8e7..09056b374ad 100644 --- a/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp +++ b/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp @@ -23,6 +23,7 @@ #include "precompiled.hpp" #include "compiler/disassembler.hpp" +#include "oops/compressedKlass.hpp" #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index 4d45d3de290..6aec03e8db0 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -38,6 +38,7 @@ #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/accessDecorators.hpp" +#include "oops/compressedKlass.inline.hpp" #include "oops/compressedOops.inline.hpp" #include "oops/klass.inline.hpp" #include "prims/methodHandles.hpp" diff --git a/src/hotspot/cpu/x86/relocInfo_x86.cpp b/src/hotspot/cpu/x86/relocInfo_x86.cpp index 2d20137e84f..8a6da794421 100644 --- a/src/hotspot/cpu/x86/relocInfo_x86.cpp +++ b/src/hotspot/cpu/x86/relocInfo_x86.cpp @@ -27,6 +27,7 @@ #include "code/relocInfo.hpp" #include "memory/universe.hpp" #include "nativeInst_x86.hpp" +#include "oops/compressedKlass.inline.hpp" #include "oops/compressedOops.inline.hpp" #include "oops/klass.inline.hpp" #include "oops/oop.inline.hpp" diff --git a/src/hotspot/share/cds/archiveBuilder.cpp b/src/hotspot/share/cds/archiveBuilder.cpp index 65dd5921c82..636a955ba74 100644 --- a/src/hotspot/share/cds/archiveBuilder.cpp +++ b/src/hotspot/share/cds/archiveBuilder.cpp @@ -41,6 +41,7 @@ #include "memory/allStatic.hpp" #include "memory/memRegion.hpp" #include "memory/resourceArea.hpp" +#include "oops/compressedKlass.inline.hpp" #include "oops/instanceKlass.hpp" #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index b32db56644a..b87ef1e447c 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -61,7 +61,7 @@ #include "memory/metaspaceClosure.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" -#include "oops/compressedOops.inline.hpp" +#include "oops/compressedKlass.hpp" #include "oops/instanceMirrorKlass.hpp" #include "oops/klass.inline.hpp" #include "oops/objArrayOop.hpp" diff --git a/src/hotspot/share/gc/x/xDebug.gdb b/src/hotspot/share/gc/x/xDebug.gdb index d8f79d589c8..2dbf578b07b 100644 --- a/src/hotspot/share/gc/x/xDebug.gdb +++ b/src/hotspot/share/gc/x/xDebug.gdb @@ -51,7 +51,7 @@ define zpo printf "\t Page: %llu\n", ((uintptr_t)$obj & XAddressOffsetMask) >> XGranuleSizeShift x/16gx $obj if (UseCompressedClassPointers) - set $klass = (Klass*)(void*)((uintptr_t)CompressedKlassPointers::_narrow_klass._base +((uintptr_t)$obj->_metadata->_compressed_klass << CompressedKlassPointers::_narrow_klass._shift)) + set $klass = (Klass*)(void*)((uintptr_t)CompressedKlassPointers::_base +((uintptr_t)$obj->_metadata->_compressed_klass << CompressedKlassPointers::_shift)) else set $klass = $obj->_metadata->_klass end diff --git a/src/hotspot/share/gc/z/zDebug.gdb b/src/hotspot/share/gc/z/zDebug.gdb index 181da66b9c9..d502eea7ce3 100644 --- a/src/hotspot/share/gc/z/zDebug.gdb +++ b/src/hotspot/share/gc/z/zDebug.gdb @@ -51,7 +51,7 @@ define zpo printf "\t Page: %llu\n", ((uintptr_t)$obj & ZAddressOffsetMask) >> ZGranuleSizeShift x/16gx $obj if (UseCompressedClassPointers) - set $klass = (Klass*)(void*)((uintptr_t)CompressedKlassPointers::_narrow_klass._base +((uintptr_t)$obj->_metadata->_compressed_klass << CompressedKlassPointers::_narrow_klass._shift)) + set $klass = (Klass*)(void*)((uintptr_t)CompressedKlassPointers::_base +((uintptr_t)$obj->_metadata->_compressed_klass << CompressedKlassPointers::_shift)) else set $klass = $obj->_metadata->_klass end diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdKlassQueue.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdKlassQueue.cpp index c76048218e1..a341d31b0d6 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdKlassQueue.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdKlassQueue.cpp @@ -31,7 +31,7 @@ #include "jfr/utilities/jfrEpochQueue.inline.hpp" #include "jfr/utilities/jfrTypes.hpp" #include "memory/metaspace.hpp" -#include "oops/compressedOops.hpp" +#include "oops/compressedKlass.inline.hpp" #include "utilities/macros.hpp" #ifdef VM_LITTLE_ENDIAN diff --git a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp index fab377076c7..dd8badcecdc 100644 --- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp +++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp @@ -32,7 +32,7 @@ #include "jvmci/jvmciCompilerToVM.hpp" #include "jvmci/jvmciRuntime.hpp" #include "memory/universe.hpp" -#include "oops/compressedOops.inline.hpp" +#include "oops/compressedKlass.inline.hpp" #include "oops/klass.inline.hpp" #include "prims/jvmtiExport.hpp" #include "prims/methodHandles.hpp" diff --git a/src/hotspot/share/memory/metaspace.cpp b/src/hotspot/share/memory/metaspace.cpp index 10524082f19..3f4b9d0ea08 100644 --- a/src/hotspot/share/memory/metaspace.cpp +++ b/src/hotspot/share/memory/metaspace.cpp @@ -47,6 +47,7 @@ #include "memory/metaspaceUtils.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" +#include "oops/compressedKlass.inline.hpp" #include "oops/compressedOops.hpp" #include "prims/jvmtiExport.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/memory/metaspace/metaspaceCommon.hpp b/src/hotspot/share/memory/metaspace/metaspaceCommon.hpp index e2c85e97a4c..a13ef1b3251 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceCommon.hpp +++ b/src/hotspot/share/memory/metaspace/metaspaceCommon.hpp @@ -26,6 +26,7 @@ #ifndef SHARE_MEMORY_METASPACE_METASPACECOMMON_HPP #define SHARE_MEMORY_METASPACE_METASPACECOMMON_HPP +#include "oops/compressedKlass.hpp" #include "runtime/globals.hpp" #include "utilities/align.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/memory/virtualspace.cpp b/src/hotspot/share/memory/virtualspace.cpp index ae898bec3af..dbbf5a3dd5f 100644 --- a/src/hotspot/share/memory/virtualspace.cpp +++ b/src/hotspot/share/memory/virtualspace.cpp @@ -26,6 +26,7 @@ #include "logging/log.hpp" #include "memory/resourceArea.hpp" #include "memory/virtualspace.hpp" +#include "oops/compressedKlass.hpp" #include "oops/compressedOops.hpp" #include "oops/markWord.hpp" #include "oops/oop.inline.hpp" diff --git a/src/hotspot/share/oops/compressedKlass.cpp b/src/hotspot/share/oops/compressedKlass.cpp new file mode 100644 index 00000000000..3821e967af9 --- /dev/null +++ b/src/hotspot/share/oops/compressedKlass.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2019, 2023, 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 "oops/compressedKlass.hpp" +#include "runtime/globals.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/ostream.hpp" + +address CompressedKlassPointers::_base = nullptr; +int CompressedKlassPointers::_shift = 0; +size_t CompressedKlassPointers::_range = 0; + +#ifdef _LP64 + +// Given a klass range [addr, addr+len) and a given encoding scheme, assert that this scheme covers the range, then +// set this encoding scheme. Used by CDS at runtime to re-instate the scheme used to pre-compute klass ids for +// archived heap objects. +void CompressedKlassPointers::initialize_for_given_encoding(address addr, size_t len, address requested_base, int requested_shift) { + assert(is_valid_base(requested_base), "Address must be a valid encoding base"); + address const end = addr + len; + + const int narrow_klasspointer_bits = sizeof(narrowKlass) * 8; + const size_t encoding_range_size = nth_bit(narrow_klasspointer_bits + requested_shift); + address encoding_range_end = requested_base + encoding_range_size; + + // Note: it would be technically valid for the encoding base to precede the start of the Klass range. But we only call + // this function from CDS, and therefore know this to be true. + assert(requested_base == addr, "Invalid requested base"); + assert(encoding_range_end >= end, "Encoding does not cover the full Klass range"); + + set_base(requested_base); + set_shift(requested_shift); + set_range(encoding_range_size); +} + +// Given an address range [addr, addr+len) which the encoding is supposed to +// cover, choose base, shift and range. +// The address range is the expected range of uncompressed Klass pointers we +// will encounter (and the implicit promise that there will be no Klass +// structures outside this range). +void CompressedKlassPointers::initialize(address addr, size_t len) { + assert(is_valid_base(addr), "Address must be a valid encoding base"); + address const end = addr + len; + + address base; + int shift; + size_t range; + + // Attempt to run with encoding base == zero + if (end <= (address)KlassEncodingMetaspaceMax) { + base = 0; + } else { + base = addr; + } + + // Highest offset a Klass* can ever have in relation to base. + range = end - base; + + // We may not even need a shift if the range fits into 32bit: + const uint64_t UnscaledClassSpaceMax = (uint64_t(max_juint) + 1); + if (range < UnscaledClassSpaceMax) { + shift = 0; + } else { + shift = LogKlassAlignmentInBytes; + } + + set_base(base); + set_shift(shift); + set_range(range); +} + +// Given an address p, return true if p can be used as an encoding base. +// (Some platforms have restrictions of what constitutes a valid base address). +bool CompressedKlassPointers::is_valid_base(address p) { +#ifdef AARCH64 + // Below 32G, base must be aligned to 4G. + // Above that point, base must be aligned to 32G + if (p < (address)(32 * G)) { + return is_aligned(p, 4 * G); + } + return is_aligned(p, (4 << LogKlassAlignmentInBytes) * G); +#else + return true; +#endif +} + +void CompressedKlassPointers::print_mode(outputStream* st) { + st->print_cr("Narrow klass base: " PTR_FORMAT ", Narrow klass shift: %d, " + "Narrow klass range: " SIZE_FORMAT_X, p2i(base()), shift(), + range()); +} + +void CompressedKlassPointers::set_base(address base) { + assert(UseCompressedClassPointers, "no compressed klass ptrs?"); + _base = base; +} + +void CompressedKlassPointers::set_shift(int shift) { + assert(shift == 0 || shift == LogKlassAlignmentInBytes, "invalid shift for klass ptrs"); + _shift = shift; +} + +void CompressedKlassPointers::set_range(size_t range) { + assert(UseCompressedClassPointers, "no compressed klass ptrs?"); + _range = range; +} + +#endif // _LP64 diff --git a/src/hotspot/share/oops/compressedKlass.hpp b/src/hotspot/share/oops/compressedKlass.hpp new file mode 100644 index 00000000000..e4a2550a599 --- /dev/null +++ b/src/hotspot/share/oops/compressedKlass.hpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2019, 2023, 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_OOPS_COMPRESSEDKLASS_HPP +#define SHARE_OOPS_COMPRESSEDKLASS_HPP + +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" + +class outputStream; +class Klass; + +// If compressed klass pointers then use narrowKlass. +typedef juint narrowKlass; + +const int LogKlassAlignmentInBytes = 3; +const int KlassAlignmentInBytes = 1 << LogKlassAlignmentInBytes; + +// Maximal size of compressed class space. Above this limit compression is not possible. +// Also upper bound for placement of zero based class space. (Class space is further limited +// to be < 3G, see arguments.cpp.) +const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlassAlignmentInBytes; + +// For UseCompressedClassPointers. +class CompressedKlassPointers : public AllStatic { + friend class VMStructs; + + static address _base; + static int _shift; + + // Together with base, this defines the address range within which Klass + // structures will be located: [base, base+range). While the maximal + // possible encoding range is 4|32G for shift 0|3, if we know beforehand + // the expected range of Klass* pointers will be smaller, a platform + // could use this info to optimize encoding. + static size_t _range; + + static void set_base(address base); + static void set_range(size_t range); + static void set_shift(int shift); + +public: + + // Given an address p, return true if p can be used as an encoding base. + // (Some platforms have restrictions of what constitutes a valid base + // address). + static bool is_valid_base(address p); + + // Given a klass range [addr, addr+len) and a given encoding scheme, assert that this scheme covers the range, then + // set this encoding scheme. Used by CDS at runtime to re-instate the scheme used to pre-compute klass ids for + // archived heap objects. + static void initialize_for_given_encoding(address addr, size_t len, address requested_base, int requested_shift); + + // Given an address range [addr, addr+len) which the encoding is supposed to + // cover, choose base, shift and range. + // The address range is the expected range of uncompressed Klass pointers we + // will encounter (and the implicit promise that there will be no Klass + // structures outside this range). + static void initialize(address addr, size_t len); + + static void print_mode(outputStream* st); + + static address base() { return _base; } + static size_t range() { return _range; } + static int shift() { return _shift; } + + static bool is_null(Klass* v) { return v == nullptr; } + static bool is_null(narrowKlass v) { return v == 0; } + + static inline Klass* decode_raw(narrowKlass v, address base, int shift); + static inline Klass* decode_raw(narrowKlass v); + static inline Klass* decode_not_null(narrowKlass v); + static inline Klass* decode_not_null(narrowKlass v, address base, int shift); + static inline Klass* decode(narrowKlass v); + static inline narrowKlass encode_not_null(Klass* v); + static inline narrowKlass encode_not_null(Klass* v, address base, int shift); + static inline narrowKlass encode(Klass* v); + +}; + +#endif // SHARE_OOPS_COMPRESSEDKLASS_HPP diff --git a/src/hotspot/share/oops/compressedKlass.inline.hpp b/src/hotspot/share/oops/compressedKlass.inline.hpp new file mode 100644 index 00000000000..134e9fec863 --- /dev/null +++ b/src/hotspot/share/oops/compressedKlass.inline.hpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2017, 2023, 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_OOPS_COMPRESSEDKLASS_INLINE_HPP +#define SHARE_OOPS_COMPRESSEDKLASS_INLINE_HPP + +#include "oops/compressedKlass.hpp" + +#include "memory/universe.hpp" +#include "oops/oop.hpp" +#include "utilities/align.hpp" +#include "utilities/globalDefinitions.hpp" + +static inline bool check_alignment(Klass* v) { + return (intptr_t)v % KlassAlignmentInBytes == 0; +} + +inline Klass* CompressedKlassPointers::decode_raw(narrowKlass v) { + return decode_raw(v, base(), shift()); +} + +inline Klass* CompressedKlassPointers::decode_raw(narrowKlass v, address narrow_base, int shift) { + return (Klass*)((uintptr_t)narrow_base +((uintptr_t)v << shift)); +} + +inline Klass* CompressedKlassPointers::decode_not_null(narrowKlass v) { + return decode_not_null(v, base(), shift()); +} + +inline Klass* CompressedKlassPointers::decode_not_null(narrowKlass v, address narrow_base, int shift) { + assert(!is_null(v), "narrow klass value can never be zero"); + Klass* result = decode_raw(v, narrow_base, shift); + assert(check_alignment(result), "address not aligned: " PTR_FORMAT, p2i(result)); + return result; +} + +inline Klass* CompressedKlassPointers::decode(narrowKlass v) { + return is_null(v) ? nullptr : decode_not_null(v); +} + +inline narrowKlass CompressedKlassPointers::encode_not_null(Klass* v) { + return encode_not_null(v, base(), shift()); +} + +inline narrowKlass CompressedKlassPointers::encode_not_null(Klass* v, address narrow_base, int shift) { + assert(!is_null(v), "klass value can never be zero"); + assert(check_alignment(v), "Address not aligned"); + uint64_t pd = (uint64_t)(pointer_delta(v, narrow_base, 1)); + assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding"); + uint64_t result = pd >> shift; + assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow"); + assert(decode_not_null((narrowKlass)result, narrow_base, shift) == v, "reversibility"); + return (narrowKlass)result; +} + +inline narrowKlass CompressedKlassPointers::encode(Klass* v) { + return is_null(v) ? (narrowKlass)0 : encode_not_null(v); +} + +#endif // SHARE_OOPS_COMPRESSEDKLASS_INLINE_HPP diff --git a/src/hotspot/share/oops/compressedOops.cpp b/src/hotspot/share/oops/compressedOops.cpp index 3ee5e431c4d..08f78b1d773 100644 --- a/src/hotspot/share/oops/compressedOops.cpp +++ b/src/hotspot/share/oops/compressedOops.cpp @@ -177,108 +177,3 @@ void CompressedOops::print_mode(outputStream* st) { } st->cr(); } - -// For UseCompressedClassPointers. -NarrowPtrStruct CompressedKlassPointers::_narrow_klass = { nullptr, 0, true }; - -// CompressedClassSpaceSize set to 1GB, but appear 3GB away from _narrow_ptrs_base during CDS dump. -// (Todo: we should #ifdef out CompressedKlassPointers for 32bit completely and fix all call sites which -// are compiled for 32bit to LP64_ONLY). -size_t CompressedKlassPointers::_range = 0; - -#ifdef _LP64 - -// Given a klass range [addr, addr+len) and a given encoding scheme, assert that this scheme covers the range, then -// set this encoding scheme. Used by CDS at runtime to re-instate the scheme used to pre-compute klass ids for -// archived heap objects. -void CompressedKlassPointers::initialize_for_given_encoding(address addr, size_t len, address requested_base, int requested_shift) { - assert(is_valid_base(requested_base), "Address must be a valid encoding base"); - address const end = addr + len; - - const int narrow_klasspointer_bits = sizeof(narrowKlass) * 8; - const size_t encoding_range_size = nth_bit(narrow_klasspointer_bits + requested_shift); - address encoding_range_end = requested_base + encoding_range_size; - - // Note: it would be technically valid for the encoding base to precede the start of the Klass range. But we only call - // this function from CDS, and therefore know this to be true. - assert(requested_base == addr, "Invalid requested base"); - assert(encoding_range_end >= end, "Encoding does not cover the full Klass range"); - - set_base(requested_base); - set_shift(requested_shift); - set_range(encoding_range_size); -} - -// Given an address range [addr, addr+len) which the encoding is supposed to -// cover, choose base, shift and range. -// The address range is the expected range of uncompressed Klass pointers we -// will encounter (and the implicit promise that there will be no Klass -// structures outside this range). -void CompressedKlassPointers::initialize(address addr, size_t len) { - assert(is_valid_base(addr), "Address must be a valid encoding base"); - address const end = addr + len; - - address base; - int shift; - size_t range; - - // Attempt to run with encoding base == zero - if (end <= (address)KlassEncodingMetaspaceMax) { - base = 0; - } else { - base = addr; - } - - // Highest offset a Klass* can ever have in relation to base. - range = end - base; - - // We may not even need a shift if the range fits into 32bit: - const uint64_t UnscaledClassSpaceMax = (uint64_t(max_juint) + 1); - if (range < UnscaledClassSpaceMax) { - shift = 0; - } else { - shift = LogKlassAlignmentInBytes; - } - - set_base(base); - set_shift(shift); - set_range(range); -} - -// Given an address p, return true if p can be used as an encoding base. -// (Some platforms have restrictions of what constitutes a valid base address). -bool CompressedKlassPointers::is_valid_base(address p) { -#ifdef AARCH64 - // Below 32G, base must be aligned to 4G. - // Above that point, base must be aligned to 32G - if (p < (address)(32 * G)) { - return is_aligned(p, 4 * G); - } - return is_aligned(p, (4 << LogKlassAlignmentInBytes) * G); -#else - return true; -#endif -} - -void CompressedKlassPointers::print_mode(outputStream* st) { - st->print_cr("Narrow klass base: " PTR_FORMAT ", Narrow klass shift: %d, " - "Narrow klass range: " SIZE_FORMAT_X, p2i(base()), shift(), - range()); -} - -void CompressedKlassPointers::set_base(address base) { - assert(UseCompressedClassPointers, "no compressed klass ptrs?"); - _narrow_klass._base = base; -} - -void CompressedKlassPointers::set_shift(int shift) { - assert(shift == 0 || shift == LogKlassAlignmentInBytes, "invalid shift for klass ptrs"); - _narrow_klass._shift = shift; -} - -void CompressedKlassPointers::set_range(size_t range) { - assert(UseCompressedClassPointers, "no compressed klass ptrs?"); - _range = range; -} - -#endif // _LP64 diff --git a/src/hotspot/share/oops/compressedOops.hpp b/src/hotspot/share/oops/compressedOops.hpp index 28bb6982abf..cd3f00393ca 100644 --- a/src/hotspot/share/oops/compressedOops.hpp +++ b/src/hotspot/share/oops/compressedOops.hpp @@ -40,7 +40,7 @@ struct NarrowPtrStruct { address _base; // Number of shift bits for encoding/decoding narrow ptrs. // 0 if using wide ptrs or zero based unscaled narrow ptrs, - // LogMinObjAlignmentInBytes/LogKlassAlignmentInBytes otherwise. + // LogMinObjAlignmentInBytes otherwise. int _shift; // Generate code with implicit null checks for narrow ptrs. bool _use_implicit_null_checks; @@ -140,60 +140,4 @@ public: static inline narrowOop narrow_oop_cast(T i); }; -// For UseCompressedClassPointers. -class CompressedKlassPointers : public AllStatic { - friend class VMStructs; - - static NarrowPtrStruct _narrow_klass; - - // Together with base, this defines the address range within which Klass - // structures will be located: [base, base+range). While the maximal - // possible encoding range is 4|32G for shift 0|3, if we know beforehand - // the expected range of Klass* pointers will be smaller, a platform - // could use this info to optimize encoding. - static size_t _range; - - static void set_base(address base); - static void set_range(size_t range); - static void set_shift(int shift); - -public: - - // Given an address p, return true if p can be used as an encoding base. - // (Some platforms have restrictions of what constitutes a valid base - // address). - static bool is_valid_base(address p); - - // Given a klass range [addr, addr+len) and a given encoding scheme, assert that this scheme covers the range, then - // set this encoding scheme. Used by CDS at runtime to re-instate the scheme used to pre-compute klass ids for - // archived heap objects. - static void initialize_for_given_encoding(address addr, size_t len, address requested_base, int requested_shift); - - // Given an address range [addr, addr+len) which the encoding is supposed to - // cover, choose base, shift and range. - // The address range is the expected range of uncompressed Klass pointers we - // will encounter (and the implicit promise that there will be no Klass - // structures outside this range). - static void initialize(address addr, size_t len); - - static void print_mode(outputStream* st); - - static address base() { return _narrow_klass._base; } - static size_t range() { return _range; } - static int shift() { return _narrow_klass._shift; } - - static bool is_null(Klass* v) { return v == nullptr; } - static bool is_null(narrowKlass v) { return v == 0; } - - static inline Klass* decode_raw(narrowKlass v, address base, int shift); - static inline Klass* decode_raw(narrowKlass v); - static inline Klass* decode_not_null(narrowKlass v); - static inline Klass* decode_not_null(narrowKlass v, address base, int shift); - static inline Klass* decode(narrowKlass v); - static inline narrowKlass encode_not_null(Klass* v); - static inline narrowKlass encode_not_null(Klass* v, address base, int shift); - static inline narrowKlass encode(Klass* v); - -}; - #endif // SHARE_OOPS_COMPRESSEDOOPS_HPP diff --git a/src/hotspot/share/oops/compressedOops.inline.hpp b/src/hotspot/share/oops/compressedOops.inline.hpp index eb662530b50..191c376686c 100644 --- a/src/hotspot/share/oops/compressedOops.inline.hpp +++ b/src/hotspot/share/oops/compressedOops.inline.hpp @@ -118,50 +118,4 @@ inline narrowOop CompressedOops::narrow_oop_cast(T i) { return static_cast(narrow_value); } -static inline bool check_alignment(Klass* v) { - return (intptr_t)v % KlassAlignmentInBytes == 0; -} - -inline Klass* CompressedKlassPointers::decode_raw(narrowKlass v) { - return decode_raw(v, base(), shift()); -} - -inline Klass* CompressedKlassPointers::decode_raw(narrowKlass v, address narrow_base, int shift) { - return (Klass*)((uintptr_t)narrow_base +((uintptr_t)v << shift)); -} - -inline Klass* CompressedKlassPointers::decode_not_null(narrowKlass v) { - return decode_not_null(v, base(), shift()); -} - -inline Klass* CompressedKlassPointers::decode_not_null(narrowKlass v, address narrow_base, int shift) { - assert(!is_null(v), "narrow klass value can never be zero"); - Klass* result = decode_raw(v, narrow_base, shift); - assert(check_alignment(result), "address not aligned: " PTR_FORMAT, p2i(result)); - return result; -} - -inline Klass* CompressedKlassPointers::decode(narrowKlass v) { - return is_null(v) ? nullptr : decode_not_null(v); -} - -inline narrowKlass CompressedKlassPointers::encode_not_null(Klass* v) { - return encode_not_null(v, base(), shift()); -} - -inline narrowKlass CompressedKlassPointers::encode_not_null(Klass* v, address narrow_base, int shift) { - assert(!is_null(v), "klass value can never be zero"); - assert(check_alignment(v), "Address not aligned"); - uint64_t pd = (uint64_t)(pointer_delta(v, narrow_base, 1)); - assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding"); - uint64_t result = pd >> shift; - assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow"); - assert(decode_not_null((narrowKlass)result, narrow_base, shift) == v, "reversibility"); - return (narrowKlass)result; -} - -inline narrowKlass CompressedKlassPointers::encode(Klass* v) { - return is_null(v) ? (narrowKlass)0 : encode_not_null(v); -} - #endif // SHARE_OOPS_COMPRESSEDOOPS_INLINE_HPP diff --git a/src/hotspot/share/oops/oop.cpp b/src/hotspot/share/oops/oop.cpp index a0b3de53649..c2c78ce581e 100644 --- a/src/hotspot/share/oops/oop.cpp +++ b/src/hotspot/share/oops/oop.cpp @@ -30,6 +30,7 @@ #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/access.inline.hpp" +#include "oops/compressedKlass.inline.hpp" #include "oops/compressedOops.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/verifyOopClosure.hpp" diff --git a/src/hotspot/share/oops/oop.hpp b/src/hotspot/share/oops/oop.hpp index 933847fe377..50d8b6041b6 100644 --- a/src/hotspot/share/oops/oop.hpp +++ b/src/hotspot/share/oops/oop.hpp @@ -27,6 +27,7 @@ #include "memory/iterator.hpp" #include "memory/memRegion.hpp" +#include "oops/compressedKlass.hpp" #include "oops/accessDecorators.hpp" #include "oops/markWord.hpp" #include "oops/metadata.hpp" diff --git a/src/hotspot/share/oops/oop.inline.hpp b/src/hotspot/share/oops/oop.inline.hpp index a0477ce376e..a9b88e32651 100644 --- a/src/hotspot/share/oops/oop.inline.hpp +++ b/src/hotspot/share/oops/oop.inline.hpp @@ -32,7 +32,7 @@ #include "oops/access.inline.hpp" #include "oops/arrayKlass.hpp" #include "oops/arrayOop.hpp" -#include "oops/compressedOops.inline.hpp" +#include "oops/compressedKlass.inline.hpp" #include "oops/instanceKlass.hpp" #include "oops/markWord.hpp" #include "oops/oopsHierarchy.hpp" diff --git a/src/hotspot/share/oops/oopsHierarchy.hpp b/src/hotspot/share/oops/oopsHierarchy.hpp index 060c1b97d10..b01153da46d 100644 --- a/src/hotspot/share/oops/oopsHierarchy.hpp +++ b/src/hotspot/share/oops/oopsHierarchy.hpp @@ -37,9 +37,6 @@ // Global offset instead of address for an oop within a java object. enum class narrowOop : uint32_t { null = 0 }; -// If compressed klass pointers then use narrowKlass. -typedef juint narrowKlass; - typedef void* OopOrNarrowOopStar; #ifndef CHECK_UNHANDLED_OOPS diff --git a/src/hotspot/share/opto/matcher.hpp b/src/hotspot/share/opto/matcher.hpp index d7cff3d3f43..bac09c8e411 100644 --- a/src/hotspot/share/opto/matcher.hpp +++ b/src/hotspot/share/opto/matcher.hpp @@ -27,6 +27,7 @@ #include "libadt/vectset.hpp" #include "memory/resourceArea.hpp" +#include "oops/compressedKlass.hpp" #include "oops/compressedOops.hpp" #include "opto/node.hpp" #include "opto/phaseX.hpp" diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 83df87bbb13..bbf912f0080 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -41,6 +41,7 @@ #include "logging/logStream.hpp" #include "logging/logTag.hpp" #include "memory/allocation.inline.hpp" +#include "oops/compressedKlass.hpp" #include "oops/instanceKlass.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiAgentList.hpp" diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index fe9772982a8..89511362dc1 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -39,7 +39,7 @@ #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" -#include "oops/compressedOops.inline.hpp" +#include "oops/compressedKlass.inline.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiAgent.hpp" #include "prims/jvm_misc.hpp" diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 537f063a2b1..dd7ed0e8a42 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -379,8 +379,8 @@ /* CompressedKlassPointers */ \ /***************************/ \ \ - static_field(CompressedKlassPointers, _narrow_klass._base, address) \ - static_field(CompressedKlassPointers, _narrow_klass._shift, int) \ + static_field(CompressedKlassPointers, _base, address) \ + static_field(CompressedKlassPointers, _shift, int) \ \ /**********/ \ /* Memory */ \ diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp index 6cb00d338ff..a1547e7ed43 100644 --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -584,11 +584,6 @@ extern int MinObjAlignmentInBytesMask; extern int LogMinObjAlignment; extern int LogMinObjAlignmentInBytes; -const int LogKlassAlignmentInBytes = 3; -const int LogKlassAlignment = LogKlassAlignmentInBytes - LogHeapWordSize; -const int KlassAlignmentInBytes = 1 << LogKlassAlignmentInBytes; -const int KlassAlignment = KlassAlignmentInBytes / HeapWordSize; - // Maximal size of heap where unscaled compression can be used. Also upper bound // for heap placement: 4GB. const uint64_t UnscaledOopHeapMax = (uint64_t(max_juint) + 1); @@ -596,11 +591,6 @@ const uint64_t UnscaledOopHeapMax = (uint64_t(max_juint) + 1); // placement for zero based compression algorithm: UnscaledOopHeapMax << LogMinObjAlignmentInBytes. extern uint64_t OopEncodingHeapMax; -// Maximal size of compressed class space. Above this limit compression is not possible. -// Also upper bound for placement of zero based class space. (Class space is further limited -// to be < 3G, see arguments.cpp.) -const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlassAlignmentInBytes; - // Machine dependent stuff // The maximum size of the code cache. Can be overridden by targets. diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/CompressedKlassPointers.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/CompressedKlassPointers.java index b8c0ead9e45..ac397aea4e2 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/CompressedKlassPointers.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/CompressedKlassPointers.java @@ -58,8 +58,8 @@ public class CompressedKlassPointers { private static synchronized void initialize(TypeDataBase db) { Type type = db.lookupType("CompressedKlassPointers"); - baseField = type.getAddressField("_narrow_klass._base"); - shiftField = type.getCIntegerField("_narrow_klass._shift"); + baseField = type.getAddressField("_base"); + shiftField = type.getCIntegerField("_shift"); } public CompressedKlassPointers() {