< prev index next > src/hotspot/share/oops/klass.hpp
Print this page
friend class JVMCIVMStructs;
public:
// Klass Kinds for all subclasses of Klass
enum KlassKind {
InstanceKlassKind,
+ InlineKlassKind,
InstanceRefKlassKind,
InstanceMirrorKlassKind,
InstanceClassLoaderKlassKind,
InstanceStackChunkKlassKind,
TypeArrayKlassKind,
+ FlatArrayKlassKind,
ObjArrayKlassKind,
UnknownKlassKind
};
static const uint KLASS_KIND_COUNT = ObjArrayKlassKind + 1;
//
// 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.
// Some flags created by the JVM, not in the class file itself,
// are in _misc_flags below.
JFR_ONLY(DEFINE_TRACE_ID_FIELD;)
+ markWord _prototype_header; // inline type and inline array mark patterns
// Bitmap and hash code used by hashed secondary supers.
uintx _bitmap;
uint8_t _hash_slot;
private:
static const int _lh_log2_element_size_mask = BitsPerLong-1;
static const int _lh_element_type_shift = BitsPerByte*1;
static const int _lh_element_type_mask = right_n_bits(BitsPerByte); // shifted mask
static const int _lh_header_size_shift = BitsPerByte*2;
static const int _lh_header_size_mask = right_n_bits(BitsPerByte); // shifted mask
- static const int _lh_array_tag_bits = 2;
+ static const int _lh_array_tag_bits = 3;
static const int _lh_array_tag_shift = BitsPerInt - _lh_array_tag_bits;
- static const int _lh_array_tag_obj_value = ~0x01; // 0x80000000 >> 30
- 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;
+
+ // null-free array flag bit under the array tag bits, shift one more to get array tag value
+ static const int _lh_null_free_shift = _lh_array_tag_shift - 1;
+ static const int _lh_null_free_mask = 1;
+
+ static const jint _lh_array_tag_flat_value_bit_inplace = (jint) (1 << _lh_array_tag_shift);
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;
}
}
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_flatArray(jint lh) {
+ return (juint)_lh_array_tag_vt_value == (juint)(lh >> _lh_array_tag_shift);
+ }
+ static bool layout_helper_is_null_free(jint lh) {
+ assert(layout_helper_is_flatArray(lh) || layout_helper_is_objArray(lh), "must be array of inline types");
+ return ((lh >> _lh_null_free_shift) & _lh_null_free_mask);
+ }
+ static jint layout_helper_set_null_free(jint lh) {
+ lh |= (_lh_null_free_mask << _lh_null_free_shift);
+ assert(layout_helper_is_null_free(lh), "Bad encoding");
+ return lh;
}
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_PRIMITIVE_OBJECT, "sanity");
return (BasicType) btvalue;
}
// Want a pattern to quickly diff against layout header in register
// find something less clever!
}
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_PRIMITIVE_OBJECT || 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) {
+ static jint array_layout_helper(jint tag, bool null_free, int hsize, BasicType etype, int log2_esize) {
return (tag << _lh_array_tag_shift)
+ | ((null_free ? 1 : 0) << _lh_null_free_shift)
| (hsize << _lh_header_size_shift)
| ((int)etype << _lh_element_type_shift)
| (log2_esize << _lh_log2_element_size_shift);
}
static jint instance_layout_helper(jint size, bool slow_path_flag) {
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_flatArray_klass_slow() const { return false; }
#endif // ASSERT
+ // current implementation uses this method even in non debug builds
+ virtual bool is_inline_klass_slow() const { return false; }
public:
// Fast non-virtual versions
#ifndef ASSERT
#define assert_same_query(xval, xcheck) xval
}
public:
#endif
bool is_instance_klass() const { return assert_same_query(_kind <= InstanceStackChunkKlassKind, is_instance_klass_slow()); }
- // Other is anything that is not one of the more specialized kinds of InstanceKlass.
- bool is_other_instance_klass() const { return _kind == InstanceKlassKind; }
+ bool is_inline_klass() const { return assert_same_query(_kind == InlineKlassKind, is_inline_klass_slow()); }
bool is_reference_instance_klass() const { return _kind == InstanceRefKlassKind; }
bool is_mirror_instance_klass() const { return _kind == InstanceMirrorKlassKind; }
bool is_class_loader_instance_klass() const { return _kind == InstanceClassLoaderKlassKind; }
bool is_array_klass() const { return assert_same_query( _kind >= TypeArrayKlassKind, is_array_klass_slow()); }
bool is_stack_chunk_instance_klass() const { return _kind == InstanceStackChunkKlassKind; }
+ bool is_flatArray_klass() const { return assert_same_query( _kind == FlatArrayKlassKind, is_flatArray_klass_slow()); }
bool is_objArray_klass() const { return assert_same_query( _kind == ObjArrayKlassKind, is_objArray_klass_slow()); }
bool is_typeArray_klass() const { return assert_same_query( _kind == TypeArrayKlassKind, is_typeArray_klass_slow()); }
#undef assert_same_query
+ inline bool is_null_free_array_klass() const { return layout_helper_is_null_free(layout_helper()); }
+
// Access flags
AccessFlags access_flags() const { return _access_flags; }
void set_access_flags(AccessFlags flags) { _access_flags = flags; }
bool is_public() const { return _access_flags.is_public(); }
bool is_final() const { return _access_flags.is_final(); }
bool is_interface() const { return _access_flags.is_interface(); }
bool is_abstract() const { return _access_flags.is_abstract(); }
- bool is_super() const { return _access_flags.is_super(); }
bool is_synthetic() const { return _access_flags.is_synthetic(); }
+ bool is_identity_class() const { return _access_flags.is_identity_class(); }
void set_is_synthetic() { _access_flags.set_is_synthetic(); }
bool has_finalizer() const { return _misc_flags.has_finalizer(); }
void set_has_finalizer() { _misc_flags.set_has_finalizer(true); }
bool is_hidden() const { return _misc_flags.is_hidden_class(); }
void set_is_hidden() { _misc_flags.set_is_hidden_class(true); }
inline bool is_non_strong_hidden() const;
bool is_cloneable() const;
void set_is_cloneable();
+ // inline types and inline type array patterns
+ markWord prototype_header() const {
+ return _prototype_header;
+ }
+ static inline markWord default_prototype_header(Klass* k) {
+ return (k == nullptr) ? markWord::prototype() : k->prototype_header();
+ }
+
+ inline void set_prototype_header(markWord header);
+ static ByteSize prototype_header_offset() { return in_ByteSize(offset_of(Klass, _prototype_header)); }
+
JFR_ONLY(DEFINE_TRACE_ID_METHODS;)
virtual void metaspace_pointers_do(MetaspaceClosure* iter);
virtual MetaspaceObj::Type type() const { return ClassType; }
< prev index next >