1 /*
  2  * Copyright (c) 2021 SAP SE. All rights reserved.
  3  * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
  4  *
  5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  6  *
  7  * This code is free software; you can redistribute it and/or modify it
  8  * under the terms of the GNU General Public License version 2 only, as
  9  * published by the Free Software Foundation.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  *
 25  */
 26 
 27 #ifndef SHARE_OOPS_COMPRESSEDKLASS_HPP
 28 #define SHARE_OOPS_COMPRESSEDKLASS_HPP
 29 
 30 #include "memory/allStatic.hpp"
 31 #include "utilities/globalDefinitions.hpp"
 32 
 33 class outputStream;
 34 class Klass;
 35 
 36 // Narrow Klass pointer constants;
 37 #ifdef _LP64
 38 const int LogKlassAlignmentInBytes = 9; // 512 byte alignment (Lilliput)
 39 #else
 40 const int LogKlassAlignmentInBytes = 3; // traditional 64-bit alignment
 41 #endif
 42 
 43 const int KlassAlignmentInBytes    = 1 << LogKlassAlignmentInBytes;
 44 
 45 // Max. allowed size of compressed class pointer, in bits
 46 const  int      MaxNarrowKlassPointerBits = 22;
 47 
 48 // Mask to mask in the bits which are valid to be set in a narrow Klass pointer
 49 const uint64_t  NarrowKlassPointerBitMask = ((((uint64_t)1) << MaxNarrowKlassPointerBits) - 1);
 50 
 51 // Maximal size of compressed class pointer encoding range (2G with 22bit class ptr and 9 bit alignment).
 52 const  uint64_t KlassEncodingMetaspaceMax = UCONST64(1) << (MaxNarrowKlassPointerBits + LogKlassAlignmentInBytes);
 53 
 54 // If compressed klass pointers then use narrowKlass.
 55 typedef uint32_t narrowKlass;
 56 
 57 class CompressedKlassPointers : public AllStatic {
 58   friend class VMStructs;
 59   friend class ArchiveBuilder;
 60 
 61   static address _base;
 62 
 63   // Shift is actually a constant; we keep this just for the SA (see vmStructs.cpp and
 64   // sun/jvm/hotspot/oops/CompressedKlassPointers.java)
 65   static int _shift_copy;
 66 
 67   // The decode/encode versions taking an explicit base are for the sole use of CDS
 68   // (see ArchiveBuilder).
 69   static inline Klass* decode_raw(narrowKlass v, address base);
 70   static inline Klass* decode_not_null(narrowKlass v, address base);
 71   static inline narrowKlass encode_not_null(Klass* v, address base);
 72   DEBUG_ONLY(static inline void verify_klass_pointer(const Klass* v, address base));
 73 
 74 public:
 75 
 76   // Given an address p, return true if p can be used as an encoding base.
 77   //  (Some platforms have restrictions of what constitutes a valid base
 78   //   address).
 79   static bool is_valid_base(address p);
 80 
 81   // Given an address range [addr, addr+len) which the encoding is supposed to
 82   //  cover, choose base, shift and range.
 83   //  The address range is the expected range of uncompressed Klass pointers we
 84   //  will encounter (and the implicit promise that there will be no Klass
 85   //  structures outside this range).
 86   static void initialize(address addr, size_t len);
 87 
 88   static void     print_mode(outputStream* st);
 89 
 90   // The encoding base. Note: this is not necessarily the base address of the
 91   // class space nor the base address of the CDS archive.
 92   static address  base()             { return  _base; }
 93 
 94   // End of the encoding range.
 95   static address  end()              { return base() + KlassEncodingMetaspaceMax; }
 96 
 97   // Shift == LogKlassAlignmentInBytes (TODO: unify)
 98   static int      shift()            { return  LogKlassAlignmentInBytes; }
 99 
100   static bool is_null(Klass* v)      { return v == NULL; }
101   static bool is_null(narrowKlass v) { return v == 0; }
102 
103   static inline Klass* decode_raw(narrowKlass v);
104   static inline Klass* decode_not_null(narrowKlass v);
105   static inline Klass* decode(narrowKlass v);
106   static inline narrowKlass encode_not_null(Klass* v);
107   static inline narrowKlass encode(Klass* v);
108 
109   DEBUG_ONLY(static inline void verify_klass_pointer(const Klass* v));
110   DEBUG_ONLY(static inline void verify_narrow_klass_pointer(narrowKlass v);)
111 
112 };
113 
114 #endif // SHARE_OOPS_COMPRESSEDOOPS_HPP