6964458: Reimplement class meta-data storage to use native memory

Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes

Co-authored-by: Stefan Karlsson <stefan.karlsson@oracle.com>
Co-authored-by: Mikael Gerdin <mikael.gerdin@oracle.com>
Co-authored-by: Tom Rodriguez <tom.rodriguez@oracle.com>
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
This commit is contained in:
Jon Masamitsu 2012-09-01 13:25:18 -04:00 committed by Coleen Phillimore
parent 36eee7c8c8
commit 5c58d27aac
853 changed files with 26124 additions and 82956 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -46,24 +46,24 @@
#define JAVA_1_5_VERSION 49
static void trace_class_resolution(klassOop to_class) {
static void trace_class_resolution(Klass* to_class) {
ResourceMark rm;
int line_number = -1;
const char * source_file = NULL;
klassOop caller = NULL;
Klass* caller = NULL;
JavaThread* jthread = JavaThread::current();
if (jthread->has_last_Java_frame()) {
vframeStream vfst(jthread);
// skip over any frames belonging to java.lang.Class
while (!vfst.at_end() &&
instanceKlass::cast(vfst.method()->method_holder())->name() == vmSymbols::java_lang_Class()) {
InstanceKlass::cast(vfst.method()->method_holder())->name() == vmSymbols::java_lang_Class()) {
vfst.next();
}
if (!vfst.at_end()) {
// this frame is a likely suspect
caller = vfst.method()->method_holder();
line_number = vfst.method()->line_number_from_bci(vfst.bci());
Symbol* s = instanceKlass::cast(vfst.method()->method_holder())->source_file_name();
Symbol* s = InstanceKlass::cast(vfst.method()->method_holder())->source_file_name();
if (s != NULL) {
source_file = s->as_C_string();
}
@ -254,7 +254,7 @@ void Reflection::array_set(jvalue* value, arrayOop a, int index, BasicType value
if (value_type == T_OBJECT) {
oop obj = (oop) value->l;
if (obj != NULL) {
klassOop element_klass = objArrayKlass::cast(a->klass())->element_klass();
Klass* element_klass = objArrayKlass::cast(a->klass())->element_klass();
if (!obj->is_a(element_klass)) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "array element type mismatch");
}
@ -301,7 +301,7 @@ void Reflection::array_set(jvalue* value, arrayOop a, int index, BasicType value
}
klassOop Reflection::basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS) {
Klass* Reflection::basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS) {
assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking");
BasicType type = java_lang_Class::primitive_type(basic_type_mirror);
if (type == T_VOID) {
@ -312,7 +312,7 @@ klassOop Reflection::basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAP
}
oop Reflection:: basic_type_arrayklass_to_mirror(klassOop basic_type_arrayklass, TRAPS) {
oop Reflection:: basic_type_arrayklass_to_mirror(Klass* basic_type_arrayklass, TRAPS) {
BasicType type = typeArrayKlass::cast(basic_type_arrayklass)->element_type();
return Universe::java_mirror(type);
}
@ -326,10 +326,10 @@ arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) {
THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
}
if (java_lang_Class::is_primitive(element_mirror)) {
klassOop tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
return typeArrayKlass::cast(tak)->allocate(length, THREAD);
} else {
klassOop k = java_lang_Class::as_klassOop(element_mirror);
Klass* k = java_lang_Class::as_Klass(element_mirror);
if (Klass::cast(k)->oop_is_array() && arrayKlass::cast(k)->dimension() >= MAX_DIM) {
THROW_0(vmSymbols::java_lang_IllegalArgumentException());
}
@ -360,12 +360,12 @@ arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop di
dimensions[i] = d;
}
klassOop klass;
Klass* klass;
int dim = len;
if (java_lang_Class::is_primitive(element_mirror)) {
klass = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
} else {
klass = java_lang_Class::as_klassOop(element_mirror);
klass = java_lang_Class::as_Klass(element_mirror);
if (Klass::cast(klass)->oop_is_array()) {
int k_dim = arrayKlass::cast(klass)->dimension();
if (k_dim + len > MAX_DIM) {
@ -386,7 +386,7 @@ oop Reflection::array_component_type(oop mirror, TRAPS) {
return NULL;
}
klassOop klass = java_lang_Class::as_klassOop(mirror);
Klass* klass = java_lang_Class::as_Klass(mirror);
if (!Klass::cast(klass)->oop_is_array()) {
return NULL;
}
@ -401,7 +401,7 @@ oop Reflection::array_component_type(oop mirror, TRAPS) {
result2 = Klass::cast(objArrayKlass::cast(klass)->element_klass())->java_mirror();
}
} else {
klassOop lower_dim = arrayKlass::cast(klass)->lower_dimension();
Klass* lower_dim = arrayKlass::cast(klass)->lower_dimension();
assert(Klass::cast(lower_dim)->oop_is_array(), "just checking");
result2 = Klass::cast(lower_dim)->java_mirror();
}
@ -411,7 +411,7 @@ oop Reflection::array_component_type(oop mirror, TRAPS) {
}
bool Reflection::reflect_check_access(klassOop field_class, AccessFlags acc, klassOop target_class, bool is_method_invoke, TRAPS) {
bool Reflection::reflect_check_access(Klass* field_class, AccessFlags acc, Klass* target_class, bool is_method_invoke, TRAPS) {
// field_class : declaring class
// acc : declared field access
// target_class : for protected
@ -424,7 +424,7 @@ bool Reflection::reflect_check_access(klassOop field_class, AccessFlags acc, kla
// that case (same as classic).
ResourceMark rm(THREAD);
assert(THREAD->is_Java_thread(), "sanity check");
klassOop client_class = ((JavaThread *)THREAD)->security_get_caller_class(is_method_invoke ? 0 : 1);
Klass* client_class = ((JavaThread *)THREAD)->security_get_caller_class(is_method_invoke ? 0 : 1);
if (client_class != field_class) {
if (!verify_class_access(client_class, field_class, false)
@ -454,13 +454,13 @@ bool Reflection::reflect_check_access(klassOop field_class, AccessFlags acc, kla
}
bool Reflection::verify_class_access(klassOop current_class, klassOop new_class, bool classloader_only) {
bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, bool classloader_only) {
// Verify that current_class can access new_class. If the classloader_only
// flag is set, we automatically allow any accesses in which current_class
// doesn't have a classloader.
if ((current_class == NULL) ||
(current_class == new_class) ||
(instanceKlass::cast(new_class)->is_public()) ||
(InstanceKlass::cast(new_class)->is_public()) ||
is_same_class_package(current_class, new_class)) {
return true;
}
@ -475,13 +475,13 @@ bool Reflection::verify_class_access(klassOop current_class, klassOop new_class,
return can_relax_access_check_for(current_class, new_class, classloader_only);
}
static bool under_host_klass(instanceKlass* ik, klassOop host_klass) {
static bool under_host_klass(InstanceKlass* ik, Klass* host_klass) {
DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000);
for (;;) {
klassOop hc = (klassOop) ik->host_klass();
Klass* hc = (Klass*) ik->host_klass();
if (hc == NULL) return false;
if (hc == host_klass) return true;
ik = instanceKlass::cast(hc);
ik = InstanceKlass::cast(hc);
// There's no way to make a host class loop short of patching memory.
// Therefore there cannot be a loop here unles there's another bug.
@ -491,9 +491,9 @@ static bool under_host_klass(instanceKlass* ik, klassOop host_klass) {
}
bool Reflection::can_relax_access_check_for(
klassOop accessor, klassOop accessee, bool classloader_only) {
instanceKlass* accessor_ik = instanceKlass::cast(accessor);
instanceKlass* accessee_ik = instanceKlass::cast(accessee);
Klass* accessor, Klass* accessee, bool classloader_only) {
InstanceKlass* accessor_ik = InstanceKlass::cast(accessor);
InstanceKlass* accessee_ik = InstanceKlass::cast(accessee);
// If either is on the other's host_klass chain, access is OK,
// because one is inside the other.
@ -513,9 +513,9 @@ bool Reflection::can_relax_access_check_for(
}
}
bool Reflection::verify_field_access(klassOop current_class,
klassOop resolved_class,
klassOop field_class,
bool Reflection::verify_field_access(Klass* current_class,
Klass* resolved_class,
Klass* field_class,
AccessFlags access,
bool classloader_only,
bool protected_restriction) {
@ -569,12 +569,12 @@ bool Reflection::verify_field_access(klassOop current_class,
}
bool Reflection::is_same_class_package(klassOop class1, klassOop class2) {
return instanceKlass::cast(class1)->is_same_class_package(class2);
bool Reflection::is_same_class_package(Klass* class1, Klass* class2) {
return InstanceKlass::cast(class1)->is_same_class_package(class2);
}
bool Reflection::is_same_package_member(klassOop class1, klassOop class2, TRAPS) {
return instanceKlass::cast(class1)->is_same_package_member(class2, THREAD);
bool Reflection::is_same_package_member(Klass* class1, Klass* class2, TRAPS) {
return InstanceKlass::cast(class1)->is_same_package_member(class2, THREAD);
}
@ -592,9 +592,9 @@ void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassH
int ooff = iter.outer_class_info_index();
if (inner_is_member && ioff != 0 && ooff != 0) {
klassOop o = cp->klass_at(ooff, CHECK);
Klass* o = cp->klass_at(ooff, CHECK);
if (o == outer()) {
klassOop i = cp->klass_at(ioff, CHECK);
Klass* i = cp->klass_at(ioff, CHECK);
if (i == inner()) {
return;
}
@ -602,7 +602,7 @@ void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassH
}
if (!inner_is_member && ioff != 0 && ooff == 0 &&
cp->klass_name_at_matches(inner, ioff)) {
klassOop i = cp->klass_at(ioff, CHECK);
Klass* i = cp->klass_at(ioff, CHECK);
if (i == inner()) {
return;
}
@ -630,9 +630,9 @@ oop get_mirror_from_signature(methodHandle method, SignatureStream* ss, TRAPS) {
case T_OBJECT:
case T_ARRAY:
Symbol* name = ss->as_symbol(CHECK_NULL);
oop loader = instanceKlass::cast(method->method_holder())->class_loader();
oop protection_domain = instanceKlass::cast(method->method_holder())->protection_domain();
klassOop k = SystemDictionary::resolve_or_fail(
oop loader = InstanceKlass::cast(method->method_holder())->class_loader();
oop protection_domain = InstanceKlass::cast(method->method_holder())->protection_domain();
Klass* k = SystemDictionary::resolve_or_fail(
name,
Handle(THREAD, loader),
Handle(THREAD, protection_domain),
@ -680,9 +680,9 @@ Handle Reflection::new_type(Symbol* signature, KlassHandle k, TRAPS) {
return Handle(THREAD, Universe::java_mirror(type));
}
oop loader = instanceKlass::cast(k())->class_loader();
oop loader = InstanceKlass::cast(k())->class_loader();
oop protection_domain = Klass::cast(k())->protection_domain();
klassOop result = SystemDictionary::resolve_or_fail(signature,
Klass* result = SystemDictionary::resolve_or_fail(signature,
Handle(THREAD, loader),
Handle(THREAD, protection_domain),
true, CHECK_(Handle()));
@ -748,13 +748,16 @@ oop Reflection::new_method(methodHandle method, bool intern_name, bool for_const
java_lang_reflect_Method::set_signature(mh(), sig());
}
if (java_lang_reflect_Method::has_annotations_field()) {
java_lang_reflect_Method::set_annotations(mh(), method->annotations());
typeArrayOop an_oop = Annotations::make_java_array(method->annotations(), CHECK_NULL);
java_lang_reflect_Method::set_annotations(mh(), an_oop);
}
if (java_lang_reflect_Method::has_parameter_annotations_field()) {
java_lang_reflect_Method::set_parameter_annotations(mh(), method->parameter_annotations());
typeArrayOop an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
java_lang_reflect_Method::set_parameter_annotations(mh(), an_oop);
}
if (java_lang_reflect_Method::has_annotation_default_field()) {
java_lang_reflect_Method::set_annotation_default(mh(), method->annotation_default());
typeArrayOop an_oop = Annotations::make_java_array(method->annotation_default(), CHECK_NULL);
java_lang_reflect_Method::set_annotation_default(mh(), an_oop);
}
return mh();
}
@ -791,10 +794,12 @@ oop Reflection::new_constructor(methodHandle method, TRAPS) {
java_lang_reflect_Constructor::set_signature(ch(), sig());
}
if (java_lang_reflect_Constructor::has_annotations_field()) {
java_lang_reflect_Constructor::set_annotations(ch(), method->annotations());
typeArrayOop an_oop = Annotations::make_java_array(method->annotations(), CHECK_NULL);
java_lang_reflect_Constructor::set_annotations(ch(), an_oop);
}
if (java_lang_reflect_Constructor::has_parameter_annotations_field()) {
java_lang_reflect_Constructor::set_parameter_annotations(ch(), method->parameter_annotations());
typeArrayOop an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
java_lang_reflect_Constructor::set_parameter_annotations(ch(), an_oop);
}
return ch();
}
@ -811,7 +816,7 @@ oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) {
name = java_lang_String::create_from_symbol(field_name, CHECK_NULL);
}
Symbol* signature = fd->signature();
KlassHandle holder (THREAD, fd->field_holder());
instanceKlassHandle holder (THREAD, fd->field_holder());
Handle type = new_type(signature, holder, CHECK_NULL);
Handle rh = java_lang_reflect_Field::create(CHECK_NULL);
@ -829,7 +834,8 @@ oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) {
java_lang_reflect_Field::set_signature(rh(), sig());
}
if (java_lang_reflect_Field::has_annotations_field()) {
java_lang_reflect_Field::set_annotations(rh(), fd->annotations());
typeArrayOop an_oop = Annotations::make_java_array(fd->annotations(), CHECK_NULL);
java_lang_reflect_Field::set_annotations(rh(), an_oop);
}
return rh();
}
@ -882,7 +888,7 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
method = reflected_method;
} else {
// resolve based on the receiver
if (instanceKlass::cast(reflected_method->method_holder())->is_interface()) {
if (InstanceKlass::cast(reflected_method->method_holder())->is_interface()) {
// resolve interface call
if (ReflectionWrapResolutionErrors) {
// new default: 6531596
@ -905,10 +911,10 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
// if the method can be overridden, we resolve using the vtable index.
int index = reflected_method->vtable_index();
method = reflected_method;
if (index != methodOopDesc::nonvirtual_vtable_index) {
if (index != Method::nonvirtual_vtable_index) {
// target_klass might be an arrayKlassOop but all vtables start at
// the same place. The cast is to avoid virtual call and assertion.
instanceKlass* inst = (instanceKlass*)target_klass()->klass_part();
InstanceKlass* inst = (InstanceKlass*)target_klass();
method = methodHandle(THREAD, inst->method_at_vtable(index));
}
if (!method.is_null()) {
@ -919,7 +925,7 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
ResourceMark rm(THREAD);
Handle h_origexception = Exceptions::new_exception(THREAD,
vmSymbols::java_lang_AbstractMethodError(),
methodOopDesc::name_and_sig_as_C_string(Klass::cast(target_klass()),
Method::name_and_sig_as_C_string(Klass::cast(target_klass()),
method->name(),
method->signature()));
JavaCallArguments args(h_origexception);
@ -929,7 +935,7 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
} else {
ResourceMark rm(THREAD);
THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(),
methodOopDesc::name_and_sig_as_C_string(Klass::cast(target_klass()),
Method::name_and_sig_as_C_string(Klass::cast(target_klass()),
method->name(),
method->signature()));
}
@ -944,7 +950,7 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
if (method.is_null()) {
ResourceMark rm(THREAD);
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(),
methodOopDesc::name_and_sig_as_C_string(Klass::cast(klass()),
Method::name_and_sig_as_C_string(Klass::cast(klass()),
reflected_method->name(),
reflected_method->signature()));
}
@ -1003,7 +1009,7 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
}
} else {
if (arg != NULL) {
klassOop k = java_lang_Class::as_klassOop(type_mirror);
Klass* k = java_lang_Class::as_Klass(type_mirror);
if (!arg->is_a(k)) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
}
@ -1079,8 +1085,8 @@ oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle
rtype = T_OBJECT;
}
instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(mirror));
methodOop m = klass->method_with_idnum(slot);
instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror));
Method* m = klass->method_with_idnum(slot);
if (m == NULL) {
THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
}
@ -1096,8 +1102,8 @@ oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args,
bool override = java_lang_reflect_Constructor::override(constructor_mirror) != 0;
objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(mirror));
methodOop m = klass->method_with_idnum(slot);
instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror));
Method* m = klass->method_with_idnum(slot);
if (m == NULL) {
THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
}