diff --git a/src/hotspot/share/ci/ciArray.cpp b/src/hotspot/share/ci/ciArray.cpp index 82d8b04e9f9..e45258668ca 100644 --- a/src/hotspot/share/ci/ciArray.cpp +++ b/src/hotspot/share/ci/ciArray.cpp @@ -133,7 +133,7 @@ bool ciArray::is_atomic() { } if (oop->is_flatArray()) { FlatArrayKlass* fak = FlatArrayKlass::cast(oop->klass()); - if (fak->element_klass()->is_naturally_atomic() || fak->layout_kind() == LayoutKind::ATOMIC_FLAT || fak->layout_kind() == LayoutKind::NULLABLE_ATOMIC_FLAT) { + if (fak->element_klass()->is_naturally_atomic() || LayoutKindHelper::is_atomic_flat(fak->layout_kind())) { return true; } } diff --git a/src/hotspot/share/oops/arrayKlass.cpp b/src/hotspot/share/oops/arrayKlass.cpp index cc4840ffaa0..faf3ff77133 100644 --- a/src/hotspot/share/oops/arrayKlass.cpp +++ b/src/hotspot/share/oops/arrayKlass.cpp @@ -218,6 +218,24 @@ oop ArrayKlass::component_mirror() const { return java_lang_Class::component_mirror(java_mirror()); } +ArrayKlass::ArrayProperties ArrayKlass::array_properties_from_layout(LayoutKind lk) { + ArrayKlass::ArrayProperties props = ArrayKlass::ArrayProperties::DEFAULT; + switch(lk) { + case LayoutKind::ATOMIC_FLAT: + props = ArrayKlass::ArrayProperties::NULL_RESTRICTED; + break; + case LayoutKind::NON_ATOMIC_FLAT: + props = (ArrayKlass::ArrayProperties)(ArrayKlass::ArrayProperties::NULL_RESTRICTED | ArrayKlass::ArrayProperties::NON_ATOMIC); + break; + case LayoutKind::NULLABLE_ATOMIC_FLAT: + props = ArrayKlass::ArrayProperties::DEFAULT; + break; + default: + ShouldNotReachHere(); + } + return props; +} + // JVMTI support jint ArrayKlass::jvmti_class_status() const { diff --git a/src/hotspot/share/oops/arrayKlass.hpp b/src/hotspot/share/oops/arrayKlass.hpp index df9bab21f5d..5b43096461b 100644 --- a/src/hotspot/share/oops/arrayKlass.hpp +++ b/src/hotspot/share/oops/arrayKlass.hpp @@ -26,6 +26,7 @@ #define SHARE_OOPS_ARRAYKLASS_HPP #include "oops/klass.hpp" +#include "oops/layoutKind.hpp" class fieldDescriptor; class klassVtable; @@ -38,7 +39,7 @@ class ArrayKlass: public Klass { public: enum ArrayProperties : uint32_t { - DEFAULT = 0, + DEFAULT = 0, // NULLABLE and ATOMIC NULL_RESTRICTED = 1 << 0, NON_ATOMIC = 1 << 1, // FINAL = 1 << 2, @@ -50,6 +51,8 @@ class ArrayKlass: public Klass { static bool is_null_restricted(ArrayProperties props) { return (props & NULL_RESTRICTED) != 0; } static bool is_non_atomic(ArrayProperties props) { return (props & NON_ATOMIC) != 0; } + static ArrayProperties array_properties_from_layout(LayoutKind lk); + private: // If you add a new field that points to any metaspace object, you // must add this field to ArrayKlass::metaspace_pointers_do(). diff --git a/src/hotspot/share/oops/flatArrayKlass.cpp b/src/hotspot/share/oops/flatArrayKlass.cpp index dc91a0156c2..aef3db27caa 100644 --- a/src/hotspot/share/oops/flatArrayKlass.cpp +++ b/src/hotspot/share/oops/flatArrayKlass.cpp @@ -57,7 +57,7 @@ FlatArrayKlass::FlatArrayKlass(Klass* element_klass, Symbol* name, ArrayProperties props, LayoutKind lk) : ObjArrayKlass(1, element_klass, name, Kind, props, markWord::flat_array_prototype(lk)) { assert(element_klass->is_inline_klass(), "Expected Inline"); - assert(lk == LayoutKind::NON_ATOMIC_FLAT || lk == LayoutKind::ATOMIC_FLAT || lk == LayoutKind::NULLABLE_ATOMIC_FLAT, "Must be a flat layout"); + assert(LayoutKindHelper::is_flat(lk), "Must be a flat layout"); set_element_klass(InlineKlass::cast(element_klass)); set_class_loader_data(element_klass->class_loader_data()); @@ -151,7 +151,7 @@ jint FlatArrayKlass::array_layout_helper(InlineKlass* vk, LayoutKind lk) { BasicType etype = T_FLAT_ELEMENT; int esize = log2i_exact(round_up_power_of_2(vk->layout_size_in_bytes(lk))); int hsize = arrayOopDesc::base_offset_in_bytes(etype); - bool null_free = lk != LayoutKind::NULLABLE_ATOMIC_FLAT; + bool null_free = !LayoutKindHelper::is_nullable_flat(lk); int lh = Klass::array_layout_helper(_lh_array_tag_flat_value, null_free, hsize, etype, esize); assert(lh < (int)_lh_neutral_value, "must look like an array layout"); @@ -286,7 +286,7 @@ void FlatArrayKlass::copy_array(arrayOop s, int src_pos, flatArrayHandle hd(THREAD, da); flatArrayHandle hs(THREAD, sa); // source and destination layouts mismatch, simpler solution is to copy through an intermediate buffer (heap instance) - bool need_null_check = fsk->layout_kind() == LayoutKind::NULLABLE_ATOMIC_FLAT && fdk->layout_kind() != LayoutKind::NULLABLE_ATOMIC_FLAT; + bool need_null_check = LayoutKindHelper::is_nullable_flat(fsk->layout_kind()) && !LayoutKindHelper::is_nullable_flat(fdk->layout_kind()); oop buffer = vk->allocate_instance(CHECK); address dst = (address) hd->value_at_addr(dst_pos, fdk->layout_helper()); address src = (address) hs->value_at_addr(src_pos, fsk->layout_helper()); diff --git a/src/hotspot/share/oops/layoutKind.hpp b/src/hotspot/share/oops/layoutKind.hpp index b58c51436e2..e3d862671cb 100644 --- a/src/hotspot/share/oops/layoutKind.hpp +++ b/src/hotspot/share/oops/layoutKind.hpp @@ -26,6 +26,7 @@ #define SHARE_OOPS_LAYOUTKIND_HPP #include "utilities/globalDefinitions.hpp" +#include "memory/allStatic.hpp" // LayoutKind is an enum used to indicate which layout has been used for a given value field. // Each layout has its own properties and its own access protocol that is detailed below. @@ -81,4 +82,17 @@ enum class LayoutKind : uint32_t { UNKNOWN = 5 // used for uninitialized fields of type LayoutKind }; +class LayoutKindHelper : AllStatic { + public: + static bool is_flat(LayoutKind lk) { + return lk == LayoutKind::NON_ATOMIC_FLAT || lk == LayoutKind::ATOMIC_FLAT || lk == LayoutKind::NULLABLE_ATOMIC_FLAT; + } + static bool is_atomic_flat(LayoutKind lk) { + return lk == LayoutKind::ATOMIC_FLAT || lk == LayoutKind::NULLABLE_ATOMIC_FLAT; + } + static bool is_nullable_flat(LayoutKind lk) { + return lk == LayoutKind::NULLABLE_ATOMIC_FLAT; + } +}; + #endif // SHARE_OOPS_LAYOUTKIND_HPP diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 5ea2469079c..1478a5c0ad5 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -2887,8 +2887,8 @@ bool LibraryCallKit::inline_unsafe_flat_access(bool is_store, AccessKind kind) { } else { if (UseArrayFlattening) { // Flat array must have an exact type - bool is_null_free = layout != LayoutKind::NULLABLE_ATOMIC_FLAT; - bool is_atomic = layout != LayoutKind::NON_ATOMIC_FLAT; + bool is_null_free = !LayoutKindHelper::is_nullable_flat(layout); + bool is_atomic = LayoutKindHelper::is_atomic_flat(layout); Node* new_base = cast_to_flat_array(base, value_klass, is_null_free, !is_null_free, is_atomic); replace_in_map(base, new_base); base = new_base; @@ -2924,8 +2924,8 @@ bool LibraryCallKit::inline_unsafe_flat_access(bool is_store, AccessKind kind) { const TypePtr* ptr_type = (decorators & C2_MISMATCHED) != 0 ? TypeRawPtr::BOTTOM : _gvn.type(ptr)->is_ptr(); access_store_at(base, ptr, ptr_type, value, value_type, T_OBJECT, decorators); } else { - bool atomic = layout != LayoutKind::NON_ATOMIC_FLAT; - bool null_free = layout != LayoutKind::NULLABLE_ATOMIC_FLAT; + bool atomic = LayoutKindHelper::is_atomic_flat(layout); + bool null_free = !LayoutKindHelper::is_nullable_flat(layout); value->as_InlineType()->store_flat(this, base, ptr, atomic, immutable_memory, null_free, decorators); } @@ -2938,8 +2938,8 @@ bool LibraryCallKit::inline_unsafe_flat_access(bool is_store, AccessKind kind) { Node* oop = access_load_at(base, ptr, ptr_type, Type::get_const_type(value_klass), T_OBJECT, decorators); result = InlineTypeNode::make_from_oop(this, oop, value_klass); } else { - bool atomic = layout != LayoutKind::NON_ATOMIC_FLAT; - bool null_free = layout != LayoutKind::NULLABLE_ATOMIC_FLAT; + bool atomic = LayoutKindHelper::is_atomic_flat(layout); + bool null_free = !LayoutKindHelper::is_nullable_flat(layout); result = InlineTypeNode::make_from_flat(this, value_klass, base, ptr, atomic, immutable_memory, null_free, decorators); } diff --git a/src/hotspot/share/opto/runtime.cpp b/src/hotspot/share/opto/runtime.cpp index 378660cd451..51e76f03b74 100644 --- a/src/hotspot/share/opto/runtime.cpp +++ b/src/hotspot/share/opto/runtime.cpp @@ -378,20 +378,7 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, oopDe Handle holder(current, array_type->klass_holder()); // keep the array klass alive FlatArrayKlass* fak = FlatArrayKlass::cast(array_type); InlineKlass* vk = fak->element_klass(); - ArrayKlass::ArrayProperties props = ArrayKlass::ArrayProperties::DEFAULT; - switch(fak->layout_kind()) { - case LayoutKind::ATOMIC_FLAT: - props = ArrayKlass::ArrayProperties::NULL_RESTRICTED; - break; - case LayoutKind::NON_ATOMIC_FLAT: - props = (ArrayKlass::ArrayProperties)(ArrayKlass::ArrayProperties::NULL_RESTRICTED | ArrayKlass::ArrayProperties::NON_ATOMIC); - break; - case LayoutKind::NULLABLE_ATOMIC_FLAT: - props = ArrayKlass::ArrayProperties::NON_ATOMIC; - break; - default: - ShouldNotReachHere(); - } + ArrayKlass::ArrayProperties props = ArrayKlass::array_properties_from_layout(fak->layout_kind()); result = oopFactory::new_flatArray(vk, len, props, fak->layout_kind(), THREAD); if (array_type->is_null_free_array_klass() && !h_init_val.is_null()) { // Null-free arrays need to be initialized diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 99c2dc244b0..c7d1fe812e4 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -445,20 +445,7 @@ JVM_ENTRY(jarray, JVM_CopyOfSpecialArray(JNIEnv *env, jarray orig, jint from, ji if (org->is_flatArray()) { FlatArrayKlass* fak = FlatArrayKlass::cast(org->klass()); LayoutKind lk = fak->layout_kind(); - ArrayKlass::ArrayProperties props = ArrayKlass::ArrayProperties::DEFAULT; - switch(lk) { - case LayoutKind::ATOMIC_FLAT: - props = ArrayKlass::ArrayProperties::NULL_RESTRICTED; - break; - case LayoutKind::NON_ATOMIC_FLAT: - props = (ArrayKlass::ArrayProperties)(ArrayKlass::ArrayProperties::NULL_RESTRICTED | ArrayKlass::ArrayProperties::NON_ATOMIC); - break; - case LayoutKind::NULLABLE_ATOMIC_FLAT: - props = ArrayKlass::ArrayProperties::NON_ATOMIC; - break; - default: - ShouldNotReachHere(); - } + ArrayKlass::ArrayProperties props = ArrayKlass::array_properties_from_layout(lk); array = oopFactory::new_flatArray(vk, len, props, lk, CHECK_NULL); arrayHandle ah(THREAD, (arrayOop)array); int end = to < oh()->length() ? to : oh()->length(); @@ -556,9 +543,7 @@ JVM_ENTRY(jboolean, JVM_IsAtomicArray(JNIEnv *env, jobject obj)) if (oop->is_refArray()) return true; if (oop->is_flatArray()) { FlatArrayKlass* fak = FlatArrayKlass::cast(oop->klass()); - if (fak->layout_kind() == LayoutKind::ATOMIC_FLAT || fak->layout_kind() == LayoutKind::NULLABLE_ATOMIC_FLAT) { - return true; - } + if (LayoutKindHelper::is_atomic_flat(fak->layout_kind())) return true; if (fak->element_klass()->is_naturally_atomic()) return true; } return false; diff --git a/src/hotspot/share/prims/jvmtiTagMap.cpp b/src/hotspot/share/prims/jvmtiTagMap.cpp index f0e708ff84a..2cae92f674e 100644 --- a/src/hotspot/share/prims/jvmtiTagMap.cpp +++ b/src/hotspot/share/prims/jvmtiTagMap.cpp @@ -1398,8 +1398,7 @@ void IterateThroughHeapObjectClosure::visit_flat_fields(const JvmtiHeapwalkObjec field_offset += obj.offset() - obj.inline_klass()->payload_offset(); } // check for possible nulls - bool can_be_null = field->layout_kind() == LayoutKind::NULLABLE_ATOMIC_FLAT; - if (can_be_null) { + if (LayoutKindHelper::is_nullable_flat(field->layout_kind())) { address payload = cast_from_oop
(obj.obj()) + field_offset; if (field->inline_klass()->is_payload_marked_as_null(payload)) { continue; @@ -1421,7 +1420,7 @@ void IterateThroughHeapObjectClosure::visit_flat_array_elements(const JvmtiHeapw flatArrayOop array = flatArrayOop(obj.obj()); FlatArrayKlass* faklass = FlatArrayKlass::cast(array->klass()); InlineKlass* vk = InlineKlass::cast(faklass->element_klass()); - bool need_null_check = faklass->layout_kind() == LayoutKind::NULLABLE_ATOMIC_FLAT; + bool need_null_check = LayoutKindHelper::is_nullable_flat(faklass->layout_kind()); for (int index = 0; index < array->length(); index++) { address addr = (address)array->value_at_addr(index, faklass->layout_helper()); @@ -2876,7 +2875,7 @@ inline bool VM_HeapWalkOperation::iterate_over_flat_array(const JvmtiHeapwalkObj flatArrayOop array = flatArrayOop(o.obj()); FlatArrayKlass* faklass = FlatArrayKlass::cast(array->klass()); InlineKlass* vk = InlineKlass::cast(faklass->element_klass()); - bool need_null_check = faklass->layout_kind() == LayoutKind::NULLABLE_ATOMIC_FLAT; + bool need_null_check = LayoutKindHelper::is_nullable_flat(faklass->layout_kind()); // array reference to its class oop mirror = faklass->java_mirror(); @@ -3100,8 +3099,7 @@ inline bool VM_HeapWalkOperation::iterate_over_object(const JvmtiHeapwalkObject& if (!is_primitive_field_type(type)) { if (field->is_flat()) { // check for possible nulls - bool can_be_null = field->layout_kind() == LayoutKind::NULLABLE_ATOMIC_FLAT; - if (can_be_null) { + if (LayoutKindHelper::is_nullable_flat(field->layout_kind())) { address payload = cast_from_oop(o.obj()) + field_offset; if (field->inline_klass()->is_payload_marked_as_null(payload)) { continue; diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp index c135a222e43..91c3f0332fe 100644 --- a/src/hotspot/share/prims/unsafe.cpp +++ b/src/hotspot/share/prims/unsafe.cpp @@ -433,20 +433,7 @@ UNSAFE_ENTRY(jarray, Unsafe_NewSpecialArray(JNIEnv *env, jobject unsafe, jclass if (!UseArrayFlattening || !vk->is_layout_supported(lk)) { THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "Layout not supported"); } - ArrayKlass::ArrayProperties props = ArrayKlass::ArrayProperties::DEFAULT; - switch(lk) { - case LayoutKind::ATOMIC_FLAT: - props = ArrayKlass::ArrayProperties::NULL_RESTRICTED; - break; - case LayoutKind::NON_ATOMIC_FLAT: - props = (ArrayKlass::ArrayProperties)(ArrayKlass::ArrayProperties::NULL_RESTRICTED | ArrayKlass::ArrayProperties::NON_ATOMIC); - break; - case LayoutKind::NULLABLE_ATOMIC_FLAT: - props = ArrayKlass::ArrayProperties::NON_ATOMIC; - break; - default: - ShouldNotReachHere(); - } + ArrayKlass::ArrayProperties props = ArrayKlass::array_properties_from_layout(lk); oop array = oopFactory::new_flatArray(vk, len, props, lk, CHECK_NULL); return (jarray) JNIHandles::make_local(THREAD, array); } UNSAFE_END diff --git a/src/hotspot/share/services/heapDumper.cpp b/src/hotspot/share/services/heapDumper.cpp index f69c83f44e7..27d6d88f46f 100644 --- a/src/hotspot/share/services/heapDumper.cpp +++ b/src/hotspot/share/services/heapDumper.cpp @@ -866,7 +866,7 @@ class DumperClassCacheTableEntry : public CHeapObj