diff -r 73a726751507 -r 389049f3f393 src/share/vm/oops/cpCacheOop.hpp --- a/src/share/vm/oops/cpCacheOop.hpp Fri Oct 30 10:12:52 2009 -0700 +++ b/src/share/vm/oops/cpCacheOop.hpp Fri Oct 30 16:22:59 2009 -0700 @@ -154,7 +154,8 @@ }; // Initialization - void set_initial_state(int index); // sets entry to initial state + void initialize_entry(int original_index); // initialize primary entry + void initialize_secondary_entry(int main_index); // initialize secondary entry void set_field( // sets entry to resolved field state Bytecodes::Code get_code, // the bytecode used for reading the field @@ -251,6 +252,7 @@ // Code generation support static WordSize size() { return in_WordSize(sizeof(ConstantPoolCacheEntry) / HeapWordSize); } + static ByteSize size_in_bytes() { return in_ByteSize(sizeof(ConstantPoolCacheEntry)); } static ByteSize indices_offset() { return byte_offset_of(ConstantPoolCacheEntry, _indices); } static ByteSize f1_offset() { return byte_offset_of(ConstantPoolCacheEntry, _f1); } static ByteSize f2_offset() { return byte_offset_of(ConstantPoolCacheEntry, _f2); } @@ -321,6 +323,7 @@ ConstantPoolCacheEntry* base() const { return (ConstantPoolCacheEntry*)((address)this + in_bytes(base_offset())); } friend class constantPoolCacheKlass; + friend class ConstantPoolCacheEntry; public: // Initialization @@ -329,7 +332,8 @@ // Secondary indexes. // They must look completely different from normal indexes. // The main reason is that byte swapping is sometimes done on normal indexes. - // Also, it is helpful for debugging to tell the two apart. + // Also, some of the CP accessors do different things for secondary indexes. + // Finally, it is helpful for debugging to tell the two apart. static bool is_secondary_index(int i) { return (i < 0); } static int decode_secondary_index(int i) { assert(is_secondary_index(i), ""); return ~i; } static int encode_secondary_index(int i) { assert(!is_secondary_index(i), ""); return ~i; } @@ -337,18 +341,35 @@ // Accessors void set_constant_pool(constantPoolOop pool) { oop_store_without_check((oop*)&_constant_pool, (oop)pool); } constantPoolOop constant_pool() const { return _constant_pool; } - ConstantPoolCacheEntry* entry_at(int i) const { assert(0 <= i && i < length(), "index out of bounds"); return base() + i; } + // Fetches the entry at the given index. + // The entry may be either primary or secondary. + // In either case the index must not be encoded or byte-swapped in any way. + ConstantPoolCacheEntry* entry_at(int i) const { + assert(0 <= i && i < length(), "index out of bounds"); + return base() + i; + } + // Fetches the secondary entry referred to by index. + // The index may be a secondary index, and must not be byte-swapped. + ConstantPoolCacheEntry* secondary_entry_at(int i) const { + int raw_index = i; + if (is_secondary_index(i)) { // correct these on the fly + raw_index = decode_secondary_index(i); + } + assert(entry_at(raw_index)->is_secondary_entry(), "not a secondary entry"); + return entry_at(raw_index); + } + // Given a primary or secondary index, fetch the corresponding primary entry. + // Indirect through the secondary entry, if the index is encoded as a secondary index. + // The index must not be byte-swapped. ConstantPoolCacheEntry* main_entry_at(int i) const { - ConstantPoolCacheEntry* e; + int primary_index = i; if (is_secondary_index(i)) { // run through an extra level of indirection: - i = decode_secondary_index(i); - e = entry_at(i); - i = e->main_entry_index(); + int raw_index = decode_secondary_index(i); + primary_index = entry_at(raw_index)->main_entry_index(); } - e = entry_at(i); - assert(!e->is_secondary_entry(), "only one level of indirection"); - return e; + assert(!entry_at(primary_index)->is_secondary_entry(), "only one level of indirection"); + return entry_at(primary_index); } // GC support @@ -359,6 +380,12 @@ // Code generation static ByteSize base_offset() { return in_ByteSize(sizeof(constantPoolCacheOopDesc)); } + static ByteSize entry_offset(int raw_index) { + int index = raw_index; + if (is_secondary_index(raw_index)) + index = decode_secondary_index(raw_index); + return (base_offset() + ConstantPoolCacheEntry::size_in_bytes() * index); + } // RedefineClasses() API support: // If any entry of this constantPoolCache points to any of