Tue, 11 Nov 2014 11:05:41 +0100
8056071: compiler/whitebox/IsMethodCompilableTest.java fails with 'method() is not compilable after 3 iterations'
Summary: Always use MDO if valid and always compile trivial methods with C1 if available.
Reviewed-by: kvn, iveresov
duke@435 | 1 | /* |
hseigel@5528 | 2 | * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
trims@1907 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | * or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | * questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
stefank@2314 | 25 | #ifndef SHARE_VM_OOPS_OOPSHIERARCHY_HPP |
stefank@2314 | 26 | #define SHARE_VM_OOPS_OOPSHIERARCHY_HPP |
stefank@2314 | 27 | |
stefank@2314 | 28 | #include "runtime/globals.hpp" |
stefank@2314 | 29 | #include "utilities/globalDefinitions.hpp" |
stefank@2314 | 30 | |
duke@435 | 31 | // OBJECT hierarchy |
duke@435 | 32 | // This hierarchy is a representation hierarchy, i.e. if A is a superclass |
duke@435 | 33 | // of B, A's representation is a prefix of B's representation. |
duke@435 | 34 | |
coleenp@548 | 35 | typedef juint narrowOop; // Offset instead of address for an oop within a java object |
hseigel@5528 | 36 | |
hseigel@5528 | 37 | // If compressed klass pointers then use narrowKlass. |
hseigel@5528 | 38 | typedef juint narrowKlass; |
hseigel@5528 | 39 | |
ysr@1280 | 40 | typedef void* OopOrNarrowOopStar; |
coleenp@4037 | 41 | typedef class markOopDesc* markOop; |
coleenp@548 | 42 | |
duke@435 | 43 | #ifndef CHECK_UNHANDLED_OOPS |
duke@435 | 44 | |
coleenp@548 | 45 | typedef class oopDesc* oop; |
duke@435 | 46 | typedef class instanceOopDesc* instanceOop; |
coleenp@548 | 47 | typedef class arrayOopDesc* arrayOop; |
coleenp@548 | 48 | typedef class objArrayOopDesc* objArrayOop; |
coleenp@548 | 49 | typedef class typeArrayOopDesc* typeArrayOop; |
duke@435 | 50 | |
duke@435 | 51 | #else |
duke@435 | 52 | |
duke@435 | 53 | // When CHECK_UNHANDLED_OOPS is defined, an "oop" is a class with a |
duke@435 | 54 | // carefully chosen set of constructors and conversion operators to go |
duke@435 | 55 | // to and from the underlying oopDesc pointer type. |
duke@435 | 56 | // |
duke@435 | 57 | // Because oop and its subclasses <type>Oop are class types, arbitrary |
hseigel@5784 | 58 | // conversions are not accepted by the compiler. Applying a cast to |
hseigel@5784 | 59 | // an oop will cause the best matched conversion operator to be |
hseigel@5784 | 60 | // invoked returning the underlying oopDesc* type if appropriate. |
hseigel@5784 | 61 | // No copy constructors, explicit user conversions or operators of |
hseigel@5784 | 62 | // numerical type should be defined within the oop class. Most C++ |
hseigel@5784 | 63 | // compilers will issue a compile time error concerning the overloading |
hseigel@5784 | 64 | // ambiguity between operators of numerical and pointer types. If |
hseigel@5784 | 65 | // a conversion to or from an oop to a numerical type is needed, |
hseigel@5784 | 66 | // use the inline template methods, cast_*_oop, defined below. |
hseigel@5784 | 67 | // |
duke@435 | 68 | // Converting NULL to oop to Handle implicit is no longer accepted by the |
duke@435 | 69 | // compiler because there are too many steps in the conversion. Use Handle() |
duke@435 | 70 | // instead, which generates less code anyway. |
duke@435 | 71 | |
duke@435 | 72 | class Thread; |
duke@435 | 73 | class PromotedObject; |
duke@435 | 74 | |
duke@435 | 75 | |
duke@435 | 76 | class oop { |
duke@435 | 77 | oopDesc* _o; |
duke@435 | 78 | |
duke@435 | 79 | void register_oop(); |
duke@435 | 80 | void unregister_oop(); |
duke@435 | 81 | |
duke@435 | 82 | // friend class markOop; |
duke@435 | 83 | public: |
duke@435 | 84 | void set_obj(const void* p) { |
duke@435 | 85 | raw_set_obj(p); |
duke@435 | 86 | if (CheckUnhandledOops) register_oop(); |
duke@435 | 87 | } |
duke@435 | 88 | void raw_set_obj(const void* p) { _o = (oopDesc*)p; } |
duke@435 | 89 | |
duke@435 | 90 | oop() { set_obj(NULL); } |
hseigel@5784 | 91 | oop(const oop& o) { set_obj(o.obj()); } |
duke@435 | 92 | oop(const volatile oop& o) { set_obj(o.obj()); } |
duke@435 | 93 | oop(const void* p) { set_obj(p); } |
duke@435 | 94 | ~oop() { |
duke@435 | 95 | if (CheckUnhandledOops) unregister_oop(); |
duke@435 | 96 | } |
duke@435 | 97 | |
duke@435 | 98 | oopDesc* obj() const volatile { return _o; } |
duke@435 | 99 | |
duke@435 | 100 | // General access |
duke@435 | 101 | oopDesc* operator->() const { return obj(); } |
duke@435 | 102 | bool operator==(const oop o) const { return obj() == o.obj(); } |
duke@435 | 103 | bool operator==(void *p) const { return obj() == p; } |
coleenp@4037 | 104 | bool operator!=(const volatile oop o) const { return obj() != o.obj(); } |
duke@435 | 105 | bool operator!=(void *p) const { return obj() != p; } |
duke@435 | 106 | |
duke@435 | 107 | bool operator<(oop o) const { return obj() < o.obj(); } |
duke@435 | 108 | bool operator>(oop o) const { return obj() > o.obj(); } |
duke@435 | 109 | bool operator<=(oop o) const { return obj() <= o.obj(); } |
duke@435 | 110 | bool operator>=(oop o) const { return obj() >= o.obj(); } |
duke@435 | 111 | bool operator!() const { return !obj(); } |
duke@435 | 112 | |
hseigel@5784 | 113 | // Assignment |
hseigel@5784 | 114 | oop& operator=(const oop& o) { _o = o.obj(); return *this; } |
hseigel@5784 | 115 | #ifndef SOLARIS |
hseigel@5784 | 116 | volatile oop& operator=(const oop& o) volatile { _o = o.obj(); return *this; } |
hseigel@5784 | 117 | #endif |
hseigel@5784 | 118 | volatile oop& operator=(const volatile oop& o) volatile { _o = o.obj(); return *this; } |
hseigel@5784 | 119 | |
hseigel@5784 | 120 | // Explict user conversions |
duke@435 | 121 | operator void* () const { return (void *)obj(); } |
hseigel@5784 | 122 | #ifndef SOLARIS |
hseigel@5784 | 123 | operator void* () const volatile { return (void *)obj(); } |
hseigel@5784 | 124 | #endif |
duke@435 | 125 | operator HeapWord* () const { return (HeapWord*)obj(); } |
duke@435 | 126 | operator oopDesc* () const { return obj(); } |
duke@435 | 127 | operator intptr_t* () const { return (intptr_t*)obj(); } |
duke@435 | 128 | operator PromotedObject* () const { return (PromotedObject*)obj(); } |
duke@435 | 129 | operator markOop () const { return markOop(obj()); } |
duke@435 | 130 | |
duke@435 | 131 | operator address () const { return (address)obj(); } |
duke@435 | 132 | |
duke@435 | 133 | // from javaCalls.cpp |
duke@435 | 134 | operator jobject () const { return (jobject)obj(); } |
duke@435 | 135 | // from javaClasses.cpp |
duke@435 | 136 | operator JavaThread* () const { return (JavaThread*)obj(); } |
xlu@948 | 137 | |
xlu@948 | 138 | #ifndef _LP64 |
duke@435 | 139 | // from jvm.cpp |
duke@435 | 140 | operator jlong* () const { return (jlong*)obj(); } |
xlu@948 | 141 | #endif |
duke@435 | 142 | |
duke@435 | 143 | // from parNewGeneration and other things that want to get to the end of |
coleenp@4142 | 144 | // an oop for stuff (like ObjArrayKlass.cpp) |
duke@435 | 145 | operator oop* () const { return (oop *)obj(); } |
duke@435 | 146 | }; |
duke@435 | 147 | |
duke@435 | 148 | #define DEF_OOP(type) \ |
duke@435 | 149 | class type##OopDesc; \ |
duke@435 | 150 | class type##Oop : public oop { \ |
duke@435 | 151 | public: \ |
duke@435 | 152 | type##Oop() : oop() {} \ |
hseigel@5784 | 153 | type##Oop(const oop& o) : oop(o) {} \ |
duke@435 | 154 | type##Oop(const volatile oop& o) : oop(o) {} \ |
duke@435 | 155 | type##Oop(const void* p) : oop(p) {} \ |
duke@435 | 156 | operator type##OopDesc* () const { return (type##OopDesc*)obj(); } \ |
duke@435 | 157 | type##OopDesc* operator->() const { \ |
duke@435 | 158 | return (type##OopDesc*)obj(); \ |
duke@435 | 159 | } \ |
hseigel@5784 | 160 | type##Oop& operator=(const type##Oop& o) { \ |
hseigel@5784 | 161 | oop::operator=(o); \ |
hseigel@5784 | 162 | return *this; \ |
hseigel@5784 | 163 | } \ |
hseigel@5784 | 164 | NOT_SOLARIS( \ |
hseigel@5784 | 165 | volatile type##Oop& operator=(const type##Oop& o) volatile { \ |
hseigel@5784 | 166 | (void)const_cast<oop&>(oop::operator=(o)); \ |
hseigel@5784 | 167 | return *this; \ |
hseigel@5784 | 168 | }) \ |
hseigel@5784 | 169 | volatile type##Oop& operator=(const volatile type##Oop& o) volatile {\ |
hseigel@5784 | 170 | (void)const_cast<oop&>(oop::operator=(o)); \ |
hseigel@5784 | 171 | return *this; \ |
hseigel@5784 | 172 | } \ |
coleenp@4037 | 173 | }; |
duke@435 | 174 | |
duke@435 | 175 | DEF_OOP(instance); |
duke@435 | 176 | DEF_OOP(array); |
duke@435 | 177 | DEF_OOP(objArray); |
duke@435 | 178 | DEF_OOP(typeArray); |
duke@435 | 179 | |
duke@435 | 180 | #endif // CHECK_UNHANDLED_OOPS |
duke@435 | 181 | |
hseigel@5784 | 182 | // For CHECK_UNHANDLED_OOPS, it is ambiguous C++ behavior to have the oop |
hseigel@5784 | 183 | // structure contain explicit user defined conversions of both numerical |
hseigel@5784 | 184 | // and pointer type. Define inline methods to provide the numerical conversions. |
hseigel@5784 | 185 | template <class T> inline oop cast_to_oop(T value) { |
hseigel@5784 | 186 | return (oop)(CHECK_UNHANDLED_OOPS_ONLY((void *))(value)); |
hseigel@5784 | 187 | } |
hseigel@5784 | 188 | template <class T> inline T cast_from_oop(oop o) { |
hseigel@5784 | 189 | return (T)(CHECK_UNHANDLED_OOPS_ONLY((void*))o); |
hseigel@5784 | 190 | } |
hseigel@5784 | 191 | |
coleenp@4037 | 192 | // The metadata hierarchy is separate from the oop hierarchy |
coleenp@4037 | 193 | |
coleenp@4037 | 194 | // class MetaspaceObj |
coleenp@4037 | 195 | class ConstMethod; |
coleenp@4037 | 196 | class ConstantPoolCache; |
coleenp@4037 | 197 | class MethodData; |
coleenp@4037 | 198 | // class Metadata |
coleenp@4037 | 199 | class Method; |
coleenp@4037 | 200 | class ConstantPool; |
coleenp@4037 | 201 | // class CHeapObj |
coleenp@4037 | 202 | class CompiledICHolder; |
coleenp@4037 | 203 | |
coleenp@4037 | 204 | |
duke@435 | 205 | // The klass hierarchy is separate from the oop hierarchy. |
duke@435 | 206 | |
duke@435 | 207 | class Klass; |
coleenp@4037 | 208 | class InstanceKlass; |
coleenp@4047 | 209 | class InstanceMirrorKlass; |
coleenp@4047 | 210 | class InstanceClassLoaderKlass; |
coleenp@4047 | 211 | class InstanceRefKlass; |
coleenp@4142 | 212 | class ArrayKlass; |
coleenp@4142 | 213 | class ObjArrayKlass; |
coleenp@4142 | 214 | class TypeArrayKlass; |
stefank@2314 | 215 | |
stefank@2314 | 216 | #endif // SHARE_VM_OOPS_OOPSHIERARCHY_HPP |