8130115: REDO - Reduce Symbol::_identity_hash to 2 bytes
authorminqi
Fri, 14 Aug 2015 10:10:35 -0700
changeset 32357 43087bc6dd04
parent 32349 8b5eb3750c41
child 32358 4cccd6794b0f
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
hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/Address.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/dummy/DummyAddress.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcAddress.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteAddress.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgAddress.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Symbol.java
hotspot/src/share/vm/oops/symbol.cpp
hotspot/src/share/vm/oops/symbol.hpp
hotspot/src/share/vm/runtime/vmStructs.cpp
--- 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)                                   \