--- old/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java Tue Jun 30 09:18:15 2015 +++ new/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java Tue Jun 30 09:18:14 2015 @@ -47,7 +47,7 @@ Type type = db.lookupType("Symbol"); length = type.getCIntegerField("_length"); baseOffset = type.getField("_body").getOffset(); - idHash = type.getJShortField("_identity_hash"); + idHash = type.getCIntegerField("_identity_hash"); } // Format: @@ -81,9 +81,9 @@ return addr.getJByteAt(baseOffset + index); } - private static JShortField idHash; + private static CIntegerField idHash; - public short identityHash() { return (short)idHash.getValue(this.addr); } + public int identityHash() { return (int)idHash.getValue(this.addr); } public boolean equals(byte[] modUTF8Chars) { int l = (int) getLength(); --- old/src/share/vm/oops/symbol.cpp Tue Jun 30 09:18:18 2015 +++ new/src/share/vm/oops/symbol.cpp Tue Jun 30 09:18:17 2015 @@ -35,7 +35,7 @@ Symbol::Symbol(const u1* name, int length, int refcount) { _refcount = refcount; _length = length; - _identity_hash = (short)os::random(); + _identity_hash = os::random(); for (int i = 0; i < _length; i++) { byte_at_put(i, name[i]); } --- old/src/share/vm/oops/symbol.hpp Tue Jun 30 09:18:20 2015 +++ new/src/share/vm/oops/symbol.hpp Tue Jun 30 09:18:19 2015 @@ -102,19 +102,24 @@ // type without virtual functions. class ClassLoaderData; -class Symbol : public MetaspaceObj { - friend class VMStructs; - friend class SymbolTable; - friend class MoveSymbols; - - private: +// We separate the fields in SymbolBase from Symbol::_body so that +// Symbol::size(int) can correctly calculate the space needed. +class SymbolBase : public MetaspaceObj { + public: ATOMIC_SHORT_PAIR( volatile short _refcount, // needs atomic operation unsigned short _length // number of UTF8 characters in the symbol (does not need atomic op) ); - short _identity_hash; - jbyte _body[2]; + int _identity_hash; +}; +class Symbol : private SymbolBase { + friend class VMStructs; + friend class SymbolTable; + friend class MoveSymbols; + private: + jbyte _body[1]; + enum { // max_symbol_length is constrained by type of _length max_symbol_length = (1 << 16) -1 @@ -121,7 +126,7 @@ }; static int size(int length) { - size_t sz = heap_word_size(sizeof(Symbol) + (length > 2 ? length - 2 : 0)); + size_t sz = heap_word_size(sizeof(SymbolBase) + (length > 0 ? length : 0)); return align_object_size(sz); } @@ -145,12 +150,9 @@ // Returns the largest size symbol we can safely hold. static int max_length() { return max_symbol_length; } - unsigned identity_hash() { - unsigned addr_bits = (unsigned)((uintptr_t)this >> (LogMinObjAlignmentInBytes + 3)); - return (unsigned)_identity_hash | - ((addr_bits ^ (_length << 8) ^ (( _body[0] << 8) | _body[1])) << 16); - } + int identity_hash() { return _identity_hash; } + // For symbol table alternate hashing unsigned int new_hash(juint seed); --- old/src/share/vm/runtime/vmStructs.cpp Tue Jun 30 09:18:23 2015 +++ new/src/share/vm/runtime/vmStructs.cpp Tue Jun 30 09:18:22 2015 @@ -403,7 +403,7 @@ nonstatic_field(ObjArrayKlass, _element_klass, Klass*) \ nonstatic_field(ObjArrayKlass, _bottom_klass, Klass*) \ volatile_nonstatic_field(Symbol, _refcount, short) \ - nonstatic_field(Symbol, _identity_hash, short) \ + nonstatic_field(Symbol, _identity_hash, int) \ nonstatic_field(Symbol, _length, unsigned short) \ unchecked_nonstatic_field(Symbol, _body, sizeof(jbyte)) /* NOTE: no type */ \ nonstatic_field(TypeArrayKlass, _max_length, int) \