< 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"
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 {
+ comp_mirror = Handle(THREAD, element_klass->java_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 (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 (CDSConfig::is_dumping_heap()) {
create_scratch_mirror(k, CHECK);
}
} else {
assert(fixup_mirror_list() != nullptr, "fixup_mirror_list not initialized");
//
// 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()) {
+ if ((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
}
if (name == nullptr) {
st->print("<null>");
return;
}
- if (is_instance) st->print("L");
+ if (is_instance) {
+ st->print("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) {
}
void java_lang_Class::release_set_array_klass(oop java_class, Klass* klass) {
assert(klass->is_klass() && klass->is_array_klass(), "should be array klass");
+ if (klass->is_flatArray_klass() || (klass->is_objArray_klass() && ObjArrayKlass::cast(klass)->is_null_free_array_klass())) {
+ // TODO 8336006 Ignore flat / null-free arrays
+ return;
+ }
java_class->release_metadata_field_put(_array_klass_offset, klass);
}
BasicType java_lang_Class::primitive_type(oop java_class) {
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 = m->access_flags().as_method_flags();
- if (m->is_object_initializer()) {
- flags |= java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR;
+ if (m->is_object_constructor()) {
+ flags |= java_lang_invoke_MemberName::MN_IS_OBJECT_CONSTRUCTOR;
} else {
// Note: Static initializers can be here. Record them as plain methods.
flags |= java_lang_invoke_MemberName::MN_IS_METHOD;
}
if (m->caller_sensitive()) {
int java_lang_reflect_Field::_clazz_offset;
int java_lang_reflect_Field::_name_offset;
int java_lang_reflect_Field::_type_offset;
int java_lang_reflect_Field::_slot_offset;
int java_lang_reflect_Field::_modifiers_offset;
- int java_lang_reflect_Field::_trusted_final_offset;
+ int java_lang_reflect_Field::_flags_offset;
int java_lang_reflect_Field::_signature_offset;
int java_lang_reflect_Field::_annotations_offset;
#define FIELD_FIELDS_DO(macro) \
macro(_clazz_offset, k, vmSymbols::clazz_name(), class_signature, false); \
macro(_name_offset, k, vmSymbols::name_name(), string_signature, false); \
macro(_type_offset, k, vmSymbols::type_name(), class_signature, false); \
macro(_slot_offset, k, vmSymbols::slot_name(), int_signature, false); \
macro(_modifiers_offset, k, vmSymbols::modifiers_name(), int_signature, false); \
- macro(_trusted_final_offset, k, vmSymbols::trusted_final_name(), bool_signature, false); \
+ macro(_flags_offset, k, vmSymbols::flags_name(), int_signature, false); \
macro(_signature_offset, k, vmSymbols::signature_name(), string_signature, false); \
macro(_annotations_offset, k, vmSymbols::annotations_name(), byte_array_signature, false);
void java_lang_reflect_Field::compute_offsets() {
InstanceKlass* k = vmClasses::reflect_Field_klass();
void java_lang_reflect_Field::set_modifiers(oop field, int value) {
field->int_field_put(_modifiers_offset, value);
}
- void java_lang_reflect_Field::set_trusted_final(oop field) {
- field->bool_field_put(_trusted_final_offset, true);
+ void java_lang_reflect_Field::set_flags(oop field, int value) {
+ field->int_field_put(_flags_offset, value);
}
void java_lang_reflect_Field::set_signature(oop field, oop value) {
field->obj_field_put(_signature_offset, value);
}
bool is_reference = ik->reference_type() != REF_NONE;
assert(!is_reference || ik->is_subclass_of(vmClasses::Reference_klass()), "sanity");
return is_reference;
}
- int java_lang_boxing_object::_value_offset;
- int java_lang_boxing_object::_long_value_offset;
+ int java_lang_boxing_object::_sub32bits_value_offset;
+ int java_lang_boxing_object::_32bits_value_offset;
+ int java_lang_boxing_object::_64bits_value_offset;
#define BOXING_FIELDS_DO(macro) \
- macro(_value_offset, integerKlass, "value", int_signature, false); \
- macro(_long_value_offset, longKlass, "value", long_signature, false);
+ macro(_sub32bits_value_offset, byteKlass, "value", byte_signature, false); \
+ macro(_32bits_value_offset, intKlass, "value", int_signature, false); \
+ macro(_64bits_value_offset, longKlass, "value", long_signature, false);
void java_lang_boxing_object::compute_offsets() {
- InstanceKlass* integerKlass = vmClasses::Integer_klass();
+ InstanceKlass* byteKlass = vmClasses::Byte_klass();
+ InstanceKlass* intKlass = vmClasses::Integer_klass();
InstanceKlass* longKlass = vmClasses::Long_klass();
BOXING_FIELDS_DO(FIELD_COMPUTE_OFFSET);
}
#if INCLUDE_CDS
oop java_lang_boxing_object::create(BasicType type, jvalue* value, TRAPS) {
oop box = initialize_and_allocate(type, CHECK_NULL);
if (box == nullptr) return nullptr;
switch (type) {
case T_BOOLEAN:
- box->bool_field_put(_value_offset, value->z);
+ box->bool_field_put(_sub32bits_value_offset, value->z);
break;
case T_CHAR:
- box->char_field_put(_value_offset, value->c);
+ box->char_field_put(_sub32bits_value_offset, value->c);
break;
case T_FLOAT:
- box->float_field_put(_value_offset, value->f);
+ box->float_field_put(_32bits_value_offset, value->f);
break;
case T_DOUBLE:
- box->double_field_put(_long_value_offset, value->d);
+ box->double_field_put(_64bits_value_offset, value->d);
break;
case T_BYTE:
- box->byte_field_put(_value_offset, value->b);
+ box->byte_field_put(_sub32bits_value_offset, value->b);
break;
case T_SHORT:
- box->short_field_put(_value_offset, value->s);
+ box->short_field_put(_sub32bits_value_offset, value->s);
break;
case T_INT:
- box->int_field_put(_value_offset, value->i);
+ box->int_field_put(_32bits_value_offset, value->i);
break;
case T_LONG:
- box->long_field_put(_long_value_offset, value->j);
+ box->long_field_put(_64bits_value_offset, value->j);
break;
default:
return nullptr;
}
return box;
BasicType java_lang_boxing_object::get_value(oop box, jvalue* value) {
BasicType type = vmClasses::box_klass_type(box->klass());
switch (type) {
case T_BOOLEAN:
- value->z = box->bool_field(_value_offset);
+ value->z = box->bool_field(_sub32bits_value_offset);
break;
case T_CHAR:
- value->c = box->char_field(_value_offset);
+ value->c = box->char_field(_sub32bits_value_offset);
break;
case T_FLOAT:
- value->f = box->float_field(_value_offset);
+ value->f = box->float_field(_32bits_value_offset);
break;
case T_DOUBLE:
- value->d = box->double_field(_long_value_offset);
+ value->d = box->double_field(_64bits_value_offset);
break;
case T_BYTE:
- value->b = box->byte_field(_value_offset);
+ value->b = box->byte_field(_sub32bits_value_offset);
break;
case T_SHORT:
- value->s = box->short_field(_value_offset);
+ value->s = box->short_field(_sub32bits_value_offset);
break;
case T_INT:
- value->i = box->int_field(_value_offset);
+ value->i = box->int_field(_32bits_value_offset);
break;
case T_LONG:
- value->j = box->long_field(_long_value_offset);
+ value->j = box->long_field(_64bits_value_offset);
break;
default:
return T_ILLEGAL;
} // end switch
return type;
BasicType java_lang_boxing_object::set_value(oop box, jvalue* value) {
BasicType type = vmClasses::box_klass_type(box->klass());
switch (type) {
case T_BOOLEAN:
- box->bool_field_put(_value_offset, value->z);
+ box->bool_field_put(_sub32bits_value_offset, value->z);
break;
case T_CHAR:
- box->char_field_put(_value_offset, value->c);
+ box->char_field_put(_sub32bits_value_offset, value->c);
break;
case T_FLOAT:
- box->float_field_put(_value_offset, value->f);
+ box->float_field_put(_32bits_value_offset, value->f);
break;
case T_DOUBLE:
- box->double_field_put(_long_value_offset, value->d);
+ box->double_field_put(_64bits_value_offset, value->d);
break;
case T_BYTE:
- box->byte_field_put(_value_offset, value->b);
+ box->byte_field_put(_sub32bits_value_offset, value->b);
break;
case T_SHORT:
- box->short_field_put(_value_offset, value->s);
+ box->short_field_put(_sub32bits_value_offset, value->s);
break;
case T_INT:
- box->int_field_put(_value_offset, value->i);
+ box->int_field_put(_32bits_value_offset, value->i);
break;
case T_LONG:
- box->long_field_put(_long_value_offset, value->j);
+ box->long_field_put(_64bits_value_offset, value->j);
break;
default:
return T_ILLEGAL;
} // end switch
return type;
void java_lang_invoke_MemberName::set_flags(oop mname, int flags) {
assert(is_instance(mname), "wrong type");
mname->int_field_put(_flags_offset, flags);
}
-
// Return vmtarget from ResolvedMethodName method field through indirection
Method* java_lang_invoke_MemberName::vmtarget(oop mname) {
assert(is_instance(mname), "wrong type");
oop method = mname->obj_field(_method_offset);
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);
}
void JavaClasses::check_offsets() {
bool valid = true;
- #define CHECK_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
- valid &= check_offset(klass_name, cpp_klass_name :: _##field_name ## _offset, #field_name, field_sig)
+ #define CHECK_SUB32BITS_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
+ valid &= check_offset(klass_name, cpp_klass_name :: _ ##sub32bits_ ## field_name ## _offset, #field_name, field_sig)
+
+ #define CHECK_32BITS_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
+ valid &= check_offset(klass_name, cpp_klass_name :: _##32bits_ ## field_name ## _offset, #field_name, field_sig)
+
+ #define CHECK_64BITS_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
+ valid &= check_offset(klass_name, cpp_klass_name :: _##64bits_ ## field_name ## _offset, #field_name, field_sig)
- #define CHECK_LONG_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
- valid &= check_offset(klass_name, cpp_klass_name :: _##long_ ## field_name ## _offset, #field_name, field_sig)
// Boxed primitive objects (java_lang_boxing_object)
- CHECK_OFFSET("java/lang/Boolean", java_lang_boxing_object, value, "Z");
- CHECK_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C");
- CHECK_OFFSET("java/lang/Float", java_lang_boxing_object, value, "F");
- CHECK_LONG_OFFSET("java/lang/Double", java_lang_boxing_object, value, "D");
- CHECK_OFFSET("java/lang/Byte", java_lang_boxing_object, value, "B");
- CHECK_OFFSET("java/lang/Short", java_lang_boxing_object, value, "S");
- CHECK_OFFSET("java/lang/Integer", java_lang_boxing_object, value, "I");
- CHECK_LONG_OFFSET("java/lang/Long", java_lang_boxing_object, value, "J");
+ CHECK_SUB32BITS_OFFSET("java/lang/Boolean", java_lang_boxing_object, value, "Z");
+ CHECK_SUB32BITS_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C");
+ CHECK_32BITS_OFFSET("java/lang/Float", java_lang_boxing_object, value, "F");
+ CHECK_64BITS_OFFSET("java/lang/Double", java_lang_boxing_object, value, "D");
+ CHECK_SUB32BITS_OFFSET("java/lang/Byte", java_lang_boxing_object, value, "B");
+ CHECK_SUB32BITS_OFFSET("java/lang/Short", java_lang_boxing_object, value, "S");
+ CHECK_32BITS_OFFSET("java/lang/Integer", java_lang_boxing_object, value, "I");
+ CHECK_64BITS_OFFSET("java/lang/Long", java_lang_boxing_object, value, "J");
if (!valid) vm_exit_during_initialization("Field offset verification failed");
}
#endif // PRODUCT
< prev index next >