8130115: REDO - Reduce Symbol::_identity_hash to 2 bytes
Summary: Convert Symbol::_identity_hash from integer to short integer to save two bytes. Also change identity_hash() to have 'this' and first two bytes of symbol join the calculation.
Reviewed-by: iklam, coleenp, shade
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/Address.java Wed Aug 12 14:18:12 2015 -0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/Address.java Fri Aug 14 10:10:35 2015 -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();
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java Wed Aug 12 14:18:12 2015 -0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java Fri Aug 14 10:10:35 2015 -0700
@@ -288,7 +288,7 @@
return new BsdAddress(debugger, value);
}
-
+ public long asLongValue() { return addr; }
//--------------------------------------------------------------------------------
// Internals only below this point
//
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dummy/DummyAddress.java Wed Aug 12 14:18:12 2015 -0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dummy/DummyAddress.java Fri Aug 14 10:10:35 2015 -0700
@@ -275,6 +275,7 @@
return new DummyAddress(debugger, value);
}
+ public long asLongValue() { return addr; }
//--------------------------------------------------------------------------------
// Internals only below this point
//
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java Wed Aug 12 14:18:12 2015 -0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java Fri Aug 14 10:10:35 2015 -0700
@@ -288,6 +288,7 @@
return new LinuxAddress(debugger, value);
}
+ public long asLongValue() { return addr; }
//--------------------------------------------------------------------------------
// Internals only below this point
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcAddress.java Wed Aug 12 14:18:12 2015 -0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcAddress.java Fri Aug 14 10:10:35 2015 -0700
@@ -283,7 +283,7 @@
return new ProcAddress(debugger, value);
}
-
+ public long asLongValue() { return addr; }
//--------------------------------------------------------------------------------
// Internals only below this point
//
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteAddress.java Wed Aug 12 14:18:12 2015 -0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteAddress.java Fri Aug 14 10:10:35 2015 -0700
@@ -281,7 +281,7 @@
return new RemoteAddress(debugger, value);
}
-
+ public long asLongValue() { return addr; }
//--------------------------------------------------------------------------------
// Internals only below this point
//
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgAddress.java Wed Aug 12 14:18:12 2015 -0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgAddress.java Fri Aug 14 10:10:35 2015 -0700
@@ -292,6 +292,7 @@
return new WindbgAddress(debugger, value);
}
+ public long asLongValue() { return addr; }
//--------------------------------------------------------------------------------
// Internals only below this point
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java Wed Aug 12 14:18:12 2015 -0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java Fri Aug 14 10:10:35 2015 -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();
--- a/hotspot/src/share/vm/oops/symbol.cpp Wed Aug 12 14:18:12 2015 -0400
+++ b/hotspot/src/share/vm/oops/symbol.cpp Fri Aug 14 10:10:35 2015 -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]);
}
--- a/hotspot/src/share/vm/oops/symbol.hpp Wed Aug 12 14:18:12 2015 -0400
+++ b/hotspot/src/share/vm/oops/symbol.hpp Fri Aug 14 10:10:35 2015 -0700
@@ -106,23 +106,18 @@
#define PERM_REFCOUNT -1
#endif
-// 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:
+class Symbol : public MetaspaceObj {
+ friend class VMStructs;
+ friend class SymbolTable;
+ friend class MoveSymbols;
+
+ private:
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 {
- friend class VMStructs;
- friend class SymbolTable;
- friend class MoveSymbols;
- private:
- jbyte _body[1];
+ short _identity_hash;
+ jbyte _body[2];
enum {
// max_symbol_length is constrained by type of _length
@@ -130,7 +125,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);
}
@@ -154,8 +149,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 & 0xffff) |
+ ((addr_bits ^ (_length << 8) ^ (( _body[0] << 8) | _body[1])) << 16);
+ }
// For symbol table alternate hashing
unsigned int new_hash(juint seed);
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Aug 12 14:18:12 2015 -0400
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Aug 14 10:10:35 2015 -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) \