< prev index next > src/hotspot/share/classfile/javaClasses.cpp
Print this page
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/fieldInfo.hpp"
#include "oops/fieldStreams.inline.hpp"
+ #include "oops/flatArrayKlass.hpp"
+ #include "oops/inlineKlass.inline.hpp"
#include "oops/instanceKlass.inline.hpp"
- #include "oops/instanceMirrorKlass.hpp"
+ #include "oops/instanceMirrorKlass.inline.hpp"
#include "oops/klass.hpp"
#include "oops/klass.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
int java_lang_Class::_static_oop_field_count_offset;
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::_primary_mirror_offset;
+ int java_lang_Class::_secondary_mirror_offset;
int java_lang_Class::_signers_offset;
int java_lang_Class::_name_offset;
int java_lang_Class::_source_file_offset;
int java_lang_Class::_classData_offset;
int java_lang_Class::_classRedefinedCount_offset;
set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror()));
// It might also have a component mirror. This mirror must already exist.
if (k->is_array_klass()) {
- if (k->is_typeArray_klass()) {
+ if (k->is_flatArray_klass()) {
+ Klass* element_klass = (Klass*) FlatArrayKlass::cast(k)->element_klass();
+ assert(element_klass->is_inline_klass(), "Must be inline type component");
+ if (is_scratch) {
+ comp_mirror = Handle(THREAD, HeapShared::scratch_java_mirror(element_klass));
+ } else {
+ InlineKlass* vk = InlineKlass::cast(element_klass);
+ comp_mirror = Handle(THREAD, vk->val_mirror());
+ }
+ } else if (k->is_typeArray_klass()) {
BasicType type = TypeArrayKlass::cast(k)->element_type();
if (is_scratch) {
comp_mirror = Handle(THREAD, HeapShared::scratch_java_mirror(type));
} else {
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 != nullptr, "Must have an element klass");
+ oop comp_oop = element_klass->java_mirror();
+ if (element_klass->is_inline_klass()) {
+ InlineKlass* ik = InlineKlass::cast(element_klass);
+ comp_oop = k->name()->is_Q_array_signature() ? ik->val_mirror() : ik->ref_mirror();
+ }
if (is_scratch) {
comp_mirror = Handle(THREAD, HeapShared::scratch_java_mirror(element_klass));
} else {
- comp_mirror = Handle(THREAD, element_klass->java_mirror());
+ comp_mirror = Handle(THREAD, comp_oop);
}
}
assert(comp_mirror() != nullptr, "must have a mirror");
// Two-way link between the array klass and its component mirror:
if (comp_mirror() != nullptr) {
// Set after k->java_mirror() is published, because compiled code running
// concurrently doesn't expect a k to have a null java_mirror.
release_set_array_klass(comp_mirror(), k);
}
+
+ if (k->is_inline_klass()) {
+ oop secondary_mirror = create_secondary_mirror(k, mirror, CHECK);
+ set_primary_mirror(mirror(), mirror());
+ set_secondary_mirror(mirror(), secondary_mirror);
+ }
if (DumpSharedSpaces) {
create_scratch_mirror(k, CHECK);
}
} else {
assert(fixup_mirror_list() != nullptr, "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_secondary_mirror(Klass* k, Handle mirror, TRAPS) {
+ assert(k->is_inline_klass(), "primitive class");
+ // Allocate mirror (java.lang.Class instance)
+ oop mirror_oop = InstanceMirrorKlass::cast(vmClasses::Class_klass())->allocate_instance(k, CHECK_0);
+ Handle secondary_mirror(THREAD, mirror_oop);
+
+ java_lang_Class::set_klass(secondary_mirror(), k);
+ java_lang_Class::set_static_oop_field_count(secondary_mirror(), static_oop_field_count(mirror()));
+
+ set_protection_domain(secondary_mirror(), protection_domain(mirror()));
+ set_class_loader(secondary_mirror(), class_loader(mirror()));
+ // ## handle if java.base is not yet defined
+ set_module(secondary_mirror(), module(mirror()));
+ set_primary_mirror(secondary_mirror(), mirror());
+ set_secondary_mirror(secondary_mirror(), secondary_mirror());
+ return secondary_mirror();
+ }
#if INCLUDE_CDS_JAVA_HEAP
// The "scratch mirror" stores the states of the mirror object that can be
// decided at dump time (such as the initial values of the static fields, the
// component mirror, etc). At runtime, more information is added to it by
//
// Note: we archive the "scratch mirror" instead of k->java_mirror(), because the
// latter may contain dumptime-specific information that cannot be archived
// (e.g., ClassLoaderData*, or static fields that are modified by Java code execution).
void java_lang_Class::create_scratch_mirror(Klass* k, TRAPS) {
- if (k->class_loader() != nullptr &&
- k->class_loader() != SystemDictionary::java_platform_loader() &&
- k->class_loader() != SystemDictionary::java_system_loader()) {
+ // Inline classes encapsulate two mirror objects, a value mirror (primitive value mirror)
+ // and a reference mirror (primitive class mirror), skip over scratch mirror allocation
+ // for inline classes, they will not be part of shared archive and will be created while
+ // restoring unshared fileds. Refer Klass::restore_unshareable_info() for more details.
+ if (k->is_inline_klass() ||
+ (k->class_loader() != nullptr &&
+ k->class_loader() != SystemDictionary::java_platform_loader() &&
+ k->class_loader() != SystemDictionary::java_system_loader())) {
// We only archive the mirrors of classes loaded by the built-in loaders
return;
}
Handle protection_domain, classData; // set to null. Will be reinitialized at runtime
oop java_lang_Class::component_mirror(oop java_class) {
assert(_component_mirror_offset != 0, "must be set");
return java_class->obj_field(_component_mirror_offset);
}
+ oop java_lang_Class::primary_mirror(oop java_class) {
+ assert(_primary_mirror_offset != 0, "must be set");
+ return java_class->obj_field(_primary_mirror_offset);
+ }
+
+ void java_lang_Class::set_primary_mirror(oop java_class, oop mirror) {
+ assert(_primary_mirror_offset != 0, "must be set");
+ java_class->obj_field_put(_primary_mirror_offset, mirror);
+ }
+
+ oop java_lang_Class::secondary_mirror(oop java_class) {
+ assert(_secondary_mirror_offset != 0, "must be set");
+ return java_class->obj_field(_secondary_mirror_offset);
+ }
+
+ void java_lang_Class::set_secondary_mirror(oop java_class, oop mirror) {
+ assert(_secondary_mirror_offset != 0, "must be set");
+ java_class->obj_field_put(_secondary_mirror_offset, mirror);
+ }
+
objArrayOop java_lang_Class::signers(oop java_class) {
assert(_signers_offset != 0, "must be set");
return (objArrayOop)java_class->obj_field(_signers_offset);
}
void java_lang_Class::set_signers(oop java_class, objArrayOop signers) {
void java_lang_Class::print_signature(oop java_class, outputStream* st) {
assert(is_instance(java_class), "must be a Class object");
Symbol* name = nullptr;
bool is_instance = false;
+ bool is_Q_descriptor = false;
if (is_primitive(java_class)) {
name = vmSymbols::type_signature(primitive_type(java_class));
} else {
Klass* k = as_Klass(java_class);
is_instance = k->is_instance_klass();
+ is_Q_descriptor = k->is_inline_klass() && is_secondary_mirror(java_class);
name = k->name();
}
if (name == nullptr) {
st->print("<null>");
return;
}
- if (is_instance) st->print("L");
+ if (is_instance) {
+ st->print(is_Q_descriptor ? "Q" : "L");
+ }
st->write((char*) name->base(), (int) name->utf8_length());
if (is_instance) st->print(";");
}
Symbol* java_lang_Class::as_signature(oop java_class, bool intern_if_not_found) {
if (!k->is_instance_klass()) {
name = k->name();
name->increment_refcount();
} else {
ResourceMark rm;
- const char* sigstr = k->signature_name();
- int siglen = (int) strlen(sigstr);
+ const char* sigstr;
+ if (k->is_inline_klass() && is_secondary_mirror(java_class)) {
+ sigstr = InlineKlass::cast(k)->val_signature_name();
+ } else {
+ sigstr = k->signature_name();
+ }
+ int siglen = (int) strlen(sigstr);
if (!intern_if_not_found) {
name = SymbolTable::probe(sigstr, siglen);
} else {
name = SymbolTable::new_symbol(sigstr, siglen);
}
#define CLASS_FIELDS_DO(macro) \
macro(_classRedefinedCount_offset, k, "classRedefinedCount", int_signature, false); \
macro(_class_loader_offset, k, "classLoader", classloader_signature, false); \
macro(_component_mirror_offset, k, "componentType", class_signature, false); \
+ macro(_primary_mirror_offset, k, "primaryType", class_signature, false); \
+ macro(_secondary_mirror_offset, k, "secondaryType", class_signature, false); \
macro(_module_offset, k, "module", module_signature, false); \
macro(_name_offset, k, "name", string_signature, false); \
macro(_classData_offset, k, "classData", object_signature, false);
void java_lang_Class::compute_offsets() {
if (!skip_throwableInit_check) {
assert(skip_fillInStackTrace_check, "logic error in backtrace filtering");
// skip <init> methods of the exception class and superclasses
// This is similar to classic VM.
- if (method->name() == vmSymbols::object_initializer_name() &&
+ if (method->is_object_constructor() &&
throwable->is_a(method->method_holder())) {
continue;
} else {
// there are none or we've seen them all - either way stop checking
skip_throwableInit_check = true;
}
#endif
static int get_flags(const methodHandle& m) {
int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS );
- if (m->is_initializer()) {
- flags |= java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR;
+ if (m->is_object_constructor()) {
+ flags |= java_lang_invoke_MemberName::MN_IS_OBJECT_CONSTRUCTOR;
} else {
flags |= java_lang_invoke_MemberName::MN_IS_METHOD;
}
if (m->caller_sensitive()) {
flags |= java_lang_invoke_MemberName::MN_CALLER_SENSITIVE;
return method == nullptr ? nullptr : java_lang_invoke_ResolvedMethodName::vmtarget(method);
}
bool java_lang_invoke_MemberName::is_method(oop mname) {
assert(is_instance(mname), "must be MemberName");
- return (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0;
+ return (flags(mname) & (MN_IS_METHOD | MN_IS_OBJECT_CONSTRUCTOR)) > 0;
}
void java_lang_invoke_MemberName::set_method(oop mname, oop resolved_method) {
assert(is_instance(mname), "wrong type");
mname->obj_field_put(_method_offset, resolved_method);
< prev index next >