< prev index next >

src/hotspot/share/oops/klass.hpp

Print this page

        

*** 26,35 **** --- 26,37 ---- #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,55 **** InstanceKlassID, InstanceRefKlassID, InstanceMirrorKlassID, InstanceClassLoaderKlassID, TypeArrayKlassID, ObjArrayKlassID }; ! const uint KLASS_ID_COUNT = 6; // // A Klass provides: // 1: language level class object (method dictionary etc.) // 2: provide vm dispatch behavior for the object --- 44,58 ---- InstanceKlassID, InstanceRefKlassID, InstanceMirrorKlassID, InstanceClassLoaderKlassID, TypeArrayKlassID, + ValueArrayKlassID, ObjArrayKlassID }; ! 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,106 **** // // 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 // 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. --- 99,109 ---- // // 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, 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,361 **** _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 }; ! static const unsigned int _lh_array_tag_type_value = 0Xffffffff; // ~0x00, // 0xC0000000 >> 30 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; } --- 349,365 ---- _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 = 3, ! _lh_array_tag_shift = BitsPerInt - _lh_array_tag_bits }; ! 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,394 **** } 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); } 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); } 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"); return (BasicType) btvalue; } // Want a pattern to quickly diff against layout header in register // find something less clever! --- 372,399 ---- } static bool layout_helper_is_array(jint lh) { return (jint)lh < (jint)_lh_neutral_value; } static bool layout_helper_is_typeArray(jint lh) { ! return (juint) _lh_array_tag_type_value == (juint)(lh >> _lh_array_tag_shift); } static bool layout_helper_is_objArray(jint lh) { ! 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) || btvalue == T_VALUETYPE, "sanity"); return (BasicType) btvalue; } // Want a pattern to quickly diff against layout header in register // find something less clever!
*** 405,415 **** } 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, "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) --- 410,420 ---- } 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(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,496 **** 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); } // array class with this klass as element type ! Klass* array_klass(TRAPS) { return array_klass_impl(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(); virtual oop protection_domain() const = 0; oop class_loader() const; --- 483,513 ---- 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(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(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(ArrayStorageProperties storage_props, int rank); ! Klass* array_klass_or_null(ArrayStorageProperties storage_props); virtual oop protection_domain() const = 0; oop class_loader() const;
*** 499,510 **** // 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); // 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; } --- 516,527 ---- // 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(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,556 **** --- 564,575 ---- // 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,572 **** --- 581,594 ---- 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,597 **** --- 610,624 ---- 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,629 **** --- 647,660 ---- // 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 >