< prev index next >
src/hotspot/share/oops/klass.hpp
Print this page
@@ -26,10 +26,11 @@
#define SHARE_OOPS_KLASS_HPP
#include "classfile/classLoaderData.hpp"
#include "memory/iterator.hpp"
#include "memory/memRegion.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 +43,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 +98,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.
@@ -345,16 +347,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;
}
@@ -367,27 +370,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!
@@ -404,11 +408,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)
@@ -546,10 +550,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;
@@ -561,11 +567,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
@@ -587,10 +596,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; }
@@ -619,10 +633,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 >