mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-15 12:55:07 +00:00
8196786: [PPC64+s390] ConstantDynamic support
Reviewed-by: psandoz, dsamersoff
This commit is contained in:
parent
4f8c5b6949
commit
eb3ec99500
@ -492,6 +492,8 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result
|
||||
// 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)
|
||||
|
||||
@ -314,7 +314,7 @@ void TemplateTable::ldc(bool wide) {
|
||||
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 @@ void TemplateTable::ldc(bool wide) {
|
||||
|
||||
__ 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 @@ void TemplateTable::fast_aldc(bool wide) {
|
||||
// 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::fast_aldc(bool wide) {
|
||||
|
||||
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 @@ void TemplateTable::ldc2_w() {
|
||||
__ 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);
|
||||
__ b(exit);
|
||||
|
||||
__ bind(Llong);
|
||||
__ bind(not_double);
|
||||
__ cmpdi(CCR0, Rtag, JVM_CONSTANT_Long);
|
||||
__ bne(CCR0, not_long);
|
||||
__ ldx(R17_tos, Rcpool, Rindex);
|
||||
__ push(ltos);
|
||||
__ b(exit);
|
||||
|
||||
__ bind(Lexit);
|
||||
__ 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.
|
||||
|
||||
@ -389,6 +389,8 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result
|
||||
#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)
|
||||
|
||||
@ -450,7 +450,7 @@ void TemplateTable::sipush() {
|
||||
|
||||
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 @@ void TemplateTable::ldc(bool wide) {
|
||||
__ 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 @@ void TemplateTable::fast_aldc(bool wide) {
|
||||
|
||||
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_brne(L_resolved);
|
||||
__ 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::fast_aldc(bool wide) {
|
||||
|
||||
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 @@ void TemplateTable::ldc2_w() {
|
||||
|
||||
// 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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user