# HG changeset patch # User rkennke # Date 1525262533 -7200 # Wed May 02 14:02:13 2018 +0200 # Node ID 5d9fb983dff326852a4182ac78135a26ed3bad31 # Parent 8bc967d30f7a1b02235abd9a87fa29a285ae0a01 [mq]: primitives2.patch diff --git a/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp --- a/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp @@ -33,6 +33,7 @@ bool on_heap = (decorators & IN_HEAP) != 0; bool on_root = (decorators & IN_ROOT) != 0; bool oop_not_null = (decorators & OOP_NOT_NULL) != 0; + bool atomic = (decorators & MO_RELAXED) != 0; switch (type) { case T_OBJECT: @@ -57,6 +58,37 @@ } break; } + case T_BOOLEAN: __ load_unsigned_byte(dst, src); break; + case T_BYTE: __ load_signed_byte(dst, src); break; + case T_CHAR: __ load_unsigned_short(dst, src); break; + case T_SHORT: __ load_signed_short(dst, src); break; + case T_INT: __ movl (dst, src); break; + case T_ADDRESS: __ movptr(dst, src); break; + case T_FLOAT: + assert(dst == noreg, "only to ftos"); + __ load_float(src); + break; + case T_DOUBLE: + assert(dst == noreg, "only to dtos"); + __ load_double(src); + break; + case T_LONG: + assert(dst == noreg, "only to ltos"); +#ifdef _LP64 + __ movq(rax, src); +#else + if (atomic) { + __ fild_d(src); // Must load atomically + __ subptr(rsp,2*wordSize); // Make space for store + __ fistp_d(Address(rsp,0)); + __ pop(rax); + __ pop(rdx); + } else { + __ movl(rax, src); + __ movl(rdx, src.plus_disp(wordSize)); + } +#endif + break; default: Unimplemented(); } } @@ -66,6 +98,7 @@ bool on_heap = (decorators & IN_HEAP) != 0; bool on_root = (decorators & IN_ROOT) != 0; bool oop_not_null = (decorators & OOP_NOT_NULL) != 0; + bool atomic = (decorators & MO_RELAXED) != 0; switch (type) { case T_OBJECT: @@ -105,6 +138,47 @@ } break; } + case T_BOOLEAN: + __ andl(val, 0x1); // boolean is true if LSB is 1 + __ movb(dst, val); + break; + case T_BYTE: + __ movb(dst, val); + break; + case T_SHORT: + __ movw(dst, val); + break; + case T_CHAR: + __ movw(dst, val); + break; + case T_INT: + __ movl(dst, val); + break; + case T_LONG: + assert(val == noreg, "only tos"); +#ifdef _LP64 + __ movq(dst, rax); +#else + if (atomic) { + __ push(rdx); + __ push(rax); // Must update atomically with FIST + __ fild_d(Address(rsp,0)); // So load into FPU register + __ fistp_d(dst); // and put into memory atomically + __ addptr(rsp, 2*wordSize); + } else { + __ movptr(dst, rax); + __ movptr(dst.plus_disp(wordSize), rdx); + } +#endif + break; + case T_FLOAT: + assert(val == noreg, "only tos"); + __ store_float(dst); + break; + case T_DOUBLE: + assert(val == noreg, "only tos"); + __ store_double(dst); + break; default: Unimplemented(); } } diff --git a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp @@ -491,11 +491,9 @@ bool on_reference = on_weak || on_phantom; // tty->print_cr("RB src.base: %s", src.base()->name()); // __ verify_oop(src.base(), "broken oop before RB"); - /* if (in_heap) { read_barrier_not_null(masm, src.base()); } - */ // __ verify_oop(src.base(), "broken oop before RB"); BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); if (ShenandoahKeepAliveBarrier && on_oop && on_reference) { @@ -519,11 +517,9 @@ bool in_heap = (decorators & IN_HEAP) != 0; bool in_concurrent_root = (decorators & IN_CONCURRENT_ROOT) != 0; - /* if (in_heap) { write_barrier(masm, dst.base()); } - */ if (type == T_OBJECT || type == T_ARRAY) { bool needs_pre_barrier = in_heap || in_concurrent_root; bool needs_post_barrier = val != noreg && in_heap && UseShenandoahMatrix; diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp --- a/src/hotspot/cpu/x86/interp_masm_x86.cpp +++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp @@ -507,16 +507,15 @@ // convert from field index to resolved_references() index and from // word index to byte offset. Since this is a java object, it can be compressed Register tmp = index; // reuse - shll(tmp, LogBytesPerHeapOop); get_constant_pool(result); // load pointer for resolved_references[] objArray movptr(result, Address(result, ConstantPool::cache_offset_in_bytes())); movptr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes())); resolve_oop_handle(result); - // Add in the index - addptr(result, tmp); - load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + load_heap_oop(result, Address(result, index, + UseCompressedOops ? Address::times_4 : Address::times_ptr, + arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // The resulting oop is null if the reference is not yet resolved. // It is Universe::the_null_sentinel() if the reference resolved to NULL via condy. } diff --git a/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp b/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp --- a/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp +++ b/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp @@ -84,19 +84,20 @@ __ clear_jweak_tag(robj); __ movptr(robj, Address(robj, 0)); // *obj - __ resolve_for_read(0, robj); __ mov (roffset, c_rarg2); __ shrptr(roffset, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); switch (type) { - case T_BOOLEAN: __ movzbl (rax, Address(robj, roffset, Address::times_1)); break; - case T_BYTE: __ movsbl (rax, Address(robj, roffset, Address::times_1)); break; - case T_CHAR: __ movzwl (rax, Address(robj, roffset, Address::times_1)); break; - case T_SHORT: __ movswl (rax, Address(robj, roffset, Address::times_1)); break; - case T_INT: __ movl (rax, Address(robj, roffset, Address::times_1)); break; - case T_LONG: __ movq (rax, Address(robj, roffset, Address::times_1)); break; + case T_BOOLEAN: + case T_BYTE: + case T_CHAR: + case T_SHORT: + case T_INT: + case T_LONG: + __ access_load_at(type, IN_HEAP, rax, Address(robj, roffset, Address::times_1), noreg, noreg); + break; default: ShouldNotReachHere(); } @@ -187,17 +188,13 @@ __ clear_jweak_tag(robj); __ movptr(robj, Address(robj, 0)); // *obj - __ resolve_for_read(0, robj); __ mov (roffset, c_rarg2); __ shrptr(roffset, 2); // offset assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); speculative_load_pclist[count] = __ pc(); - switch (type) { - case T_FLOAT: __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break; - case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break; - default: ShouldNotReachHere(); - } + + __ access_load_at(type, IN_HEAP, noreg, Address(robj, roffset, Address::times_1), noreg, noreg); if (os::is_MP()) { __ lea(rcounter_addr, counter); diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -6422,7 +6422,6 @@ void MacroAssembler::resolve_oop_handle(Register result) { // OopHandle::resolve is an indirection. movptr(result, Address(result, 0)); - resolve_for_read(OOP_NOT_NULL, result); // TODO: Not needed. } void MacroAssembler::load_mirror(Register mirror, Register method) { diff --git a/src/hotspot/cpu/x86/methodHandles_x86.cpp b/src/hotspot/cpu/x86/methodHandles_x86.cpp --- a/src/hotspot/cpu/x86/methodHandles_x86.cpp +++ b/src/hotspot/cpu/x86/methodHandles_x86.cpp @@ -167,18 +167,16 @@ //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); }); // Load the invoker, as MH -> MH.form -> LF.vmentry - __ resolve_for_read(0, recv); __ verify_oop(recv); __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), temp2); - __ resolve_for_read(0, method_temp); __ verify_oop(method_temp); __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), temp2); - __ resolve_for_read(0, method_temp); __ verify_oop(method_temp); __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2); - __ resolve_for_read(OOP_NOT_NULL, method_temp); __ verify_oop(method_temp); - __ movptr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()))); + __ access_load_at(T_ADDRESS, IN_HEAP, method_temp, + Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())), + noreg, noreg); if (VerifyMethodHandles && !for_compiler_entry) { // make sure recv is already on stack @@ -387,7 +385,6 @@ // rsi/r13 - interpreter linkage (if interpreted) // rcx, rdx, rsi, rdi, r8 - compiler arguments (if compiled) - __ resolve_for_read(0, member_reg); Label L_incompatible_class_change_error; switch (iid) { case vmIntrinsics::_linkToSpecial: @@ -395,8 +392,7 @@ verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); } __ load_heap_oop(rbx_method, member_vmtarget); - __ resolve_for_read(0, rbx_method); - __ movptr(rbx_method, vmtarget_method); + __ access_load_at(T_ADDRESS, IN_HEAP, rbx_method, vmtarget_method, noreg, noreg); break; case vmIntrinsics::_linkToStatic: @@ -404,8 +400,7 @@ verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); } __ load_heap_oop(rbx_method, member_vmtarget); - __ resolve_for_read(0, rbx_method); - __ movptr(rbx_method, vmtarget_method); + __ access_load_at(T_ADDRESS, IN_HEAP, rbx_method, vmtarget_method, noreg, noreg); break; case vmIntrinsics::_linkToVirtual: @@ -419,7 +414,7 @@ // pick out the vtable index from the MemberName, and then we can discard it: Register temp2_index = temp2; - __ movptr(temp2_index, member_vmindex); + __ access_load_at(T_ADDRESS, IN_HEAP, temp2_index, member_vmindex, noreg, noreg); if (VerifyMethodHandles) { Label L_index_ok; @@ -451,7 +446,7 @@ __ verify_klass_ptr(temp3_intf); Register rbx_index = rbx_method; - __ movptr(rbx_index, member_vmindex); + __ access_load_at(T_ADDRESS, IN_HEAP, rbx_index, member_vmindex, noreg, noreg); if (VerifyMethodHandles) { Label L; __ cmpl(rbx_index, 0); diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -2474,7 +2474,7 @@ // Load the oop from the handle __ movptr(obj_reg, Address(oop_handle_reg, 0)); - __ resolve_for_write(0, obj_reg); + __ resolve_for_write(OOP_NOT_NULL, obj_reg); if (UseBiasedLocking) { __ biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, lock_done, &slow_path_lock); } @@ -2655,7 +2655,7 @@ // Get locked oop from the handle we passed to jni __ movptr(obj_reg, Address(oop_handle_reg, 0)); - __ resolve_for_write(0, obj_reg); + __ resolve_for_write(OOP_NOT_NULL, obj_reg); Label done; diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp @@ -633,7 +633,7 @@ #endif // ASSERT __ bind(done); - __ resolve_for_write(0, rax); + __ resolve_for_write(OOP_NOT_NULL, rax); } // add space for monitor & lock @@ -739,7 +739,6 @@ NOT_LP64(__ push(rsi)); // Load the value of the referent field. - __ resolve_for_read(OOP_NOT_NULL, rax); const Address field_address(rax, referent_offset); __ load_heap_oop(rax, field_address, /*tmp1*/ rbx, /*tmp_thread*/ rdx, ON_WEAK_OOP_REF); diff --git a/src/hotspot/cpu/x86/templateTable_x86.cpp b/src/hotspot/cpu/x86/templateTable_x86.cpp --- a/src/hotspot/cpu/x86/templateTable_x86.cpp +++ b/src/hotspot/cpu/x86/templateTable_x86.cpp @@ -767,10 +767,10 @@ // rax: index // rdx: array index_check(rdx, rax); // kills rbx - __ resolve_for_read(OOP_NOT_NULL, rdx); - __ movl(rax, Address(rdx, rax, - Address::times_4, - arrayOopDesc::base_offset_in_bytes(T_INT))); + __ access_load_at(T_INT, IN_HEAP, rax, Address(rdx, rax, + Address::times_4, + arrayOopDesc::base_offset_in_bytes(T_INT)), + noreg, noreg); } void TemplateTable::laload() { @@ -780,9 +780,10 @@ index_check(rdx, rax); // kills rbx NOT_LP64(__ mov(rbx, rax)); // rbx,: index - __ resolve_for_read(OOP_NOT_NULL, rdx); - __ movptr(rax, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize)); - NOT_LP64(__ movl(rdx, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 1 * wordSize))); + __ access_load_at(T_LONG, IN_HEAP, noreg /* ltos */, + Address(rdx, rbx, Address::times_8, + arrayOopDesc::base_offset_in_bytes(T_LONG)), + noreg, noreg); } @@ -792,10 +793,11 @@ // rax: index // rdx: array index_check(rdx, rax); // kills rbx - __ resolve_for_read(OOP_NOT_NULL, rdx); - __ load_float(Address(rdx, rax, - Address::times_4, - arrayOopDesc::base_offset_in_bytes(T_FLOAT))); + __ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, + Address(rdx, rax, + Address::times_4, + arrayOopDesc::base_offset_in_bytes(T_FLOAT)), + noreg, noreg); } void TemplateTable::daload() { @@ -803,10 +805,11 @@ // rax: index // rdx: array index_check(rdx, rax); // kills rbx - __ resolve_for_read(OOP_NOT_NULL, rdx); - __ load_double(Address(rdx, rax, - Address::times_8, - arrayOopDesc::base_offset_in_bytes(T_DOUBLE))); + __ access_load_at(T_DOUBLE, IN_HEAP, noreg /* dtos */, + Address(rdx, rax, + Address::times_8, + arrayOopDesc::base_offset_in_bytes(T_DOUBLE)), + noreg, noreg); } void TemplateTable::aaload() { @@ -814,7 +817,6 @@ // rax: index // rdx: array index_check(rdx, rax); // kills rbx - __ resolve_for_read(OOP_NOT_NULL, rdx); do_oop_load(_masm, Address(rdx, rax, UseCompressedOops ? Address::times_4 : Address::times_ptr, @@ -828,8 +830,9 @@ // rax: index // rdx: array index_check(rdx, rax); // kills rbx - __ resolve_for_read(OOP_NOT_NULL, rdx); - __ load_signed_byte(rax, Address(rdx, rax, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE))); + __ access_load_at(T_BYTE, IN_HEAP, rax, + Address(rdx, rax, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)), + noreg, noreg); } void TemplateTable::caload() { @@ -837,8 +840,9 @@ // rax: index // rdx: array index_check(rdx, rax); // kills rbx - __ resolve_for_read(OOP_NOT_NULL, rdx); - __ load_unsigned_short(rax, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); + __ access_load_at(T_CHAR, IN_HEAP, rax, + Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)), + noreg, noreg); } // iload followed by caload frequent pair @@ -851,11 +855,9 @@ // rax: index // rdx: array index_check(rdx, rax); // kills rbx - __ resolve_for_read(OOP_NOT_NULL, rdx); - __ load_unsigned_short(rax, - Address(rdx, rax, - Address::times_2, - arrayOopDesc::base_offset_in_bytes(T_CHAR))); + __ access_load_at(T_CHAR, IN_HEAP, rax, + Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)), + noreg, noreg); } @@ -864,8 +866,9 @@ // rax: index // rdx: array index_check(rdx, rax); // kills rbx - __ resolve_for_read(OOP_NOT_NULL, rdx); - __ load_signed_short(rax, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_SHORT))); + __ access_load_at(T_SHORT, IN_HEAP, rax, + Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_SHORT)), + noreg, noreg); } void TemplateTable::iload(int n) { @@ -1057,11 +1060,9 @@ // rbx: index // rdx: array index_check(rdx, rbx); // prefer index in rbx - __ resolve_for_write(OOP_NOT_NULL, rdx); - __ movl(Address(rdx, rbx, - Address::times_4, - arrayOopDesc::base_offset_in_bytes(T_INT)), - rax); + __ access_store_at(T_INT, IN_HEAP, Address(rdx, rbx, + Address::times_4, + arrayOopDesc::base_offset_in_bytes(T_INT)), rax, noreg, noreg); } void TemplateTable::lastore() { @@ -1072,9 +1073,7 @@ // rdx: high(value) index_check(rcx, rbx); // prefer index in rbx, // rbx,: index - __ resolve_for_write(OOP_NOT_NULL, rcx); - __ movptr(Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize), rax); - NOT_LP64(__ movl(Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG) + 1 * wordSize), rdx)); + __ access_store_at(T_LONG, IN_HEAP, Address(rcx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_LONG)), noreg /* ltos */, noreg, noreg); } @@ -1085,8 +1084,7 @@ // rbx: index // rdx: array index_check(rdx, rbx); // prefer index in rbx - __ resolve_for_write(OOP_NOT_NULL, rdx); - __ store_float(Address(rdx, rbx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_FLOAT))); + __ access_store_at(T_FLOAT, IN_HEAP, Address(rdx, rbx, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_FLOAT)), noreg /* ftos */, noreg, noreg); } void TemplateTable::dastore() { @@ -1096,8 +1094,7 @@ // rbx: index // rdx: array index_check(rdx, rbx); // prefer index in rbx - __ resolve_for_write(OOP_NOT_NULL, rdx); - __ store_double(Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_DOUBLE))); + __ access_store_at(T_DOUBLE, IN_HEAP, Address(rdx, rbx, Address::times_8, arrayOopDesc::base_offset_in_bytes(T_DOUBLE)), noreg /* ftos */, noreg, noreg); } void TemplateTable::aastore() { @@ -1113,7 +1110,6 @@ arrayOopDesc::base_offset_in_bytes(T_OBJECT)); index_check_without_pop(rdx, rcx); // kills rbx - __ resolve_for_write(OOP_NOT_NULL, rdx); __ testptr(rax, rax); __ jcc(Assembler::zero, is_null); @@ -1123,13 +1119,10 @@ __ load_klass(rax, rdx); __ movptr(rax, Address(rax, ObjArrayKlass::element_klass_offset())); - // Compress array + index*oopSize + 12 into a single register. Frees rcx. - __ lea(rdx, element_address); // Generate subtype check. Blows rcx, rdi // Superklass in rax. Subklass in rbx. __ gen_subtype_check(rbx, ok_is_subtype); - // Come here on failure // object is at TOS __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry)); @@ -1139,8 +1132,9 @@ // Get the value we will store __ movptr(rax, at_tos()); + __ movl(rcx, at_tos_p1()); // index // Now store using the appropriate barrier - do_oop_store(_masm, Address(rdx, 0), rax, IN_HEAP_ARRAY); + do_oop_store(_masm, element_address, rax, IN_HEAP_ARRAY); __ jmp(done); // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx] @@ -1162,7 +1156,6 @@ // rbx: index // rdx: array index_check(rdx, rbx); // prefer index in rbx - __ resolve_for_write(OOP_NOT_NULL, rdx); // Need to check whether array is boolean or byte // since both types share the bastore bytecode. __ load_klass(rcx, rdx); @@ -1173,10 +1166,10 @@ __ jccb(Assembler::zero, L_skip); __ andl(rax, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1 __ bind(L_skip); - __ movb(Address(rdx, rbx, - Address::times_1, - arrayOopDesc::base_offset_in_bytes(T_BYTE)), - rax); + __ access_store_at(T_BYTE, IN_HEAP, Address(rdx, rbx, + Address::times_1, + arrayOopDesc::base_offset_in_bytes(T_BYTE)), + rax, noreg, noreg); } void TemplateTable::castore() { @@ -1186,11 +1179,10 @@ // rbx: index // rdx: array index_check(rdx, rbx); // prefer index in rbx - __ resolve_for_write(OOP_NOT_NULL, rdx); - __ movw(Address(rdx, rbx, - Address::times_2, - arrayOopDesc::base_offset_in_bytes(T_CHAR)), - rax); + __ access_store_at(T_CHAR, IN_HEAP, Address(rdx, rbx, + Address::times_2, + arrayOopDesc::base_offset_in_bytes(T_CHAR)), + rax, noreg, noreg); } @@ -2864,10 +2856,8 @@ load_field_cp_cache_entry(obj, cache, index, off, flags, is_static); if (!is_static) pop_and_check_object(obj); - __ resolve_for_read(OOP_NOT_NULL, obj); const Address field(obj, off, Address::times_1, 0*wordSize); - NOT_LP64(const Address hi(obj, off, Address::times_1, 1*wordSize)); Label Done, notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; @@ -2879,7 +2869,7 @@ __ jcc(Assembler::notZero, notByte); // btos - __ load_signed_byte(rax, field); + __ access_load_at(T_BYTE, IN_HEAP, rax, field, noreg, noreg); __ push(btos); // Rewrite bytecode to be faster if (!is_static && rc == may_rewrite) { @@ -2892,7 +2882,7 @@ __ jcc(Assembler::notEqual, notBool); // ztos (same code as btos) - __ load_signed_byte(rax, field); + __ access_load_at(T_BOOLEAN, IN_HEAP, rax, field, noreg, noreg); __ push(ztos); // Rewrite bytecode to be faster if (!is_static && rc == may_rewrite) { @@ -2916,7 +2906,7 @@ __ cmpl(flags, itos); __ jcc(Assembler::notEqual, notInt); // itos - __ movl(rax, field); + __ access_load_at(T_INT, IN_HEAP, rax, field, noreg, noreg); __ push(itos); // Rewrite bytecode to be faster if (!is_static && rc == may_rewrite) { @@ -2928,7 +2918,7 @@ __ cmpl(flags, ctos); __ jcc(Assembler::notEqual, notChar); // ctos - __ load_unsigned_short(rax, field); + __ access_load_at(T_CHAR, IN_HEAP, rax, field, noreg, noreg); __ push(ctos); // Rewrite bytecode to be faster if (!is_static && rc == may_rewrite) { @@ -2940,7 +2930,7 @@ __ cmpl(flags, stos); __ jcc(Assembler::notEqual, notShort); // stos - __ load_signed_short(rax, field); + __ access_load_at(T_SHORT, IN_HEAP, rax, field, noreg, noreg); __ push(stos); // Rewrite bytecode to be faster if (!is_static && rc == may_rewrite) { @@ -2952,20 +2942,11 @@ __ cmpl(flags, ltos); __ jcc(Assembler::notEqual, notLong); // ltos - -#ifndef _LP64 - // Generate code as if volatile. There just aren't enough registers to - // save that information and this code is faster than the test. - __ fild_d(field); // Must load atomically - __ subptr(rsp,2*wordSize); // Make space for store - __ fistp_d(Address(rsp,0)); - __ pop(rax); - __ pop(rdx); -#else - __ movq(rax, field); -#endif - + // Generate code as if volatile (x86_32). There just aren't enough registers to + // save that information and this code is faster than the test. + __ access_load_at(T_LONG, IN_HEAP | MO_RELAXED, noreg /* ltos */, field, noreg, noreg); __ push(ltos); + // Rewrite bytecode to be faster LP64_ONLY(if (!is_static && rc == may_rewrite) patch_bytecode(Bytecodes::_fast_lgetfield, bc, rbx)); __ jmp(Done); @@ -2975,6 +2956,7 @@ __ jcc(Assembler::notEqual, notFloat); // ftos + __ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg); __ load_float(field); __ push(ftos); // Rewrite bytecode to be faster @@ -2989,7 +2971,7 @@ __ jcc(Assembler::notEqual, notDouble); #endif // dtos - __ load_double(field); + __ access_load_at(T_DOUBLE, IN_HEAP, noreg /* ftos */, field, noreg, noreg); __ push(dtos); // Rewrite bytecode to be faster if (!is_static && rc == may_rewrite) { @@ -3148,8 +3130,7 @@ { __ pop(btos); if (!is_static) pop_and_check_object(obj); - __ resolve_for_write(OOP_NOT_NULL, obj); - __ movb(field, rax); + __ access_store_at(T_BYTE, IN_HEAP, field, rax, noreg, noreg); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx, true, byte_no); } @@ -3164,9 +3145,7 @@ { __ pop(ztos); if (!is_static) pop_and_check_object(obj); - __ resolve_for_write(OOP_NOT_NULL, obj); - __ andl(rax, 0x1); - __ movb(field, rax); + __ access_store_at(T_BOOLEAN, IN_HEAP, field, rax, noreg, noreg); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_zputfield, bc, rbx, true, byte_no); } @@ -3181,7 +3160,6 @@ { __ pop(atos); if (!is_static) pop_and_check_object(obj); - __ resolve_for_write(OOP_NOT_NULL, obj); // Store into the field do_oop_store(_masm, field, rax); if (!is_static && rc == may_rewrite) { @@ -3198,8 +3176,7 @@ { __ pop(itos); if (!is_static) pop_and_check_object(obj); - __ resolve_for_write(OOP_NOT_NULL, obj); - __ movl(field, rax); + __ access_store_at(T_INT, IN_HEAP, field, rax, noreg, noreg); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no); } @@ -3214,8 +3191,7 @@ { __ pop(ctos); if (!is_static) pop_and_check_object(obj); - __ resolve_for_write(OOP_NOT_NULL, obj); - __ movw(field, rax); + __ access_store_at(T_CHAR, IN_HEAP, field, rax, noreg, noreg); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx, true, byte_no); } @@ -3230,8 +3206,7 @@ { __ pop(stos); if (!is_static) pop_and_check_object(obj); - __ resolve_for_write(OOP_NOT_NULL, obj); - __ movw(field, rax); + __ access_store_at(T_SHORT, IN_HEAP, field, rax, noreg, noreg); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx, true, byte_no); } @@ -3247,8 +3222,7 @@ { __ pop(ltos); if (!is_static) pop_and_check_object(obj); - __ resolve_for_write(OOP_NOT_NULL, obj); - __ movq(field, rax); + __ access_store_at(T_LONG, IN_HEAP, field, noreg /* ltos*/, noreg, noreg); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx, true, byte_no); } @@ -3264,11 +3238,7 @@ if (!is_static) pop_and_check_object(obj); // Replace with real volatile test - __ push(rdx); - __ push(rax); // Must update atomically with FIST - __ fild_d(Address(rsp,0)); // So load into FPU register - __ fistp_d(field); // and put into memory atomically - __ addptr(rsp, 2*wordSize); + __ access_store_at(T_LONG, IN_HEAP | MO_RELAXED, field, noreg /* ltos */, noreg, noreg); // volatile_barrier(); volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | Assembler::StoreStore)); @@ -3279,8 +3249,8 @@ __ pop(ltos); // overwrites rdx if (!is_static) pop_and_check_object(obj); - __ movptr(hi, rdx); - __ movptr(field, rax); + + __ access_store_at(T_LONG, IN_HEAP | MO_RELAXED, field, noreg /* ltos */, noreg, noreg); // Don't rewrite to _fast_lputfield for potential volatile case. __ jmp(notVolatile); } @@ -3294,8 +3264,7 @@ { __ pop(ftos); if (!is_static) pop_and_check_object(obj); - __ resolve_for_write(OOP_NOT_NULL, obj); - __ store_float(field); + __ access_store_at(T_FLOAT, IN_HEAP, field, noreg /* ftos */, noreg, noreg); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx, true, byte_no); } @@ -3312,8 +3281,7 @@ { __ pop(dtos); if (!is_static) pop_and_check_object(obj); - __ resolve_for_write(OOP_NOT_NULL, obj); - __ store_double(field); + __ access_store_at(T_DOUBLE, IN_HEAP, field, noreg /* ftos */, noreg, noreg); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx, true, byte_no); } @@ -3435,7 +3403,6 @@ // Get object from stack pop_and_check_object(rcx); - __ resolve_for_write(OOP_NOT_NULL, rcx); // field address const Address field(rcx, rbx, Address::times_1); @@ -3447,30 +3414,31 @@ break; case Bytecodes::_fast_lputfield: #ifdef _LP64 - __ movq(field, rax); + __ access_store_at(T_LONG, IN_HEAP, field, noreg /* ltos */, noreg, noreg); #else - __ stop("should not be rewritten"); + __ stop("should not be rewritten"); #endif break; case Bytecodes::_fast_iputfield: - __ movl(field, rax); + __ access_store_at(T_INT, IN_HEAP, field, rax, noreg, noreg); break; case Bytecodes::_fast_zputfield: - __ andl(rax, 0x1); // boolean is true if LSB is 1 - // fall through to bputfield + __ access_store_at(T_BOOLEAN, IN_HEAP, field, rax, noreg, noreg); + break; case Bytecodes::_fast_bputfield: - __ movb(field, rax); + __ access_store_at(T_BYTE, IN_HEAP, field, rax, noreg, noreg); break; case Bytecodes::_fast_sputfield: - // fall through + __ access_store_at(T_SHORT, IN_HEAP, field, rax, noreg, noreg); + break; case Bytecodes::_fast_cputfield: - __ movw(field, rax); + __ access_store_at(T_CHAR, IN_HEAP, field, rax, noreg, noreg); break; case Bytecodes::_fast_fputfield: - __ store_float(field); + __ access_store_at(T_FLOAT, IN_HEAP, field, noreg /* ftos*/, noreg, noreg); break; case Bytecodes::_fast_dputfield: - __ store_double(field); + __ access_store_at(T_DOUBLE, IN_HEAP, field, noreg /* ftos*/, noreg, noreg); break; default: ShouldNotReachHere(); @@ -3527,7 +3495,6 @@ // rax: object __ verify_oop(rax); __ null_check(rax); - __ resolve_for_read(OOP_NOT_NULL, rax); Address field(rax, rbx, Address::times_1); // access field @@ -3538,28 +3505,28 @@ break; case Bytecodes::_fast_lgetfield: #ifdef _LP64 - __ movq(rax, field); + __ access_load_at(T_LONG, IN_HEAP, noreg /* ltos */, field, noreg, noreg); #else __ stop("should not be rewritten"); #endif break; case Bytecodes::_fast_igetfield: - __ movl(rax, field); + __ access_load_at(T_INT, IN_HEAP, rax, field, noreg, noreg); break; case Bytecodes::_fast_bgetfield: - __ movsbl(rax, field); + __ access_load_at(T_BYTE, IN_HEAP, rax, field, noreg, noreg); break; case Bytecodes::_fast_sgetfield: - __ load_signed_short(rax, field); + __ access_load_at(T_SHORT, IN_HEAP, rax, field, noreg, noreg); break; case Bytecodes::_fast_cgetfield: - __ load_unsigned_short(rax, field); + __ access_load_at(T_CHAR, IN_HEAP, rax, field, noreg, noreg); break; case Bytecodes::_fast_fgetfield: - __ load_float(field); + __ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg); break; case Bytecodes::_fast_dgetfield: - __ load_double(field); + __ access_load_at(T_DOUBLE, IN_HEAP, noreg /* ftos */, field, noreg, noreg); break; default: ShouldNotReachHere(); @@ -3589,18 +3556,17 @@ // next instruction) __ increment(rbcp); __ null_check(rax); - __ resolve_for_read(OOP_NOT_NULL, rax); const Address field = Address(rax, rbx, Address::times_1, 0*wordSize); switch (state) { case itos: - __ movl(rax, field); + __ access_load_at(T_INT, IN_HEAP, rax, field, noreg, noreg); break; case atos: do_oop_load(_masm, field, rax); __ verify_oop(rax); break; case ftos: - __ load_float(field); + __ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg); break; default: ShouldNotReachHere();