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

Merge lworld #424

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

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_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();
}