Tue, 15 Sep 2009 21:53:47 -0700
6863023: need non-perm oops in code cache for JSR 292
Summary: Make a special root-list for those few nmethods which might contain non-perm oops.
Reviewed-by: twisti, kvn, never, jmasa, ysr
duke@435 | 1 | /* |
duke@435 | 2 | * Copyright 1999-2006 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 | // ciObject |
duke@435 | 26 | // |
duke@435 | 27 | // This class represents an oop in the HotSpot virtual machine. |
duke@435 | 28 | // Its subclasses are structured in a hierarchy which mirrors |
duke@435 | 29 | // an aggregate of the VM's oop and klass hierarchies (see |
duke@435 | 30 | // oopHierarchy.hpp). Each instance of ciObject holds a handle |
duke@435 | 31 | // to a corresponding oop on the VM side and provides routines |
duke@435 | 32 | // for accessing the information in its oop. By using the ciObject |
duke@435 | 33 | // hierarchy for accessing oops in the VM, the compiler ensures |
duke@435 | 34 | // that it is safe with respect to garbage collection; that is, |
duke@435 | 35 | // GC and compilation can proceed independently without |
duke@435 | 36 | // interference. |
duke@435 | 37 | // |
duke@435 | 38 | // Within the VM, the oop and klass hierarchies are separate. |
duke@435 | 39 | // The compiler interface does not preserve this separation -- |
duke@435 | 40 | // the distinction between `klassOop' and `Klass' are not |
duke@435 | 41 | // reflected in the interface and instead the Klass hierarchy |
duke@435 | 42 | // is directly modeled as the subclasses of ciKlass. |
duke@435 | 43 | class ciObject : public ResourceObj { |
duke@435 | 44 | CI_PACKAGE_ACCESS |
duke@435 | 45 | friend class ciEnv; |
duke@435 | 46 | |
duke@435 | 47 | private: |
duke@435 | 48 | // A JNI handle referring to an oop in the VM. This |
duke@435 | 49 | // handle may, in a small set of cases, correctly be NULL. |
duke@435 | 50 | jobject _handle; |
duke@435 | 51 | ciKlass* _klass; |
duke@435 | 52 | uint _ident; |
duke@435 | 53 | |
jrose@1424 | 54 | enum { FLAG_BITS = 2 }; |
duke@435 | 55 | enum { |
jrose@1424 | 56 | PERM_FLAG = 1, |
jrose@1424 | 57 | SCAVENGABLE_FLAG = 2 |
duke@435 | 58 | }; |
duke@435 | 59 | protected: |
duke@435 | 60 | ciObject(); |
duke@435 | 61 | ciObject(oop o); |
duke@435 | 62 | ciObject(Handle h); |
duke@435 | 63 | ciObject(ciKlass* klass); |
duke@435 | 64 | |
duke@435 | 65 | jobject handle() const { return _handle; } |
duke@435 | 66 | // Get the VM oop that this object holds. |
duke@435 | 67 | oop get_oop() const { |
duke@435 | 68 | assert(_handle != NULL, "null oop"); |
duke@435 | 69 | return JNIHandles::resolve_non_null(_handle); |
duke@435 | 70 | } |
duke@435 | 71 | |
jrose@1424 | 72 | void init_flags_from(oop x) { |
jrose@1424 | 73 | int flags = 0; |
jrose@1424 | 74 | if (x != NULL) { |
jrose@1424 | 75 | if (x->is_perm()) |
jrose@1424 | 76 | flags |= PERM_FLAG; |
jrose@1424 | 77 | if (x->is_scavengable()) |
jrose@1424 | 78 | flags |= SCAVENGABLE_FLAG; |
jrose@1424 | 79 | } |
jrose@1424 | 80 | _ident |= flags; |
duke@435 | 81 | } |
duke@435 | 82 | |
duke@435 | 83 | // Virtual behavior of the print() method. |
duke@435 | 84 | virtual void print_impl(outputStream* st) {} |
duke@435 | 85 | |
duke@435 | 86 | virtual const char* type_string() { return "ciObject"; } |
duke@435 | 87 | |
duke@435 | 88 | void set_ident(uint id); |
duke@435 | 89 | public: |
duke@435 | 90 | // The klass of this ciObject. |
duke@435 | 91 | ciKlass* klass(); |
duke@435 | 92 | |
duke@435 | 93 | // A number unique to this object. |
duke@435 | 94 | uint ident(); |
duke@435 | 95 | |
duke@435 | 96 | // Are two ciObjects equal? |
duke@435 | 97 | bool equals(ciObject* obj); |
duke@435 | 98 | |
duke@435 | 99 | // A hash value for the convenience of compilers. |
duke@435 | 100 | int hash(); |
duke@435 | 101 | |
jrose@1424 | 102 | // Tells if this oop has an encoding as a constant. |
jrose@1424 | 103 | // True if is_scavengable is false. |
jrose@1424 | 104 | // Also true if ScavengeRootsInCode is non-zero. |
duke@435 | 105 | // If it does not have an encoding, the compiler is responsible for |
duke@435 | 106 | // making other arrangements for dealing with the oop. |
jrose@1424 | 107 | // See ciEnv::make_array |
jrose@1424 | 108 | bool can_be_constant(); |
jrose@1424 | 109 | |
jrose@1424 | 110 | // Tells if this oop should be made a constant. |
jrose@1424 | 111 | // True if is_scavengable is false or ScavengeRootsInCode > 1. |
jrose@1424 | 112 | bool should_be_constant(); |
duke@435 | 113 | |
duke@435 | 114 | // Is this object guaranteed to be in the permanent part of the heap? |
duke@435 | 115 | // If so, CollectedHeap::can_elide_permanent_oop_store_barriers is relevant. |
duke@435 | 116 | // If the answer is false, no guarantees are made. |
duke@435 | 117 | bool is_perm() { return (_ident & PERM_FLAG) != 0; } |
duke@435 | 118 | |
jrose@1424 | 119 | // Might this object possibly move during a scavenge operation? |
jrose@1424 | 120 | // If the answer is true and ScavengeRootsInCode==0, the oop cannot be embedded in code. |
jrose@1424 | 121 | bool is_scavengable() { return (_ident & SCAVENGABLE_FLAG) != 0; } |
jrose@1424 | 122 | |
duke@435 | 123 | // The address which the compiler should embed into the |
duke@435 | 124 | // generated code to represent this oop. This address |
duke@435 | 125 | // is not the true address of the oop -- it will get patched |
duke@435 | 126 | // during nmethod creation. |
duke@435 | 127 | // |
duke@435 | 128 | // Usage note: no address arithmetic allowed. Oop must |
duke@435 | 129 | // be registered with the oopRecorder. |
jrose@1424 | 130 | jobject constant_encoding(); |
duke@435 | 131 | |
duke@435 | 132 | // What kind of ciObject is this? |
duke@435 | 133 | virtual bool is_null_object() const { return false; } |
duke@435 | 134 | virtual bool is_instance() { return false; } |
duke@435 | 135 | virtual bool is_method() { return false; } |
duke@435 | 136 | virtual bool is_method_data() { return false; } |
duke@435 | 137 | virtual bool is_array() { return false; } |
duke@435 | 138 | virtual bool is_obj_array() { return false; } |
duke@435 | 139 | virtual bool is_type_array() { return false; } |
duke@435 | 140 | virtual bool is_symbol() { return false; } |
duke@435 | 141 | virtual bool is_type() { return false; } |
duke@435 | 142 | virtual bool is_return_address() { return false; } |
duke@435 | 143 | virtual bool is_klass() { return false; } |
duke@435 | 144 | virtual bool is_instance_klass() { return false; } |
duke@435 | 145 | virtual bool is_method_klass() { return false; } |
duke@435 | 146 | virtual bool is_array_klass() { return false; } |
duke@435 | 147 | virtual bool is_obj_array_klass() { return false; } |
duke@435 | 148 | virtual bool is_type_array_klass() { return false; } |
duke@435 | 149 | virtual bool is_symbol_klass() { return false; } |
duke@435 | 150 | virtual bool is_klass_klass() { return false; } |
duke@435 | 151 | virtual bool is_instance_klass_klass() { return false; } |
duke@435 | 152 | virtual bool is_array_klass_klass() { return false; } |
duke@435 | 153 | virtual bool is_obj_array_klass_klass() { return false; } |
duke@435 | 154 | virtual bool is_type_array_klass_klass() { return false; } |
duke@435 | 155 | |
duke@435 | 156 | // Is this a type or value which has no associated class? |
duke@435 | 157 | // It is true of primitive types and null objects. |
duke@435 | 158 | virtual bool is_classless() const { return false; } |
duke@435 | 159 | |
duke@435 | 160 | // Is this ciObject a Java Language Object? That is, |
duke@435 | 161 | // is the ciObject an instance or an array |
duke@435 | 162 | virtual bool is_java_object() { return false; } |
duke@435 | 163 | |
duke@435 | 164 | // Does this ciObject represent a Java Language class? |
duke@435 | 165 | // That is, is the ciObject an instanceKlass or arrayKlass? |
duke@435 | 166 | virtual bool is_java_klass() { return false; } |
duke@435 | 167 | |
duke@435 | 168 | // Is this ciObject the ciInstanceKlass representing |
duke@435 | 169 | // java.lang.Object()? |
duke@435 | 170 | virtual bool is_java_lang_Object() { return false; } |
duke@435 | 171 | |
duke@435 | 172 | // Does this ciObject refer to a real oop in the VM? |
duke@435 | 173 | // |
duke@435 | 174 | // Note: some ciObjects refer to oops which have yet to be |
duke@435 | 175 | // created. We refer to these as "unloaded". Specifically, |
duke@435 | 176 | // there are unloaded ciMethods, ciObjArrayKlasses, and |
duke@435 | 177 | // ciInstanceKlasses. By convention the ciNullObject is |
duke@435 | 178 | // considered loaded, and primitive types are considered loaded. |
duke@435 | 179 | bool is_loaded() const { |
duke@435 | 180 | return handle() != NULL || is_classless(); |
duke@435 | 181 | } |
duke@435 | 182 | |
duke@435 | 183 | // Subclass casting with assertions. |
duke@435 | 184 | ciNullObject* as_null_object() { |
duke@435 | 185 | assert(is_null_object(), "bad cast"); |
duke@435 | 186 | return (ciNullObject*)this; |
duke@435 | 187 | } |
duke@435 | 188 | ciInstance* as_instance() { |
duke@435 | 189 | assert(is_instance(), "bad cast"); |
duke@435 | 190 | return (ciInstance*)this; |
duke@435 | 191 | } |
duke@435 | 192 | ciMethod* as_method() { |
duke@435 | 193 | assert(is_method(), "bad cast"); |
duke@435 | 194 | return (ciMethod*)this; |
duke@435 | 195 | } |
duke@435 | 196 | ciMethodData* as_method_data() { |
duke@435 | 197 | assert(is_method_data(), "bad cast"); |
duke@435 | 198 | return (ciMethodData*)this; |
duke@435 | 199 | } |
duke@435 | 200 | ciArray* as_array() { |
duke@435 | 201 | assert(is_array(), "bad cast"); |
duke@435 | 202 | return (ciArray*)this; |
duke@435 | 203 | } |
duke@435 | 204 | ciObjArray* as_obj_array() { |
duke@435 | 205 | assert(is_obj_array(), "bad cast"); |
duke@435 | 206 | return (ciObjArray*)this; |
duke@435 | 207 | } |
duke@435 | 208 | ciTypeArray* as_type_array() { |
duke@435 | 209 | assert(is_type_array(), "bad cast"); |
duke@435 | 210 | return (ciTypeArray*)this; |
duke@435 | 211 | } |
duke@435 | 212 | ciSymbol* as_symbol() { |
duke@435 | 213 | assert(is_symbol(), "bad cast"); |
duke@435 | 214 | return (ciSymbol*)this; |
duke@435 | 215 | } |
duke@435 | 216 | ciType* as_type() { |
duke@435 | 217 | assert(is_type(), "bad cast"); |
duke@435 | 218 | return (ciType*)this; |
duke@435 | 219 | } |
duke@435 | 220 | ciReturnAddress* as_return_address() { |
duke@435 | 221 | assert(is_return_address(), "bad cast"); |
duke@435 | 222 | return (ciReturnAddress*)this; |
duke@435 | 223 | } |
duke@435 | 224 | ciKlass* as_klass() { |
duke@435 | 225 | assert(is_klass(), "bad cast"); |
duke@435 | 226 | return (ciKlass*)this; |
duke@435 | 227 | } |
duke@435 | 228 | ciInstanceKlass* as_instance_klass() { |
duke@435 | 229 | assert(is_instance_klass(), "bad cast"); |
duke@435 | 230 | return (ciInstanceKlass*)this; |
duke@435 | 231 | } |
duke@435 | 232 | ciMethodKlass* as_method_klass() { |
duke@435 | 233 | assert(is_method_klass(), "bad cast"); |
duke@435 | 234 | return (ciMethodKlass*)this; |
duke@435 | 235 | } |
duke@435 | 236 | ciArrayKlass* as_array_klass() { |
duke@435 | 237 | assert(is_array_klass(), "bad cast"); |
duke@435 | 238 | return (ciArrayKlass*)this; |
duke@435 | 239 | } |
duke@435 | 240 | ciObjArrayKlass* as_obj_array_klass() { |
duke@435 | 241 | assert(is_obj_array_klass(), "bad cast"); |
duke@435 | 242 | return (ciObjArrayKlass*)this; |
duke@435 | 243 | } |
duke@435 | 244 | ciTypeArrayKlass* as_type_array_klass() { |
duke@435 | 245 | assert(is_type_array_klass(), "bad cast"); |
duke@435 | 246 | return (ciTypeArrayKlass*)this; |
duke@435 | 247 | } |
duke@435 | 248 | ciSymbolKlass* as_symbol_klass() { |
duke@435 | 249 | assert(is_symbol_klass(), "bad cast"); |
duke@435 | 250 | return (ciSymbolKlass*)this; |
duke@435 | 251 | } |
duke@435 | 252 | ciKlassKlass* as_klass_klass() { |
duke@435 | 253 | assert(is_klass_klass(), "bad cast"); |
duke@435 | 254 | return (ciKlassKlass*)this; |
duke@435 | 255 | } |
duke@435 | 256 | ciInstanceKlassKlass* as_instance_klass_klass() { |
duke@435 | 257 | assert(is_instance_klass_klass(), "bad cast"); |
duke@435 | 258 | return (ciInstanceKlassKlass*)this; |
duke@435 | 259 | } |
duke@435 | 260 | ciArrayKlassKlass* as_array_klass_klass() { |
duke@435 | 261 | assert(is_array_klass_klass(), "bad cast"); |
duke@435 | 262 | return (ciArrayKlassKlass*)this; |
duke@435 | 263 | } |
duke@435 | 264 | ciObjArrayKlassKlass* as_obj_array_klass_klass() { |
duke@435 | 265 | assert(is_obj_array_klass_klass(), "bad cast"); |
duke@435 | 266 | return (ciObjArrayKlassKlass*)this; |
duke@435 | 267 | } |
duke@435 | 268 | ciTypeArrayKlassKlass* as_type_array_klass_klass() { |
duke@435 | 269 | assert(is_type_array_klass_klass(), "bad cast"); |
duke@435 | 270 | return (ciTypeArrayKlassKlass*)this; |
duke@435 | 271 | } |
duke@435 | 272 | |
duke@435 | 273 | // Print debugging output about this ciObject. |
duke@435 | 274 | void print(outputStream* st = tty); |
duke@435 | 275 | |
duke@435 | 276 | // Print debugging output about the oop this ciObject represents. |
duke@435 | 277 | void print_oop(outputStream* st = tty); |
duke@435 | 278 | }; |