Skip to content
This repository has been archived by the owner on Aug 31, 2022. It is now read-only.
/ jdk11 Public archive

Commit

Permalink
8186209: Tool support for ConstantDynamic
Browse files Browse the repository at this point in the history
8186046: Minimal ConstantDynamic support
8190972: Ensure that AOT/Graal filters out class files containing CONSTANT_Dynamic ahead of full AOT support

Co-authored-by: Lois Foltan <lois.foltan@oracle.com>
Co-authored-by: John Rose <john.r.rose@oracle.com>
Reviewed-by: acorn, coleenp, kvn
  • Loading branch information
3 people committed Sep 8, 2017
1 parent 52d3bf2 commit e55a059
Show file tree
Hide file tree
Showing 114 changed files with 11,762 additions and 404 deletions.
2 changes: 2 additions & 0 deletions src/hotspot/cpu/x86/interp_masm_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,8 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(
// Add in the index
addptr(result, tmp);
load_heap_oop(result, Address(result, 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.
}

// load cpool->resolved_klass_at(index)
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/cpu/x86/macroAssembler_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,8 @@ void MacroAssembler::warn(const char* msg) {
andq(rsp, -16); // align stack as required by push_CPU_state and call
push_CPU_state(); // keeps alignment at 16 bytes
lea(c_rarg0, ExternalAddress((address) msg));
call_VM_leaf(CAST_FROM_FN_PTR(address, warning), c_rarg0);
lea(rax, ExternalAddress(CAST_FROM_FN_PTR(address, warning)));
call(rax);
pop_CPU_state();
mov(rsp, rbp);
pop(rbp);
Expand Down
173 changes: 151 additions & 22 deletions src/hotspot/cpu/x86/templateTable_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ void TemplateTable::sipush() {
void TemplateTable::ldc(bool wide) {
transition(vtos, vtos);
Register rarg = NOT_LP64(rcx) LP64_ONLY(c_rarg1);
Label call_ldc, notFloat, notClass, Done;
Label call_ldc, notFloat, notClass, notInt, Done;

if (wide) {
__ get_unsigned_2_byte_index_at_bcp(rbx, 1);
Expand Down Expand Up @@ -465,19 +465,18 @@ void TemplateTable::ldc(bool wide) {
__ jmp(Done);

__ bind(notFloat);
#ifdef ASSERT
{
Label L;
__ cmpl(rdx, JVM_CONSTANT_Integer);
__ jcc(Assembler::equal, L);
// String and Object are rewritten to fast_aldc
__ stop("unexpected tag type in ldc");
__ bind(L);
}
#endif
// itos JVM_CONSTANT_Integer only
__ cmpl(rdx, JVM_CONSTANT_Integer);
__ jccb(Assembler::notEqual, notInt);

// itos
__ movl(rax, Address(rcx, rbx, Address::times_ptr, base_offset));
__ push(itos);
__ jmp(Done);

// assume the tag is for condy; if not, the VM runtime will tell us
__ bind(notInt);
condy_helper(Done);

__ bind(Done);
}

Expand All @@ -487,6 +486,7 @@ void TemplateTable::fast_aldc(bool wide) {

Register result = rax;
Register tmp = rdx;
Register rarg = NOT_LP64(rcx) LP64_ONLY(c_rarg1);
int index_size = wide ? sizeof(u2) : sizeof(u1);

Label resolved;
Expand All @@ -496,51 +496,180 @@ void TemplateTable::fast_aldc(bool wide) {
assert_different_registers(result, tmp);
__ get_cache_index_at_bcp(tmp, 1, index_size);
__ load_resolved_reference_at_index(result, tmp);
__ testl(result, result);
__ testptr(result, result);
__ jcc(Assembler::notZero, resolved);

address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);

// first time invocation - must resolve first
__ movl(tmp, (int)bytecode());
__ call_VM(result, entry, tmp);

__ movl(rarg, (int)bytecode());
__ call_VM(result, entry, rarg);
__ bind(resolved);

{ // Check for the null sentinel.
// If we just called the VM, that already did the mapping for us,
// but it's harmless to retry.
Label notNull;
ExternalAddress null_sentinel((address)Universe::the_null_sentinel_addr());
__ movptr(tmp, null_sentinel);
__ cmpptr(tmp, result);
__ jccb(Assembler::notEqual, notNull);
__ xorptr(result, result); // NULL object reference
__ bind(notNull);
}

if (VerifyOops) {
__ verify_oop(result);
}
}

void TemplateTable::ldc2_w() {
transition(vtos, vtos);
Label Long, Done;
Label notDouble, notLong, Done;
__ get_unsigned_2_byte_index_at_bcp(rbx, 1);

__ get_cpool_and_tags(rcx, rax);
const int base_offset = ConstantPool::header_size() * wordSize;
const int tags_offset = Array<u1>::base_offset_in_bytes();

// get type
__ cmpb(Address(rax, rbx, Address::times_1, tags_offset),
JVM_CONSTANT_Double);
__ jccb(Assembler::notEqual, Long);
__ movzbl(rdx, Address(rax, rbx, Address::times_1, tags_offset));
__ cmpl(rdx, JVM_CONSTANT_Double);
__ jccb(Assembler::notEqual, notDouble);

// dtos
__ load_double(Address(rcx, rbx, Address::times_ptr, base_offset));
__ push(dtos);

__ jmpb(Done);
__ bind(Long);
__ jmp(Done);
__ bind(notDouble);
__ cmpl(rdx, JVM_CONSTANT_Long);
__ jccb(Assembler::notEqual, notLong);

// ltos
__ movptr(rax, Address(rcx, rbx, Address::times_ptr, base_offset + 0 * wordSize));
NOT_LP64(__ movptr(rdx, Address(rcx, rbx, Address::times_ptr, base_offset + 1 * wordSize)));
__ push(ltos);
__ jmp(Done);

__ bind(notLong);
condy_helper(Done);

__ bind(Done);
}

void TemplateTable::condy_helper(Label& Done) {
const Register obj = rax;
const Register off = rbx;
const Register flags = rcx;
const Register rarg = NOT_LP64(rcx) LP64_ONLY(c_rarg1);
__ movl(rarg, (int)bytecode());
call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), rarg);
#ifndef _LP64
// borrow rdi from locals
__ get_thread(rdi);
__ get_vm_result_2(flags, rdi);
__ restore_locals();
#else
__ get_vm_result_2(flags, r15_thread);
#endif
// VMr = obj = base address to find primitive value to push
// VMr2 = flags = (tos, off) using format of CPCE::_flags
__ movl(off, flags);
__ andl(off, ConstantPoolCacheEntry::field_index_mask);
const Address field(obj, off, Address::times_1, 0*wordSize);

// What sort of thing are we loading?
__ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
__ andl(flags, ConstantPoolCacheEntry::tos_state_mask);

switch (bytecode()) {
case Bytecodes::_ldc:
case Bytecodes::_ldc_w:
{
// tos in (itos, ftos, stos, btos, ctos, ztos)
Label notInt, notFloat, notShort, notByte, notChar, notBool;
__ cmpl(flags, itos);
__ jcc(Assembler::notEqual, notInt);
// itos
__ movl(rax, field);
__ push(itos);
__ jmp(Done);

__ bind(notInt);
__ cmpl(flags, ftos);
__ jcc(Assembler::notEqual, notFloat);
// ftos
__ load_float(field);
__ push(ftos);
__ jmp(Done);

__ bind(notFloat);
__ cmpl(flags, stos);
__ jcc(Assembler::notEqual, notShort);
// stos
__ load_signed_short(rax, field);
__ push(stos);
__ jmp(Done);

__ bind(notShort);
__ cmpl(flags, btos);
__ jcc(Assembler::notEqual, notByte);
// btos
__ load_signed_byte(rax, field);
__ push(btos);
__ jmp(Done);

__ bind(notByte);
__ cmpl(flags, ctos);
__ jcc(Assembler::notEqual, notChar);
// ctos
__ load_unsigned_short(rax, field);
__ push(ctos);
__ jmp(Done);

__ bind(notChar);
__ cmpl(flags, ztos);
__ jcc(Assembler::notEqual, notBool);
// ztos
__ load_signed_byte(rax, field);
__ push(ztos);
__ jmp(Done);

__ bind(notBool);
break;
}

case Bytecodes::_ldc2_w:
{
Label notLong, notDouble;
__ cmpl(flags, ltos);
__ jcc(Assembler::notEqual, notLong);
// ltos
__ movptr(rax, field);
NOT_LP64(__ movptr(rdx, field.plus_disp(4)));
__ push(ltos);
__ jmp(Done);

__ bind(notLong);
__ cmpl(flags, dtos);
__ jcc(Assembler::notEqual, notDouble);
// dtos
__ load_double(field);
__ push(dtos);
__ jmp(Done);

__ bind(notDouble);
break;
}

default:
ShouldNotReachHere();
}

__ stop("bad ldc/condy");
}

void TemplateTable::locals_index(Register reg, int offset) {
__ load_unsigned_byte(reg, at_bcp(offset));
__ negptr(reg);
Expand Down
14 changes: 12 additions & 2 deletions src/hotspot/share/c1/c1_GraphBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,8 @@ void GraphBuilder::ScopeData::incr_num_returns() {
void GraphBuilder::load_constant() {
ciConstant con = stream()->get_constant();
if (con.basic_type() == T_ILLEGAL) {
// FIXME: an unresolved Dynamic constant can get here,
// and that should not terminate the whole compilation.
BAILOUT("could not resolve a constant");
} else {
ValueType* t = illegalType;
Expand All @@ -893,11 +895,19 @@ void GraphBuilder::load_constant() {
ciObject* obj = con.as_object();
if (!obj->is_loaded()
|| (PatchALot && obj->klass() != ciEnv::current()->String_klass())) {
// A Class, MethodType, MethodHandle, or String.
// Unloaded condy nodes show up as T_ILLEGAL, above.
patch_state = copy_state_before();
t = new ObjectConstant(obj);
} else {
assert(obj->is_instance(), "must be java_mirror of klass");
t = new InstanceConstant(obj->as_instance());
// Might be a Class, MethodType, MethodHandle, or Dynamic constant
// result, which might turn out to be an array.
if (obj->is_null_object())
t = objectNull;
else if (obj->is_array())
t = new ArrayConstant(obj->as_array());
else
t = new InstanceConstant(obj->as_instance());
}
break;
}
Expand Down
29 changes: 28 additions & 1 deletion src/hotspot/share/ci/ciEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,34 @@ ciConstant ciEnv::get_constant_by_index_impl(const constantPoolHandle& cpool,
int index = pool_index;
if (cache_index >= 0) {
assert(index < 0, "only one kind of index at a time");
index = cpool->object_to_cp_index(cache_index);
oop obj = cpool->resolved_references()->obj_at(cache_index);
if (obj != NULL) {
if (obj == Universe::the_null_sentinel()) {
return ciConstant(T_OBJECT, get_object(NULL));
}
BasicType bt = T_OBJECT;
if (cpool->tag_at(index).is_dynamic_constant())
bt = FieldType::basic_type(cpool->uncached_signature_ref_at(index));
if (is_reference_type(bt)) {
} else {
// we have to unbox the primitive value
if (!is_java_primitive(bt)) return ciConstant();
jvalue value;
BasicType bt2 = java_lang_boxing_object::get_value(obj, &value);
assert(bt2 == bt, "");
switch (bt2) {
case T_DOUBLE: return ciConstant(value.d);
case T_FLOAT: return ciConstant(value.f);
case T_LONG: return ciConstant(value.j);
case T_INT: return ciConstant(bt2, value.i);
case T_SHORT: return ciConstant(bt2, value.s);
case T_BYTE: return ciConstant(bt2, value.b);
case T_CHAR: return ciConstant(bt2, value.c);
case T_BOOLEAN: return ciConstant(bt2, value.z);
default: return ciConstant();
}
}
ciObject* ciobj = get_object(obj);
if (ciobj->is_array()) {
return ciConstant(T_ARRAY, ciobj);
Expand All @@ -594,7 +620,6 @@ ciConstant ciEnv::get_constant_by_index_impl(const constantPoolHandle& cpool,
return ciConstant(T_OBJECT, ciobj);
}
}
index = cpool->object_to_cp_index(cache_index);
}
constantTag tag = cpool->tag_at(index);
if (tag.is_int()) {
Expand Down Expand Up @@ -650,6 +675,8 @@ ciConstant ciEnv::get_constant_by_index_impl(const constantPoolHandle& cpool,
ciSymbol* signature = get_symbol(cpool->method_handle_signature_ref_at(index));
ciObject* ciobj = get_unloaded_method_handle_constant(callee, name, signature, ref_kind);
return ciConstant(T_OBJECT, ciobj);
} else if (tag.is_dynamic_constant()) {
return ciConstant();
} else {
ShouldNotReachHere();
return ciConstant();
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/ci/ciReplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@ class CompileReplay : public StackObj {
case JVM_CONSTANT_Float:
case JVM_CONSTANT_MethodHandle:
case JVM_CONSTANT_MethodType:
case JVM_CONSTANT_Dynamic:
case JVM_CONSTANT_InvokeDynamic:
if (tag != cp->tag_at(i).value()) {
report_error("tag mismatch: wrong class files?");
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/ci/ciStreams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ ciConstant ciBytecodeStream::get_constant() {
// constant.
constantTag ciBytecodeStream::get_constant_pool_tag(int index) const {
VM_ENTRY_MARK;
return _method->get_Method()->constants()->tag_at(index);
BasicType bt = _method->get_Method()->constants()->basic_type_for_constant_at(index);
return constantTag::ofBasicType(bt);
}

// ------------------------------------------------------------------
Expand Down

0 comments on commit e55a059

Please sign in to comment.