Mon, 09 Jun 2008 11:51:19 -0400
6687581: Make CMS work with compressed oops
Summary: Make FreeChunk read markword instead of LSB in _klass pointer to indicate that it's a FreeChunk for compressed oops.
Reviewed-by: ysr, jmasa
duke@435 | 1 | /* |
duke@435 | 2 | * Copyright 1997-2007 Sun Microsystems, Inc. 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 | * |
duke@435 | 19 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
duke@435 | 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
duke@435 | 21 | * have any questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
duke@435 | 25 | // OBJECT hierarchy |
duke@435 | 26 | // This hierarchy is a representation hierarchy, i.e. if A is a superclass |
duke@435 | 27 | // of B, A's representation is a prefix of B's representation. |
duke@435 | 28 | |
coleenp@548 | 29 | typedef juint narrowOop; // Offset instead of address for an oop within a java object |
coleenp@548 | 30 | typedef class klassOopDesc* wideKlassOop; // to keep SA happy and unhandled oop |
coleenp@548 | 31 | // detector happy. |
coleenp@548 | 32 | |
duke@435 | 33 | #ifndef CHECK_UNHANDLED_OOPS |
duke@435 | 34 | |
coleenp@548 | 35 | typedef class oopDesc* oop; |
duke@435 | 36 | typedef class instanceOopDesc* instanceOop; |
coleenp@548 | 37 | typedef class methodOopDesc* methodOop; |
coleenp@548 | 38 | typedef class constMethodOopDesc* constMethodOop; |
coleenp@548 | 39 | typedef class methodDataOopDesc* methodDataOop; |
coleenp@548 | 40 | typedef class arrayOopDesc* arrayOop; |
coleenp@548 | 41 | typedef class objArrayOopDesc* objArrayOop; |
coleenp@548 | 42 | typedef class typeArrayOopDesc* typeArrayOop; |
coleenp@548 | 43 | typedef class constantPoolOopDesc* constantPoolOop; |
coleenp@548 | 44 | typedef class constantPoolCacheOopDesc* constantPoolCacheOop; |
coleenp@548 | 45 | typedef class symbolOopDesc* symbolOop; |
coleenp@548 | 46 | typedef class klassOopDesc* klassOop; |
coleenp@548 | 47 | typedef class markOopDesc* markOop; |
duke@435 | 48 | typedef class compiledICHolderOopDesc* compiledICHolderOop; |
duke@435 | 49 | |
duke@435 | 50 | #else |
duke@435 | 51 | |
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 |
duke@435 | 58 | // conversions are not accepted by the compiler, and you may get a message |
duke@435 | 59 | // about overloading ambiguity (between long and int is common when converting |
duke@435 | 60 | // from a constant in 64 bit mode), or unable to convert from type to 'oop'. |
duke@435 | 61 | // Applying a cast to one of these conversion operators first will get to the |
duke@435 | 62 | // underlying oopDesc* type if appropriate. |
duke@435 | 63 | // Converting NULL to oop to Handle implicit is no longer accepted by the |
duke@435 | 64 | // compiler because there are too many steps in the conversion. Use Handle() |
duke@435 | 65 | // instead, which generates less code anyway. |
duke@435 | 66 | |
duke@435 | 67 | class Thread; |
duke@435 | 68 | typedef class markOopDesc* markOop; |
duke@435 | 69 | class PromotedObject; |
duke@435 | 70 | |
duke@435 | 71 | |
duke@435 | 72 | class oop { |
duke@435 | 73 | oopDesc* _o; |
duke@435 | 74 | |
duke@435 | 75 | void register_oop(); |
duke@435 | 76 | void unregister_oop(); |
duke@435 | 77 | |
duke@435 | 78 | // friend class markOop; |
duke@435 | 79 | public: |
duke@435 | 80 | void set_obj(const void* p) { |
duke@435 | 81 | raw_set_obj(p); |
duke@435 | 82 | if (CheckUnhandledOops) register_oop(); |
duke@435 | 83 | } |
duke@435 | 84 | void raw_set_obj(const void* p) { _o = (oopDesc*)p; } |
duke@435 | 85 | |
duke@435 | 86 | oop() { set_obj(NULL); } |
duke@435 | 87 | oop(const volatile oop& o) { set_obj(o.obj()); } |
duke@435 | 88 | oop(const void* p) { set_obj(p); } |
duke@435 | 89 | oop(intptr_t i) { set_obj((void *)i); } |
duke@435 | 90 | #ifdef _LP64 |
duke@435 | 91 | oop(int i) { set_obj((void *)i); } |
duke@435 | 92 | #endif |
duke@435 | 93 | ~oop() { |
duke@435 | 94 | if (CheckUnhandledOops) unregister_oop(); |
duke@435 | 95 | } |
duke@435 | 96 | |
duke@435 | 97 | oopDesc* obj() const volatile { return _o; } |
duke@435 | 98 | |
duke@435 | 99 | // General access |
duke@435 | 100 | oopDesc* operator->() const { return obj(); } |
duke@435 | 101 | bool operator==(const oop o) const { return obj() == o.obj(); } |
duke@435 | 102 | bool operator==(void *p) const { return obj() == p; } |
duke@435 | 103 | bool operator!=(const oop o) const { return obj() != o.obj(); } |
duke@435 | 104 | bool operator!=(void *p) const { return obj() != p; } |
duke@435 | 105 | bool operator==(intptr_t p) const { return obj() == (oopDesc*)p; } |
duke@435 | 106 | bool operator!=(intptr_t p) const { return obj() != (oopDesc*)p; } |
duke@435 | 107 | |
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>=(oop o) const { return obj() >= o.obj(); } |
duke@435 | 112 | bool operator!() const { return !obj(); } |
duke@435 | 113 | |
duke@435 | 114 | // Cast |
duke@435 | 115 | operator void* () const { return (void *)obj(); } |
duke@435 | 116 | operator HeapWord* () const { return (HeapWord*)obj(); } |
duke@435 | 117 | operator oopDesc* () const { return obj(); } |
duke@435 | 118 | operator intptr_t* () const { return (intptr_t*)obj(); } |
duke@435 | 119 | operator PromotedObject* () const { return (PromotedObject*)obj(); } |
duke@435 | 120 | operator markOop () const { return markOop(obj()); } |
duke@435 | 121 | |
duke@435 | 122 | operator address () const { return (address)obj(); } |
duke@435 | 123 | operator intptr_t () const { return (intptr_t)obj(); } |
duke@435 | 124 | |
duke@435 | 125 | // from javaCalls.cpp |
duke@435 | 126 | operator jobject () const { return (jobject)obj(); } |
duke@435 | 127 | // from javaClasses.cpp |
duke@435 | 128 | operator JavaThread* () const { return (JavaThread*)obj(); } |
duke@435 | 129 | // from jvm.cpp |
duke@435 | 130 | operator jlong* () const { return (jlong*)obj(); } |
duke@435 | 131 | |
duke@435 | 132 | // from parNewGeneration and other things that want to get to the end of |
duke@435 | 133 | // an oop for stuff (like constMethodKlass.cpp, objArrayKlass.cpp) |
duke@435 | 134 | operator oop* () const { return (oop *)obj(); } |
duke@435 | 135 | }; |
duke@435 | 136 | |
duke@435 | 137 | #define DEF_OOP(type) \ |
duke@435 | 138 | class type##OopDesc; \ |
duke@435 | 139 | class type##Oop : public oop { \ |
duke@435 | 140 | public: \ |
duke@435 | 141 | type##Oop() : oop() {} \ |
duke@435 | 142 | type##Oop(const volatile oop& o) : oop(o) {} \ |
duke@435 | 143 | type##Oop(const void* p) : oop(p) {} \ |
duke@435 | 144 | operator type##OopDesc* () const { return (type##OopDesc*)obj(); } \ |
duke@435 | 145 | type##OopDesc* operator->() const { \ |
duke@435 | 146 | return (type##OopDesc*)obj(); \ |
duke@435 | 147 | } \ |
duke@435 | 148 | }; \ |
duke@435 | 149 | |
duke@435 | 150 | DEF_OOP(instance); |
duke@435 | 151 | DEF_OOP(method); |
duke@435 | 152 | DEF_OOP(methodData); |
duke@435 | 153 | DEF_OOP(array); |
duke@435 | 154 | DEF_OOP(constMethod); |
duke@435 | 155 | DEF_OOP(constantPool); |
duke@435 | 156 | DEF_OOP(constantPoolCache); |
duke@435 | 157 | DEF_OOP(objArray); |
duke@435 | 158 | DEF_OOP(typeArray); |
duke@435 | 159 | DEF_OOP(symbol); |
duke@435 | 160 | DEF_OOP(klass); |
duke@435 | 161 | DEF_OOP(compiledICHolder); |
duke@435 | 162 | |
duke@435 | 163 | #endif // CHECK_UNHANDLED_OOPS |
duke@435 | 164 | |
duke@435 | 165 | // The klass hierarchy is separate from the oop hierarchy. |
duke@435 | 166 | |
duke@435 | 167 | class Klass; |
duke@435 | 168 | class instanceKlass; |
duke@435 | 169 | class instanceRefKlass; |
duke@435 | 170 | class methodKlass; |
duke@435 | 171 | class constMethodKlass; |
duke@435 | 172 | class methodDataKlass; |
duke@435 | 173 | class klassKlass; |
duke@435 | 174 | class instanceKlassKlass; |
duke@435 | 175 | class arrayKlassKlass; |
duke@435 | 176 | class objArrayKlassKlass; |
duke@435 | 177 | class typeArrayKlassKlass; |
duke@435 | 178 | class arrayKlass; |
duke@435 | 179 | class objArrayKlass; |
duke@435 | 180 | class typeArrayKlass; |
coleenp@548 | 181 | class constantPoolKlass; |
coleenp@548 | 182 | class constantPoolCacheKlass; |
coleenp@548 | 183 | class symbolKlass; |
duke@435 | 184 | class compiledICHolderKlass; |