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_INLINE_HPP
28 #define SHARE_OOPS_COMPRESSEDKLASS_INLINE_HPP
29 
30 #include "oops/compressedKlass.hpp"
31 #include "memory/allStatic.hpp"
32 #include "utilities/align.hpp"
33 #include "utilities/globalDefinitions.hpp"
34 
35 
36 inline Klass* CompressedKlassPointers::decode_raw(narrowKlass v) {
37   return decode_raw(v, base());
38 }
39 
40 inline Klass* CompressedKlassPointers::decode_raw(narrowKlass v, address narrow_base) {
41   return (Klass*)(void*)((uintptr_t)narrow_base +((uintptr_t)v << shift()));
42 }
43 
44 inline Klass* CompressedKlassPointers::decode_not_null(narrowKlass v) {
45   return decode_not_null(v, base());
46 }
47 
48 inline Klass* CompressedKlassPointers::decode_not_null(narrowKlass v, address narrow_base) {
49   assert(!is_null(v), "narrow klass value can never be zero");
50   Klass* result = decode_raw(v, narrow_base);
51   DEBUG_ONLY(verify_klass_pointer(result, narrow_base));
52   return result;
53 }
54 
55 inline Klass* CompressedKlassPointers::decode(narrowKlass v) {
56   return is_null(v) ? (Klass*)NULL : decode_not_null(v);
57 }
58 
59 inline narrowKlass CompressedKlassPointers::encode_not_null(Klass* v) {
60   return encode_not_null(v, base());
61 }
62 
63 inline narrowKlass CompressedKlassPointers::encode_not_null(Klass* v, address narrow_base) {
64   DEBUG_ONLY(verify_klass_pointer(v, narrow_base));
65   uint64_t v2 = (uint64_t)(pointer_delta((void*)v, narrow_base, 1));
66   v2 >>= shift();
67   assert(v2 <= UINT_MAX, "narrow klass pointer overflow");
68   narrowKlass result = (narrowKlass)v2;
69   DEBUG_ONLY(verify_narrow_klass_pointer(result));
70   assert(decode_not_null(result, narrow_base) == v, "reversibility");
71   return result;
72 }
73 
74 inline narrowKlass CompressedKlassPointers::encode(Klass* v) {
75   return is_null(v) ? (narrowKlass)0 : encode_not_null(v);
76 }
77 
78 #ifdef ASSERT
79 inline void CompressedKlassPointers::verify_klass_pointer(const Klass* v, address narrow_base) {
80   assert(is_aligned(v, KlassAlignmentInBytes), "misaligned Klass* pointer (" PTR_FORMAT ")", p2i(v));
81   address end = narrow_base + KlassEncodingMetaspaceMax;
82   assert((address)v >= narrow_base && (address)v < end,
83          "Klass (" PTR_FORMAT ") located outside encoding range [" PTR_FORMAT ", " PTR_FORMAT ")",
84          p2i(v), p2i(narrow_base), p2i(end));
85 }
86 
87 inline void CompressedKlassPointers::verify_klass_pointer(const Klass* v) {
88   verify_klass_pointer(v, base());
89 }
90 
91 inline void CompressedKlassPointers::verify_narrow_klass_pointer(narrowKlass v) {
92   // Make sure we only use the lower n bits
93   assert((((uint64_t)v) & ~NarrowKlassPointerBitMask) == 0, "%x: not a valid narrow klass pointer", v);
94 }
95 #endif
96 
97 #endif // SHARE_OOPS_COMPRESSEDOOPS_HPP