diff a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp
--- a/src/hotspot/share/runtime/synchronizer.cpp
+++ b/src/hotspot/share/runtime/synchronizer.cpp
@@ -61,10 +61,11 @@
 #include "utilities/align.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
 #include "utilities/globalCounter.inline.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/fastHash.hpp"
 #include "utilities/linkedlist.hpp"
 #include "utilities/preserveException.hpp"
 
 class ObjectMonitorDeflationLogging;
 
@@ -926,11 +927,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 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.
@@ -945,11 +946,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 {
+  } 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);
@@ -958,35 +959,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 (value == 0) value = 0xBAD;
-  assert(value != markWord::no_hash, "invariant");
+  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 (;;) {
-    intptr_t hash = mark.hash();
-    if (hash != 0) {
-      return hash;
-    }
+    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, mark);
+        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 = get_next_hash(current, obj);
-    const markWord old_mark = mark;
-    const markWord new_mark = old_mark.copy_set_hash(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;
+      mark = obj->cas_set_mark(new_mark, old_mark);
+      if (old_mark == mark) {
+        return hash;
+      }
     }
   }
 }
 
 intptr_t ObjectSynchronizer::FastHashCode(Thread* current, oop obj) {
