Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8267428: Several features lack the EnableValhalla guard #417

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -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);