diff --git a/src/hotspot/share/classfile/vmIntrinsics.cpp b/src/hotspot/share/classfile/vmIntrinsics.cpp index bf490f0de91..33d72a29697 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.cpp +++ b/src/hotspot/share/classfile/vmIntrinsics.cpp @@ -336,8 +336,6 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) { case vmIntrinsics::_updateByteBufferCRC32: if (!UseCRC32Intrinsics) return true; break; - case vmIntrinsics::_makePrivateBuffer: - case vmIntrinsics::_finishPrivateBuffer: case vmIntrinsics::_getReference: case vmIntrinsics::_getBoolean: case vmIntrinsics::_getByte: @@ -347,7 +345,6 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) { case vmIntrinsics::_getLong: case vmIntrinsics::_getFloat: case vmIntrinsics::_getDouble: - case vmIntrinsics::_getValue: case vmIntrinsics::_getFlatValue: case vmIntrinsics::_putReference: case vmIntrinsics::_putBoolean: @@ -358,7 +355,6 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) { case vmIntrinsics::_putLong: case vmIntrinsics::_putFloat: case vmIntrinsics::_putDouble: - case vmIntrinsics::_putValue: case vmIntrinsics::_putFlatValue: case vmIntrinsics::_getReferenceVolatile: case vmIntrinsics::_getBooleanVolatile: diff --git a/src/hotspot/share/classfile/vmIntrinsics.hpp b/src/hotspot/share/classfile/vmIntrinsics.hpp index ac1a6e59f2d..ea4f8abf3cf 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.hpp +++ b/src/hotspot/share/classfile/vmIntrinsics.hpp @@ -736,8 +736,6 @@ class methodHandle; do_signature(putFloat_signature, "(Ljava/lang/Object;JF)V") \ do_signature(getDouble_signature, "(Ljava/lang/Object;J)D") \ do_signature(putDouble_signature, "(Ljava/lang/Object;JD)V") \ - do_signature(getValue_signature, "(Ljava/lang/Object;JLjava/lang/Class;)Ljava/lang/Object;") \ - do_signature(putValue_signature, "(Ljava/lang/Object;JLjava/lang/Class;Ljava/lang/Object;)V") \ do_signature(getFlatValue_signature, "(Ljava/lang/Object;JILjava/lang/Class;)Ljava/lang/Object;") \ do_signature(putFlatValue_signature, "(Ljava/lang/Object;JILjava/lang/Class;Ljava/lang/Object;)V") \ \ @@ -750,10 +748,7 @@ class methodHandle; do_name(getLong_name,"getLong") do_name(putLong_name,"putLong") \ do_name(getFloat_name,"getFloat") do_name(putFloat_name,"putFloat") \ do_name(getDouble_name,"getDouble") do_name(putDouble_name,"putDouble") \ - do_name(getValue_name,"getValue") do_name(putValue_name,"putValue") \ do_name(getFlatValue_name,"getFlatValue") do_name(putFlatValue_name,"putFlatValue") \ - do_name(makePrivateBuffer_name,"makePrivateBuffer") \ - do_name(finishPrivateBuffer_name,"finishPrivateBuffer") \ \ do_intrinsic(_getReference, jdk_internal_misc_Unsafe, getReference_name, getReference_signature, F_RN) \ do_intrinsic(_getBoolean, jdk_internal_misc_Unsafe, getBoolean_name, getBoolean_signature, F_RN) \ @@ -764,7 +759,6 @@ class methodHandle; do_intrinsic(_getLong, jdk_internal_misc_Unsafe, getLong_name, getLong_signature, F_RN) \ do_intrinsic(_getFloat, jdk_internal_misc_Unsafe, getFloat_name, getFloat_signature, F_RN) \ do_intrinsic(_getDouble, jdk_internal_misc_Unsafe, getDouble_name, getDouble_signature, F_RN) \ - do_intrinsic(_getValue, jdk_internal_misc_Unsafe, getValue_name, getValue_signature, F_RN) \ do_intrinsic(_getFlatValue, jdk_internal_misc_Unsafe, getFlatValue_name, getFlatValue_signature, F_RN) \ do_intrinsic(_putReference, jdk_internal_misc_Unsafe, putReference_name, putReference_signature, F_RN) \ do_intrinsic(_putBoolean, jdk_internal_misc_Unsafe, putBoolean_name, putBoolean_signature, F_RN) \ @@ -775,12 +769,8 @@ class methodHandle; do_intrinsic(_putLong, jdk_internal_misc_Unsafe, putLong_name, putLong_signature, F_RN) \ do_intrinsic(_putFloat, jdk_internal_misc_Unsafe, putFloat_name, putFloat_signature, F_RN) \ do_intrinsic(_putDouble, jdk_internal_misc_Unsafe, putDouble_name, putDouble_signature, F_RN) \ - do_intrinsic(_putValue, jdk_internal_misc_Unsafe, putValue_name, putValue_signature, F_RN) \ do_intrinsic(_putFlatValue, jdk_internal_misc_Unsafe, putFlatValue_name, putFlatValue_signature, F_RN) \ \ - do_intrinsic(_makePrivateBuffer, jdk_internal_misc_Unsafe, makePrivateBuffer_name, object_object_signature, F_RN) \ - do_intrinsic(_finishPrivateBuffer, jdk_internal_misc_Unsafe, finishPrivateBuffer_name, object_object_signature, F_RN) \ - \ do_name(getReferenceVolatile_name,"getReferenceVolatile") do_name(putReferenceVolatile_name,"putReferenceVolatile") \ do_name(getBooleanVolatile_name,"getBooleanVolatile") do_name(putBooleanVolatile_name,"putBooleanVolatile") \ do_name(getByteVolatile_name,"getByteVolatile") do_name(putByteVolatile_name,"putByteVolatile") \ diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp index acb4dd3d32d..78d4800d774 100644 --- a/src/hotspot/share/opto/c2compiler.cpp +++ b/src/hotspot/share/opto/c2compiler.cpp @@ -653,8 +653,6 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_getCharsStringU: case vmIntrinsics::_getCharStringU: case vmIntrinsics::_putCharStringU: - case vmIntrinsics::_makePrivateBuffer: - case vmIntrinsics::_finishPrivateBuffer: case vmIntrinsics::_getReference: case vmIntrinsics::_getBoolean: case vmIntrinsics::_getByte: @@ -664,7 +662,6 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_getLong: case vmIntrinsics::_getFloat: case vmIntrinsics::_getDouble: - case vmIntrinsics::_getValue: case vmIntrinsics::_getFlatValue: case vmIntrinsics::_putReference: case vmIntrinsics::_putBoolean: @@ -675,7 +672,6 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_putLong: case vmIntrinsics::_putFloat: case vmIntrinsics::_putDouble: - case vmIntrinsics::_putValue: case vmIntrinsics::_putFlatValue: case vmIntrinsics::_getReferenceVolatile: case vmIntrinsics::_getBooleanVolatile: diff --git a/src/hotspot/share/opto/doCall.cpp b/src/hotspot/share/opto/doCall.cpp index b7a6f7d8438..e98bf213cdb 100644 --- a/src/hotspot/share/opto/doCall.cpp +++ b/src/hotspot/share/opto/doCall.cpp @@ -99,7 +99,6 @@ static bool arg_can_be_larval(ciMethod* callee, int arg_idx) { } switch (callee->intrinsic_id()) { - case vmIntrinsicID::_finishPrivateBuffer: case vmIntrinsicID::_putBoolean: case vmIntrinsicID::_putBooleanOpaque: case vmIntrinsicID::_putBooleanRelease: @@ -140,7 +139,6 @@ static bool arg_can_be_larval(ciMethod* callee, int arg_idx) { case vmIntrinsicID::_putReferenceOpaque: case vmIntrinsicID::_putReferenceRelease: case vmIntrinsicID::_putReferenceVolatile: - case vmIntrinsicID::_putValue: return true; default: return false; @@ -206,21 +204,7 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool // methods. If these methods are replaced with specialized code, // then we return it as the inlined version of the call. CallGenerator* cg_intrinsic = nullptr; - if (callee->intrinsic_id() == vmIntrinsics::_makePrivateBuffer || callee->intrinsic_id() == vmIntrinsics::_finishPrivateBuffer) { - // These methods must be inlined so that we don't have larval value objects crossing method - // boundaries - assert(!call_does_dispatch, "callee should not be virtual %s", callee->name()->as_utf8()); - CallGenerator* cg = find_intrinsic(callee, call_does_dispatch); - - if (cg == nullptr) { - // This is probably because the intrinsics is disabled from the command line - char reason[256]; - jio_snprintf(reason, sizeof(reason), "cannot find an intrinsics for %s", callee->name()->as_utf8()); - C->record_method_not_compilable(reason); - return nullptr; - } - return cg; - } else if (allow_inline && allow_intrinsics) { + if (allow_inline && allow_intrinsics) { CallGenerator* cg = find_intrinsic(callee, call_does_dispatch); if (cg != nullptr) { if (cg->is_predicated()) { @@ -876,7 +860,7 @@ void Parse::do_call() { record_profiled_return_for_speculation(); } - if (!rtype->is_void() && cg->method()->intrinsic_id() != vmIntrinsicID::_makePrivateBuffer) { + if (!rtype->is_void()) { Node* retnode = peek(); const Type* rettype = gvn().type(retnode); if (rettype->is_inlinetypeptr() && !retnode->is_InlineType()) { diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index 4cb6d82e42f..e4903e3ac0f 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -3528,14 +3528,7 @@ Node* GraphKit::gen_checkcast(Node* obj, Node* superklass, Node* *failure_contro const TypeKlassPtr* klass_ptr_type = _gvn.type(superklass)->is_klassptr(); const Type* obj_type = _gvn.type(obj); if (obj_type->is_inlinetypeptr() && !obj_type->maybe_null() && klass_ptr_type->klass_is_exact() && obj_type->inline_klass() == klass_ptr_type->exact_klass(true)) { - // Special case: larval inline objects must not be scalarized. They are also generally not - // allowed to participate in most operations except as the first operand of putfield, or as an - // argument to a constructor invocation with it being a receiver, Unsafe::putXXX with it being - // the first argument, or Unsafe::finishPrivateBuffer. This allows us to aggressively scalarize - // value objects in all other places. This special case comes from the limitation of the Java - // language, Unsafe::makePrivateBuffer returns an Object that is checkcast-ed to the concrete - // value type. We must do this first because C->static_subtype_check may do nothing when - // StressReflectiveCode is set. + // TODO remnant to support old makePrivateBuffer generic cast, we can probably remove this now return obj; } diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index aa162d6503b..5c397619850 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -327,8 +327,6 @@ bool LibraryCallKit::try_to_inline(int predicate) { case vmIntrinsics::_inflateStringC: case vmIntrinsics::_inflateStringB: return inline_string_copy(!is_compress); - case vmIntrinsics::_makePrivateBuffer: return inline_unsafe_make_private_buffer(); - case vmIntrinsics::_finishPrivateBuffer: return inline_unsafe_finish_private_buffer(); case vmIntrinsics::_getReference: return inline_unsafe_access(!is_store, T_OBJECT, Relaxed, false); case vmIntrinsics::_getBoolean: return inline_unsafe_access(!is_store, T_BOOLEAN, Relaxed, false); case vmIntrinsics::_getByte: return inline_unsafe_access(!is_store, T_BYTE, Relaxed, false); @@ -338,7 +336,6 @@ bool LibraryCallKit::try_to_inline(int predicate) { case vmIntrinsics::_getLong: return inline_unsafe_access(!is_store, T_LONG, Relaxed, false); case vmIntrinsics::_getFloat: return inline_unsafe_access(!is_store, T_FLOAT, Relaxed, false); case vmIntrinsics::_getDouble: return inline_unsafe_access(!is_store, T_DOUBLE, Relaxed, false); - case vmIntrinsics::_getValue: return inline_unsafe_access(!is_store, T_OBJECT, Relaxed, false, true); case vmIntrinsics::_putReference: return inline_unsafe_access( is_store, T_OBJECT, Relaxed, false); case vmIntrinsics::_putBoolean: return inline_unsafe_access( is_store, T_BOOLEAN, Relaxed, false); @@ -349,7 +346,6 @@ bool LibraryCallKit::try_to_inline(int predicate) { case vmIntrinsics::_putLong: return inline_unsafe_access( is_store, T_LONG, Relaxed, false); case vmIntrinsics::_putFloat: return inline_unsafe_access( is_store, T_FLOAT, Relaxed, false); case vmIntrinsics::_putDouble: return inline_unsafe_access( is_store, T_DOUBLE, Relaxed, false); - case vmIntrinsics::_putValue: return inline_unsafe_access( is_store, T_OBJECT, Relaxed, false, true); case vmIntrinsics::_getReferenceVolatile: return inline_unsafe_access(!is_store, T_OBJECT, Volatile, false); case vmIntrinsics::_getBooleanVolatile: return inline_unsafe_access(!is_store, T_BOOLEAN, Volatile, false); @@ -2400,7 +2396,7 @@ DecoratorSet LibraryCallKit::mo_decorator_for_access_kind(AccessKind kind) { } } -bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, const AccessKind kind, const bool unaligned, const bool is_flat) { +bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, const AccessKind kind, const bool unaligned) { if (callee()->is_static()) return false; // caller must have the capability! DecoratorSet decorators = C2_UNSAFE_ACCESS; guarantee(!is_store || kind != Acquire, "Acquire accesses can be produced only for loads"); @@ -2425,13 +2421,13 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c // Object getReference(Object base, int/long offset), etc. BasicType rtype = sig->return_type()->basic_type(); assert(rtype == type, "getter must return the expected value"); - assert(sig->count() == 2 || (is_flat && sig->count() == 3), "oop getter has 2 or 3 arguments"); + assert(sig->count() == 2, "oop getter has 2 arguments"); assert(sig->type_at(0)->basic_type() == T_OBJECT, "getter base is object"); assert(sig->type_at(1)->basic_type() == T_LONG, "getter offset is correct"); } else { // void putReference(Object base, int/long offset, Object x), etc. assert(sig->return_type()->basic_type() == T_VOID, "putter must not return a value"); - assert(sig->count() == 3 || (is_flat && sig->count() == 4), "oop putter has 3 arguments"); + assert(sig->count() == 3, "oop putter has 3 arguments"); assert(sig->type_at(0)->basic_type() == T_OBJECT, "putter base is object"); assert(sig->type_at(1)->basic_type() == T_LONG, "putter offset is correct"); BasicType vtype = sig->type_at(sig->count()-1)->basic_type(); @@ -2458,19 +2454,6 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled"); - ciInlineKlass* inline_klass = nullptr; - if (is_flat) { - const TypeInstPtr* cls = _gvn.type(argument(4))->isa_instptr(); - if (cls == nullptr || cls->const_oop() == nullptr) { - return false; - } - ciType* mirror_type = cls->const_oop()->as_instance()->java_mirror_type(); - if (!mirror_type->is_inlinetype()) { - return false; - } - inline_klass = mirror_type->as_inline_klass(); - } - if (base->is_InlineType()) { assert(!is_store, "InlineTypeNodes are non-larval value objects"); InlineTypeNode* vt = base->as_InlineType(); @@ -2487,7 +2470,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c if (bt == T_ARRAY || bt == T_NARROWOOP) { bt = T_OBJECT; } - if (bt == type && (!field->is_flat() || field->type() == inline_klass)) { + if (bt == type && (!field->is_flat())) { Node* value = vt->field_value_by_offset(off, false); if (value->is_InlineType()) { value = value->as_InlineType()->adjust_scalarization_depth(this); @@ -2517,7 +2500,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c assert(!stopped(), "Inlining of unsafe access failed: address construction stopped unexpectedly"); if (_gvn.type(base->uncast())->isa_ptr() == TypePtr::NULL_PTR) { - if (type != T_OBJECT && (inline_klass == nullptr || !inline_klass->has_object_fields())) { + if (type != T_OBJECT) { decorators |= IN_NATIVE; // off-heap primitive access } else { set_map(old_map); @@ -2535,7 +2518,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c decorators |= IN_HEAP; } - Node* val = is_store ? argument(4 + (is_flat ? 1 : 0)) : nullptr; + Node* val = is_store ? argument(4) : nullptr; const TypePtr* adr_type = _gvn.type(adr)->isa_ptr(); if (adr_type == TypePtr::NULL_PTR) { @@ -2580,7 +2563,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c bt = type2field[field->type()->basic_type()]; } } - assert(bt == alias_type->basic_type() || is_flat, "should match"); + assert(bt == alias_type->basic_type(), "should match"); } else { bt = alias_type->basic_type(); } @@ -2607,31 +2590,8 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c mismatched = true; // conservatively mark all "wide" on-heap accesses as mismatched } - if (is_flat) { - if (adr_type->isa_instptr()) { - if (field == nullptr || field->type() != inline_klass) { - mismatched = true; - } - } else if (adr_type->isa_aryptr()) { - const Type* elem = adr_type->is_aryptr()->elem(); - if (!adr_type->is_flat() || elem->inline_klass() != inline_klass) { - mismatched = true; - } - } else { - mismatched = true; - } - if (is_store) { - const Type* val_t = _gvn.type(val); - if (!val_t->is_inlinetypeptr() || val_t->inline_klass() != inline_klass) { - set_map(old_map); - set_sp(old_sp); - return false; - } - } - } - destruct_map_clone(old_map); - assert(!mismatched || is_flat || alias_type->adr_type()->is_oopptr(), "off-heap access can't be mismatched"); + assert(!mismatched || alias_type->adr_type()->is_oopptr(), "off-heap access can't be mismatched"); if (mismatched) { decorators |= C2_MISMATCHED; @@ -2644,7 +2604,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c decorators |= mo_decorator_for_access_kind(kind); if (!is_store) { - if (type == T_OBJECT && !is_flat) { + if (type == T_OBJECT) { const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type); if (tjp != nullptr) { value_type = tjp; @@ -2671,15 +2631,11 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c } if (p == nullptr) { // Could not constant fold the load - if (is_flat) { - p = InlineTypeNode::make_from_flat(this, inline_klass, base, adr, adr_type, false, false, true); - } else { - p = access_load_at(heap_base_oop, adr, adr_type, value_type, type, decorators); - const TypeOopPtr* ptr = value_type->make_oopptr(); - if (ptr != nullptr && ptr->is_inlinetypeptr()) { - // Load a non-flattened inline type from memory - p = InlineTypeNode::make_from_oop(this, p, ptr->inline_klass()); - } + p = access_load_at(heap_base_oop, adr, adr_type, value_type, type, decorators); + const TypeOopPtr* ptr = value_type->make_oopptr(); + if (ptr != nullptr && ptr->is_inlinetypeptr()) { + // Load a non-flattened inline type from memory + p = InlineTypeNode::make_from_oop(this, p, ptr->inline_klass()); } // Normalize the value returned by getBoolean in the following cases if (type == T_BOOLEAN && @@ -2718,11 +2674,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c val = ConvL2X(val); val = gvn().transform(new CastX2PNode(val)); } - if (is_flat) { - val->as_InlineType()->store_flat(this, base, adr, false, false, true, decorators); - } else { - access_store_at(heap_base_oop, adr, adr_type, val, value_type, type, decorators); - } + access_store_at(heap_base_oop, adr, adr_type, val, value_type, type, decorators); } return true; @@ -2897,72 +2849,6 @@ bool LibraryCallKit::inline_unsafe_flat_access(bool is_store, AccessKind kind) { } } -bool LibraryCallKit::inline_unsafe_make_private_buffer() { - Node* receiver = argument(0); - Node* value = argument(1); - - const Type* type = gvn().type(value); - if (!type->is_inlinetypeptr()) { - C->record_method_not_compilable("value passed to Unsafe::makePrivateBuffer is not of a constant value type"); - return false; - } - - null_check(receiver); - if (stopped()) { - return true; - } - - value = null_check(value); - if (stopped()) { - return true; - } - - ciInlineKlass* vk = type->inline_klass(); - Node* klass = makecon(TypeKlassPtr::make(vk)); - Node* obj = new_instance(klass); - AllocateNode::Ideal_allocation(obj)->_larval = true; - - assert(value->is_InlineType(), "must be an InlineTypeNode"); - Node* payload_ptr = basic_plus_adr(obj, vk->payload_offset()); - value->as_InlineType()->store_flat(this, obj, payload_ptr, false, true, true, IN_HEAP | MO_UNORDERED); - - set_result(obj); - return true; -} - -bool LibraryCallKit::inline_unsafe_finish_private_buffer() { - Node* receiver = argument(0); - Node* buffer = argument(1); - - const Type* type = gvn().type(buffer); - if (!type->is_inlinetypeptr()) { - C->record_method_not_compilable("value passed to Unsafe::finishPrivateBuffer is not of a constant value type"); - return false; - } - - AllocateNode* alloc = AllocateNode::Ideal_allocation(buffer); - if (alloc == nullptr) { - C->record_method_not_compilable("value passed to Unsafe::finishPrivateBuffer must be allocated by Unsafe::makePrivateBuffer"); - return false; - } - - null_check(receiver); - if (stopped()) { - return true; - } - - // Unset the larval bit in the object header - Node* old_header = make_load(control(), buffer, TypeX_X, TypeX_X->basic_type(), MemNode::unordered, LoadNode::Pinned); - Node* new_header = gvn().transform(new AndXNode(old_header, MakeConX(~markWord::larval_bit_in_place))); - access_store_at(buffer, buffer, type->is_ptr(), new_header, TypeX_X, TypeX_X->basic_type(), MO_UNORDERED | IN_HEAP); - - // We must ensure that the buffer is properly published - insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out(AllocateNode::RawAddress)); - assert(!type->maybe_null(), "result of an allocation should not be null"); - set_result(InlineTypeNode::make_from_oop(this, buffer, type->inline_klass())); - return true; -} - //----------------------------inline_unsafe_load_store---------------------------- // This method serves a couple of different customers (depending on LoadStoreKind): // diff --git a/src/hotspot/share/opto/library_call.hpp b/src/hotspot/share/opto/library_call.hpp index ce69058495f..27f218aa7cb 100644 --- a/src/hotspot/share/opto/library_call.hpp +++ b/src/hotspot/share/opto/library_call.hpp @@ -253,7 +253,7 @@ class LibraryCallKit : public GraphKit { typedef enum { Relaxed, Opaque, Volatile, Acquire, Release } AccessKind; DecoratorSet mo_decorator_for_access_kind(AccessKind kind); - bool inline_unsafe_access(bool is_store, BasicType type, AccessKind kind, bool is_unaligned, bool is_flat = false); + bool inline_unsafe_access(bool is_store, BasicType type, AccessKind kind, bool is_unaligned); bool inline_unsafe_flat_access(bool is_store, AccessKind kind); static bool klass_needs_init_guard(Node* kls); bool inline_unsafe_allocate(); @@ -262,8 +262,6 @@ class LibraryCallKit : public GraphKit { bool inline_unsafe_writeback0(); bool inline_unsafe_writebackSync0(bool is_pre); bool inline_unsafe_copyMemory(); - bool inline_unsafe_make_private_buffer(); - bool inline_unsafe_finish_private_buffer(); bool inline_unsafe_setMemory(); bool inline_native_currentCarrierThread(); diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp index 3874f9735a9..8aa74572241 100644 --- a/src/hotspot/share/prims/unsafe.cpp +++ b/src/hotspot/share/prims/unsafe.cpp @@ -451,28 +451,6 @@ UNSAFE_ENTRY(jarray, Unsafe_NewSpecialArray(JNIEnv *env, jobject unsafe, jclass return (jarray) JNIHandles::make_local(THREAD, array); } UNSAFE_END -UNSAFE_ENTRY(jobject, Unsafe_GetValue(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jclass vc)) { - oop base = JNIHandles::resolve(obj); - if (base == nullptr) { - THROW_NULL(vmSymbols::java_lang_NullPointerException()); - } - Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(vc)); - InlineKlass* vk = InlineKlass::cast(k); - assert_and_log_unsafe_value_access(base, offset, vk); - LayoutKind lk = LayoutKind::UNKNOWN; - if (base->is_array()) { - FlatArrayKlass* fak = FlatArrayKlass::cast(base->klass()); - lk = fak->layout_kind(); - } else { - fieldDescriptor fd; - InstanceKlass::cast(base->klass())->find_field_from_offset(offset, false, &fd); - lk = fd.field_holder()->inline_layout_info(fd.index()).kind(); - } - Handle base_h(THREAD, base); - oop v = vk->read_payload_from_addr(base_h(), offset, lk, CHECK_NULL); - return JNIHandles::make_local(THREAD, v); -} UNSAFE_END - UNSAFE_ENTRY(jobject, Unsafe_GetFlatValue(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint layoutKind, jclass vc)) { assert(layoutKind != (int)LayoutKind::REFERENCE, "This method handles only flat layouts"); oop base = JNIHandles::resolve(obj); @@ -488,28 +466,6 @@ UNSAFE_ENTRY(jobject, Unsafe_GetFlatValue(JNIEnv *env, jobject unsafe, jobject o return JNIHandles::make_local(THREAD, v); } UNSAFE_END -UNSAFE_ENTRY(void, Unsafe_PutValue(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jclass vc, jobject value)) { - oop base = JNIHandles::resolve(obj); - if (base == nullptr) { - THROW(vmSymbols::java_lang_NullPointerException()); - } - Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(vc)); - InlineKlass* vk = InlineKlass::cast(k); - assert(!base->is_inline_type() || base->mark().is_larval_state(), "must be an object instance or a larval inline type"); - assert_and_log_unsafe_value_access(base, offset, vk); - LayoutKind lk = LayoutKind::UNKNOWN; - if (base->is_array()) { - FlatArrayKlass* fak = FlatArrayKlass::cast(base->klass()); - lk = fak->layout_kind(); - } else { - fieldDescriptor fd; - InstanceKlass::cast(base->klass())->find_field_from_offset(offset, false, &fd); - lk = fd.field_holder()->inline_layout_info(fd.index()).kind(); - } - oop v = JNIHandles::resolve(value); - vk->write_value_to_addr(v, ((char*)(oopDesc*)base) + offset, lk, true, CHECK); -} UNSAFE_END - UNSAFE_ENTRY(void, Unsafe_PutFlatValue(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint layoutKind, jclass vc, jobject value)) { assert(layoutKind != (int)LayoutKind::REFERENCE, "This method handles only flat layouts"); oop base = JNIHandles::resolve(obj); @@ -525,26 +481,6 @@ UNSAFE_ENTRY(void, Unsafe_PutFlatValue(JNIEnv *env, jobject unsafe, jobject obj, vk->write_value_to_addr(v, ((char*)(oopDesc*)base) + offset, lk, true, CHECK); } UNSAFE_END -UNSAFE_ENTRY(jobject, Unsafe_MakePrivateBuffer(JNIEnv *env, jobject unsafe, jobject value)) { - oop v = JNIHandles::resolve_non_null(value); - assert(v->is_inline_type(), "must be an inline type instance"); - Handle vh(THREAD, v); - InlineKlass* vk = InlineKlass::cast(v->klass()); - instanceOop new_value = vk->allocate_instance_buffer(CHECK_NULL); - vk->copy_payload_to_addr(vk->payload_addr(vh()), vk->payload_addr(new_value), LayoutKind::BUFFERED, false); - markWord mark = new_value->mark(); - new_value->set_mark(mark.enter_larval_state()); - return JNIHandles::make_local(THREAD, new_value); -} UNSAFE_END - -UNSAFE_ENTRY(jobject, Unsafe_FinishPrivateBuffer(JNIEnv *env, jobject unsafe, jobject value)) { - oop v = JNIHandles::resolve(value); - assert(v->mark().is_larval_state(), "must be a larval value"); - markWord mark = v->mark(); - v->set_mark(mark.exit_larval_state()); - return JNIHandles::make_local(THREAD, v); -} UNSAFE_END - UNSAFE_ENTRY(jobject, Unsafe_GetReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { oop p = JNIHandles::resolve(obj); assert_field_offset_sane(p, offset); @@ -1201,12 +1137,8 @@ static JNINativeMethod jdk_internal_misc_Unsafe_methods[] = { {CC "arrayLayout0", CC "(" OBJ_ARR ")I", FN_PTR(Unsafe_ArrayLayout)}, {CC "fieldLayout0", CC "(" OBJ ")I", FN_PTR(Unsafe_FieldLayout)}, {CC "newSpecialArray", CC "(" CLS "II)[" OBJ, FN_PTR(Unsafe_NewSpecialArray)}, - {CC "getValue", CC "(" OBJ "J" CLS ")" OBJ, FN_PTR(Unsafe_GetValue)}, {CC "getFlatValue", CC "(" OBJ "JI" CLS ")" OBJ, FN_PTR(Unsafe_GetFlatValue)}, - {CC "putValue", CC "(" OBJ "J" CLS OBJ ")V", FN_PTR(Unsafe_PutValue)}, {CC "putFlatValue", CC "(" OBJ "JI" CLS OBJ ")V", FN_PTR(Unsafe_PutFlatValue)}, - {CC "makePrivateBuffer", CC "(" OBJ ")" OBJ, FN_PTR(Unsafe_MakePrivateBuffer)}, - {CC "finishPrivateBuffer", CC "(" OBJ ")" OBJ, FN_PTR(Unsafe_FinishPrivateBuffer)}, {CC "valueHeaderSize", CC "(" CLS ")J", FN_PTR(Unsafe_ValueHeaderSize)}, {CC "getUncompressedObject", CC "(" ADR ")" OBJ, FN_PTR(Unsafe_GetUncompressedObject)}, diff --git a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java index 52b7d8bf03e..b6035750e47 100644 --- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java +++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java @@ -294,25 +294,9 @@ public native Object[] newSpecialArray(Class componentType, * {@code o} object at the given offset, or (if {@code o} is null) * from the memory address whose numerical value is the given offset. * - * @param o Java heap object in which the variable resides, if any, else - * null - * @param offset indication of where the variable resides in a Java heap - * object, if any, else a memory address locating the variable - * statically - * @param valueType value type - * @param the type of a value - * @return the value fetched from the indicated Java variable - * @throws RuntimeException No defined exceptions are thrown, not even - * {@link NullPointerException} - */ - @IntrinsicCandidate - public native V getValue(Object o, long offset, Class valueType); - - /** - * Fetches a value of type {@code } from a given Java variable. - * More specifically, fetches a field or array element within the given - * {@code o} object at the given offset, or (if {@code o} is null) - * from the memory address whose numerical value is the given offset. + * @apiNote + * The returned object is newly allocated into the heap, because flat + * values lack object headers and thus can't be used as objects directly. * * @param o Java heap object in which the variable resides, if any, else * null @@ -331,27 +315,6 @@ public native Object[] newSpecialArray(Class componentType, @IntrinsicCandidate public native V getFlatValue(Object o, long offset, int layoutKind, Class valueType); - - /** - * Stores the given value into a given Java variable. - * - * Unless the reference {@code o} being stored is either null - * or matches the field type, the results are undefined. - * - * @param o Java heap object in which the variable resides, if any, else - * null - * @param offset indication of where the variable resides in a Java heap - * object, if any, else a memory address locating the variable - * statically - * @param valueType value type - * @param v the value to store into the indicated Java variable - * @param the type of a value - * @throws RuntimeException No defined exceptions are thrown, not even - * {@link NullPointerException} - */ - @IntrinsicCandidate - public native void putValue(Object o, long offset, Class valueType, V v); - /** * Stores the given value into a given Java variable. * @@ -375,26 +338,6 @@ public native Object[] newSpecialArray(Class componentType, @IntrinsicCandidate public native void putFlatValue(Object o, long offset, int layoutKind, Class valueType, V v); - /** - * Returns an object instance with a private buffered value whose layout - * and contents is exactly the given value instance. The return object - * is in the larval state that can be updated using the unsafe put operation. - * - * @param value a value instance - * @param the type of the given value instance - */ - @IntrinsicCandidate - public native V makePrivateBuffer(V value); - - /** - * Exits the larval state and returns a value instance. - * - * @param value a value instance - * @param the type of the given value instance - */ - @IntrinsicCandidate - public native V finishPrivateBuffer(V value); - /** * Returns the header size of the given value type. * diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java index 80ee8f4fe22..b678576fcb7 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java @@ -407,24 +407,6 @@ public void test21_verifier() { Asserts.assertEQ(res, v.x); } - MyValue1 test22_vt; - - @Test - @IR(failOn = {CALL_UNSAFE}) - public void test22(MyValue1 v) { - v = U.makePrivateBuffer(v); - U.putInt(v, X_OFFSET, rI); - v = U.finishPrivateBuffer(v); - test22_vt = v; - } - - @Run(test = "test22") - public void test22_verifier() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - test22(v.setX(v, 0)); - Asserts.assertEQ(test22_vt.hash(), v.hash()); - } - @Test @IR(failOn = {CALL_UNSAFE}) public int test23(MyValue1 v, long offset) { @@ -769,22 +751,6 @@ public void test38_verifier() { Asserts.assertEQ(vt.hash(), test31_vt.hash()); } - @Test - @IR(failOn = {CALL_UNSAFE}) - public MyValue1 test39(MyValue1 v) { - v = U.makePrivateBuffer(v); - U.putInt(v, X_OFFSET, rI); - v = U.finishPrivateBuffer(v); - return v; - } - - @Run(test = "test39") - public void test39_verifier() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - MyValue1 res = test39(v.setX(v, 0)); - Asserts.assertEQ(res.hash(), v.hash()); - } - // Test value class array creation via reflection @Test public Object[] test40(Class componentType, int len) { @@ -1748,27 +1714,6 @@ public void test83_verifier(RunInfo info) { } } - /* TODO: 8322547: Unsafe::putInt checks the larval bit which leads to a VM crash - @Test - @IR(failOn = {CALL_UNSAFE}) - public MyValue1 test84(MyValue1 v) { - v = U.makePrivateBuffer(v); - for (int i = 0; i < 10; i++) { - U.putInt(v, X_OFFSET, i); - } - U.putInt(v, X_OFFSET, rI); - v = U.finishPrivateBuffer(v); - return v; - } - - @Run(test = "test84") - public void test84_verifier() { - MyValue1 v1 = MyValue1.createWithFieldsInline(rI, rL); - MyValue1 v2 = test84(MyValue1.setX(v1, 0)); - Asserts.assertEQ(v1.hash(), v2.hash()); - } - */ - static value class MyValueClonable implements Cloneable { int x; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLarvalState.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLarvalState.java deleted file mode 100644 index 770633557cf..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLarvalState.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2023, Arm Limited. All rights reserved. - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @test - * @bug 8303416 - * @summary Fix JVM crash at Unsafe_FinishPrivateBuffer - * @library /test/lib - * @enablePreview - * @modules java.base/jdk.internal.misc - * @run main/othervm compiler.valhalla.inlinetypes.TestLarvalState - */ - -package compiler.valhalla.inlinetypes; - -import java.lang.reflect.*; -import java.util.Random; - -import jdk.internal.misc.Unsafe; -import jdk.test.lib.Asserts; -import jdk.test.lib.Utils; - -public class TestLarvalState { - private static int LENGTH = 10000; - - private static final Random RD = Utils.getRandomInstance(); - - static byte[] arr = new byte[LENGTH]; - - static { - for (int i = 0; i < LENGTH; i++) { - arr[i] = (byte) RD.nextInt(127); - } - } - - public static byte test(byte b) { - Value obj = new Value(); - obj = Unsafe.getUnsafe().makePrivateBuffer(obj); - Unsafe.getUnsafe().putByte(obj, obj.offset, b); - obj = Unsafe.getUnsafe().finishPrivateBuffer(obj); - return Unsafe.getUnsafe().getByte(obj, obj.offset); - } - - public static void main(String[] args) { - byte actual = 0; - for (int i = 0; i < LENGTH; i++) { - actual += test(arr[i]); - } - - byte expected = 0; - for (int i = 0; i < LENGTH; i++) { - expected += arr[i]; - } - Asserts.assertEquals(expected, actual); - } - - static value class Value { - byte field = 0; - - static long offset = fieldOffset(); - - private static long fieldOffset() { - try { - var f = Value.class.getDeclaredField("field"); - return Unsafe.getUnsafe().objectFieldOffset(f); - } catch (Exception e) { - System.out.println(e); - } - return -1L; - } - } -} - diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestTearing.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestTearing.java index f28c5a0fb8e..96ca8e8a71d 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestTearing.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestTearing.java @@ -113,14 +113,6 @@ MyValue incrementAndCheck() { Asserts.assertEQ(x, y, "Inconsistent field values"); return new MyValue((short)(x + 1), (short)(y + 1)); } - - MyValue incrementAndCheckUnsafe() { - Asserts.assertEQ(x, y, "Inconsistent field values"); - MyValue vt = U.makePrivateBuffer(this); - U.putShort(vt, X_OFFSET, (short)(x + 1)); - U.putShort(vt, Y_OFFSET, (short)(y + 1)); - return U.finishPrivateBuffer(vt); - } } public class TestTearing { @@ -231,22 +223,22 @@ public void run() { array11[0] = ((MyValue)array11[0]).incrementAndCheck(); array12[0] = ((MyValue)array12[0]).incrementAndCheck(); - test.field1 = test.field1.incrementAndCheckUnsafe(); - test.field2 = test.field2.incrementAndCheckUnsafe(); - test.field3 = test.field3.incrementAndCheckUnsafe(); - test.field4 = test.field4.incrementAndCheckUnsafe(); - array1[0] = array1[0].incrementAndCheckUnsafe(); - array2[0] = array2[0].incrementAndCheckUnsafe(); - array3[0] = array3[0].incrementAndCheckUnsafe(); - array4[0] = array4[0].incrementAndCheckUnsafe(); - array5[0] = array5[0].incrementAndCheckUnsafe(); - array6[0] = array6[0].incrementAndCheckUnsafe(); - array7[0] = ((MyValue)array7[0]).incrementAndCheckUnsafe(); - array8[0] = ((MyValue)array8[0]).incrementAndCheckUnsafe(); - array9[0] = ((MyValue)array9[0]).incrementAndCheckUnsafe(); - array10[0] = ((MyValue)array10[0]).incrementAndCheckUnsafe(); - array11[0] = ((MyValue)array11[0]).incrementAndCheckUnsafe(); - array12[0] = ((MyValue)array12[0]).incrementAndCheckUnsafe(); + test.field1 = test.field1.incrementAndCheck(); + test.field2 = test.field2.incrementAndCheck(); + test.field3 = test.field3.incrementAndCheck(); + test.field4 = test.field4.incrementAndCheck(); + array1[0] = array1[0].incrementAndCheck(); + array2[0] = array2[0].incrementAndCheck(); + array3[0] = array3[0].incrementAndCheck(); + array4[0] = array4[0].incrementAndCheck(); + array5[0] = array5[0].incrementAndCheck(); + array6[0] = array6[0].incrementAndCheck(); + array7[0] = ((MyValue)array7[0]).incrementAndCheck(); + array8[0] = ((MyValue)array8[0]).incrementAndCheck(); + array9[0] = ((MyValue)array9[0]).incrementAndCheck(); + array10[0] = ((MyValue)array10[0]).incrementAndCheck(); + array11[0] = ((MyValue)array11[0]).incrementAndCheck(); + array12[0] = ((MyValue)array12[0]).incrementAndCheck(); try { test.field1 = (MyValue)incrementAndCheck_mh.invokeExact(test.field1); diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/UnsafeTest.java b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/UnsafeTest.java index 2794b8603fc..84d21dbb49b 100644 --- a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/UnsafeTest.java +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/UnsafeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,53 +90,6 @@ static value class Value3 { } - public static void test0() throws Throwable { - printValueClass(Value3.class, 0); - - Value1 v1 = new Value1(new Point(10,10), new Point(20,20), new Point(30,30)); - Value2 v2 = new Value2(v1, 20); - Value3 v3 = new Value3(v2, List.of("Value3")); - long off_o = U.objectFieldOffset(Value3.class, "o"); - long off_v = U.objectFieldOffset(Value3.class, "v"); - long off_i = U.objectFieldOffset(Value2.class, "i"); - long off_v2 = U.objectFieldOffset(Value2.class, "v"); - - long off_point = U.objectFieldOffset(Value1.class, "point"); - - List list = List.of("Value1", "Value2", "Value3"); - Value3 v = v3; - try { - v = U.makePrivateBuffer(v); - // patch v3.o - U.putReference(v, off_o, list); - // patch v3.v.i; - U.putInt(v, off_v + off_i - U.valueHeaderSize(Value2.class), 999); - // patch v3.v.v.point - U.putValue(v, off_v + off_v2 - U.valueHeaderSize(Value2.class) + off_point - U.valueHeaderSize(Value1.class), - Point.class, new Point(100, 100)); - } finally { - v = U.finishPrivateBuffer(v); - } - - assertEquals(v.v.v.point, new Point(100, 100)); - assertEquals(v.v.i, 999); - assertEquals(v.o, list); - assertEquals(v.v.v.array, v1.array); - - Value1 nv1 = new Value1(new Point(70,70), new Point(80,80), new Point(90,90)); - Value2 nv2 = new Value2(nv1, 100); - Value3 nv3 = new Value3(nv2, list); - - try { - v = U.makePrivateBuffer(v); - // patch v3.v - U.putValue(v, off_v2, Value2.class, nv2); - } finally { - v = U.finishPrivateBuffer(v); - } - assertEquals(v, nv3); - } - static void printValueClass(Class vc, int level) { String indent = ""; for (int i=0; i < level; i++) { @@ -205,52 +158,8 @@ static class Container1 { TestValue1 value; } - // Testing of nullable flat field supports in Unsafe.getFlatValue()/Unsafe.putValue() + // Testing of nullable flat field supports in Unsafe.getFlatValue()/Unsafe.putFlatValue() public static void testNullableFlatFields() throws Throwable { - Container1 c = new Container1(); - Class cc = Container1.class; - Field field = cc.getDeclaredField("value"); - Class fc = TestValue1.class; - long offset = U.objectFieldOffset(field); - if (!U.isFlatField(field)) return; // Field not flattened (due to VM flags?), test doesn't apply - // Initial value of the field must be null - Asserts.assertNull(U.getValue(c, offset, fc)); - // Writing all zero value to the field, field must become non-null - TestValue1 val0 = new TestValue1((short)0, (short)0); - U.putValue(c, offset, fc, val0); - TestValue1 rval = U.getValue(c, offset, fc); - Asserts.assertNotNull(rval); - Asserts.assertEQ((short)0, rval.s0); - Asserts.assertEQ((short)0, rval.s1); - Asserts.assertEQ((short)0, c.value.s0); - Asserts.assertEQ((short)0, c.value.s1); - // Writing null to the field, field must become null again - U.putValue(c, offset, fc, null); - Asserts.assertNull(U.getValue(c, offset, fc)); - Asserts.assertNull(c.value); - // Writing non zero value to the field - TestValue1 val1 = new TestValue1((short)-1, (short)-2); - U.putValue(c, offset, fc, val1); - rval = U.getValue(c, offset, fc); - Asserts.assertNotNull(rval); - Asserts.assertNotNull(c.value); - Asserts.assertEQ((short)-1, rval.s0); - Asserts.assertEQ((short)-2, rval.s1); - Asserts.assertEQ((short)-1, c.value.s0); - Asserts.assertEQ((short)-2, c.value.s1); - // Writing a different non zero value - TestValue1 val2 = new TestValue1((short)Short.MAX_VALUE, (short)3); - U.putValue(c, offset, fc, val2); - rval = U.getValue(c, offset, fc); - Asserts.assertNotNull(rval); - Asserts.assertNotNull(c.value); - Asserts.assertEQ(Short.MAX_VALUE, c.value.s0); - Asserts.assertEQ((short)3, rval.s1); - Asserts.assertEQ(Short.MAX_VALUE, c.value.s0); - Asserts.assertEQ((short)3, rval.s1); - } - - public static void testNullableFlatFields2() throws Throwable { Container1 c = new Container1(); Class cc = Container1.class; Field field = cc.getDeclaredField("value"); @@ -295,64 +204,8 @@ public static void testNullableFlatFields2() throws Throwable { Asserts.assertEQ((short)3, rval.s1); } - // Testing of nullable flat arrays supports in Unsafe.getValue()/Unsafe.putValue() - public static void testNullableFlatArrays() throws Throwable { - final int ARRAY_LENGTH = 10; - TestValue1[] array = (TestValue1[])ValueClass.newNullableAtomicArray(TestValue1.class, ARRAY_LENGTH); - Asserts.assertTrue(ValueClass.isFlatArray(array)); - long baseOffset = U.arrayBaseOffset(array); - int scaleIndex = U.arrayIndexScale(array); - for (int i = 0; i < ARRAY_LENGTH; i++) { - Asserts.assertNull(U.getValue(array, baseOffset + i * scaleIndex, TestValue1.class)); - } - TestValue1 val = new TestValue1((short)0, (short)0); - for (int i = 0; i < ARRAY_LENGTH; i++) { - if (i % 2 == 0) { - U.putValue(array, baseOffset + i * scaleIndex, TestValue1.class, val ); - } - } - for (int i = 0; i < ARRAY_LENGTH; i++) { - if (i % 2 == 0) { - Asserts.assertNotNull(U.getValue(array, baseOffset + i * scaleIndex, TestValue1.class)); - Asserts.assertNotNull(array[i]); - } else { - Asserts.assertNull(U.getValue(array, baseOffset + i * scaleIndex, TestValue1.class)); - Asserts.assertNull(array[i]); - } - } - TestValue1 val2 = new TestValue1((short)Short.MAX_VALUE, (short)Short.MIN_VALUE); - for (int i = 0; i < ARRAY_LENGTH; i++) { - if (i % 2 != 0) { - U.putValue(array, baseOffset + i * scaleIndex, TestValue1.class, val2 ); - } else { - U.putValue(array, baseOffset + i * scaleIndex, TestValue1.class, null ); - } - } - for (int i = 0; i < ARRAY_LENGTH; i++) { - if (i % 2 != 0) { - TestValue1 rval = U.getValue(array, baseOffset + i * scaleIndex, TestValue1.class); - Asserts.assertNotNull(rval); - Asserts.assertEQ(val2.s0, rval.s0); - Asserts.assertEQ(val2.s1, rval.s1); - Asserts.assertNotNull(array[i]); - Asserts.assertEQ(val2.s0, array[i].s0); - Asserts.assertEQ(val2.s1, array[i].s1); - } else { - Asserts.assertNull(U.getValue(array, baseOffset + i * scaleIndex, TestValue1.class)); - Asserts.assertNull(array[i]); - } - } - for (int i = 0; i < ARRAY_LENGTH; i++) { - U.putValue(array, baseOffset + i * scaleIndex, TestValue1.class, null ); - } - for (int i = 0; i < ARRAY_LENGTH; i++) { - Asserts.assertNull(U.getValue(array, baseOffset + i * scaleIndex, TestValue1.class)); - Asserts.assertNull(array[i]); - } - } - // Testing of nullable flat arrays supports in Unsafe.getFlatValue()/Unsafe.putFlatValue() - public static void testNullableFlatArrays2() throws Throwable { + public static void testNullableFlatArrays() throws Throwable { final int ARRAY_LENGTH = 10; TestValue1[] array = (TestValue1[])ValueClass.newNullableAtomicArray(TestValue1.class, ARRAY_LENGTH); long baseOffset = U.arrayBaseOffset(array); @@ -408,12 +261,9 @@ public static void testNullableFlatArrays2() throws Throwable { } public static void main(String[] args) throws Throwable { - test0(); test1(); testNullableFlatFields(); - testNullableFlatFields2(); testNullableFlatArrays(); - testNullableFlatArrays2(); } }