< prev index next >

src/hotspot/share/runtime/synchronizer.cpp

Print this page
*** 62,10 ***
--- 62,11 ---
  #include "runtime/vmThread.hpp"
  #include "utilities/align.hpp"
  #include "utilities/dtrace.hpp"
  #include "utilities/events.hpp"
  #include "utilities/globalDefinitions.hpp"
+ #include "utilities/fastHash.hpp"
  #include "utilities/linkedlist.hpp"
  #include "utilities/preserveException.hpp"
  
  class ObjectMonitorDeflationLogging;
  

*** 930,11 ***
  //   (objects allocated back-to-back, in particular).  This could potentially
  //   result in hashtable collisions and reduced hashtable efficiency.
  //   There are simple ways to "diffuse" the middle address bits over the
  //   generated hashCode values:
  
! static intptr_t get_next_hash(Thread* current, oop obj) {
    intptr_t value = 0;
    if (hashCode == 0) {
      // This form uses global Park-Miller RNG.
      // On MP system we'll have lots of RW access to a global, so the
      // mechanism induces lots of coherency traffic.
--- 931,11 ---
  //   (objects allocated back-to-back, in particular).  This could potentially
  //   result in hashtable collisions and reduced hashtable efficiency.
  //   There are simple ways to "diffuse" the middle address bits over the
  //   generated hashCode values:
  
! intptr_t ObjectSynchronizer::get_next_hash(Thread* current, oop obj) {
    intptr_t value = 0;
    if (hashCode == 0) {
      // This form uses global Park-Miller RNG.
      // On MP system we'll have lots of RW access to a global, so the
      // mechanism induces lots of coherency traffic.

*** 949,11 ***
      value = 1;            // for sensitivity testing
    } else if (hashCode == 3) {
      value = ++GVars.hc_sequence;
    } else if (hashCode == 4) {
      value = cast_from_oop<intptr_t>(obj);
!   } else {
      // Marsaglia's xor-shift scheme with thread-specific state
      // This is probably the best overall implementation -- we'll
      // likely make this the default in future releases.
      unsigned t = current->_hashStateX;
      t ^= (t << 11);
--- 950,11 ---
      value = 1;            // for sensitivity testing
    } else if (hashCode == 3) {
      value = ++GVars.hc_sequence;
    } else if (hashCode == 4) {
      value = cast_from_oop<intptr_t>(obj);
!   } else if (hashCode == 5) {
      // Marsaglia's xor-shift scheme with thread-specific state
      // This is probably the best overall implementation -- we'll
      // likely make this the default in future releases.
      unsigned t = current->_hashStateX;
      t ^= (t << 11);

*** 962,35 ***
      current->_hashStateZ = current->_hashStateW;
      unsigned v = current->_hashStateW;
      v = (v ^ (v >> 19)) ^ (t ^ (t >> 8));
      current->_hashStateW = v;
      value = v;
    }
  
    value &= markWord::hash_mask;
!   if (value == 0) value = 0xBAD;
!   assert(value != markWord::no_hash, "invariant");
    return value;
  }
  
  static intptr_t install_hash_code(Thread* current, oop obj) {
    assert(UseObjectMonitorTable && LockingMode == LM_LIGHTWEIGHT, "must be");
  
    markWord mark = obj->mark_acquire();
    for (;;) {
!     intptr_t hash = mark.hash();
!     if (hash != 0) {
!       return hash;
!     }
  
!     hash = get_next_hash(current, obj);
!     const markWord old_mark = mark;
!     const markWord new_mark = old_mark.copy_set_hash(hash);
  
!     mark = obj->cas_set_mark(new_mark, old_mark);
!     if (old_mark == mark) {
!       return hash;
      }
    }
  }
  
  intptr_t ObjectSynchronizer::FastHashCode(Thread* current, oop obj) {
--- 963,65 ---
      current->_hashStateZ = current->_hashStateW;
      unsigned v = current->_hashStateW;
      v = (v ^ (v >> 19)) ^ (t ^ (t >> 8));
      current->_hashStateW = v;
      value = v;
+   } else {
+     assert(UseCompactObjectHeaders, "Only with compact i-hash");
+ #ifdef _LP64
+     uint64_t val = cast_from_oop<uint64_t>(obj);
+     uint32_t hash = FastHash::get_hash32((uint32_t)val, (uint32_t)(val >> 32));
+ #else
+     uint32_t val = cast_from_oop<uint32_t>(obj);
+     uint32_t hash = FastHash::get_hash32(val, UCONST64(0xAAAAAAAA));
+ #endif
+     value= static_cast<intptr_t>(hash);
    }
  
    value &= markWord::hash_mask;
!   if (hashCode != 6 && value == 0) value = 0xBAD;
!   assert(value != markWord::no_hash || hashCode == 6, "invariant");
    return value;
  }
  
  static intptr_t install_hash_code(Thread* current, oop obj) {
    assert(UseObjectMonitorTable && LockingMode == LM_LIGHTWEIGHT, "must be");
  
    markWord mark = obj->mark_acquire();
    for (;;) {
!     if (UseCompactObjectHeaders) {
!       if (mark.is_hashed()) {
!         return LightweightSynchronizer::get_hash(mark, obj);
!       }
+       intptr_t hash = ObjectSynchronizer::get_next_hash(current, obj);  // get a new hash
+       markWord new_mark;
+       if (mark.is_not_hashed_expanded()) {
+         new_mark = mark.set_hashed_expanded();
+         int offset = mark.klass()->hash_offset_in_bytes(obj);
+         obj->int_field_put(offset, (jint) hash);
+       } else {
+         new_mark = mark.set_hashed_not_expanded();
+       }
+       markWord old_mark = obj->cas_set_mark(new_mark, mark);
+       if (old_mark == mark) {
+         return hash;
+       }
+       mark = old_mark;
+     } else {
+       intptr_t hash = mark.hash();
+       if (hash != 0) {
+         return hash;
+       }
  
!       hash = ObjectSynchronizer::get_next_hash(current, obj);
!       const markWord old_mark = mark;
!       const markWord new_mark = old_mark.copy_set_hash(hash);
  
!       mark = obj->cas_set_mark(new_mark, old_mark);
!       if (old_mark == mark) {
!         return hash;
+       }
      }
    }
  }
  
  intptr_t ObjectSynchronizer::FastHashCode(Thread* current, oop obj) {
< prev index next >