--- old/agent/src/share/classes/sun/jvm/hotspot/debugger/Address.java 2015-07-14 18:27:38.820593802 -0700 +++ new/agent/src/share/classes/sun/jvm/hotspot/debugger/Address.java 2015-07-14 18:27:38.704588083 -0700 @@ -209,4 +209,7 @@ returns the result as an Address. Returns null if the result was zero. */ public Address xorWithMask(long mask) throws UnsupportedOperationException; + + // return address as long integer. + public long asLongValue(); } --- old/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java 2015-07-14 18:27:39.291617025 -0700 +++ new/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java 2015-07-14 18:27:39.172611157 -0700 @@ -288,7 +288,7 @@ return new BsdAddress(debugger, value); } - + public long asLongValue() { return addr; } //-------------------------------------------------------------------------------- // Internals only below this point // --- old/agent/src/share/classes/sun/jvm/hotspot/debugger/dummy/DummyAddress.java 2015-07-14 18:27:39.767640492 -0700 +++ new/agent/src/share/classes/sun/jvm/hotspot/debugger/dummy/DummyAddress.java 2015-07-14 18:27:39.648634625 -0700 @@ -275,6 +275,7 @@ return new DummyAddress(debugger, value); } + public long asLongValue() { return addr; } //-------------------------------------------------------------------------------- // Internals only below this point // --- old/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java 2015-07-14 18:27:40.298666672 -0700 +++ new/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java 2015-07-14 18:27:40.176660659 -0700 @@ -288,6 +288,7 @@ return new LinuxAddress(debugger, value); } + public long asLongValue() { return addr; } //-------------------------------------------------------------------------------- // Internals only below this point --- old/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcAddress.java 2015-07-14 18:27:40.793691078 -0700 +++ new/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcAddress.java 2015-07-14 18:27:40.670685013 -0700 @@ -283,7 +283,7 @@ return new ProcAddress(debugger, value); } - + public long asLongValue() { return addr; } //-------------------------------------------------------------------------------- // Internals only below this point // --- old/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteAddress.java 2015-07-14 18:27:41.286715384 -0700 +++ new/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteAddress.java 2015-07-14 18:27:41.166709467 -0700 @@ -281,7 +281,7 @@ return new RemoteAddress(debugger, value); } - + public long asLongValue() { return addr; } //-------------------------------------------------------------------------------- // Internals only below this point // --- old/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgAddress.java 2015-07-14 18:27:41.767739100 -0700 +++ new/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgAddress.java 2015-07-14 18:27:41.648733233 -0700 @@ -292,6 +292,7 @@ return new WindbgAddress(debugger, value); } + public long asLongValue() { return addr; } //-------------------------------------------------------------------------------- // Internals only below this point --- old/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java 2015-07-14 18:27:42.274764096 -0700 +++ new/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java 2015-07-14 18:27:42.156758279 -0700 @@ -80,10 +80,19 @@ public byte getByteAt(long index) { return addr.getJByteAt(baseOffset + index); } - + // _identity_hash is a short private static CIntegerField idHash; - public int identityHash() { return (int)idHash.getValue(this.addr); } + public int identityHash() { + long addr_value = getAddress().asLongValue(); + int addr_bits = (int)(addr_value >> (VM.getVM().getLogMinObjAlignmentInBytes() + 3)); + int length = (int)getLength(); + int byte0 = getByteAt(0); + int byte1 = getByteAt(1); + int id_hash = (int)(0xffff & idHash.getValue(this.addr)); + return id_hash | + ((addr_bits ^ (length << 8) ^ ((byte0 << 8) | byte1)) << 16); + } public boolean equals(byte[] modUTF8Chars) { int l = (int) getLength(); --- old/src/share/vm/oops/symbol.cpp 2015-07-14 18:27:42.752787665 -0700 +++ new/src/share/vm/oops/symbol.cpp 2015-07-14 18:27:42.630781650 -0700 @@ -35,7 +35,7 @@ Symbol::Symbol(const u1* name, int length, int refcount) { _refcount = refcount; _length = length; - _identity_hash = os::random(); + _identity_hash = (short)os::random(); for (int i = 0; i < _length; i++) { byte_at_put(i, name[i]); } --- old/src/share/vm/oops/symbol.hpp 2015-07-14 18:27:43.227811084 -0700 +++ new/src/share/vm/oops/symbol.hpp 2015-07-14 18:27:43.107805167 -0700 @@ -102,23 +102,18 @@ // type without virtual functions. class ClassLoaderData; -// 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) - ); - int _identity_hash; -}; - -class Symbol : private SymbolBase { +class Symbol : public MetaspaceObj { friend class VMStructs; friend class SymbolTable; friend class MoveSymbols; + private: - jbyte _body[1]; + 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]; enum { // max_symbol_length is constrained by type of _length @@ -126,7 +121,7 @@ }; static int size(int length) { - size_t sz = heap_word_size(sizeof(SymbolBase) + (length > 0 ? length : 0)); + size_t sz = heap_word_size(sizeof(Symbol) + (length > 2 ? length - 2 : 0)); return align_object_size(sz); } @@ -150,8 +145,11 @@ // Returns the largest size symbol we can safely hold. static int max_length() { return max_symbol_length; } - - int identity_hash() { return _identity_hash; } + 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); + } // For symbol table alternate hashing unsigned int new_hash(juint seed); --- old/src/share/vm/runtime/vmStructs.cpp 2015-07-14 18:27:43.810839828 -0700 +++ new/src/share/vm/runtime/vmStructs.cpp 2015-07-14 18:27:43.685833665 -0700 @@ -405,7 +405,7 @@ nonstatic_field(ObjArrayKlass, _element_klass, Klass*) \ nonstatic_field(ObjArrayKlass, _bottom_klass, Klass*) \ volatile_nonstatic_field(Symbol, _refcount, short) \ - nonstatic_field(Symbol, _identity_hash, int) \ + nonstatic_field(Symbol, _identity_hash, short) \ nonstatic_field(Symbol, _length, unsigned short) \ unchecked_nonstatic_field(Symbol, _body, sizeof(jbyte)) /* NOTE: no type */ \ nonstatic_field(TypeArrayKlass, _max_length, int) \