Skip to content
Permalink
Browse files
Merge lworld
  • Loading branch information
David Simms committed May 25, 2021
2 parents 375479e + e150bd9 commit bca447bb2ff095ac72e82edec3a452c70e21b984
Showing 22 changed files with 679 additions and 168 deletions.
@@ -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_null_free_inline_type, uninitialized;
// Issue below if the static field has not been initialized yet
__ test_field_is_null_free_inline_type(flags2, rscratch1, is_null_free_inline_type);
// field is not a null free inline type
__ push(atos);
__ jmp(Done);
// field is a null free inline type, must not return null even if uninitialized
__ bind(is_null_free_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_null_free_inline_type, uninitialized;
// Issue below if the static field has not been initialized yet
__ test_field_is_null_free_inline_type(flags2, rscratch1, is_null_free_inline_type);
// field is not a null free inline type
__ push(atos);
__ jmp(Done);
// field is a null free inline type, must not return null even if uninitialized
__ bind(is_null_free_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_null_free_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_null_free_inline_type(flags2, rscratch1, is_inline_type);
}
// field is not a null free 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_null_free_inline_type(flags2, rscratch1, is_inline_type);
__ null_check(rax);
__ bind(is_inline_type);
if (EnableValhalla) {
__ test_field_is_not_null_free_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_null_free_inline_type(flags2, rscratch1, is_inline_type);
if (EnableValhalla) {
__ test_field_is_null_free_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()));
}
}
}
}
@@ -1112,6 +1112,7 @@ int ExceptionMessageBuilder::get_NPE_null_slot(int bci) {
case Bytecodes::_athrow:
case Bytecodes::_monitorenter:
case Bytecodes::_monitorexit:
case Bytecodes::_checkcast:
return 0;
case Bytecodes::_iaload:
case Bytecodes::_faload:
@@ -1434,6 +1435,11 @@ void ExceptionMessageBuilder::print_NPE_failed_action(outputStream *os, int bci)
print_method_name(os, _method, cp_index);
os->print("\"");
} break;
case Bytecodes::_checkcast: {
int cp_index = Bytes::get_Java_u2(code_base + pos);
ConstantPool* cp = _method->constants();
os->print("Cannot cast to null-free type \"%s\"", cp->klass_at_noresolve(cp_index)->as_C_string());
} break;

default:
assert(0, "We should have checked this bytecode in get_NPE_null_slot().");
@@ -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);
@@ -1216,7 +1216,7 @@ public TypeMirror getOriginalType(javax.lang.model.type.ErrorType errorType) {
errorType.getKind() == TypeKind.ERROR) {
return extraType2OriginalMap.computeIfAbsent(classType, tt ->
new ClassType(classType.getEnclosingType(), classType.typarams_field,
classType.tsym, classType.getMetadata(), classType.isReferenceProjection()) {
classType.tsym, classType.getMetadata(), classType.getFlavor()) {
@Override
public Type baseType() { return classType; }
@Override
@@ -52,6 +52,7 @@
import javax.tools.JavaFileObject;

import com.sun.tools.javac.code.Kinds.Kind;
import com.sun.tools.javac.code.Type.ClassType.Flavor;
import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.comp.Attr;
@@ -1343,7 +1344,7 @@ public ClassSymbol(long flags, Name name, Symbol owner) {
this(
flags,
name,
new ClassType(Type.noType, null, null),
new ClassType(Type.noType, null, null, TypeMetadata.EMPTY, Flavor.X_Typeof_X),
owner);
this.type.tsym = this;
}
@@ -1381,7 +1382,7 @@ public Type erasure(Types types) {
erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
List.nil(), this,
type.getMetadata(),
type.isReferenceProjection());
type.getFlavor());
return erasure_field;
}

@@ -1450,6 +1451,14 @@ public void complete() throws CompletionFailure {
flags_field |= (PUBLIC|STATIC);
this.type = new ErrorType(this, Type.noType);
throw ex;
} finally {
if (this.type != null && this.type.hasTag(CLASS)) {
ClassType ct = (ClassType) this.type;
ct.flavor = ct.flavor.metamorphose((this.flags_field & PRIMITIVE_CLASS) != 0);
if (this.erasure_field != null && this.erasure_field.hasTag(CLASS)) {
((ClassType) this.erasure_field).flavor = ct.flavor;
}
}
}
}

@@ -1627,6 +1636,7 @@ public void reset() {
classType.supertype_field = null;
classType.interfaces_field = null;
classType.all_interfaces_field = null;
classType.flavor = Flavor.X_Typeof_X;
}
clearAnnotationMetadata();
}

0 comments on commit bca447b

Please sign in to comment.