Skip to content
Permalink
Browse files
8267428: Several features lack the EnableValhalla guard
  • Loading branch information
fparain committed May 19, 2021
1 parent c8d7c82 commit 13e7d4a35c6d27128f03bba724cf4c8d93dd68cd
Showing with 117 additions and 103 deletions.
  1. +99 −87 src/hotspot/cpu/x86/templateTable_x86.cpp
  2. +17 −15 src/hotspot/share/classfile/classFileParser.cpp
  3. +1 −1 src/hotspot/share/oops/instanceKlass.cpp
@@ -3011,76 +3011,82 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
} else {
if (is_static) {
__ load_heap_oop(rax, field);
Label is_inline_type, uninitialized;
// Issue below if the static field has not been initialized yet
__ test_field_is_inline_type(flags2, rscratch1, is_inline_type);
// field is not an inline type
__ push(atos);
__ jmp(Done);
// field is an inline type, must not return null even if uninitialized
__ bind(is_inline_type);
__ testptr(rax, rax);
__ jcc(Assembler::zero, uninitialized);
__ push(atos);
__ jmp(Done);
__ bind(uninitialized);
__ andl(flags2, ConstantPoolCacheEntry::field_index_mask);
#ifdef _LP64
Label slow_case, finish;
__ cmpb(Address(rcx, InstanceKlass::init_state_offset()), InstanceKlass::fully_initialized);
__ jcc(Assembler::notEqual, slow_case);
__ get_default_value_oop(rcx, off, rax);
__ jmp(finish);
__ bind(slow_case);
#endif // LP64
__ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::uninitialized_static_inline_type_field),
obj, flags2);
#ifdef _LP64
__ bind(finish);
#endif // _LP64
__ verify_oop(rax);
if (EnableValhalla) {
Label is_inline_type, uninitialized;
// Issue below if the static field has not been initialized yet
__ test_field_is_inline_type(flags2, rscratch1, is_inline_type);
// field is not an inline type
__ push(atos);
__ jmp(Done);
// field is an inline type, must not return null even if uninitialized
__ bind(is_inline_type);
__ testptr(rax, rax);
__ jcc(Assembler::zero, uninitialized);
__ push(atos);
__ jmp(Done);
__ bind(uninitialized);
__ andl(flags2, ConstantPoolCacheEntry::field_index_mask);
#ifdef _LP64
Label slow_case, finish;
__ cmpb(Address(rcx, InstanceKlass::init_state_offset()), InstanceKlass::fully_initialized);
__ jcc(Assembler::notEqual, slow_case);
__ get_default_value_oop(rcx, off, rax);
__ jmp(finish);
__ bind(slow_case);
#endif // LP64
__ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::uninitialized_static_inline_type_field),
obj, flags2);
#ifdef _LP64
__ bind(finish);
#endif // _LP64
}
__ verify_oop(rax);
__ push(atos);
__ jmp(Done);
} else {
Label is_inlined, nonnull, is_inline_type, rewrite_inline;
__ test_field_is_inline_type(flags2, rscratch1, is_inline_type);
// field is not an inline type
pop_and_check_object(obj);
__ load_heap_oop(rax, field);
__ push(atos);
if (EnableValhalla) {
__ test_field_is_inline_type(flags2, rscratch1, is_inline_type);
}
// field is not an inline type
pop_and_check_object(obj);
__ load_heap_oop(rax, field);
__ push(atos);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_agetfield, bc, rbx);
}
__ jmp(Done);
if (EnableValhalla) {
__ bind(is_inline_type);
__ test_field_is_inlined(flags2, rscratch1, is_inlined);
// field is not inlined
__ movptr(rax, rcx); // small dance required to preserve the klass_holder somewhere
pop_and_check_object(obj);
__ push(rax);
__ load_heap_oop(rax, field);
__ pop(rcx);
__ testptr(rax, rax);
__ jcc(Assembler::notZero, nonnull);
__ andl(flags2, ConstantPoolCacheEntry::field_index_mask);
__ get_inline_type_field_klass(rcx, flags2, rbx);
__ get_default_value_oop(rbx, rcx, rax);
__ bind(nonnull);
__ verify_oop(rax);
__ push(atos);
__ jmp(rewrite_inline);
__ bind(is_inlined);
// field is inlined
__ andl(flags2, ConstantPoolCacheEntry::field_index_mask);
pop_and_check_object(rax);
__ read_inlined_field(rcx, flags2, rbx, rax);
__ verify_oop(rax);
__ push(atos);
__ bind(rewrite_inline);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_agetfield, bc, rbx);
patch_bytecode(Bytecodes::_fast_qgetfield, bc, rbx);
}
__ jmp(Done);
__ bind(is_inline_type);
__ test_field_is_inlined(flags2, rscratch1, is_inlined);
// field is not inlined
__ movptr(rax, rcx); // small dance required to preserve the klass_holder somewhere
pop_and_check_object(obj);
__ push(rax);
__ load_heap_oop(rax, field);
__ pop(rcx);
__ testptr(rax, rax);
__ jcc(Assembler::notZero, nonnull);
__ andl(flags2, ConstantPoolCacheEntry::field_index_mask);
__ get_inline_type_field_klass(rcx, flags2, rbx);
__ get_default_value_oop(rbx, rcx, rax);
__ bind(nonnull);
__ verify_oop(rax);
__ push(atos);
__ jmp(rewrite_inline);
__ bind(is_inlined);
// field is inlined
__ andl(flags2, ConstantPoolCacheEntry::field_index_mask);
pop_and_check_object(rax);
__ read_inlined_field(rcx, flags2, rbx, rax);
__ verify_oop(rax);
__ push(atos);
__ bind(rewrite_inline);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_qgetfield, bc, rbx);
}
__ jmp(Done);
}
}

@@ -3392,14 +3398,18 @@ void TemplateTable::putfield_or_static_helper(int byte_no, bool is_static, Rewri
__ pop(atos);
if (is_static) {
Label is_inline_type;
__ test_field_is_not_inline_type(flags2, rscratch1, is_inline_type);
__ null_check(rax);
__ bind(is_inline_type);
if (EnableValhalla) {
__ test_field_is_not_inline_type(flags2, rscratch1, is_inline_type);
__ null_check(rax);
__ bind(is_inline_type);
}
do_oop_store(_masm, field, rax);
__ jmp(Done);
} else {
Label is_inline_type, is_inlined, rewrite_not_inline, rewrite_inline;
__ test_field_is_inline_type(flags2, rscratch1, is_inline_type);
if (EnableValhalla) {
__ test_field_is_inline_type(flags2, rscratch1, is_inline_type);
}
// Not an inline type
pop_and_check_object(obj);
// Store into the field
@@ -3409,28 +3419,30 @@ void TemplateTable::putfield_or_static_helper(int byte_no, bool is_static, Rewri
patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no);
}
__ jmp(Done);
// Implementation of the inline type semantic
__ bind(is_inline_type);
__ null_check(rax);
__ test_field_is_inlined(flags2, rscratch1, is_inlined);
// field is not inlined
pop_and_check_object(obj);
// Store into the field
do_oop_store(_masm, field, rax);
__ jmp(rewrite_inline);
__ bind(is_inlined);
// field is inlined
pop_and_check_object(obj);
assert_different_registers(rax, rdx, obj, off);
__ load_klass(rdx, rax, rscratch1);
__ data_for_oop(rax, rax, rdx);
__ addptr(obj, off);
__ access_value_copy(IN_HEAP, rax, obj, rdx);
__ bind(rewrite_inline);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_qputfield, bc, rbx, true, byte_no);
if (EnableValhalla) {
// Implementation of the inline type semantic
__ bind(is_inline_type);
__ null_check(rax);
__ test_field_is_inlined(flags2, rscratch1, is_inlined);
// field is not inlined
pop_and_check_object(obj);
// Store into the field
do_oop_store(_masm, field, rax);
__ jmp(rewrite_inline);
__ bind(is_inlined);
// field is inlined
pop_and_check_object(obj);
assert_different_registers(rax, rdx, obj, off);
__ load_klass(rdx, rax, rscratch1);
__ data_for_oop(rax, rax, rdx);
__ addptr(obj, off);
__ access_value_copy(IN_HEAP, rax, obj, rdx);
__ bind(rewrite_inline);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_qputfield, bc, rbx, true, byte_no);
}
__ jmp(Done);
}
__ jmp(Done);
}
}
}
@@ -6624,7 +6624,7 @@ void ClassFileParser::post_process_parsed_stream(const ClassFileStream* const st
set_invalid_inline_super();
}

if (!is_inline_type() && invalid_inline_super() && (_super_klass == NULL || !_super_klass->invalid_inline_super())
if (EnableValhalla && !is_inline_type() && invalid_inline_super() && (_super_klass == NULL || !_super_klass->invalid_inline_super())
&& !_implements_identityObject && class_name() != vmSymbols::java_lang_IdentityObject()) {
_temp_local_interfaces->append(vmClasses::IdentityObject_klass());
_has_injected_identityObject = true;
@@ -6691,20 +6691,22 @@ void ClassFileParser::post_process_parsed_stream(const ClassFileStream* const st
assert(_parsed_annotations != NULL, "invariant");


for (AllFieldStream fs(_fields, cp); !fs.done(); fs.next()) {
if (Signature::basic_type(fs.signature()) == T_INLINE_TYPE && !fs.access_flags().is_static()) {
// Pre-load inline class
Klass* klass = SystemDictionary::resolve_inline_type_field_or_fail(&fs,
Handle(THREAD, _loader_data->class_loader()),
_protection_domain, true, CHECK);
assert(klass != NULL, "Sanity check");
if (!klass->access_flags().is_inline_type()) {
assert(klass->is_instance_klass(), "Sanity check");
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(),
err_msg("Class %s expects class %s to be an inline type, but it is not",
_class_name->as_C_string(),
InstanceKlass::cast(klass)->external_name()));
if (EnableValhalla) {
for (AllFieldStream fs(_fields, cp); !fs.done(); fs.next()) {
if (Signature::basic_type(fs.signature()) == T_INLINE_TYPE && !fs.access_flags().is_static()) {
// Pre-load inline class
Klass* klass = SystemDictionary::resolve_inline_type_field_or_fail(&fs,
Handle(THREAD, _loader_data->class_loader()),
_protection_domain, true, CHECK);
assert(klass != NULL, "Sanity check");
if (!klass->access_flags().is_inline_type()) {
assert(klass->is_instance_klass(), "Sanity check");
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(),
err_msg("Class %s expects class %s to be an inline type, but it is not",
_class_name->as_C_string(),
InstanceKlass::cast(klass)->external_name()));
}
}
}
}
@@ -996,7 +996,7 @@ bool InstanceKlass::link_class_impl(TRAPS) {

// Could it be possible to do the following processing only if the
// class uses inline types?
{
if (EnableValhalla) {
ResourceMark rm(THREAD);
for (int i = 0; i < methods()->length(); i++) {
Method* m = methods()->at(i);

0 comments on commit 13e7d4a

Please sign in to comment.