src/share/vm/oops/cpCacheOop.hpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2639
8033953d67ff
child 2982
ddd894528dbc
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

duke@435 1 /*
stefank@2534 2 * Copyright (c) 1998, 2011, 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_CPCACHEOOP_HPP
stefank@2314 26 #define SHARE_VM_OOPS_CPCACHEOOP_HPP
stefank@2314 27
stefank@2314 28 #include "interpreter/bytecodes.hpp"
stefank@2314 29 #include "memory/allocation.hpp"
stefank@2314 30 #include "oops/arrayOop.hpp"
stefank@2314 31 #include "utilities/array.hpp"
stefank@2314 32
duke@435 33 // A ConstantPoolCacheEntry describes an individual entry of the constant
duke@435 34 // pool cache. There's 2 principal kinds of entries: field entries for in-
duke@435 35 // stance & static field access, and method entries for invokes. Some of
duke@435 36 // the entry layout is shared and looks as follows:
duke@435 37 //
duke@435 38 // bit number |31 0|
duke@435 39 // bit length |-8--|-8--|---16----|
duke@435 40 // --------------------------------
duke@435 41 // _indices [ b2 | b1 | index ]
duke@435 42 // _f1 [ entry specific ]
duke@435 43 // _f2 [ entry specific ]
duke@435 44 // _flags [t|f|vf|v|m|h|unused|field_index] (for field entries)
duke@435 45 // bit length |4|1|1 |1|1|0|---7--|----16-----]
duke@435 46 // _flags [t|f|vf|v|m|h|unused|eidx|psze] (for method entries)
duke@435 47 // bit length |4|1|1 |1|1|1|---7--|-8--|-8--]
duke@435 48
duke@435 49 // --------------------------------
duke@435 50 //
duke@435 51 // with:
duke@435 52 // index = original constant pool index
duke@435 53 // b1 = bytecode 1
duke@435 54 // b2 = bytecode 2
duke@435 55 // psze = parameters size (method entries only)
duke@435 56 // eidx = interpreter entry index (method entries only)
duke@435 57 // field_index = index into field information in holder instanceKlass
duke@435 58 // The index max is 0xffff (max number of fields in constant pool)
duke@435 59 // and is multiplied by (instanceKlass::next_offset) when accessing.
duke@435 60 // t = TosState (see below)
duke@435 61 // f = field is marked final (see below)
duke@435 62 // vf = virtual, final (method entries only : is_vfinal())
duke@435 63 // v = field is volatile (see below)
duke@435 64 // m = invokeinterface used for method in class Object (see below)
duke@435 65 // h = RedefineClasses/Hotswap bit (see below)
duke@435 66 //
duke@435 67 // The flags after TosState have the following interpretation:
duke@435 68 // bit 27: f flag true if field is marked final
duke@435 69 // bit 26: vf flag true if virtual final method
duke@435 70 // bit 25: v flag true if field is volatile (only for fields)
duke@435 71 // bit 24: m flag true if invokeinterface used for method in class Object
duke@435 72 // bit 23: 0 for fields, 1 for methods
duke@435 73 //
duke@435 74 // The flags 31, 30, 29, 28 together build a 4 bit number 0 to 8 with the
duke@435 75 // following mapping to the TosState states:
duke@435 76 //
duke@435 77 // btos: 0
duke@435 78 // ctos: 1
duke@435 79 // stos: 2
duke@435 80 // itos: 3
duke@435 81 // ltos: 4
duke@435 82 // ftos: 5
duke@435 83 // dtos: 6
duke@435 84 // atos: 7
duke@435 85 // vtos: 8
duke@435 86 //
duke@435 87 // Entry specific: field entries:
duke@435 88 // _indices = get (b1 section) and put (b2 section) bytecodes, original constant pool index
duke@435 89 // _f1 = field holder
duke@435 90 // _f2 = field offset in words
duke@435 91 // _flags = field type information, original field index in field holder
duke@435 92 // (field_index section)
duke@435 93 //
duke@435 94 // Entry specific: method entries:
duke@435 95 // _indices = invoke code for f1 (b1 section), invoke code for f2 (b2 section),
duke@435 96 // original constant pool index
duke@435 97 // _f1 = method for all but virtual calls, unused by virtual calls
duke@435 98 // (note: for interface calls, which are essentially virtual,
duke@435 99 // contains klassOop for the corresponding interface.
jrose@1161 100 // for invokedynamic, f1 contains the CallSite object for the invocation
duke@435 101 // _f2 = method/vtable index for virtual calls only, unused by all other
duke@435 102 // calls. The vf flag indicates this is a method pointer not an
duke@435 103 // index.
duke@435 104 // _flags = field type info (f section),
duke@435 105 // virtual final entry (vf),
duke@435 106 // interpreter entry index (eidx section),
duke@435 107 // parameter size (psze section)
duke@435 108 //
duke@435 109 // Note: invokevirtual & invokespecial bytecodes can share the same constant
duke@435 110 // pool entry and thus the same constant pool cache entry. All invoke
duke@435 111 // bytecodes but invokevirtual use only _f1 and the corresponding b1
duke@435 112 // bytecode, while invokevirtual uses only _f2 and the corresponding
duke@435 113 // b2 bytecode. The value of _flags is shared for both types of entries.
duke@435 114 //
duke@435 115 // The fields are volatile so that they are stored in the order written in the
duke@435 116 // source code. The _indices field with the bytecode must be written last.
duke@435 117
duke@435 118 class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
duke@435 119 friend class VMStructs;
jrose@1161 120 friend class constantPoolCacheKlass;
jrose@1957 121 friend class constantPoolOopDesc; //resolve_constant_at_impl => set_f1
jrose@1161 122
duke@435 123 private:
duke@435 124 volatile intx _indices; // constant pool index & rewrite bytecodes
duke@435 125 volatile oop _f1; // entry specific oop field
duke@435 126 volatile intx _f2; // entry specific int/oop field
duke@435 127 volatile intx _flags; // flags
duke@435 128
duke@435 129
duke@435 130 #ifdef ASSERT
duke@435 131 bool same_methodOop(oop cur_f1, oop f1);
duke@435 132 #endif
duke@435 133
duke@435 134 void set_bytecode_1(Bytecodes::Code code);
duke@435 135 void set_bytecode_2(Bytecodes::Code code);
duke@435 136 void set_f1(oop f1) {
duke@435 137 oop existing_f1 = _f1; // read once
duke@435 138 assert(existing_f1 == NULL || existing_f1 == f1, "illegal field change");
duke@435 139 oop_store(&_f1, f1);
duke@435 140 }
twisti@2258 141 void set_f1_if_null_atomic(oop f1);
duke@435 142 void set_f2(intx f2) { assert(_f2 == 0 || _f2 == f2, "illegal field change"); _f2 = f2; }
duke@435 143 int as_flags(TosState state, bool is_final, bool is_vfinal, bool is_volatile,
duke@435 144 bool is_method_interface, bool is_method);
duke@435 145 void set_flags(intx flags) { _flags = flags; }
duke@435 146
duke@435 147 public:
duke@435 148 // specific bit values in flag field
duke@435 149 // Note: the interpreter knows this layout!
duke@435 150 enum FlagBitValues {
duke@435 151 hotSwapBit = 23,
duke@435 152 methodInterface = 24,
duke@435 153 volatileField = 25,
duke@435 154 vfinalMethod = 26,
duke@435 155 finalField = 27
duke@435 156 };
duke@435 157
duke@435 158 enum { field_index_mask = 0xFFFF };
duke@435 159
duke@435 160 // start of type bits in flags
duke@435 161 // Note: the interpreter knows this layout!
duke@435 162 enum FlagValues {
duke@435 163 tosBits = 28
duke@435 164 };
duke@435 165
duke@435 166 // Initialization
jrose@1494 167 void initialize_entry(int original_index); // initialize primary entry
jrose@1494 168 void initialize_secondary_entry(int main_index); // initialize secondary entry
duke@435 169
duke@435 170 void set_field( // sets entry to resolved field state
duke@435 171 Bytecodes::Code get_code, // the bytecode used for reading the field
duke@435 172 Bytecodes::Code put_code, // the bytecode used for writing the field
duke@435 173 KlassHandle field_holder, // the object/klass holding the field
duke@435 174 int orig_field_index, // the original field index in the field holder
duke@435 175 int field_offset, // the field offset in words in the field holder
duke@435 176 TosState field_type, // the (machine) field type
duke@435 177 bool is_final, // the field is final
duke@435 178 bool is_volatile // the field is volatile
duke@435 179 );
duke@435 180
duke@435 181 void set_method( // sets entry to resolved method entry
duke@435 182 Bytecodes::Code invoke_code, // the bytecode used for invoking the method
duke@435 183 methodHandle method, // the method/prototype if any (NULL, otherwise)
duke@435 184 int vtable_index // the vtable index if any, else negative
duke@435 185 );
duke@435 186
duke@435 187 void set_interface_call(
duke@435 188 methodHandle method, // Resolved method
duke@435 189 int index // Method index into interface
duke@435 190 );
duke@435 191
jrose@1161 192 void set_dynamic_call(
jrose@2639 193 Handle call_site, // Resolved java.lang.invoke.CallSite (f1)
jrose@1862 194 methodHandle signature_invoker // determines signature information
jrose@1161 195 );
jrose@1161 196
jrose@2015 197 // For JVM_CONSTANT_InvokeDynamic cache entries:
jrose@2015 198 void initialize_bootstrap_method_index_in_cache(int bsm_cache_index);
jrose@2015 199 int bootstrap_method_index_in_cache();
jrose@2015 200
duke@435 201 void set_parameter_size(int value) {
duke@435 202 assert(parameter_size() == 0 || parameter_size() == value,
duke@435 203 "size must not change");
duke@435 204 // Setting the parameter size by itself is only safe if the
duke@435 205 // current value of _flags is 0, otherwise another thread may have
duke@435 206 // updated it and we don't want to overwrite that value. Don't
duke@435 207 // bother trying to update it once it's nonzero but always make
duke@435 208 // sure that the final parameter size agrees with what was passed.
duke@435 209 if (_flags == 0) {
duke@435 210 Atomic::cmpxchg_ptr((value & 0xFF), &_flags, 0);
duke@435 211 }
duke@435 212 guarantee(parameter_size() == value, "size must not change");
duke@435 213 }
duke@435 214
duke@435 215 // Which bytecode number (1 or 2) in the index field is valid for this bytecode?
duke@435 216 // Returns -1 if neither is valid.
duke@435 217 static int bytecode_number(Bytecodes::Code code) {
duke@435 218 switch (code) {
duke@435 219 case Bytecodes::_getstatic : // fall through
duke@435 220 case Bytecodes::_getfield : // fall through
duke@435 221 case Bytecodes::_invokespecial : // fall through
duke@435 222 case Bytecodes::_invokestatic : // fall through
jrose@2017 223 case Bytecodes::_invokedynamic : // fall through
duke@435 224 case Bytecodes::_invokeinterface : return 1;
duke@435 225 case Bytecodes::_putstatic : // fall through
duke@435 226 case Bytecodes::_putfield : // fall through
duke@435 227 case Bytecodes::_invokevirtual : return 2;
duke@435 228 default : break;
duke@435 229 }
duke@435 230 return -1;
duke@435 231 }
duke@435 232
duke@435 233 // Has this bytecode been resolved? Only valid for invokes and get/put field/static.
duke@435 234 bool is_resolved(Bytecodes::Code code) const {
duke@435 235 switch (bytecode_number(code)) {
duke@435 236 case 1: return (bytecode_1() == code);
duke@435 237 case 2: return (bytecode_2() == code);
duke@435 238 }
duke@435 239 return false; // default: not resolved
duke@435 240 }
duke@435 241
duke@435 242 // Accessors
jrose@1161 243 bool is_secondary_entry() const { return (_indices & 0xFFFF) == 0; }
jrose@1161 244 int constant_pool_index() const { assert((_indices & 0xFFFF) != 0, "must be main entry");
jrose@1161 245 return (_indices & 0xFFFF); }
jrose@1161 246 int main_entry_index() const { assert((_indices & 0xFFFF) == 0, "must be secondary entry");
jrose@1161 247 return ((uintx)_indices >> 16); }
duke@435 248 Bytecodes::Code bytecode_1() const { return Bytecodes::cast((_indices >> 16) & 0xFF); }
duke@435 249 Bytecodes::Code bytecode_2() const { return Bytecodes::cast((_indices >> 24) & 0xFF); }
duke@435 250 volatile oop f1() const { return _f1; }
jrose@2015 251 bool is_f1_null() const { return (oop)_f1 == NULL; } // classifies a CPC entry as unbound
duke@435 252 intx f2() const { return _f2; }
duke@435 253 int field_index() const;
duke@435 254 int parameter_size() const { return _flags & 0xFF; }
duke@435 255 bool is_vfinal() const { return ((_flags & (1 << vfinalMethod)) == (1 << vfinalMethod)); }
duke@435 256 bool is_volatile() const { return ((_flags & (1 << volatileField)) == (1 << volatileField)); }
duke@435 257 bool is_methodInterface() const { return ((_flags & (1 << methodInterface)) == (1 << methodInterface)); }
duke@435 258 bool is_byte() const { return (((uintx) _flags >> tosBits) == btos); }
duke@435 259 bool is_char() const { return (((uintx) _flags >> tosBits) == ctos); }
duke@435 260 bool is_short() const { return (((uintx) _flags >> tosBits) == stos); }
duke@435 261 bool is_int() const { return (((uintx) _flags >> tosBits) == itos); }
duke@435 262 bool is_long() const { return (((uintx) _flags >> tosBits) == ltos); }
duke@435 263 bool is_float() const { return (((uintx) _flags >> tosBits) == ftos); }
duke@435 264 bool is_double() const { return (((uintx) _flags >> tosBits) == dtos); }
duke@435 265 bool is_object() const { return (((uintx) _flags >> tosBits) == atos); }
duke@435 266 TosState flag_state() const { assert( ( (_flags >> tosBits) & 0x0F ) < number_of_states, "Invalid state in as_flags");
duke@435 267 return (TosState)((_flags >> tosBits) & 0x0F); }
duke@435 268
duke@435 269 // Code generation support
duke@435 270 static WordSize size() { return in_WordSize(sizeof(ConstantPoolCacheEntry) / HeapWordSize); }
jrose@1494 271 static ByteSize size_in_bytes() { return in_ByteSize(sizeof(ConstantPoolCacheEntry)); }
duke@435 272 static ByteSize indices_offset() { return byte_offset_of(ConstantPoolCacheEntry, _indices); }
duke@435 273 static ByteSize f1_offset() { return byte_offset_of(ConstantPoolCacheEntry, _f1); }
duke@435 274 static ByteSize f2_offset() { return byte_offset_of(ConstantPoolCacheEntry, _f2); }
duke@435 275 static ByteSize flags_offset() { return byte_offset_of(ConstantPoolCacheEntry, _flags); }
duke@435 276
duke@435 277 // GC Support
duke@435 278 void oops_do(void f(oop*));
duke@435 279 void oop_iterate(OopClosure* blk);
duke@435 280 void oop_iterate_m(OopClosure* blk, MemRegion mr);
duke@435 281 void follow_contents();
duke@435 282 void adjust_pointers();
duke@435 283
duke@435 284 #ifndef SERIALGC
duke@435 285 // Parallel Old
duke@435 286 void follow_contents(ParCompactionManager* cm);
duke@435 287 #endif // SERIALGC
duke@435 288
duke@435 289 void update_pointers();
duke@435 290
duke@435 291 // RedefineClasses() API support:
duke@435 292 // If this constantPoolCacheEntry refers to old_method then update it
duke@435 293 // to refer to new_method.
duke@435 294 // trace_name_printed is set to true if the current call has
duke@435 295 // printed the klass name so that other routines in the adjust_*
duke@435 296 // group don't print the klass name.
duke@435 297 bool adjust_method_entry(methodOop old_method, methodOop new_method,
duke@435 298 bool * trace_name_printed);
duke@435 299 bool is_interesting_method_entry(klassOop k);
duke@435 300 bool is_field_entry() const { return (_flags & (1 << hotSwapBit)) == 0; }
duke@435 301 bool is_method_entry() const { return (_flags & (1 << hotSwapBit)) != 0; }
duke@435 302
duke@435 303 // Debugging & Printing
duke@435 304 void print (outputStream* st, int index) const;
duke@435 305 void verify(outputStream* st) const;
duke@435 306
duke@435 307 static void verify_tosBits() {
duke@435 308 assert(tosBits == 28, "interpreter now assumes tosBits is 28");
duke@435 309 }
duke@435 310 };
duke@435 311
duke@435 312
duke@435 313 // A constant pool cache is a runtime data structure set aside to a constant pool. The cache
duke@435 314 // holds interpreter runtime information for all field access and invoke bytecodes. The cache
duke@435 315 // is created and initialized before a class is actively used (i.e., initialized), the indivi-
duke@435 316 // dual cache entries are filled at resolution (i.e., "link") time (see also: rewriter.*).
duke@435 317
coleenp@548 318 class constantPoolCacheOopDesc: public oopDesc {
duke@435 319 friend class VMStructs;
duke@435 320 private:
coleenp@548 321 int _length;
duke@435 322 constantPoolOop _constant_pool; // the corresponding constant pool
duke@435 323
duke@435 324 // Sizing
coleenp@548 325 debug_only(friend class ClassVerifier;)
jrose@2268 326 public:
coleenp@548 327 int length() const { return _length; }
jrose@2268 328 private:
coleenp@548 329 void set_length(int length) { _length = length; }
coleenp@548 330
duke@435 331 static int header_size() { return sizeof(constantPoolCacheOopDesc) / HeapWordSize; }
duke@435 332 static int object_size(int length) { return align_object_size(header_size() + length * in_words(ConstantPoolCacheEntry::size())); }
duke@435 333 int object_size() { return object_size(length()); }
duke@435 334
duke@435 335 // Helpers
duke@435 336 constantPoolOop* constant_pool_addr() { return &_constant_pool; }
duke@435 337 ConstantPoolCacheEntry* base() const { return (ConstantPoolCacheEntry*)((address)this + in_bytes(base_offset())); }
duke@435 338
duke@435 339 friend class constantPoolCacheKlass;
jrose@1494 340 friend class ConstantPoolCacheEntry;
duke@435 341
duke@435 342 public:
duke@435 343 // Initialization
duke@435 344 void initialize(intArray& inverse_index_map);
duke@435 345
jrose@1161 346 // Secondary indexes.
jrose@1161 347 // They must look completely different from normal indexes.
jrose@1161 348 // The main reason is that byte swapping is sometimes done on normal indexes.
jrose@1494 349 // Also, some of the CP accessors do different things for secondary indexes.
jrose@1494 350 // Finally, it is helpful for debugging to tell the two apart.
jrose@1161 351 static bool is_secondary_index(int i) { return (i < 0); }
jrose@1161 352 static int decode_secondary_index(int i) { assert(is_secondary_index(i), ""); return ~i; }
jrose@1161 353 static int encode_secondary_index(int i) { assert(!is_secondary_index(i), ""); return ~i; }
jrose@1161 354
duke@435 355 // Accessors
duke@435 356 void set_constant_pool(constantPoolOop pool) { oop_store_without_check((oop*)&_constant_pool, (oop)pool); }
duke@435 357 constantPoolOop constant_pool() const { return _constant_pool; }
jrose@1494 358 // Fetches the entry at the given index.
jrose@1494 359 // The entry may be either primary or secondary.
jrose@1494 360 // In either case the index must not be encoded or byte-swapped in any way.
jrose@1494 361 ConstantPoolCacheEntry* entry_at(int i) const {
jrose@1494 362 assert(0 <= i && i < length(), "index out of bounds");
jrose@1494 363 return base() + i;
jrose@1494 364 }
jrose@1494 365 // Fetches the secondary entry referred to by index.
jrose@1494 366 // The index may be a secondary index, and must not be byte-swapped.
jrose@1494 367 ConstantPoolCacheEntry* secondary_entry_at(int i) const {
jrose@1494 368 int raw_index = i;
jrose@1494 369 if (is_secondary_index(i)) { // correct these on the fly
jrose@1494 370 raw_index = decode_secondary_index(i);
jrose@1494 371 }
jrose@1494 372 assert(entry_at(raw_index)->is_secondary_entry(), "not a secondary entry");
jrose@1494 373 return entry_at(raw_index);
jrose@1494 374 }
jrose@1494 375 // Given a primary or secondary index, fetch the corresponding primary entry.
jrose@1494 376 // Indirect through the secondary entry, if the index is encoded as a secondary index.
jrose@1494 377 // The index must not be byte-swapped.
jrose@1161 378 ConstantPoolCacheEntry* main_entry_at(int i) const {
jrose@1494 379 int primary_index = i;
jrose@1161 380 if (is_secondary_index(i)) {
jrose@1161 381 // run through an extra level of indirection:
jrose@1494 382 int raw_index = decode_secondary_index(i);
jrose@1494 383 primary_index = entry_at(raw_index)->main_entry_index();
jrose@1161 384 }
jrose@1494 385 assert(!entry_at(primary_index)->is_secondary_entry(), "only one level of indirection");
jrose@1494 386 return entry_at(primary_index);
jrose@1161 387 }
duke@435 388
duke@435 389 // Code generation
duke@435 390 static ByteSize base_offset() { return in_ByteSize(sizeof(constantPoolCacheOopDesc)); }
jrose@1494 391 static ByteSize entry_offset(int raw_index) {
jrose@1494 392 int index = raw_index;
jrose@1494 393 if (is_secondary_index(raw_index))
jrose@1494 394 index = decode_secondary_index(raw_index);
jrose@1494 395 return (base_offset() + ConstantPoolCacheEntry::size_in_bytes() * index);
jrose@1494 396 }
duke@435 397
duke@435 398 // RedefineClasses() API support:
duke@435 399 // If any entry of this constantPoolCache points to any of
duke@435 400 // old_methods, replace it with the corresponding new_method.
duke@435 401 // trace_name_printed is set to true if the current call has
duke@435 402 // printed the klass name so that other routines in the adjust_*
duke@435 403 // group don't print the klass name.
duke@435 404 void adjust_method_entries(methodOop* old_methods, methodOop* new_methods,
duke@435 405 int methods_length, bool * trace_name_printed);
duke@435 406 };
stefank@2314 407
stefank@2314 408 #endif // SHARE_VM_OOPS_CPCACHEOOP_HPP

mercurial