diff src/share/vm/oops/oop.hpp @ 113:ba764ed4b6f2

6420645: Create a vm that uses compressed oops for up to 32gb heapsizes Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author coleenp
date Sun, 13 Apr 2008 17:43:42 -0400
parents a61af66fc99e
children b7268662a986
line wrap: on
line diff
--- a/src/share/vm/oops/oop.hpp	Fri Apr 11 09:56:35 2008 -0400
+++ b/src/share/vm/oops/oop.hpp	Sun Apr 13 17:43:42 2008 -0400
@@ -30,12 +30,12 @@
 // no virtual functions allowed
 
 // store into oop with store check
-void oop_store(oop* p, oop v);
-void oop_store(volatile oop* p, oop v);
+template <class T> void oop_store(T* p, oop v);
+template <class T> void oop_store(volatile T* p, oop v);
 
 // store into oop without store check
-void oop_store_without_check(oop* p, oop v);
-void oop_store_without_check(volatile oop* p, oop v);
+template <class T> void oop_store_without_check(T* p, oop v);
+template <class T> void oop_store_without_check(volatile T* p, oop v);
 
 
 extern bool always_do_update_barrier;
@@ -55,7 +55,10 @@
   friend class VMStructs;
  private:
   volatile markOop  _mark;
-  klassOop _klass;
+  union _metadata {
+    wideKlassOop    _klass;
+    narrowOop       _compressed_klass;
+  } _metadata;
 
   // Fast access to barrier set.  Must be initialized.
   static BarrierSet* _bs;
@@ -73,16 +76,16 @@
   // objects during a GC) -- requires a valid klass pointer
   void init_mark();
 
-  klassOop klass() const        { return _klass; }
-  oop* klass_addr() const       { return (oop*) &_klass; }
+  klassOop klass() const;
+  oop* klass_addr();
+  narrowOop* compressed_klass_addr();
 
   void set_klass(klassOop k);
   // For when the klass pointer is being used as a linked list "next" field.
   void set_klass_to_list_ptr(oop k);
 
-  // size of object header
-  static int header_size()      { return sizeof(oopDesc)/HeapWordSize; }
-  static int header_size_in_bytes() { return sizeof(oopDesc); }
+  // size of object header, aligned to platform wordSize
+  static int header_size()          { return sizeof(oopDesc)/HeapWordSize; }
 
   Klass* blueprint() const;
 
@@ -119,7 +122,6 @@
 
  private:
   // field addresses in oop
-  // byte/char/bool/short fields are always stored as full words
   void*     field_base(int offset)        const;
 
   jbyte*    byte_field_addr(int offset)   const;
@@ -130,13 +132,66 @@
   jlong*    long_field_addr(int offset)   const;
   jfloat*   float_field_addr(int offset)  const;
   jdouble*  double_field_addr(int offset) const;
+  address*  address_field_addr(int offset) const;
 
  public:
-  // need this as public for garbage collection
-  oop* obj_field_addr(int offset) const;
+  // Need this as public for garbage collection.
+  template <class T> T* obj_field_addr(int offset) const;
+
+  static bool is_null(oop obj);
+  static bool is_null(narrowOop obj);
+
+  // Decode an oop pointer from a narrowOop if compressed.
+  // These are overloaded for oop and narrowOop as are the other functions
+  // below so that they can be called in template functions.
+  static oop decode_heap_oop_not_null(oop v);
+  static oop decode_heap_oop_not_null(narrowOop v);
+  static oop decode_heap_oop(oop v);
+  static oop decode_heap_oop(narrowOop v);
+
+  // Encode an oop pointer to a narrow oop.  The or_null versions accept
+  // null oop pointer, others do not in order to eliminate the
+  // null checking branches.
+  static narrowOop encode_heap_oop_not_null(oop v);
+  static narrowOop encode_heap_oop(oop v);
+
+  // Load an oop out of the Java heap
+  static narrowOop load_heap_oop(narrowOop* p);
+  static oop       load_heap_oop(oop* p);
 
+  // Load an oop out of Java heap and decode it to an uncompressed oop.
+  static oop load_decode_heap_oop_not_null(narrowOop* p);
+  static oop load_decode_heap_oop_not_null(oop* p);
+  static oop load_decode_heap_oop(narrowOop* p);
+  static oop load_decode_heap_oop(oop* p);
+
+  // Store an oop into the heap.
+  static void store_heap_oop(narrowOop* p, narrowOop v);
+  static void store_heap_oop(oop* p, oop v);
+
+  // Encode oop if UseCompressedOops and store into the heap.
+  static void encode_store_heap_oop_not_null(narrowOop* p, oop v);
+  static void encode_store_heap_oop_not_null(oop* p, oop v);
+  static void encode_store_heap_oop(narrowOop* p, oop v);
+  static void encode_store_heap_oop(oop* p, oop v);
+
+  static void release_store_heap_oop(volatile narrowOop* p, narrowOop v);
+  static void release_store_heap_oop(volatile oop* p, oop v);
+
+  static void release_encode_store_heap_oop_not_null(volatile narrowOop* p, oop v);
+  static void release_encode_store_heap_oop_not_null(volatile oop* p, oop v);
+  static void release_encode_store_heap_oop(volatile narrowOop* p, oop v);
+  static void release_encode_store_heap_oop(volatile oop* p, oop v);
+
+  static oop atomic_exchange_oop(oop exchange_value, volatile HeapWord *dest);
+  static oop atomic_compare_exchange_oop(oop exchange_value,
+                                         volatile HeapWord *dest,
+                                         oop compare_value);
+
+  // Access to fields in a instanceOop through these methods.
   oop obj_field(int offset) const;
   void obj_field_put(int offset, oop value);
+  void obj_field_raw_put(int offset, oop value);
 
   jbyte byte_field(int offset) const;
   void byte_field_put(int offset, jbyte contents);
@@ -162,6 +217,9 @@
   jdouble double_field(int offset) const;
   void double_field_put(int offset, jdouble contents);
 
+  address address_field(int offset) const;
+  void address_field_put(int offset, address contents);
+
   oop obj_field_acquire(int offset) const;
   void release_obj_field_put(int offset, oop value);
 
@@ -207,6 +265,7 @@
   void verify_on(outputStream* st);
   void verify();
   void verify_old_oop(oop* p, bool allow_dirty);
+  void verify_old_oop(narrowOop* p, bool allow_dirty);
 
   // tells whether this oop is partially constructed (gc during class loading)
   bool partially_loaded();
@@ -228,8 +287,8 @@
   bool is_gc_marked() const;
   // Apply "MarkSweep::mark_and_push" to (the address of) every non-NULL
   // reference field in "this".
-  void follow_contents();
-  void follow_header();
+  void follow_contents(void);
+  void follow_header(void);
 
 #ifndef SERIALGC
   // Parallel Scavenge
@@ -317,6 +376,7 @@
   void     set_displaced_mark(markOop m);
 
   // for code generation
-  static int klass_offset_in_bytes()   { return offset_of(oopDesc, _klass); }
   static int mark_offset_in_bytes()    { return offset_of(oopDesc, _mark); }
+  static int klass_offset_in_bytes()   { return offset_of(oopDesc, _metadata._klass); }
+  static int klass_gap_offset_in_bytes();
 };