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

8245584: [lworld] LW3 core reflection update #53

Closed
wants to merge 5 commits 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
@@ -41,7 +41,7 @@ ciType* ciMethodType::class_to_citype(oop klass_oop) const {
ciType* ciMethodType::rtype(bool& never_null) const {
GUARDED_VM_ENTRY(
oop rtype = java_lang_invoke_MethodType::rtype(get_oop());
never_null = (java_lang_Class::inline_type_mirror(rtype) == rtype);
never_null = (java_lang_Class::as_Klass(rtype)->is_value());
return class_to_citype(rtype);
)
}
@@ -57,7 +57,7 @@ int ciMethodType::ptype_slot_count() const {
ciType* ciMethodType::ptype_at(int index, bool& never_null) const {
GUARDED_VM_ENTRY(
oop ptype = java_lang_invoke_MethodType::ptype(get_oop(), index);
never_null = (java_lang_Class::inline_type_mirror(ptype) == ptype);
never_null = (java_lang_Class::as_Klass(ptype)->is_value());
return class_to_citype(ptype);
)
}
@@ -957,23 +957,15 @@ void java_lang_Class::create_mirror(Klass* k, Handle class_loader,
Klass* element_klass = (Klass*) ValueArrayKlass::cast(k)->element_klass();
assert(element_klass->is_value(), "Must be value type component");
ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(element_klass));
comp_mirror = Handle(THREAD, vk->value_mirror());
comp_mirror = Handle(THREAD, vk->java_mirror());
} else if (k->is_typeArray_klass()) {
BasicType type = TypeArrayKlass::cast(k)->element_type();
comp_mirror = Handle(THREAD, Universe::java_mirror(type));
} else {
assert(k->is_objArray_klass(), "Must be");
Klass* element_klass = ObjArrayKlass::cast(k)->element_klass();
assert(element_klass != NULL, "Must have an element klass");
if (element_klass->is_value()) {
ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(element_klass));
assert(vk->java_mirror() == vk->value_mirror(), "primary mirror is the value mirror");
assert(vk->indirect_mirror() != NULL, "must have an indirect class mirror");
comp_mirror = k->name()->is_Q_array_signature() ? Handle(THREAD, vk->value_mirror())
: Handle(THREAD, vk->indirect_mirror());
} else {
comp_mirror = Handle(THREAD, element_klass->java_mirror());
}
comp_mirror = Handle(THREAD, element_klass->java_mirror());
}
assert(comp_mirror() != NULL, "must have a mirror");

@@ -1015,39 +1007,27 @@ void java_lang_Class::create_mirror(Klass* k, Handle class_loader,
}

if (k->is_value()) {
// create the secondary mirror for an inline class
oop indirect_mirror_oop = create_indirect_type_mirror(k, mirror, CHECK);
set_inline_type_mirror(mirror(), mirror());
set_indirect_type_mirror(mirror(), indirect_mirror_oop);
InstanceKlass* super = k->java_super();
set_val_type_mirror(mirror(), mirror());

// if the supertype is a restricted abstract class
if (super != SystemDictionary::Object_klass()) {
assert(super->access_flags().is_abstract(), "must be an abstract class");
oop ref_type_oop = super->java_mirror();
// set the reference projection type
set_ref_type_mirror(mirror(), ref_type_oop);

// set the value and reference projection types
set_val_type_mirror(ref_type_oop, mirror());
set_ref_type_mirror(ref_type_oop, ref_type_oop);
}
This conversation was marked as resolved by mlchung
Comment on lines +1013 to +1023

This comment has been minimized.

@fparain

fparain May 22, 2020
Collaborator

With this code, if the super type of the inline type is j.l.Object, Class:refType will remain null. I'm not sure that the VM code is ready to handle this situation. The only use case I've found is in LibraryCallKit::inline_value_Class_conversion(vmIntrinsics::ID id) and I'm not familiar with it (the compiler team might want to take a look at it).

This comment has been minimized.

@mlchung

mlchung May 22, 2020
Author Member

The current compiler implementation is left from LW2. It needs update for the new language model and I suspect it does not depend on the ref type.

Are you okay if I integrate this change now and follow up with the compiler team separately?

This comment has been minimized.

@TobiHartmann

TobiHartmann May 25, 2020
Member

LibraryCallKit::inline_value_Class_conversion() implements the C2 intrinsics for asIndirectType/asPrimaryType which you are removing anyway and is therefore not needed anymore. I have a patch ready that removes this and also removes all the other remaining LW2 dependencies from the compiler code (JDK-8245729). I would suggest that it should go in first.

This comment has been minimized.

@TobiHartmann

TobiHartmann May 26, 2020
Member

PR is ready:
#55

This comment has been minimized.

This comment has been minimized.

@mlchung

mlchung May 26, 2020
Author Member

Tobias, thanks. I now have updated the patch to take out the functions that are no longer needed by JIT.

}
} else {
assert(fixup_mirror_list() != NULL, "fixup_mirror_list not initialized");
fixup_mirror_list()->push(k);
}
}

// Create the secondary mirror for inline class. Sets all the fields of this java.lang.Class
// instance with the same value as the primary mirror
oop java_lang_Class::create_indirect_type_mirror(Klass* k, Handle mirror, TRAPS) {
assert(k->is_value(), "inline class");
// Allocate mirror (java.lang.Class instance)
oop mirror_oop = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
Handle indirect_mirror(THREAD, mirror_oop);

java_lang_Class::set_klass(indirect_mirror(), k);
java_lang_Class::set_static_oop_field_count(indirect_mirror(), static_oop_field_count(mirror()));
// ## do we need to set init lock?
java_lang_Class::set_init_lock(indirect_mirror(), init_lock(mirror()));

set_protection_domain(indirect_mirror(), protection_domain(mirror()));
set_class_loader(indirect_mirror(), class_loader(mirror()));
// ## handle if java.base is not yet defined
set_module(indirect_mirror(), module(mirror()));
set_inline_type_mirror(indirect_mirror(), mirror());
set_indirect_type_mirror(indirect_mirror(), indirect_mirror());
return indirect_mirror();
}

#if INCLUDE_CDS_JAVA_HEAP
// Clears mirror fields. Static final fields with initial values are reloaded
// from constant pool. The object identity hash is in the object header and is
@@ -1199,7 +1179,7 @@ oop java_lang_Class::archive_mirror(Klass* k, TRAPS) {
}

if (k->is_value()) {
// Values have a mirror and an indirect mirror. Don't handle this for now. TODO:CDS
// Values have a val type mirror and a ref type mirror. Don't handle this for now. TODO:CDS
k->set_java_mirror_handle(NULL);
return NULL;
}
@@ -1488,24 +1468,24 @@ void java_lang_Class::set_source_file(oop java_class, oop source_file) {
java_class->obj_field_put(_source_file_offset, source_file);
}

oop java_lang_Class::inline_type_mirror(oop java_class) {
assert(_inline_mirror_offset != 0, "must be set");
return java_class->obj_field(_inline_mirror_offset);
oop java_lang_Class::val_type_mirror(oop java_class) {
assert(_val_type_mirror_offset != 0, "must be set");
return java_class->obj_field(_val_type_mirror_offset);
}

void java_lang_Class::set_inline_type_mirror(oop java_class, oop mirror) {
assert(_inline_mirror_offset != 0, "must be set");
java_class->obj_field_put(_inline_mirror_offset, mirror);
void java_lang_Class::set_val_type_mirror(oop java_class, oop mirror) {
assert(_val_type_mirror_offset != 0, "must be set");
java_class->obj_field_put(_val_type_mirror_offset, mirror);
}

oop java_lang_Class::indirect_type_mirror(oop java_class) {
assert(_indirect_mirror_offset != 0, "must be set");
return java_class->obj_field(_indirect_mirror_offset);
oop java_lang_Class::ref_type_mirror(oop java_class) {
assert(_ref_type_mirror_offset != 0, "must be set");
return java_class->obj_field(_ref_type_mirror_offset);
}

void java_lang_Class::set_indirect_type_mirror(oop java_class, oop mirror) {
assert(_indirect_mirror_offset != 0, "must be set");
java_class->obj_field_put(_indirect_mirror_offset, mirror);
void java_lang_Class::set_ref_type_mirror(oop java_class, oop mirror) {
assert(_ref_type_mirror_offset != 0, "must be set");
java_class->obj_field_put(_ref_type_mirror_offset, mirror);
}

oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
@@ -1566,7 +1546,7 @@ void java_lang_Class::print_signature(oop java_class, outputStream* st) {
return;
}
if (is_instance) {
if (is_value && (java_class == inline_type_mirror(java_class))) {
if (is_value) {
st->print("Q");
} else {
st->print("L");
@@ -1592,14 +1572,7 @@ Symbol* java_lang_Class::as_signature(oop java_class, bool intern_if_not_found)
name->increment_refcount();
} else {
ResourceMark rm;
const char* sigstr;
if (k->is_value()) {
char c = (java_class == inline_type_mirror(java_class)) ?
JVM_SIGNATURE_VALUETYPE : JVM_SIGNATURE_CLASS;
sigstr = InstanceKlass::cast(k)->signature_name_of(c);
} else {
sigstr = k->signature_name();
}
const char* sigstr = k->signature_name();
int siglen = (int) strlen(sigstr);
if (!intern_if_not_found) {
name = SymbolTable::probe(sigstr, siglen);
@@ -1685,8 +1658,8 @@ int java_lang_Class::classRedefinedCount_offset = -1;
macro(_component_mirror_offset, k, "componentType", class_signature, false); \
macro(_module_offset, k, "module", module_signature, false); \
macro(_name_offset, k, "name", string_signature, false); \
macro(_inline_mirror_offset, k, "inlineType", class_signature, false); \
macro(_indirect_mirror_offset, k, "indirectType", class_signature, false); \
macro(_val_type_mirror_offset, k, "valType", class_signature, false); \
macro(_ref_type_mirror_offset, k, "refType", class_signature, false); \

void java_lang_Class::compute_offsets() {
if (offsets_computed) {
@@ -4351,8 +4324,8 @@ int java_lang_Class::_class_loader_offset;
int java_lang_Class::_module_offset;
int java_lang_Class::_protection_domain_offset;
int java_lang_Class::_component_mirror_offset;
int java_lang_Class::_inline_mirror_offset;
int java_lang_Class::_indirect_mirror_offset;
int java_lang_Class::_val_type_mirror_offset;
int java_lang_Class::_ref_type_mirror_offset;
int java_lang_Class::_init_lock_offset;
int java_lang_Class::_signers_offset;
int java_lang_Class::_name_offset;
@@ -264,8 +264,8 @@ class java_lang_Class : AllStatic {
static int _component_mirror_offset;
static int _name_offset;
static int _source_file_offset;
static int _inline_mirror_offset;
static int _indirect_mirror_offset;
static int _val_type_mirror_offset;
static int _ref_type_mirror_offset;

static bool offsets_computed;
static int classRedefinedCount_offset;
@@ -288,7 +288,6 @@ class java_lang_Class : AllStatic {
Handle protection_domain, TRAPS);
static void fixup_mirror(Klass* k, TRAPS);
static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
static oop create_indirect_type_mirror(Klass* k, Handle mirror, TRAPS);
static void update_archived_primitive_mirror_native_pointers(oop archived_mirror) NOT_CDS_JAVA_HEAP_RETURN;
static void update_archived_mirror_native_pointers(oop archived_mirror) NOT_CDS_JAVA_HEAP_RETURN;

@@ -324,7 +323,6 @@ class java_lang_Class : AllStatic {
// compiler support for class operations
static int klass_offset_in_bytes() { return _klass_offset; }
static int array_klass_offset_in_bytes() { return _array_klass_offset; }
static int inline_mirror_offset_in_bytes() { return _inline_mirror_offset; }
static int component_mirror_offset_in_bytes() { return _component_mirror_offset; }
// Support for classRedefinedCount field
static int classRedefinedCount(oop the_class_mirror);
@@ -341,14 +339,11 @@ class java_lang_Class : AllStatic {
static void set_module(oop java_class, oop module);
static oop module(oop java_class);

static void set_indirect_type_mirror(oop java_class, oop mirror);
static oop indirect_type_mirror(oop java_class);
static bool is_indirect_type(oop java_class) { // Must match "Class.isIndirectType()"
return indirect_type_mirror(java_class) == NULL || indirect_type_mirror(java_class) == java_class;
}
static void set_ref_type_mirror(oop java_class, oop mirror);
static oop ref_type_mirror(oop java_class);

static void set_inline_type_mirror(oop java_class, oop mirror);
static oop inline_type_mirror(oop java_class);
static void set_val_type_mirror(oop java_class, oop mirror);
static oop val_type_mirror(oop java_class);

static oop name(Handle java_class, TRAPS);

@@ -2754,10 +2754,6 @@ void InstanceKlass::set_source_debug_extension(const char* array, int length) {
}

const char* InstanceKlass::signature_name() const {
return signature_name_of(is_value() ? JVM_SIGNATURE_VALUETYPE : JVM_SIGNATURE_CLASS);
}

const char* InstanceKlass::signature_name_of(char c) const {
int hash_len = 0;
char hash_buf[40];

@@ -2776,7 +2772,7 @@ const char* InstanceKlass::signature_name_of(char c) const {

// Add L or Q as type indicator
int dest_index = 0;
dest[dest_index++] = c;
dest[dest_index++] = is_value() ? JVM_SIGNATURE_VALUETYPE : JVM_SIGNATURE_CLASS;

// Add the actual class name
for (int src_index = 0; src_index < src_length; ) {
@@ -1375,7 +1375,6 @@ class InstanceKlass: public Klass {

// Naming
const char* signature_name() const;
const char* signature_name_of(char c) const;

// Oop fields (and metadata) iterators
//
@@ -183,10 +183,6 @@ class ValueKlass: public InstanceKlass {
// Type testing
bool is_value_slow() const { return true; }

// value_mirror is the primary mirror
oop value_mirror() const { return java_lang_Class::inline_type_mirror(java_mirror()); }
oop indirect_mirror() const { return java_lang_Class::indirect_type_mirror(java_mirror()); }

// Casting from Klass*
static ValueKlass* cast(Klass* k);

@@ -301,7 +297,6 @@ class ValueKlass: public InstanceKlass {

void set_default_value(oop val) {
java_mirror()->obj_field_put(default_value_offset(), val);
indirect_mirror()->obj_field_put(default_value_offset(), val);
}

oop default_value();
@@ -583,15 +583,6 @@ JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jc
assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
jboolean ret = sub_klass->is_subtype_of(super_klass) ?
JNI_TRUE : JNI_FALSE;
if (sub_klass == super_klass && sub_klass->is_value()) {
// for inline class, V <: V?
ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(sub_klass));
if (sub_mirror == super_mirror || (sub_mirror == vk->value_mirror() && super_mirror == vk->indirect_mirror())) {
ret = JNI_TRUE;
} else {
ret = JNI_FALSE;
}
}
HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
return ret;
JNI_END
@@ -348,10 +348,10 @@ arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) {
if (k->is_array_klass() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
THROW_0(vmSymbols::java_lang_IllegalArgumentException());
}
if (java_lang_Class::is_indirect_type(element_mirror)) {
return oopFactory::new_objArray(k, length, THREAD);
} else {
if (k->is_value()) {
return oopFactory::new_valueArray(k, length, THREAD);
} else {
return oopFactory::new_objArray(k, length, THREAD);
}
}
}
@@ -1186,7 +1186,7 @@ oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle
BasicType rtype;
if (java_lang_Class::is_primitive(return_type_mirror)) {
rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL);
} else if (java_lang_Class::inline_type_mirror(return_type_mirror) == return_type_mirror) {
} else if (java_lang_Class::as_Klass(return_type_mirror)->is_value()) {
rtype = T_VALUETYPE;
} else {
rtype = T_OBJECT;
@@ -422,13 +422,7 @@ oop SignatureStream::as_java_mirror(Handle class_loader, Handle protection_domai
if (klass == NULL) {
return NULL;
}
if (klass->is_value()) {
ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(klass));
return _type == T_VALUETYPE ? vk->value_mirror() : vk->indirect_mirror();
} else {
assert(_type != T_VALUETYPE, "must not be value type");
return klass->java_mirror();
}
return klass->java_mirror();
}

void SignatureStream::skip_to_return_type() {