OpenJDK / loom / loom
changeset 48965:be873d8c0114
8196786: [PPC64+s390] ConstantDynamic support
Reviewed-by: psandoz, dsamersoff
author | mdoerr |
---|---|
date | Tue, 13 Feb 2018 17:38:03 +0100 |
parents | 86143b5899dc |
children | e6eb66d2e765 |
files | src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp src/hotspot/cpu/ppc/templateTable_ppc_64.cpp src/hotspot/cpu/s390/interp_masm_s390.cpp src/hotspot/cpu/s390/templateTable_s390.cpp test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java test/jdk/java/lang/invoke/condy/CondyWrongType.java |
diffstat | 7 files changed, 279 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp Tue Feb 13 16:57:01 2018 +0100 +++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp Tue Feb 13 17:38:03 2018 +0100 @@ -492,6 +492,8 @@ // Add in the index. add(result, tmp, result); load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result, is_null); + // 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. } // load cpool->resolved_klass_at(index)
--- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Tue Feb 13 16:57:01 2018 +0100 +++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Tue Feb 13 17:38:03 2018 +0100 @@ -314,7 +314,7 @@ Rcpool = R3_ARG1; transition(vtos, vtos); - Label notInt, notClass, exit; + Label notInt, notFloat, notClass, exit; __ get_cpool_and_tags(Rcpool, Rscratch2); // Set Rscratch2 = &tags. if (wide) { // Read index. @@ -356,13 +356,16 @@ __ align(32, 12); __ bind(notInt); -#ifdef ASSERT - // String and Object are rewritten to fast_aldc __ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Float); - __ asm_assert_eq("unexpected type", 0x8765); -#endif + __ bne(CCR0, notFloat); __ lfsx(F15_ftos, Rcpool, Rscratch1); __ push(ftos); + __ b(exit); + + __ align(32, 12); + // assume the tag is for condy; if not, the VM runtime will tell us + __ bind(notFloat); + condy_helper(exit); __ align(32, 12); __ bind(exit); @@ -380,6 +383,19 @@ // non-null object (CallSite, etc.) __ get_cache_index_at_bcp(Rscratch, 1, index_size); // Load index. __ load_resolved_reference_at_index(R17_tos, Rscratch, &is_null); + + // Convert null sentinel to NULL. + int simm16_rest = __ load_const_optimized(Rscratch, Universe::the_null_sentinel_addr(), R0, true); + __ ld(Rscratch, simm16_rest, Rscratch); + __ cmpld(CCR0, R17_tos, Rscratch); + if (VM_Version::has_isel()) { + __ isel_0(R17_tos, CCR0, Assembler::equal); + } else { + Label not_sentinel; + __ bne(CCR0, not_sentinel); + __ li(R17_tos, 0); + __ bind(not_sentinel); + } __ verify_oop(R17_tos); __ dispatch_epilog(atos, Bytecodes::length_for(bytecode())); @@ -395,7 +411,7 @@ void TemplateTable::ldc2_w() { transition(vtos, vtos); - Label Llong, Lexit; + Label not_double, not_long, exit; Register Rindex = R11_scratch1, Rcpool = R12_scratch2, @@ -410,23 +426,129 @@ __ addi(Rtag, Rtag, tags_offset); __ lbzx(Rtag, Rtag, Rindex); - __ sldi(Rindex, Rindex, LogBytesPerWord); + __ cmpdi(CCR0, Rtag, JVM_CONSTANT_Double); - __ bne(CCR0, Llong); - // A double can be placed at word-aligned locations in the constant pool. - // Check out Conversions.java for an example. - // Also ConstantPool::header_size() is 20, which makes it very difficult - // to double-align double on the constant pool. SG, 11/7/97 + __ bne(CCR0, not_double); __ lfdx(F15_ftos, Rcpool, Rindex); __ push(dtos); - __ b(Lexit); - - __ bind(Llong); + __ b(exit); + + __ bind(not_double); + __ cmpdi(CCR0, Rtag, JVM_CONSTANT_Long); + __ bne(CCR0, not_long); __ ldx(R17_tos, Rcpool, Rindex); __ push(ltos); - - __ bind(Lexit); + __ b(exit); + + __ bind(not_long); + condy_helper(exit); + + __ align(32, 12); + __ bind(exit); +} + +void TemplateTable::condy_helper(Label& Done) { + const Register obj = R31; + const Register off = R11_scratch1; + const Register flags = R12_scratch2; + const Register rarg = R4_ARG2; + __ li(rarg, (int)bytecode()); + call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), rarg); + __ get_vm_result_2(flags); + + // VMr = obj = base address to find primitive value to push + // VMr2 = flags = (tos, off) using format of CPCE::_flags + __ andi(off, flags, ConstantPoolCacheEntry::field_index_mask); + + // What sort of thing are we loading? + __ rldicl(flags, flags, 64-ConstantPoolCacheEntry::tos_state_shift, 64-ConstantPoolCacheEntry::tos_state_bits); + + switch (bytecode()) { + case Bytecodes::_ldc: + case Bytecodes::_ldc_w: + { + // tos in (itos, ftos, stos, btos, ctos, ztos) + Label notInt, notFloat, notShort, notByte, notChar, notBool; + __ cmplwi(CCR0, flags, itos); + __ bne(CCR0, notInt); + // itos + __ lwax(R17_tos, obj, off); + __ push(itos); + __ b(Done); + + __ bind(notInt); + __ cmplwi(CCR0, flags, ftos); + __ bne(CCR0, notFloat); + // ftos + __ lfsx(F15_ftos, obj, off); + __ push(ftos); + __ b(Done); + + __ bind(notFloat); + __ cmplwi(CCR0, flags, stos); + __ bne(CCR0, notShort); + // stos + __ lhax(R17_tos, obj, off); + __ push(stos); + __ b(Done); + + __ bind(notShort); + __ cmplwi(CCR0, flags, btos); + __ bne(CCR0, notByte); + // btos + __ lbzx(R17_tos, obj, off); + __ extsb(R17_tos, R17_tos); + __ push(btos); + __ b(Done); + + __ bind(notByte); + __ cmplwi(CCR0, flags, ctos); + __ bne(CCR0, notChar); + // ctos + __ lhzx(R17_tos, obj, off); + __ push(ctos); + __ b(Done); + + __ bind(notChar); + __ cmplwi(CCR0, flags, ztos); + __ bne(CCR0, notBool); + // ztos + __ lbzx(R17_tos, obj, off); + __ push(ztos); + __ b(Done); + + __ bind(notBool); + break; + } + + case Bytecodes::_ldc2_w: + { + Label notLong, notDouble; + __ cmplwi(CCR0, flags, ltos); + __ bne(CCR0, notLong); + // ltos + __ ldx(R17_tos, obj, off); + __ push(ltos); + __ b(Done); + + __ bind(notLong); + __ cmplwi(CCR0, flags, dtos); + __ bne(CCR0, notDouble); + // dtos + __ lfdx(F15_ftos, obj, off); + __ push(dtos); + __ b(Done); + + __ bind(notDouble); + break; + } + + default: + ShouldNotReachHere(); + } + + __ stop("bad ldc/condy"); } // Get the locals index located in the bytecode stream at bcp + offset.
--- a/src/hotspot/cpu/s390/interp_masm_s390.cpp Tue Feb 13 16:57:01 2018 +0100 +++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp Tue Feb 13 17:38:03 2018 +0100 @@ -389,6 +389,8 @@ #endif z_agr(result, index); // Address of indexed array element. load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result); + // 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. } // load cpool->resolved_klass_at(index)
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp Tue Feb 13 16:57:01 2018 +0100 +++ b/src/hotspot/cpu/s390/templateTable_s390.cpp Tue Feb 13 17:38:03 2018 +0100 @@ -450,7 +450,7 @@ void TemplateTable::ldc(bool wide) { transition(vtos, vtos); - Label call_ldc, notFloat, notClass, Done; + Label call_ldc, notFloat, notClass, notInt, Done; const Register RcpIndex = Z_tmp_1; const Register Rtags = Z_ARG2; @@ -500,22 +500,17 @@ __ z_bru(Done); __ bind(notFloat); -#ifdef ASSERT - { - Label L; - - __ z_cli(0, Raddr_type, JVM_CONSTANT_Integer); - __ z_bre(L); - // String and Object are rewritten to fast_aldc. - __ stop("unexpected tag type in ldc"); - - __ bind(L); - } -#endif + __ z_cli(0, Raddr_type, JVM_CONSTANT_Integer); + __ z_brne(notInt); // itos __ mem2reg_opt(Z_tos, Address(Z_tmp_2, RcpOffset, base_offset), false); __ push_i(Z_tos); + __ z_bru(Done); + + // assume the tag is for condy; if not, the VM runtime will tell us + __ bind(notInt); + condy_helper(Done); __ bind(Done); } @@ -528,15 +523,23 @@ const Register index = Z_tmp_2; int index_size = wide ? sizeof(u2) : sizeof(u1); - Label L_resolved; + Label L_do_resolve, L_resolved; // We are resolved if the resolved reference cache entry contains a // non-null object (CallSite, etc.). __ get_cache_index_at_bcp(index, 1, index_size); // Load index. __ load_resolved_reference_at_index(Z_tos, index); __ z_ltgr(Z_tos, Z_tos); + __ z_bre(L_do_resolve); + + // Convert null sentinel to NULL. + __ load_const_optimized(Z_R1_scratch, (intptr_t)Universe::the_null_sentinel_addr()); + __ z_cg(Z_tos, Address(Z_R1_scratch)); __ z_brne(L_resolved); - + __ clear_reg(Z_tos); + __ z_bru(L_resolved); + + __ bind(L_do_resolve); // First time invocation - must resolve first. address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); __ load_const_optimized(Z_ARG1, (int)bytecode()); @@ -548,7 +551,7 @@ void TemplateTable::ldc2_w() { transition(vtos, vtos); - Label Long, Done; + Label notDouble, notLong, Done; // Z_tmp_1 = index of cp entry __ get_2_byte_integer_at_bcp(Z_tmp_1, 1, InterpreterMacroAssembler::Unsigned); @@ -566,21 +569,132 @@ // Check type. __ z_cli(0, Z_tos, JVM_CONSTANT_Double); - __ z_brne(Long); - + __ z_brne(notDouble); // dtos __ mem2freg_opt(Z_ftos, Address(Z_tmp_2, Z_tmp_1, base_offset)); __ push_d(); __ z_bru(Done); - __ bind(Long); + __ bind(notDouble); + __ z_cli(0, Z_tos, JVM_CONSTANT_Long); + __ z_brne(notLong); // ltos __ mem2reg_opt(Z_tos, Address(Z_tmp_2, Z_tmp_1, base_offset)); __ push_l(); + __ z_bru(Done); + + __ bind(notLong); + condy_helper(Done); __ bind(Done); } +void TemplateTable::condy_helper(Label& Done) { + const Register obj = Z_tmp_1; + const Register off = Z_tmp_2; + const Register flags = Z_ARG1; + const Register rarg = Z_ARG2; + __ load_const_optimized(rarg, (int)bytecode()); + call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), rarg); + __ get_vm_result_2(flags); + + // VMr = obj = base address to find primitive value to push + // VMr2 = flags = (tos, off) using format of CPCE::_flags + assert(ConstantPoolCacheEntry::field_index_mask == 0xffff, "or use other instructions"); + __ z_llghr(off, flags); + const Address field(obj, off); + + // What sort of thing are we loading? + __ z_srl(flags, ConstantPoolCacheEntry::tos_state_shift); + // Make sure we don't need to mask flags for tos_state after the above shift. + ConstantPoolCacheEntry::verify_tos_state_shift(); + + switch (bytecode()) { + case Bytecodes::_ldc: + case Bytecodes::_ldc_w: + { + // tos in (itos, ftos, stos, btos, ctos, ztos) + Label notInt, notFloat, notShort, notByte, notChar, notBool; + __ z_cghi(flags, itos); + __ z_brne(notInt); + // itos + __ z_l(Z_tos, field); + __ push(itos); + __ z_bru(Done); + + __ bind(notInt); + __ z_cghi(flags, ftos); + __ z_brne(notFloat); + // ftos + __ z_le(Z_ftos, field); + __ push(ftos); + __ z_bru(Done); + + __ bind(notFloat); + __ z_cghi(flags, stos); + __ z_brne(notShort); + // stos + __ z_lh(Z_tos, field); + __ push(stos); + __ z_bru(Done); + + __ bind(notShort); + __ z_cghi(flags, btos); + __ z_brne(notByte); + // btos + __ z_lb(Z_tos, field); + __ push(btos); + __ z_bru(Done); + + __ bind(notByte); + __ z_cghi(flags, ctos); + __ z_brne(notChar); + // ctos + __ z_llh(Z_tos, field); + __ push(ctos); + __ z_bru(Done); + + __ bind(notChar); + __ z_cghi(flags, ztos); + __ z_brne(notBool); + // ztos + __ z_lb(Z_tos, field); + __ push(ztos); + __ z_bru(Done); + + __ bind(notBool); + break; + } + + case Bytecodes::_ldc2_w: + { + Label notLong, notDouble; + __ z_cghi(flags, ltos); + __ z_brne(notLong); + // ltos + __ z_lg(Z_tos, field); + __ push(ltos); + __ z_bru(Done); + + __ bind(notLong); + __ z_cghi(flags, dtos); + __ z_brne(notDouble); + // dtos + __ z_ld(Z_ftos, field); + __ push(dtos); + __ z_bru(Done); + + __ bind(notDouble); + break; + } + + default: + ShouldNotReachHere(); + } + + __ stop("bad ldc/condy"); +} + void TemplateTable::locals_index(Register reg, int offset) { __ z_llgc(reg, at_bcp(offset)); __ z_lcgr(reg);
--- a/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java Tue Feb 13 16:57:01 2018 +0100 +++ b/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java Tue Feb 13 17:38:03 2018 +0100 @@ -25,7 +25,7 @@ * @test * @bug 8186211 * @summary Test basic invocation of multiple ldc's of the same dynamic constant that fail resolution - * @requires os.arch == "x86_64" | os.arch=="aarch64" + * @requires os.arch != "sparcv9" * @library /lib/testlibrary/bytecode /java/lang/invoke/common * @build jdk.experimental.bytecode.BasicClassBuilder * @run testng CondyRepeatFailedResolution
--- a/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java Tue Feb 13 16:57:01 2018 +0100 +++ b/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java Tue Feb 13 17:38:03 2018 +0100 @@ -25,7 +25,7 @@ * @test * @bug 8186046 * @summary Test for condy BSMs returning primitive values or null - * @requires os.arch=="x86_64" | os.arch=="aarch64" + * @requires os.arch != "sparcv9" * @library /lib/testlibrary/bytecode * @build jdk.experimental.bytecode.BasicClassBuilder * @run testng CondyReturnPrimitiveTest
--- a/test/jdk/java/lang/invoke/condy/CondyWrongType.java Tue Feb 13 16:57:01 2018 +0100 +++ b/test/jdk/java/lang/invoke/condy/CondyWrongType.java Tue Feb 13 17:38:03 2018 +0100 @@ -25,7 +25,7 @@ * @test * @bug 8186046 * @summary Test bootstrap methods returning the wrong type - * @requires os.arch == "x86_64" | os.arch=="aarch64" + * @requires os.arch != "sparcv9" * @library /lib/testlibrary/bytecode /java/lang/invoke/common * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @run testng CondyWrongType