< prev index next >

src/hotspot/share/oops/klass.hpp

Print this page

        

@@ -26,10 +26,12 @@
 #define SHARE_OOPS_KLASS_HPP
 
 #include "classfile/classLoaderData.hpp"
 #include "memory/iterator.hpp"
 #include "memory/memRegion.hpp"
+#include "oops/arrayStorageProperties.hpp"
+#include "oops/markOop.hpp"
 #include "oops/metadata.hpp"
 #include "oops/oop.hpp"
 #include "oops/oopHandle.hpp"
 #include "utilities/accessFlags.hpp"
 #include "utilities/macros.hpp"

@@ -42,14 +44,15 @@
   InstanceKlassID,
   InstanceRefKlassID,
   InstanceMirrorKlassID,
   InstanceClassLoaderKlassID,
   TypeArrayKlassID,
+  ValueArrayKlassID,
   ObjArrayKlassID
 };
 
-const uint KLASS_ID_COUNT = 6;
+const uint KLASS_ID_COUNT = 7;
 
 //
 // A Klass provides:
 //  1: language level class object (method dictionary etc.)
 //  2: provide vm dispatch behavior for the object

@@ -96,11 +99,11 @@
   //
   // For arrays, layout helper is a negative number, containing four
   // distinct bytes, as follows:
   //    MSB:[tag, hsz, ebt, log2(esz)]:LSB
   // where:
-  //    tag is 0x80 if the elements are oops, 0xC0 if non-oops
+  //    tag is 0x80 if the elements are oops, 0xC0 if non-oops, 0xA0 if value types
   //    hsz is array header size in bytes (i.e., offset of first element)
   //    ebt is the BasicType of the elements
   //    esz is the element size in bytes
   // This packed word is arranged so as to be quickly unpacked by the
   // various fast paths that use the various subfields.

@@ -346,16 +349,17 @@
     _lh_log2_element_size_mask  = BitsPerLong-1,
     _lh_element_type_shift      = BitsPerByte*1,
     _lh_element_type_mask       = right_n_bits(BitsPerByte),  // shifted mask
     _lh_header_size_shift       = BitsPerByte*2,
     _lh_header_size_mask        = right_n_bits(BitsPerByte),  // shifted mask
-    _lh_array_tag_bits          = 2,
-    _lh_array_tag_shift         = BitsPerInt - _lh_array_tag_bits,
-    _lh_array_tag_obj_value     = ~0x01   // 0x80000000 >> 30
+    _lh_array_tag_bits          = 3,
+    _lh_array_tag_shift         = BitsPerInt - _lh_array_tag_bits
   };
 
-  static const unsigned int _lh_array_tag_type_value = 0Xffffffff; // ~0x00,  // 0xC0000000 >> 30
+  static const unsigned int _lh_array_tag_type_value = 0Xfffffffc;
+  static const unsigned int _lh_array_tag_vt_value   = 0Xfffffffd;
+  static const unsigned int _lh_array_tag_obj_value  = 0Xfffffffe;
 
   static int layout_helper_size_in_bytes(jint lh) {
     assert(lh > (jint)_lh_neutral_value, "must be instance");
     return (int) lh & ~_lh_instance_slow_path_bit;
   }

@@ -368,27 +372,28 @@
   }
   static bool layout_helper_is_array(jint lh) {
     return (jint)lh < (jint)_lh_neutral_value;
   }
   static bool layout_helper_is_typeArray(jint lh) {
-    // _lh_array_tag_type_value == (lh >> _lh_array_tag_shift);
-    return (juint)lh >= (juint)(_lh_array_tag_type_value << _lh_array_tag_shift);
+    return (juint) _lh_array_tag_type_value == (juint)(lh >> _lh_array_tag_shift);
   }
   static bool layout_helper_is_objArray(jint lh) {
-    // _lh_array_tag_obj_value == (lh >> _lh_array_tag_shift);
-    return (jint)lh < (jint)(_lh_array_tag_type_value << _lh_array_tag_shift);
+    return (juint)_lh_array_tag_obj_value == (juint)(lh >> _lh_array_tag_shift);
+  }
+  static bool layout_helper_is_valueArray(jint lh) {
+    return (juint)_lh_array_tag_vt_value == (juint)(lh >> _lh_array_tag_shift);
   }
   static int layout_helper_header_size(jint lh) {
     assert(lh < (jint)_lh_neutral_value, "must be array");
     int hsize = (lh >> _lh_header_size_shift) & _lh_header_size_mask;
     assert(hsize > 0 && hsize < (int)sizeof(oopDesc)*3, "sanity");
     return hsize;
   }
   static BasicType layout_helper_element_type(jint lh) {
     assert(lh < (jint)_lh_neutral_value, "must be array");
     int btvalue = (lh >> _lh_element_type_shift) & _lh_element_type_mask;
-    assert(btvalue >= T_BOOLEAN && btvalue <= T_OBJECT, "sanity");
+    assert((btvalue >= T_BOOLEAN && btvalue <= T_OBJECT) || btvalue == T_VALUETYPE, "sanity");
     return (BasicType) btvalue;
   }
 
   // Want a pattern to quickly diff against layout header in register
   // find something less clever!

@@ -405,11 +410,11 @@
   }
 
   static int layout_helper_log2_element_size(jint lh) {
     assert(lh < (jint)_lh_neutral_value, "must be array");
     int l2esz = (lh >> _lh_log2_element_size_shift) & _lh_log2_element_size_mask;
-    assert(l2esz <= LogBytesPerLong,
+    assert(layout_helper_element_type(lh) == T_VALUETYPE || l2esz <= LogBytesPerLong,
            "sanity. l2esz: 0x%x for lh: 0x%x", (uint)l2esz, (uint)lh);
     return l2esz;
   }
   static jint array_layout_helper(jint tag, int hsize, BasicType etype, int log2_esize) {
     return (tag        << _lh_array_tag_shift)

@@ -478,19 +483,31 @@
   Method* lookup_method(const Symbol* name, const Symbol* signature) const {
     return uncached_lookup_method(name, signature, find_overpass);
   }
 
   // array class with specific rank
-  Klass* array_klass(int rank, TRAPS)         {  return array_klass_impl(false, rank, THREAD); }
+  Klass* array_klass(int rank, TRAPS) {
+    return array_klass_impl(ArrayStorageProperties::empty, false, rank, THREAD);
+  }
+
+  Klass* array_klass(ArrayStorageProperties storage_props, int rank, TRAPS) {
+    return array_klass_impl(storage_props, false, rank, THREAD);
+  }
 
   // array class with this klass as element type
-  Klass* array_klass(TRAPS)                   {  return array_klass_impl(false, THREAD); }
+  Klass* array_klass(TRAPS) {
+    return array_klass_impl(ArrayStorageProperties::empty, false, THREAD);
+  }
+
+  Klass* array_klass(ArrayStorageProperties storage_props, TRAPS) {
+    return array_klass_impl(storage_props, false, THREAD);
+  }
 
   // These will return NULL instead of allocating on the heap:
   // NB: these can block for a mutex, like other functions with TRAPS arg.
-  Klass* array_klass_or_null(int rank);
-  Klass* array_klass_or_null();
+  Klass* array_klass_or_null(ArrayStorageProperties storage_props, int rank);
+  Klass* array_klass_or_null(ArrayStorageProperties storage_props);
 
   virtual oop protection_domain() const = 0;
 
   oop class_loader() const;
 

@@ -499,12 +516,12 @@
   // be used safely.  All uses of klass_holder need to apply the appropriate barriers,
   // except during GC.
   oop klass_holder() const { return class_loader_data()->holder_phantom(); }
 
  protected:
-  virtual Klass* array_klass_impl(bool or_null, int rank, TRAPS);
-  virtual Klass* array_klass_impl(bool or_null, TRAPS);
+  virtual Klass* array_klass_impl(ArrayStorageProperties storage_props, bool or_null, int rank, TRAPS);
+  virtual Klass* array_klass_impl(ArrayStorageProperties storage_props, bool or_null, TRAPS);
 
   // Error handling when length > max_length or length < 0
   static void check_array_allocation_length(int length, int max_length, TRAPS);
 
   void set_vtable_length(int len) { _vtable_len= len; }

@@ -547,10 +564,12 @@
   // Returns the name for a class (Resource allocated) as the class
   // would appear in a signature.
   // For arrays, this returns the name of the element with a leading '['.
   // For classes, this returns the name with a leading 'L' and a trailing ';'
   //     and the package separators as '/'.
+  // For value classes, this returns the name with a leading 'Q' and a trailing ';'
+  //     and the package separators as '/'.
   virtual const char* signature_name() const;
 
   const char* joint_in_module_of_loader(const Klass* class2, bool include_parent_loader = false) const;
   const char* class_in_module_of_loader(bool use_are = false, bool include_parent_loader = false) const;
 

@@ -562,11 +581,14 @@
  protected:
   virtual bool is_instance_klass_slow()     const { return false; }
   virtual bool is_array_klass_slow()        const { return false; }
   virtual bool is_objArray_klass_slow()     const { return false; }
   virtual bool is_typeArray_klass_slow()    const { return false; }
+  virtual bool is_valueArray_klass_slow()   const { return false; }
 #endif // ASSERT
+  // current implementation uses this method even in non debug builds
+  virtual bool is_value_slow()          const { return false; }
  public:
 
   // Fast non-virtual versions
   #ifndef ASSERT
   #define assert_same_query(xval, xcheck) xval

@@ -588,10 +610,15 @@
                                                     layout_helper_is_objArray(layout_helper()),
                                                     is_objArray_klass_slow()); }
   inline  bool is_typeArray_klass()           const { return assert_same_query(
                                                     layout_helper_is_typeArray(layout_helper()),
                                                     is_typeArray_klass_slow()); }
+  inline  bool is_value()                     const { return is_value_slow(); } //temporary hack
+  inline  bool is_valueArray_klass()          const { return assert_same_query(
+                                                    layout_helper_is_valueArray(layout_helper()),
+                                                    is_valueArray_klass_slow()); }
+
   #undef assert_same_query
 
   // Access flags
   AccessFlags access_flags() const         { return _access_flags;  }
   void set_access_flags(AccessFlags flags) { _access_flags = flags; }

@@ -620,10 +647,14 @@
   // Biased locking support
   // Note: the prototype header is always set up to be at least the
   // prototype markOop. If biased locking is enabled it may further be
   // biasable and have an epoch.
   markOop prototype_header() const      { return _prototype_header; }
+  static inline markOop default_prototype_header(Klass* k) {
+    return (k == NULL) ? markOopDesc::prototype() : k->prototype_header();
+  }
+
   // NOTE: once instances of this klass are floating around in the
   // system, this header must only be updated at a safepoint.
   // NOTE 2: currently we only ever set the prototype header to the
   // biasable prototype for instanceKlasses. There is no technical
   // reason why it could not be done for arrayKlasses aside from
< prev index next >