1/*
2 * Copyright (c) 1997, 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_OOPSHIERARCHY_HPP
26#define SHARE_OOPS_OOPSHIERARCHY_HPP
27
28#include "metaprogramming/integralConstant.hpp"
29#include "metaprogramming/primitiveConversions.hpp"
30#include "utilities/globalDefinitions.hpp"
31
32// OBJECT hierarchy
33// This hierarchy is a representation hierarchy, i.e. if A is a superclass
34// of B, A's representation is a prefix of B's representation.
35
36typedef juint narrowOop; // Offset instead of address for an oop within a java object
37
38// If compressed klass pointers then use narrowKlass.
39typedef juint narrowKlass;
40
41typedef void* OopOrNarrowOopStar;
42typedef class markOopDesc* markOop;
43
44#ifndef CHECK_UNHANDLED_OOPS
45
46typedef class oopDesc* oop;
47typedef class instanceOopDesc* instanceOop;
48typedef class arrayOopDesc* arrayOop;
49typedef class objArrayOopDesc* objArrayOop;
50typedef class typeArrayOopDesc* typeArrayOop;
51
52#else
53
54// When CHECK_UNHANDLED_OOPS is defined, an "oop" is a class with a
55// carefully chosen set of constructors and conversion operators to go
56// to and from the underlying oopDesc pointer type.
57//
58// Because oop and its subclasses <type>Oop are class types, arbitrary
59// conversions are not accepted by the compiler. Applying a cast to
60// an oop will cause the best matched conversion operator to be
61// invoked returning the underlying oopDesc* type if appropriate.
62// No copy constructors, explicit user conversions or operators of
63// numerical type should be defined within the oop class. Most C++
64// compilers will issue a compile time error concerning the overloading
65// ambiguity between operators of numerical and pointer types. If
66// a conversion to or from an oop to a numerical type is needed,
67// use the inline template methods, cast_*_oop, defined below.
68//
69// Converting NULL to oop to Handle implicit is no longer accepted by the
70// compiler because there are too many steps in the conversion. Use Handle()
71// instead, which generates less code anyway.
72
73class Thread;
74class PromotedObject;
75class oopDesc;
76
77extern bool CheckUnhandledOops;
78
79class oop {
80 oopDesc* _o;
81
82 void register_oop();
83 void unregister_oop();
84
85 // friend class markOop;
86public:
87 void set_obj(const void* p) {
88 raw_set_obj(p);
89 if (CheckUnhandledOops) register_oop();
90 }
91 void raw_set_obj(const void* p) { _o = (oopDesc*)p; }
92
93 oop() { set_obj(NULL); }
94 oop(const oop& o) { set_obj(o.obj()); }
95 oop(const volatile oop& o) { set_obj(o.obj()); }
96 oop(const void* p) { set_obj(p); }
97 ~oop() {
98 if (CheckUnhandledOops) unregister_oop();
99 }
100
101 oopDesc* obj() const volatile { return _o; }
102
103 // General access
104 oopDesc* operator->() const { return obj(); }
105 bool operator==(const oop o) const;
106 bool operator==(void *p) const { return obj() == p; }
107 bool operator!=(const volatile oop o) const;
108 bool operator!=(void *p) const { return obj() != p; }
109
110 // Assignment
111 oop& operator=(const oop& o) { _o = o.obj(); return *this; }
112 volatile oop& operator=(const oop& o) volatile { _o = o.obj(); return *this; }
113 volatile oop& operator=(const volatile oop& o) volatile { _o = o.obj(); return *this; }
114
115 // Explict user conversions
116 operator void* () const { return (void *)obj(); }
117#ifndef SOLARIS
118 operator void* () const volatile { return (void *)obj(); }
119#endif
120 operator HeapWord* () const { return (HeapWord*)obj(); }
121 operator oopDesc* () const volatile { return obj(); }
122 operator intptr_t* () const { return (intptr_t*)obj(); }
123 operator PromotedObject* () const { return (PromotedObject*)obj(); }
124 operator markOop () const volatile { return markOop(obj()); }
125 operator address () const { return (address)obj(); }
126
127 // from javaCalls.cpp
128 operator jobject () const { return (jobject)obj(); }
129
130 // from parNewGeneration and other things that want to get to the end of
131 // an oop for stuff (like ObjArrayKlass.cpp)
132 operator oop* () const { return (oop *)obj(); }
133};
134
135template<>
136struct PrimitiveConversions::Translate<oop> : public TrueType {
137 typedef oop Value;
138 typedef oopDesc* Decayed;
139
140 static Decayed decay(Value x) { return x.obj(); }
141 static Value recover(Decayed x) { return oop(x); }
142};
143
144#define DEF_OOP(type) \
145 class type##OopDesc; \
146 class type##Oop : public oop { \
147 public: \
148 type##Oop() : oop() {} \
149 type##Oop(const oop& o) : oop(o) {} \
150 type##Oop(const volatile oop& o) : oop(o) {} \
151 type##Oop(const void* p) : oop(p) {} \
152 operator type##OopDesc* () const { return (type##OopDesc*)obj(); } \
153 type##OopDesc* operator->() const { \
154 return (type##OopDesc*)obj(); \
155 } \
156 type##Oop& operator=(const type##Oop& o) { \
157 oop::operator=(o); \
158 return *this; \
159 } \
160 volatile type##Oop& operator=(const type##Oop& o) volatile { \
161 (void)const_cast<oop&>(oop::operator=(o)); \
162 return *this; \
163 } \
164 volatile type##Oop& operator=(const volatile type##Oop& o) volatile {\
165 (void)const_cast<oop&>(oop::operator=(o)); \
166 return *this; \
167 } \
168 }; \
169 \
170 template<> \
171 struct PrimitiveConversions::Translate<type##Oop> : public TrueType { \
172 typedef type##Oop Value; \
173 typedef type##OopDesc* Decayed; \
174 \
175 static Decayed decay(Value x) { return (type##OopDesc*)x.obj(); } \
176 static Value recover(Decayed x) { return type##Oop(x); } \
177 };
178
179DEF_OOP(instance);
180DEF_OOP(array);
181DEF_OOP(objArray);
182DEF_OOP(typeArray);
183
184#endif // CHECK_UNHANDLED_OOPS
185
186// For CHECK_UNHANDLED_OOPS, it is ambiguous C++ behavior to have the oop
187// structure contain explicit user defined conversions of both numerical
188// and pointer type. Define inline methods to provide the numerical conversions.
189template <class T> inline oop cast_to_oop(T value) {
190 return (oop)(CHECK_UNHANDLED_OOPS_ONLY((void *))(value));
191}
192template <class T> inline T cast_from_oop(oop o) {
193 return (T)(CHECK_UNHANDLED_OOPS_ONLY((void*))o);
194}
195
196inline bool check_obj_alignment(oop obj) {
197 return (cast_from_oop<intptr_t>(obj) & MinObjAlignmentInBytesMask) == 0;
198}
199
200// The metadata hierarchy is separate from the oop hierarchy
201
202// class MetaspaceObj
203class ConstMethod;
204class ConstantPoolCache;
205class MethodData;
206// class Metadata
207class Method;
208class ConstantPool;
209// class CHeapObj
210class CompiledICHolder;
211
212
213// The klass hierarchy is separate from the oop hierarchy.
214
215class Klass;
216class InstanceKlass;
217class InstanceMirrorKlass;
218class InstanceClassLoaderKlass;
219class InstanceRefKlass;
220class ArrayKlass;
221class ObjArrayKlass;
222class TypeArrayKlass;
223
224#endif // SHARE_OOPS_OOPSHIERARCHY_HPP
225