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