1/*
2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_OOPS_COMPRESSEDOOPS_HPP
26#define SHARE_OOPS_COMPRESSEDOOPS_HPP
27
28#include "memory/allocation.hpp"
29#include "oops/oopsHierarchy.hpp"
30#include "utilities/globalDefinitions.hpp"
31
32class outputStream;
33
34struct NarrowPtrStruct {
35 // Base address for oop-within-java-object materialization.
36 // NULL if using wide oops or zero based narrow oops.
37 address _base;
38 // Number of shift bits for encoding/decoding narrow ptrs.
39 // 0 if using wide ptrs or zero based unscaled narrow ptrs,
40 // LogMinObjAlignmentInBytes/LogKlassAlignmentInBytes otherwise.
41 int _shift;
42 // Generate code with implicit null checks for narrow ptrs.
43 bool _use_implicit_null_checks;
44};
45
46class CompressedOops : public AllStatic {
47 friend class VMStructs;
48
49 // For UseCompressedOops.
50 static NarrowPtrStruct _narrow_oop;
51
52 static address _narrow_ptrs_base;
53
54public:
55 // For UseCompressedOops
56 // Narrow Oop encoding mode:
57 // 0 - Use 32-bits oops without encoding when
58 // NarrowOopHeapBaseMin + heap_size < 4Gb
59 // 1 - Use zero based compressed oops with encoding when
60 // NarrowOopHeapBaseMin + heap_size < 32Gb
61 // 2 - Use compressed oops with disjoint heap base if
62 // base is 32G-aligned and base > 0. This allows certain
63 // optimizations in encoding/decoding.
64 // Disjoint: Bits used in base are disjoint from bits used
65 // for oops ==> oop = (cOop << 3) | base. One can disjoint
66 // the bits of an oop into base and compressed oop.
67 // 3 - Use compressed oops with heap base + encoding.
68 enum Mode {
69 UnscaledNarrowOop = 0,
70 ZeroBasedNarrowOop = 1,
71 DisjointBaseNarrowOop = 2,
72 HeapBasedNarrowOop = 3,
73 AnyNarrowOopMode = 4
74 };
75
76 static void initialize();
77
78 static void set_base(address base);
79 static void set_shift(int shift);
80 static void set_use_implicit_null_checks(bool use);
81
82 static void set_ptrs_base(address addr);
83
84 static address base() { return _narrow_oop._base; }
85 static bool is_base(void* addr) { return (base() == (address)addr); }
86 static int shift() { return _narrow_oop._shift; }
87 static bool use_implicit_null_checks() { return _narrow_oop._use_implicit_null_checks; }
88
89 static address* ptrs_base_addr() { return &_narrow_ptrs_base; }
90 static address ptrs_base() { return _narrow_ptrs_base; }
91
92 static Mode mode();
93 static const char* mode_to_string(Mode mode);
94
95 // Test whether bits of addr and possible offsets into the heap overlap.
96 static bool is_disjoint_heap_base_address(address addr);
97
98 // Check for disjoint base compressed oops.
99 static bool base_disjoint();
100
101 // Check for real heapbased compressed oops.
102 // We must subtract the base as the bits overlap.
103 // If we negate above function, we also get unscaled and zerobased.
104 static bool base_overlaps();
105
106 static void print_mode(outputStream* st);
107
108 static bool is_null(oop v) { return v == NULL; }
109 static bool is_null(narrowOop v) { return v == 0; }
110
111 static inline oop decode_raw(narrowOop v);
112 static inline oop decode_not_null(narrowOop v);
113 static inline oop decode(narrowOop v);
114 static inline narrowOop encode_not_null(oop v);
115 static inline narrowOop encode(oop v);
116
117 // No conversions needed for these overloads
118 static oop decode_not_null(oop v) { return v; }
119 static oop decode(oop v) { return v; }
120 static narrowOop encode_not_null(narrowOop v) { return v; }
121 static narrowOop encode(narrowOop v) { return v; }
122};
123
124// For UseCompressedClassPointers.
125class CompressedKlassPointers : public AllStatic {
126 friend class VMStructs;
127
128 static NarrowPtrStruct _narrow_klass;
129
130 // CompressedClassSpaceSize set to 1GB, but appear 3GB away from _narrow_ptrs_base during CDS dump.
131 static uint64_t _narrow_klass_range;
132
133public:
134 static void set_base(address base);
135 static void set_shift(int shift);
136 static void set_range(uint64_t range);
137
138 static address base() { return _narrow_klass._base; }
139 static uint64_t range() { return _narrow_klass_range; }
140 static int shift() { return _narrow_klass._shift; }
141
142 static bool is_null(Klass* v) { return v == NULL; }
143 static bool is_null(narrowKlass v) { return v == 0; }
144
145 static inline Klass* decode_raw(narrowKlass v);
146 static inline Klass* decode_not_null(narrowKlass v);
147 static inline Klass* decode(narrowKlass v);
148 static inline narrowKlass encode_not_null(Klass* v);
149 static inline narrowKlass encode(Klass* v);
150};
151
152#endif // SHARE_OOPS_COMPRESSEDOOPS_HPP
153