hotspot/src/share/vm/oops/markOop.hpp

Print this page
rev 611 : Merge

@@ -1,10 +1,10 @@
 #ifdef USE_PRAGMA_IDENT_HDR
 #pragma ident "@(#)markOop.hpp  1.66 08/11/24 12:22:54 JVM"
 #endif
 /*
- * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -30,12 +30,14 @@
 // Note that the mark is not a real oop but just a word. 
 // It is placed in the oop hierarchy for historical reasons.
 //
 // Bit-format of an object header (most significant first):
 //
-//  
-//  unused:0/25 hash:25/31 age:4 biased_lock:1 lock:2 = 32/64 bits
+//  32 bits: unused:0  hash:25 age:4 biased_lock:1 lock:2
+//  64 bits: unused:24 hash:31 cms:2 age:4 biased_lock:1 lock:2
+//           unused:20 size:35 cms:2 age:4 biased_lock:1 lock:2 (if cms
+//                                                               free chunk)
 //
 //  - hash contains the identity hash value: largest value is
 //    31 bits, see os::random().  Also, 64-bit vm's require
 //    a hash value no bigger than 32 bits because they will not
 //    properly generate a mask larger than that: see library_call.cpp

@@ -90,12 +92,13 @@
  public:
   // Constants
   enum { age_bits                 = 4,
          lock_bits                = 2,
          biased_lock_bits         = 1,
-         max_hash_bits            = BitsPerOop - age_bits - lock_bits - biased_lock_bits,
+         max_hash_bits            = BitsPerWord - age_bits - lock_bits - biased_lock_bits,
          hash_bits                = max_hash_bits > 31 ? 31 : max_hash_bits,
+         cms_bits                 = LP64_ONLY(1) NOT_LP64(0),
          epoch_bits               = 2
   };
 
   // The biased locking code currently requires that the age bits be
   // contiguous to the lock bits. Class data sharing would prefer the

@@ -107,11 +110,12 @@
   // of the biased locking code.
 
   enum { lock_shift               = 0,
          biased_lock_shift        = lock_bits,
          age_shift                = lock_bits + biased_lock_bits,
-         hash_shift               = lock_bits + biased_lock_bits + age_bits,
+         cms_shift                = age_shift + age_bits,
+         hash_shift               = cms_shift + cms_bits,
          epoch_shift              = hash_shift
   };
 
   enum { lock_mask                = right_n_bits(lock_bits),
          lock_mask_in_place       = lock_mask << lock_shift,

@@ -119,11 +123,13 @@
          biased_lock_mask_in_place= biased_lock_mask << lock_shift,
          biased_lock_bit_in_place = 1 << biased_lock_shift,
          age_mask                 = right_n_bits(age_bits),
          age_mask_in_place        = age_mask << age_shift,
          epoch_mask               = right_n_bits(epoch_bits),
-         epoch_mask_in_place      = epoch_mask << epoch_shift
+         epoch_mask_in_place      = epoch_mask << epoch_shift,
+         cms_mask                 = right_n_bits(cms_bits),
+         cms_mask_in_place        = cms_mask << cms_shift
 #ifndef _WIN64
          ,hash_mask               = right_n_bits(hash_bits),
          hash_mask_in_place       = (address_word)hash_mask << hash_shift
 #endif
   };

@@ -217,15 +223,11 @@
   // other thread.  (They should spin or block instead.  The 0 value
   // is transient and *should* be short-lived). 
   static markOop INFLATING() { return (markOop) 0; }    // inflate-in-progress
 
   // Should this header be preserved during GC?
-  bool must_be_preserved(oop obj_containing_mark) const {
-    if (!UseBiasedLocking)
-      return (!is_unlocked() || !has_no_hash());
-    return must_be_preserved_with_bias(obj_containing_mark);
-  }
+  inline bool must_be_preserved(oop obj_containing_mark) const;
   inline bool must_be_preserved_with_bias(oop obj_containing_mark) const;
 
   // Should this header (including its age bits) be preserved in the
   // case of a promotion failure during scavenge?
   // Note that we special case this situation. We want to avoid

@@ -241,26 +243,18 @@
   // place in which to call them in any of the scavengers (although
   // guarded by appropriate locks we could make one), but the
   // observation is that promotion failures are quite rare and
   // reducing the number of mark words preserved during them isn't a
   // high priority.
-  bool must_be_preserved_for_promotion_failure(oop obj_containing_mark) const {
-    if (!UseBiasedLocking)
-      return (this != prototype());
-    return must_be_preserved_with_bias_for_promotion_failure(obj_containing_mark);
-  }
+  inline bool must_be_preserved_for_promotion_failure(oop obj_containing_mark) const;
   inline bool must_be_preserved_with_bias_for_promotion_failure(oop obj_containing_mark) const;
 
   // Should this header be preserved during a scavenge where CMS is
   // the old generation?
   // (This is basically the same body as must_be_preserved_for_promotion_failure(),
   // but takes the klassOop as argument instead)
-  bool must_be_preserved_for_cms_scavenge(klassOop klass_of_obj_containing_mark) const {
-    if (!UseBiasedLocking)
-      return (this != prototype());
-    return must_be_preserved_with_bias_for_cms_scavenge(klass_of_obj_containing_mark);
-  }
+  inline bool must_be_preserved_for_cms_scavenge(klassOop klass_of_obj_containing_mark) const;
   inline bool must_be_preserved_with_bias_for_cms_scavenge(klassOop klass_of_obj_containing_mark) const;
 
   // WARNING: The following routines are used EXCLUSIVELY by 
   // synchronization functions. They are not really gc safe.
   // They must get updated if markOop layout get changed.

@@ -361,6 +355,42 @@
   // Recover address of oop from encoded form used in mark
   inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return clear_lock_bits(); }
 
   // see the definition in markOop.cpp for the gory details
   bool should_not_be_cached() const;
+
+  // These markOops indicate cms free chunk blocks and not objects.
+  // In 64 bit, the markOop is set to distinguish them from oops.
+  // These are defined in 32 bit mode for vmStructs.
+  const static uintptr_t cms_free_chunk_pattern  = 0x1;
+
+  // Constants for the size field.
+  enum { size_shift                = cms_shift + cms_bits,
+         size_bits                 = 35    // need for compressed oops 32G
+       };
+  // These values are too big for Win64
+  const static uintptr_t size_mask = LP64_ONLY(right_n_bits(size_bits))
+                                     NOT_LP64(0);
+  const static uintptr_t size_mask_in_place =
+                                     (address_word)size_mask << size_shift;
+
+#ifdef _LP64
+  static markOop cms_free_prototype() {
+    return markOop(((intptr_t)prototype() & ~cms_mask_in_place) |
+                   ((cms_free_chunk_pattern & cms_mask) << cms_shift));
+  }
+  uintptr_t cms_encoding() const {
+    return mask_bits(value() >> cms_shift, cms_mask);
+  }
+  bool is_cms_free_chunk() const {
+    return is_neutral() &&
+           (cms_encoding() & cms_free_chunk_pattern) == cms_free_chunk_pattern;
+  }
+
+  size_t get_size() const       { return (size_t)(value() >> size_shift); }
+  static markOop set_size_and_free(size_t size) {
+    assert((size & ~size_mask) == 0, "shouldn't overflow size field");
+    return markOop(((intptr_t)cms_free_prototype() & ~size_mask_in_place) |
+                   (((intptr_t)size & size_mask) << size_shift));
+  }
+#endif // _LP64
 };