--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Aug 31 16:39:35 2012 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Sat Sep 01 13:25:18 2012 -0400
@@ -25,6 +25,8 @@
#include "precompiled.hpp"
#include "classfile/classFileParser.hpp"
#include "classfile/classLoader.hpp"
+#include "classfile/classLoaderData.hpp"
+#include "classfile/classLoaderData.inline.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
@@ -33,17 +35,18 @@
#include "classfile/vmSymbols.hpp"
#include "memory/allocation.hpp"
#include "memory/gcLocker.hpp"
+#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
#include "memory/universe.inline.hpp"
-#include "oops/constantPoolOop.hpp"
+#include "oops/constantPool.hpp"
#include "oops/fieldStreams.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/klass.inline.hpp"
-#include "oops/klassOop.hpp"
#include "oops/klassVtable.hpp"
-#include "oops/methodOop.hpp"
+#include "oops/method.hpp"
#include "oops/symbol.hpp"
+#include "prims/jvm.h"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/javaCalls.hpp"
@@ -53,6 +56,7 @@
#include "runtime/timer.hpp"
#include "services/classLoadingService.hpp"
#include "services/threadService.hpp"
+#include "utilities/array.hpp"
// We generally try to create the oops directly when parsing, rather than
// allocating temporary data structures and copying the bytes twice. A
@@ -81,7 +85,7 @@
#define JAVA_7_VERSION 51
-void ClassFileParser::parse_constant_pool_entries(Handle class_loader, constantPoolHandle cp, int length, TRAPS) {
+void ClassFileParser::parse_constant_pool_entries(ClassLoaderData* loader_data, constantPoolHandle cp, int length, TRAPS) {
// Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
// this function (_current can be allocated in a register, with scalar
// replacement of aggregates). The _current pointer is copied back to
@@ -94,6 +98,7 @@
assert(cfs->allocated_on_stack(),"should be local");
u1* old_current = cfs0->current();
#endif
+ Handle class_loader(THREAD, loader_data->class_loader());
// Used for batching symbol allocations.
const char* names[SymbolTable::symbol_alloc_batch_size];
@@ -272,7 +277,7 @@
indices[names_count] = index;
hashValues[names_count++] = hash;
if (names_count == SymbolTable::symbol_alloc_batch_size) {
- SymbolTable::new_symbols(class_loader, cp, names_count, names, lengths, indices, hashValues, CHECK);
+ SymbolTable::new_symbols(loader_data, cp, names_count, names, lengths, indices, hashValues, CHECK);
names_count = 0;
}
} else {
@@ -289,7 +294,7 @@
// Allocate the remaining symbols
if (names_count > 0) {
- SymbolTable::new_symbols(class_loader, cp, names_count, names, lengths, indices, hashValues, CHECK);
+ SymbolTable::new_symbols(loader_data, cp, names_count, names, lengths, indices, hashValues, CHECK);
}
// Copy _current pointer of local copy back to stream().
@@ -325,7 +330,7 @@
return NULL;
}
-constantPoolHandle ClassFileParser::parse_constant_pool(Handle class_loader, TRAPS) {
+constantPoolHandle ClassFileParser::parse_constant_pool(ClassLoaderData* loader_data, TRAPS) {
ClassFileStream* cfs = stream();
constantPoolHandle nullHandle;
@@ -334,17 +339,16 @@
guarantee_property(
length >= 1, "Illegal constant pool size %u in class file %s",
length, CHECK_(nullHandle));
- constantPoolOop constant_pool =
- oopFactory::new_constantPool(length,
- oopDesc::IsSafeConc,
+ ConstantPool* constant_pool =
+ ConstantPool::allocate(loader_data,
+ length,
CHECK_(nullHandle));
constantPoolHandle cp (THREAD, constant_pool);
- cp->set_partially_loaded(); // Enables heap verify to work on partial constantPoolOops
ConstantPoolCleaner cp_in_error(cp); // set constant pool to be cleaned up.
// parsing constant pool entries
- parse_constant_pool_entries(class_loader, cp, length, CHECK_(nullHandle));
+ parse_constant_pool_entries(loader_data, cp, length, CHECK_(nullHandle));
int index = 1; // declared outside of loops for portability
@@ -423,9 +427,6 @@
cp->unresolved_klass_at_put(index, cp->symbol_at(class_index));
}
break;
- case JVM_CONSTANT_UnresolvedString :
- ShouldNotReachHere(); // Only JVM_CONSTANT_StringIndex should be present
- break;
case JVM_CONSTANT_StringIndex :
{
int string_index = cp->string_index_at(index);
@@ -531,12 +532,6 @@
patch_constant_pool(cp, index, cp_patch_at(index), CHECK_(nullHandle));
}
}
- // Ensure that all the patches have been used.
- for (index = 0; index < _cp_patches->length(); index++) {
- guarantee_property(!has_cp_patch_at(index),
- "Unused constant pool patch at %d in class file %s",
- index, CHECK_(nullHandle));
- }
}
if (!_need_verify) {
@@ -671,6 +666,7 @@
void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) {
assert(EnableInvokeDynamic, "");
BasicType patch_type = T_VOID;
+
switch (cp->tag_at(index).value()) {
case JVM_CONSTANT_UnresolvedClass :
@@ -680,7 +676,7 @@
guarantee_property(!java_lang_Class::is_primitive(patch()),
"Illegal class patch at %d in class file %s",
index, CHECK);
- cp->klass_at_put(index, java_lang_Class::as_klassOop(patch()));
+ cp->klass_at_put(index, java_lang_Class::as_Klass(patch()));
} else {
guarantee_property(java_lang_String::is_instance(patch()),
"Illegal class patch at %d in class file %s",
@@ -690,15 +686,10 @@
}
break;
- case JVM_CONSTANT_UnresolvedString :
- // Patching a string means pre-resolving it.
- // The spelling in the constant pool is ignored.
- // The constant reference may be any object whatever.
- // If it is not a real interned string, the constant is referred
- // to as a "pseudo-string", and must be presented to the CP
- // explicitly, because it may require scavenging.
- cp->pseudo_string_at_put(index, patch());
- break;
+ case JVM_CONSTANT_String :
+ // skip this patch and don't clear it. Needs the oop array for resolved
+ // references to be created first.
+ return;
case JVM_CONSTANT_Integer : patch_type = T_INT; goto patch_prim;
case JVM_CONSTANT_Float : patch_type = T_FLOAT; goto patch_prim;
@@ -789,27 +780,26 @@
}
-objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
+Array<Klass*>* ClassFileParser::parse_interfaces(constantPoolHandle cp,
int length,
- Handle class_loader,
+ ClassLoaderData* loader_data,
Handle protection_domain,
Symbol* class_name,
TRAPS) {
ClassFileStream* cfs = stream();
assert(length > 0, "only called for length>0");
- objArrayHandle nullHandle;
- objArrayOop interface_oop = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
- objArrayHandle interfaces (THREAD, interface_oop);
+ // FIXME: Leak at later OOM.
+ Array<Klass*>* interfaces = MetadataFactory::new_array<Klass*>(loader_data, length, NULL, CHECK_NULL);
int index;
for (index = 0; index < length; index++) {
- u2 interface_index = cfs->get_u2(CHECK_(nullHandle));
+ u2 interface_index = cfs->get_u2(CHECK_NULL);
KlassHandle interf;
check_property(
valid_cp_range(interface_index, cp->length()) &&
is_klass_reference(cp, interface_index),
"Interface name has bad constant pool index %u in class file %s",
- interface_index, CHECK_(nullHandle));
+ interface_index, CHECK_NULL);
if (cp->tag_at(interface_index).is_klass()) {
interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index));
} else {
@@ -818,12 +808,13 @@
// Don't need to check legal name because it's checked when parsing constant pool.
// But need to make sure it's not an array type.
guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
- "Bad interface name in class file %s", CHECK_(nullHandle));
+ "Bad interface name in class file %s", CHECK_NULL);
+ Handle class_loader(THREAD, loader_data->class_loader());
// Call resolve_super so classcircularity is checked
- klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
+ Klass* k = SystemDictionary::resolve_super_or_fail(class_name,
unresolved_klass, class_loader, protection_domain,
- false, CHECK_(nullHandle));
+ false, CHECK_NULL);
interf = KlassHandle(THREAD, k);
if (LinkWellKnownClasses) // my super type is well known to me
@@ -831,9 +822,9 @@
}
if (!Klass::cast(interf())->is_interface()) {
- THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", nullHandle);
+ THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", NULL);
}
- interfaces->obj_at_put(index, interf());
+ interfaces->at_put(index, interf());
}
if (!_need_verify || length <= 1) {
@@ -849,8 +840,8 @@
{
debug_only(No_Safepoint_Verifier nsv;)
for (index = 0; index < length; index++) {
- klassOop k = (klassOop)interfaces->obj_at(index);
- Symbol* name = instanceKlass::cast(k)->name();
+ Klass* k = interfaces->at(index);
+ Symbol* name = InstanceKlass::cast(k)->name();
// If no duplicates, add (name, NULL) in hashtable interface_names.
if (!put_after_lookup(name, NULL, interface_names)) {
dup = true;
@@ -859,8 +850,7 @@
}
}
if (dup) {
- classfile_parse_error("Duplicate interface name in class file %s",
- CHECK_(nullHandle));
+ classfile_parse_error("Duplicate interface name in class file %s", CHECK_NULL);
}
return interfaces;
@@ -890,7 +880,7 @@
break;
case T_OBJECT:
guarantee_property((cp->symbol_at(signature_index)->equals("Ljava/lang/String;")
- && (value_type.is_string() || value_type.is_unresolved_string())),
+ && value_type.is_string()),
"Bad string initial value in class file %s", CHECK);
break;
default:
@@ -902,13 +892,14 @@
// Parse attributes for a field.
-void ClassFileParser::parse_field_attributes(constantPoolHandle cp,
+void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data,
+ constantPoolHandle cp,
u2 attributes_count,
bool is_static, u2 signature_index,
u2* constantvalue_index_addr,
bool* is_synthetic_addr,
u2* generic_signature_index_addr,
- typeArrayHandle* field_annotations,
+ AnnotationArray** field_annotations,
ClassFileParser::FieldAnnotationCollector* parsed_annotations,
TRAPS) {
ClassFileStream* cfs = stream();
@@ -985,7 +976,8 @@
*constantvalue_index_addr = constantvalue_index;
*is_synthetic_addr = is_synthetic;
*generic_signature_index_addr = generic_signature_index;
- *field_annotations = assemble_annotations(runtime_visible_annotations,
+ *field_annotations = assemble_annotations(loader_data,
+ runtime_visible_annotations,
runtime_visible_annotations_length,
runtime_invisible_annotations,
runtime_invisible_annotations_length,
@@ -1029,7 +1021,8 @@
BAD_ALLOCATION_TYPE, // T_VOID = 14,
BAD_ALLOCATION_TYPE, // T_ADDRESS = 15,
BAD_ALLOCATION_TYPE, // T_NARROWOOP= 16,
- BAD_ALLOCATION_TYPE, // T_CONFLICT = 17,
+ BAD_ALLOCATION_TYPE, // T_METADATA = 17,
+ BAD_ALLOCATION_TYPE, // T_CONFLICT = 18,
BAD_ALLOCATION_TYPE, // 0
BAD_ALLOCATION_TYPE, // 1
BAD_ALLOCATION_TYPE, // 2
@@ -1047,7 +1040,8 @@
BAD_ALLOCATION_TYPE, // T_VOID = 14,
BAD_ALLOCATION_TYPE, // T_ADDRESS = 15,
BAD_ALLOCATION_TYPE, // T_NARROWOOP= 16,
- BAD_ALLOCATION_TYPE, // T_CONFLICT = 17,
+ BAD_ALLOCATION_TYPE, // T_METADATA = 17,
+ BAD_ALLOCATION_TYPE, // T_CONFLICT = 18,
};
static FieldAllocationType basic_type_to_atype(bool is_static, BasicType type) {
@@ -1076,15 +1070,14 @@
}
};
-
-typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
+Array<u2>* ClassFileParser::parse_fields(ClassLoaderData* loader_data,
+ Symbol* class_name,
constantPoolHandle cp, bool is_interface,
FieldAllocationCount *fac,
- objArrayHandle* fields_annotations,
+ Array<AnnotationArray*>** fields_annotations,
u2* java_fields_count_ptr, TRAPS) {
ClassFileStream* cfs = stream();
- typeArrayHandle nullHandle;
- cfs->guarantee_more(2, CHECK_(nullHandle)); // length
+ cfs->guarantee_more(2, CHECK_NULL); // length
u2 length = cfs->get_u2_fast();
*java_fields_count_ptr = length;
@@ -1116,16 +1109,16 @@
u2* fa = NEW_RESOURCE_ARRAY_IN_THREAD(
THREAD, u2, total_fields * (FieldInfo::field_slots + 1));
- typeArrayHandle field_annotations;
+ AnnotationArray* field_annotations = NULL;
// The generic signature slots start after all other fields' data.
int generic_signature_slot = total_fields * FieldInfo::field_slots;
int num_generic_signature = 0;
for (int n = 0; n < length; n++) {
- cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count
+ cfs->guarantee_more(8, CHECK_NULL); // access_flags, name_index, descriptor_index, attributes_count
AccessFlags access_flags;
jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_FIELD_MODIFIERS;
- verify_legal_field_modifiers(flags, is_interface, CHECK_(nullHandle));
+ verify_legal_field_modifiers(flags, is_interface, CHECK_NULL);
access_flags.set_flags(flags);
u2 name_index = cfs->get_u2_fast();
@@ -1133,18 +1126,18 @@
check_property(
valid_cp_range(name_index, cp_size) && cp->tag_at(name_index).is_utf8(),
"Invalid constant pool index %u for field name in class file %s",
- name_index, CHECK_(nullHandle));
+ name_index, CHECK_NULL);
Symbol* name = cp->symbol_at(name_index);
- verify_legal_field_name(name, CHECK_(nullHandle));
+ verify_legal_field_name(name, CHECK_NULL);
u2 signature_index = cfs->get_u2_fast();
check_property(
valid_cp_range(signature_index, cp_size) &&
cp->tag_at(signature_index).is_utf8(),
"Invalid constant pool index %u for field signature in class file %s",
- signature_index, CHECK_(nullHandle));
+ signature_index, CHECK_NULL);
Symbol* sig = cp->symbol_at(signature_index);
- verify_legal_field_signature(name, sig, CHECK_(nullHandle));
+ verify_legal_field_signature(name, sig, CHECK_NULL);
u2 constantvalue_index = 0;
bool is_synthetic = false;
@@ -1154,17 +1147,19 @@
u2 attributes_count = cfs->get_u2_fast();
if (attributes_count > 0) {
- parse_field_attributes(cp, attributes_count, is_static, signature_index,
+ parse_field_attributes(loader_data,
+ cp, attributes_count, is_static, signature_index,
&constantvalue_index, &is_synthetic,
&generic_signature_index, &field_annotations,
&parsed_annotations,
- CHECK_(nullHandle));
- if (field_annotations.not_null()) {
- if (fields_annotations->is_null()) {
- objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
- *fields_annotations = objArrayHandle(THREAD, md);
+ CHECK_NULL);
+ if (field_annotations != NULL) {
+ if (*fields_annotations == NULL) {
+ *fields_annotations = MetadataFactory::new_array<AnnotationArray*>(
+ loader_data, length, NULL,
+ CHECK_NULL);
}
- (*fields_annotations)->obj_at_put(n, field_annotations());
+ (*fields_annotations)->at_put(n, field_annotations);
}
if (is_synthetic) {
access_flags.set_is_synthetic();
@@ -1244,20 +1239,19 @@
// the fields array could be too long. In that case the
// fields array is trimed. Also unused slots that were reserved
// for generic signature indexes are discarded.
- typeArrayOop new_fields = oopFactory::new_permanent_shortArray(
- index * FieldInfo::field_slots + num_generic_signature,
- CHECK_(nullHandle));
- typeArrayHandle fields(THREAD, new_fields);
+ Array<u2>* fields = MetadataFactory::new_array<u2>(
+ loader_data, index * FieldInfo::field_slots + num_generic_signature,
+ CHECK_NULL);
{
int i = 0;
for (; i < index * FieldInfo::field_slots; i++) {
- new_fields->short_at_put(i, fa[i]);
+ fields->at_put(i, fa[i]);
}
for (int j = total_fields * FieldInfo::field_slots;
j < generic_signature_slot; j++) {
- new_fields->short_at_put(i++, fa[j]);
+ fields->at_put(i++, fa[j]);
}
- assert(i == new_fields->length(), "");
+ assert(i == fields->length(), "");
}
if (_need_verify && length > 1) {
@@ -1281,7 +1275,7 @@
}
if (dup) {
classfile_parse_error("Duplicate field name&signature in class file %s",
- CHECK_(nullHandle));
+ CHECK_NULL);
}
}
@@ -1296,7 +1290,8 @@
}
-u2* ClassFileParser::parse_exception_table(u4 code_length,
+u2* ClassFileParser::parse_exception_table(ClassLoaderData* loader_data,
+ u4 code_length,
u4 exception_table_length,
constantPoolHandle cp,
TRAPS) {
@@ -1578,7 +1573,8 @@
*u2_index = i2;
}
-typeArrayOop ClassFileParser::parse_stackmap_table(
+Array<u1>* ClassFileParser::parse_stackmap_table(
+ ClassLoaderData* loader_data,
u4 code_attribute_length, TRAPS) {
if (code_attribute_length == 0)
return NULL;
@@ -1594,11 +1590,10 @@
return NULL;
}
- typeArrayOop stackmap_data =
- oopFactory::new_permanent_byteArray(code_attribute_length, CHECK_NULL);
-
- stackmap_data->set_length(code_attribute_length);
- memcpy((void*)stackmap_data->byte_at_addr(0),
+ Array<u1>* stackmap_data =
+ MetadataFactory::new_array<u1>(loader_data, code_attribute_length, 0, CHECK_NULL);
+
+ memcpy((void*)stackmap_data->adr_at(0),
(void*)stackmap_table_start, code_attribute_length);
return stackmap_data;
}
@@ -1813,18 +1808,20 @@
// Note: the parse_method below is big and clunky because all parsing of the code and exceptions
// attribute is inlined. This is cumbersome to avoid since we inline most of the parts in the
-// methodOop to save footprint, so we only know the size of the resulting methodOop when the
+// Method* to save footprint, so we only know the size of the resulting Method* when the
// entire method attribute is parsed.
//
// The promoted_flags parameter is used to pass relevant access_flags
// from the method back up to the containing klass. These flag values
// are added to klass's access_flags.
-methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interface,
+methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
+ constantPoolHandle cp,
+ bool is_interface,
AccessFlags *promoted_flags,
- typeArrayHandle* method_annotations,
- typeArrayHandle* method_parameter_annotations,
- typeArrayHandle* method_default_annotations,
+ AnnotationArray** method_annotations,
+ AnnotationArray** method_parameter_annotations,
+ AnnotationArray** method_default_annotations,
TRAPS) {
ClassFileStream* cfs = stream();
methodHandle nullHandle;
@@ -1882,7 +1879,7 @@
u1* code_start = 0;
u2 exception_table_length = 0;
u2* exception_table_start = NULL;
- typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
+ Array<int>* exception_handlers = Universe::the_empty_int_array();
u2 checked_exceptions_length = 0;
u2* checked_exceptions_start = NULL;
CompressedLineNumberWriteStream* linenumber_table = NULL;
@@ -1901,7 +1898,7 @@
bool parsed_checked_exceptions_attribute = false;
bool parsed_stackmap_attribute = false;
// stackmap attribute - JDK1.5
- typeArrayHandle stackmap_data;
+ Array<u1>* stackmap_data = NULL;
u2 generic_signature_index = 0;
MethodAnnotationCollector parsed_annotations;
u1* runtime_visible_annotations = NULL;
@@ -1970,7 +1967,7 @@
exception_table_length = cfs->get_u2_fast();
if (exception_table_length > 0) {
exception_table_start =
- parse_exception_table(code_length, exception_table_length, cp, CHECK_(nullHandle));
+ parse_exception_table(loader_data, code_length, exception_table_length, cp, CHECK_(nullHandle));
}
// Parse additional attributes in code attribute
@@ -2079,9 +2076,7 @@
if (parsed_stackmap_attribute) {
classfile_parse_error("Multiple StackMapTable attributes in class file %s", CHECK_(nullHandle));
}
- typeArrayOop sm =
- parse_stackmap_table(code_attribute_length, CHECK_(nullHandle));
- stackmap_data = typeArrayHandle(THREAD, sm);
+ stackmap_data = parse_stackmap_table(loader_data, code_attribute_length, CHECK_(nullHandle));
parsed_stackmap_attribute = true;
} else {
// Skip unknown attributes
@@ -2173,17 +2168,17 @@
"Absent Code attribute in method that is not native or abstract in class file %s", CHECK_(nullHandle));
}
- // All sizing information for a methodOop is finally available, now create it
- methodOop m_oop = oopFactory::new_method(code_length, access_flags,
+ // All sizing information for a Method* is finally available, now create it
+ Method* m = Method::allocate(loader_data,
+ code_length,
+ access_flags,
linenumber_table_length,
total_lvt_length,
exception_table_length,
checked_exceptions_length,
- oopDesc::IsSafeConc,
CHECK_(nullHandle));
- methodHandle m (THREAD, m_oop);
-
- ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize);
+
+ ClassLoadingService::add_class_method_size(m->size()*HeapWordSize);
// Fill in information from fixed part (access_flags already set)
m->set_constants(cp());
@@ -2212,14 +2207,7 @@
m->set_max_stack(max_stack);
m->set_max_locals(max_locals);
- /**
- * The stackmap_data field is the flag used to indicate
- * that the methodOop and it's associated constMethodOop are partially
- * initialized and thus are exempt from pre/post GC verification. Once
- * the field is set, the oops are considered fully initialized so make
- * sure that the oops can pass verification when this field is set.
- */
- m->constMethod()->set_stackmap_data(stackmap_data());
+ m->constMethod()->set_stackmap_data(stackmap_data);
// Copy byte codes
m->set_code(code_start);
@@ -2321,17 +2309,20 @@
if (parsed_annotations.has_any_annotations())
parsed_annotations.apply_to(m);
- *method_annotations = assemble_annotations(runtime_visible_annotations,
+ *method_annotations = assemble_annotations(loader_data,
+ runtime_visible_annotations,
runtime_visible_annotations_length,
runtime_invisible_annotations,
runtime_invisible_annotations_length,
CHECK_(nullHandle));
- *method_parameter_annotations = assemble_annotations(runtime_visible_parameter_annotations,
+ *method_parameter_annotations = assemble_annotations(loader_data,
+ runtime_visible_parameter_annotations,
runtime_visible_parameter_annotations_length,
runtime_invisible_parameter_annotations,
runtime_invisible_parameter_annotations_length,
CHECK_(nullHandle));
- *method_default_annotations = assemble_annotations(annotation_default,
+ *method_default_annotations = assemble_annotations(loader_data,
+ annotation_default,
annotation_default_length,
NULL,
0,
@@ -2359,61 +2350,56 @@
// from the methods back up to the containing klass. These flag values
// are added to klass's access_flags.
-objArrayHandle ClassFileParser::parse_methods(constantPoolHandle cp, bool is_interface,
+Array<Method*>* ClassFileParser::parse_methods(ClassLoaderData* loader_data,
+ constantPoolHandle cp,
+ bool is_interface,
AccessFlags* promoted_flags,
bool* has_final_method,
- objArrayOop* methods_annotations_oop,
- objArrayOop* methods_parameter_annotations_oop,
- objArrayOop* methods_default_annotations_oop,
+ Array<AnnotationArray*>** methods_annotations,
+ Array<AnnotationArray*>** methods_parameter_annotations,
+ Array<AnnotationArray*>** methods_default_annotations,
TRAPS) {
ClassFileStream* cfs = stream();
- objArrayHandle nullHandle;
- typeArrayHandle method_annotations;
- typeArrayHandle method_parameter_annotations;
- typeArrayHandle method_default_annotations;
- cfs->guarantee_more(2, CHECK_(nullHandle)); // length
+ AnnotationArray* method_annotations = NULL;
+ AnnotationArray* method_parameter_annotations = NULL;
+ AnnotationArray* method_default_annotations = NULL;
+ cfs->guarantee_more(2, CHECK_NULL); // length
u2 length = cfs->get_u2_fast();
if (length == 0) {
- return objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
+ return Universe::the_empty_method_array();
} else {
- objArrayOop m = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
- objArrayHandle methods(THREAD, m);
+ // FIXME: Handle leaks at later failures.
+ Array<Method*>* methods = MetadataFactory::new_array<Method*>(loader_data, length, NULL, CHECK_NULL);
+
HandleMark hm(THREAD);
- objArrayHandle methods_annotations;
- objArrayHandle methods_parameter_annotations;
- objArrayHandle methods_default_annotations;
for (int index = 0; index < length; index++) {
- methodHandle method = parse_method(cp, is_interface,
+ methodHandle method = parse_method(loader_data,
+ cp, is_interface,
promoted_flags,
&method_annotations,
&method_parameter_annotations,
&method_default_annotations,
- CHECK_(nullHandle));
+ CHECK_NULL);
+
if (method->is_final()) {
*has_final_method = true;
}
- methods->obj_at_put(index, method());
- if (method_annotations.not_null()) {
- if (methods_annotations.is_null()) {
- objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
- methods_annotations = objArrayHandle(THREAD, md);
- }
- methods_annotations->obj_at_put(index, method_annotations());
+ methods->at_put(index, method());
+ if (*methods_annotations == NULL) {
+ *methods_annotations =
+ MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
}
- if (method_parameter_annotations.not_null()) {
- if (methods_parameter_annotations.is_null()) {
- objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
- methods_parameter_annotations = objArrayHandle(THREAD, md);
- }
- methods_parameter_annotations->obj_at_put(index, method_parameter_annotations());
+ (*methods_annotations)->at_put(index, method_annotations);
+ if (*methods_parameter_annotations == NULL) {
+ *methods_parameter_annotations =
+ MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
}
- if (method_default_annotations.not_null()) {
- if (methods_default_annotations.is_null()) {
- objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
- methods_default_annotations = objArrayHandle(THREAD, md);
- }
- methods_default_annotations->obj_at_put(index, method_default_annotations());
+ (*methods_parameter_annotations)->at_put(index, method_parameter_annotations);
+ if (*methods_default_annotations == NULL) {
+ *methods_default_annotations =
+ MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
}
+ (*methods_default_annotations)->at_put(index, method_default_annotations);
}
if (_need_verify && length > 1) {
// Check duplicated methods
@@ -2425,7 +2411,7 @@
{
debug_only(No_Safepoint_Verifier nsv;)
for (int i = 0; i < length; i++) {
- methodOop m = (methodOop)methods->obj_at(i);
+ Method* m = methods->at(i);
// If no duplicates, add name/signature in hashtable names_and_sigs.
if (!put_after_lookup(m->name(), m->signature(), names_and_sigs)) {
dup = true;
@@ -2435,60 +2421,54 @@
}
if (dup) {
classfile_parse_error("Duplicate method name&signature in class file %s",
- CHECK_(nullHandle));
+ CHECK_NULL);
}
}
-
- *methods_annotations_oop = methods_annotations();
- *methods_parameter_annotations_oop = methods_parameter_annotations();
- *methods_default_annotations_oop = methods_default_annotations();
-
return methods;
}
}
-typeArrayHandle ClassFileParser::sort_methods(objArrayHandle methods,
- objArrayHandle methods_annotations,
- objArrayHandle methods_parameter_annotations,
- objArrayHandle methods_default_annotations,
+Array<int>* ClassFileParser::sort_methods(ClassLoaderData* loader_data,
+ Array<Method*>* methods,
+ Array<AnnotationArray*>* methods_annotations,
+ Array<AnnotationArray*>* methods_parameter_annotations,
+ Array<AnnotationArray*>* methods_default_annotations,
TRAPS) {
- typeArrayHandle nullHandle;
- int length = methods()->length();
+ int length = methods->length();
// If JVMTI original method ordering or sharing is enabled we have to
// remember the original class file ordering.
- // We temporarily use the vtable_index field in the methodOop to store the
+ // We temporarily use the vtable_index field in the Method* to store the
// class file index, so we can read in after calling qsort.
// Put the method ordering in the shared archive.
if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) {
for (int index = 0; index < length; index++) {
- methodOop m = methodOop(methods->obj_at(index));
+ Method* m = methods->at(index);
assert(!m->valid_vtable_index(), "vtable index should not be set");
m->set_vtable_index(index);
}
}
// Sort method array by ascending method name (for faster lookups & vtable construction)
// Note that the ordering is not alphabetical, see Symbol::fast_compare
- methodOopDesc::sort_methods(methods(),
- methods_annotations(),
- methods_parameter_annotations(),
- methods_default_annotations());
+ Method::sort_methods(methods,
+ methods_annotations,
+ methods_parameter_annotations,
+ methods_default_annotations);
// If JVMTI original method ordering or sharing is enabled construct int
// array remembering the original ordering
if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) {
- typeArrayOop new_ordering = oopFactory::new_permanent_intArray(length, CHECK_(nullHandle));
- typeArrayHandle method_ordering(THREAD, new_ordering);
+ Array<int>* method_ordering = MetadataFactory::new_array<int>(loader_data, length, CHECK_NULL);
for (int index = 0; index < length; index++) {
- methodOop m = methodOop(methods->obj_at(index));
+ Method* m = methods->at(index);
int old_index = m->vtable_index();
assert(old_index >= 0 && old_index < length, "invalid method index");
- method_ordering->int_at_put(index, old_index);
- m->set_vtable_index(methodOopDesc::invalid_vtable_index);
+ method_ordering->at_put(index, old_index);
+ m->set_vtable_index(Method::invalid_vtable_index);
}
return method_ordering;
} else {
- return typeArrayHandle(THREAD, Universe::the_empty_int_array());
+ return Universe::the_empty_int_array();
}
}
@@ -2532,7 +2512,8 @@
#define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC)
// Return number of classes in the inner classes attribute table
-u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
+u2 ClassFileParser::parse_classfile_inner_classes_attribute(ClassLoaderData* loader_data,
+ u1* inner_classes_attribute_start,
bool parsed_enclosingmethod_attribute,
u2 enclosing_method_class_index,
u2 enclosing_method_method_index,
@@ -2557,8 +2538,8 @@
// enclosing_method_class_index,
// enclosing_method_method_index]
int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0);
- typeArrayOop ic = oopFactory::new_permanent_shortArray(size, CHECK_0);
- typeArrayHandle inner_classes(THREAD, ic);
+ // FIXME: Will leak on exceptions.
+ Array<u2>* inner_classes = MetadataFactory::new_array<u2>(loader_data, size, CHECK_0);
int index = 0;
int cp_size = cp->length();
cfs->guarantee_more(8 * length, CHECK_0); // 4-tuples of u2
@@ -2600,20 +2581,20 @@
verify_legal_class_modifiers(flags, CHECK_0);
inner_access_flags.set_flags(flags);
- inner_classes->short_at_put(index++, inner_class_info_index);
- inner_classes->short_at_put(index++, outer_class_info_index);
- inner_classes->short_at_put(index++, inner_name_index);
- inner_classes->short_at_put(index++, inner_access_flags.as_short());
+ inner_classes->at_put(index++, inner_class_info_index);
+ inner_classes->at_put(index++, outer_class_info_index);
+ inner_classes->at_put(index++, inner_name_index);
+ inner_classes->at_put(index++, inner_access_flags.as_short());
}
// 4347400: make sure there's no duplicate entry in the classes array
if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
for(int i = 0; i < length * 4; i += 4) {
for(int j = i + 4; j < length * 4; j += 4) {
- guarantee_property((inner_classes->ushort_at(i) != inner_classes->ushort_at(j) ||
- inner_classes->ushort_at(i+1) != inner_classes->ushort_at(j+1) ||
- inner_classes->ushort_at(i+2) != inner_classes->ushort_at(j+2) ||
- inner_classes->ushort_at(i+3) != inner_classes->ushort_at(j+3)),
+ guarantee_property((inner_classes->at(i) != inner_classes->at(j) ||
+ inner_classes->at(i+1) != inner_classes->at(j+1) ||
+ inner_classes->at(i+2) != inner_classes->at(j+2) ||
+ inner_classes->at(i+3) != inner_classes->at(j+3)),
"Duplicate entry in InnerClasses in class file %s",
CHECK_0);
}
@@ -2622,12 +2603,12 @@
// Set EnclosingMethod class and method indexes.
if (parsed_enclosingmethod_attribute) {
- inner_classes->short_at_put(index++, enclosing_method_class_index);
- inner_classes->short_at_put(index++, enclosing_method_method_index);
+ inner_classes->at_put(index++, enclosing_method_class_index);
+ inner_classes->at_put(index++, enclosing_method_method_index);
}
assert(index == size, "wrong size");
- // Update instanceKlass with inner class info.
+ // Update InstanceKlass with inner class info.
set_class_inner_classes(inner_classes);
// Restore buffer's current position.
@@ -2651,7 +2632,8 @@
set_class_generic_signature(cp->symbol_at(signature_index));
}
-void ClassFileParser::parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp,
+void ClassFileParser::parse_classfile_bootstrap_methods_attribute(ClassLoaderData* loader_data,
+ constantPoolHandle cp,
u4 attribute_byte_length, TRAPS) {
ClassFileStream* cfs = stream();
u1* current_start = cfs->current();
@@ -2673,17 +2655,14 @@
// The array begins with a series of short[2] pairs, one for each tuple.
int index_size = (attribute_array_length * 2);
- typeArrayOop operands_oop = oopFactory::new_permanent_intArray(index_size + operand_count, CHECK);
- typeArrayHandle operands(THREAD, operands_oop);
- operands_oop = NULL; // tidy
+ Array<u2>* operands = MetadataFactory::new_array<u2>(loader_data, index_size + operand_count, CHECK);
int operand_fill_index = index_size;
int cp_size = cp->length();
for (int n = 0; n < attribute_array_length; n++) {
// Store a 32-bit offset into the header of the operand array.
- assert(constantPoolOopDesc::operand_offset_at(operands(), n) == 0, "");
- constantPoolOopDesc::operand_offset_at_put(operands(), n, operand_fill_index);
+ ConstantPool::operand_offset_at_put(operands, n, operand_fill_index);
// Read a bootstrap specifier.
cfs->guarantee_more(sizeof(u2) * 2, CHECK); // bsm, argc
@@ -2695,8 +2674,8 @@
"bootstrap_method_index %u has bad constant type in class file %s",
bootstrap_method_index,
CHECK);
- operands->short_at_put(operand_fill_index++, bootstrap_method_index);
- operands->short_at_put(operand_fill_index++, argument_count);
+ operands->at_put(operand_fill_index++, bootstrap_method_index);
+ operands->at_put(operand_fill_index++, argument_count);
cfs->guarantee_more(sizeof(u2) * argument_count, CHECK); // argv[argc]
for (int j = 0; j < argument_count; j++) {
@@ -2707,28 +2686,28 @@
"argument_index %u has bad constant type in class file %s",
argument_index,
CHECK);
- operands->short_at_put(operand_fill_index++, argument_index);
+ operands->at_put(operand_fill_index++, argument_index);
}
}
- assert(operand_fill_index == operands()->length(), "exact fill");
- assert(constantPoolOopDesc::operand_array_length(operands()) == attribute_array_length, "correct decode");
+ assert(operand_fill_index == operands->length(), "exact fill");
+ assert(ConstantPool::operand_array_length(operands) == attribute_array_length, "correct decode");
u1* current_end = cfs->current();
guarantee_property(current_end == current_start + attribute_byte_length,
"Bad length on BootstrapMethods in class file %s",
CHECK);
- cp->set_operands(operands());
+ cp->set_operands(operands);
}
-
-void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp,
+void ClassFileParser::parse_classfile_attributes(ClassLoaderData* loader_data,
+ constantPoolHandle cp,
ClassFileParser::ClassAnnotationCollector* parsed_annotations,
TRAPS) {
ClassFileStream* cfs = stream();
// Set inner classes attribute to default sentinel
- set_class_inner_classes(typeArrayHandle(THREAD, Universe::the_empty_short_array()));
+ set_class_inner_classes(Universe::the_empty_short_array());
cfs->guarantee_more(2, CHECK); // attributes_count
u2 attributes_count = cfs->get_u2_fast();
bool parsed_sourcefile_attribute = false;
@@ -2844,7 +2823,7 @@
if (parsed_bootstrap_methods_attribute)
classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
parsed_bootstrap_methods_attribute = true;
- parse_classfile_bootstrap_methods_attribute(cp, attribute_length, CHECK);
+ parse_classfile_bootstrap_methods_attribute(loader_data, cp, attribute_length, CHECK);
} else {
// Unknown attribute
cfs->skip_u1(attribute_length, CHECK);
@@ -2854,7 +2833,8 @@
cfs->skip_u1(attribute_length, CHECK);
}
}
- typeArrayHandle annotations = assemble_annotations(runtime_visible_annotations,
+ AnnotationArray* annotations = assemble_annotations(loader_data,
+ runtime_visible_annotations,
runtime_visible_annotations_length,
runtime_invisible_annotations,
runtime_invisible_annotations_length,
@@ -2863,6 +2843,7 @@
if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
u2 num_of_classes = parse_classfile_inner_classes_attribute(
+ loader_data,
inner_classes_attribute_start,
parsed_innerclasses_attribute,
enclosing_method_class_index,
@@ -2895,25 +2876,34 @@
if (_sde_buffer != NULL) {
k->set_source_debug_extension(_sde_buffer, _sde_length);
}
- k->set_inner_classes(_inner_classes());
- k->set_class_annotations(_annotations());
+ k->set_inner_classes(_inner_classes);
+ if (_annotations != NULL) {
+ k->annotations()->set_class_annotations(_annotations);
+ }
}
-typeArrayHandle ClassFileParser::assemble_annotations(u1* runtime_visible_annotations,
+AnnotationArray* ClassFileParser::assemble_annotations(ClassLoaderData* loader_data,
+ u1* runtime_visible_annotations,
int runtime_visible_annotations_length,
u1* runtime_invisible_annotations,
int runtime_invisible_annotations_length, TRAPS) {
- typeArrayHandle annotations;
+ AnnotationArray* annotations = NULL;
if (runtime_visible_annotations != NULL ||
runtime_invisible_annotations != NULL) {
- typeArrayOop anno = oopFactory::new_permanent_byteArray(runtime_visible_annotations_length +
- runtime_invisible_annotations_length, CHECK_(annotations));
- annotations = typeArrayHandle(THREAD, anno);
+ annotations = MetadataFactory::new_array<u1>(loader_data,
+ runtime_visible_annotations_length +
+ runtime_invisible_annotations_length,
+ CHECK_(annotations));
if (runtime_visible_annotations != NULL) {
- memcpy(annotations->byte_at_addr(0), runtime_visible_annotations, runtime_visible_annotations_length);
+ for (int i = 0; i < runtime_visible_annotations_length; i++) {
+ annotations->at_put(i, runtime_visible_annotations[i]);
+ }
}
if (runtime_invisible_annotations != NULL) {
- memcpy(annotations->byte_at_addr(runtime_visible_annotations_length), runtime_invisible_annotations, runtime_invisible_annotations_length);
+ for (int i = 0; i < runtime_invisible_annotations_length; i++) {
+ int append = runtime_visible_annotations_length+i;
+ annotations->at_put(append, runtime_invisible_annotations[i]);
+ }
}
}
return annotations;
@@ -2935,6 +2925,7 @@
// original class bytes.
unsigned char *cached_class_file_bytes = NULL;
jint cached_class_file_length;
+ ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
ClassFileStream* cfs = stream();
// Timing
@@ -3043,7 +3034,7 @@
_relax_verify = Verifier::relax_verify_for(class_loader());
// Constant pool
- constantPoolHandle cp = parse_constant_pool(class_loader, CHECK_(nullHandle));
+ constantPoolHandle cp = parse_constant_pool(loader_data, CHECK_(nullHandle));
ConstantPoolCleaner error_handler(cp); // set constant pool to be cleaned up.
int cp_size = cp->length();
@@ -3092,7 +3083,7 @@
CHECK_(nullHandle));
}
- klassOop preserve_this_klass; // for storing result across HandleMark
+ Klass* preserve_this_klass; // for storing result across HandleMark
// release all handles when parsing is done
{ HandleMark hm(THREAD);
@@ -3146,18 +3137,18 @@
// Interfaces
u2 itfs_len = cfs->get_u2_fast();
- objArrayHandle local_interfaces;
+ Array<Klass*>* local_interfaces;
if (itfs_len == 0) {
- local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
+ local_interfaces = Universe::the_empty_klass_array();
} else {
- local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, _class_name, CHECK_(nullHandle));
+ local_interfaces = parse_interfaces(cp, itfs_len, loader_data, protection_domain, _class_name, CHECK_(nullHandle));
}
u2 java_fields_count = 0;
// Fields (offsets are filled in later)
FieldAllocationCount fac;
- objArrayHandle fields_annotations;
- typeArrayHandle fields = parse_fields(class_name, cp, access_flags.is_interface(), &fac, &fields_annotations,
+ Array<AnnotationArray*>* fields_annotations = NULL;
+ Array<u2>* fields = parse_fields(loader_data, class_name, cp, access_flags.is_interface(), &fac, &fields_annotations,
&java_fields_count,
CHECK_(nullHandle));
// Methods
@@ -3166,24 +3157,21 @@
promoted_flags.set_flags(0);
// These need to be oop pointers because they are allocated lazily
// inside parse_methods inside a nested HandleMark
- objArrayOop methods_annotations_oop = NULL;
- objArrayOop methods_parameter_annotations_oop = NULL;
- objArrayOop methods_default_annotations_oop = NULL;
- objArrayHandle methods = parse_methods(cp, access_flags.is_interface(),
+ Array<AnnotationArray*>* methods_annotations = NULL;
+ Array<AnnotationArray*>* methods_parameter_annotations = NULL;
+ Array<AnnotationArray*>* methods_default_annotations = NULL;
+ Array<Method*>* methods = parse_methods(loader_data,
+ cp, access_flags.is_interface(),
&promoted_flags,
&has_final_method,
- &methods_annotations_oop,
- &methods_parameter_annotations_oop,
- &methods_default_annotations_oop,
+ &methods_annotations,
+ &methods_parameter_annotations,
+ &methods_default_annotations,
CHECK_(nullHandle));
- objArrayHandle methods_annotations(THREAD, methods_annotations_oop);
- objArrayHandle methods_parameter_annotations(THREAD, methods_parameter_annotations_oop);
- objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);
-
// Additional attributes
ClassAnnotationCollector parsed_annotations;
- parse_classfile_attributes(cp, &parsed_annotations, CHECK_(nullHandle));
+ parse_classfile_attributes(loader_data, cp, &parsed_annotations, CHECK_(nullHandle));
// Make sure this is the end of class file stream
guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
@@ -3198,7 +3186,7 @@
"Interfaces must have java.lang.Object as superclass in class file %s",
CHECK_(nullHandle));
}
- klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
+ Klass* k = SystemDictionary::resolve_super_or_fail(class_name,
sk,
class_loader,
protection_domain,
@@ -3229,10 +3217,11 @@
}
// Compute the transitive list of all unique interfaces implemented by this class
- objArrayHandle transitive_interfaces = compute_transitive_interfaces(super_klass, local_interfaces, CHECK_(nullHandle));
+ Array<Klass*>* transitive_interfaces = compute_transitive_interfaces(loader_data, super_klass, local_interfaces, CHECK_(nullHandle));
// sort methods
- typeArrayHandle method_ordering = sort_methods(methods,
+ Array<int>* method_ordering = sort_methods(loader_data,
+ methods,
methods_annotations,
methods_parameter_annotations,
methods_default_annotations,
@@ -3249,11 +3238,11 @@
klassVtable::compute_vtable_size_and_num_mirandas(vtable_size,
num_miranda_methods,
super_klass(),
- methods(),
+ methods,
access_flags,
class_loader,
class_name,
- local_interfaces(),
+ local_interfaces,
CHECK_(nullHandle));
// Size of Java itable (in words)
@@ -3597,13 +3586,26 @@
rt = super_klass->reference_type();
}
- // We can now create the basic klassOop for this klass
- klassOop ik = oopFactory::new_instanceKlass(name, vtable_size, itable_size,
+ // We can now create the basic Klass* for this klass
+ int total_oop_map_size2 =
+ InstanceKlass::nonstatic_oop_map_size(total_oop_map_count);
+
+ Klass* ik = InstanceKlass::allocate_instance_klass(loader_data,
+ vtable_size,
+ itable_size,
static_field_size,
- total_oop_map_count,
+ total_oop_map_size2,
+ rt,
access_flags,
- rt, host_klass,
+ name,
+ super_klass(),
+ host_klass,
CHECK_(nullHandle));
+
+ // Add all classes to our internal class loader list here,
+ // including classes in the bootstrap (NULL) class loader.
+ loader_data->add_class(ik);
+
instanceKlassHandle this_klass (THREAD, ik);
assert(this_klass->static_field_size() == static_field_size, "sanity");
@@ -3618,51 +3620,61 @@
assert(this_klass->size_helper() == instance_size, "correct size_helper");
// Not yet: supers are done below to support the new subtype-checking fields
//this_klass->set_super(super_klass());
- this_klass->set_class_loader(class_loader());
+ this_klass->set_class_loader_data(loader_data);
this_klass->set_nonstatic_field_size(nonstatic_field_size);
this_klass->set_has_nonstatic_fields(has_nonstatic_fields);
this_klass->set_static_oop_field_count(fac.count[STATIC_OOP]);
cp->set_pool_holder(this_klass());
error_handler.set_in_error(false); // turn off error handler for cp
this_klass->set_constants(cp());
- this_klass->set_local_interfaces(local_interfaces());
- this_klass->set_fields(fields(), java_fields_count);
- this_klass->set_methods(methods());
+ this_klass->set_local_interfaces(local_interfaces);
+ this_klass->set_fields(fields, java_fields_count);
+ this_klass->set_methods(methods);
if (has_final_method) {
this_klass->set_has_final_method();
}
- this_klass->set_method_ordering(method_ordering());
- // The instanceKlass::_methods_jmethod_ids cache and the
- // instanceKlass::_methods_cached_itable_indices cache are
+ this_klass->set_method_ordering(method_ordering);
+ // The InstanceKlass::_methods_jmethod_ids cache and the
+ // InstanceKlass::_methods_cached_itable_indices cache are
// both managed on the assumption that the initial cache
// size is equal to the number of methods in the class. If
- // that changes, then instanceKlass::idnum_can_increment()
+ // that changes, then InstanceKlass::idnum_can_increment()
// has to be changed accordingly.
this_klass->set_initial_method_idnum(methods->length());
this_klass->set_name(cp->klass_name_at(this_class_index));
if (LinkWellKnownClasses || is_anonymous()) // I am well known to myself
cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
- this_klass->set_protection_domain(protection_domain());
- this_klass->set_fields_annotations(fields_annotations());
- this_klass->set_methods_annotations(methods_annotations());
- this_klass->set_methods_parameter_annotations(methods_parameter_annotations());
- this_klass->set_methods_default_annotations(methods_default_annotations());
+
+ if (fields_annotations != NULL ||
+ methods_annotations != NULL ||
+ methods_parameter_annotations != NULL ||
+ methods_default_annotations != NULL) {
+ // Allocate an annotation type if needed.
+ Annotations* anno = Annotations::allocate(loader_data,
+ fields_annotations, methods_annotations,
+ methods_parameter_annotations,
+ methods_default_annotations, CHECK_(nullHandle));
+ this_klass->set_annotations(anno);
+ } else {
+ this_klass->set_annotations(NULL);
+ }
+
this_klass->set_minor_version(minor_version);
this_klass->set_major_version(major_version);
- // Set up methodOop::intrinsic_id as soon as we know the names of methods.
+ // Set up Method*::intrinsic_id as soon as we know the names of methods.
// (We used to do this lazily, but now we query it in Rewriter,
// which is eagerly done for every method, so we might as well do it now,
// when everything is fresh in memory.)
- if (methodOopDesc::klass_id_for_intrinsics(this_klass->as_klassOop()) != vmSymbols::NO_SID) {
+ if (Method::klass_id_for_intrinsics(this_klass()) != vmSymbols::NO_SID) {
for (int j = 0; j < methods->length(); j++) {
- ((methodOop)methods->obj_at(j))->init_intrinsic_id();
+ methods->at(j)->init_intrinsic_id();
}
}
if (cached_class_file_bytes != NULL) {
- // JVMTI: we have an instanceKlass now, tell it about the cached bytes
+ // JVMTI: we have an InstanceKlass now, tell it about the cached bytes
this_klass->set_cached_class_file(cached_class_file_bytes,
cached_class_file_length);
}
@@ -3677,13 +3689,18 @@
}
// Fill in field values obtained by parse_classfile_attributes
- if (parsed_annotations.has_any_annotations())
+ if (parsed_annotations.has_any_annotations()) {
parsed_annotations.apply_to(this_klass);
+ }
+ // Create annotations
+ if (_annotations != NULL && this_klass->annotations() == NULL) {
+ Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
+ this_klass->set_annotations(anno);
+ }
apply_parsed_class_attributes(this_klass);
- // VerifyOops believes that once this has been set, the object is completely loaded.
// Compute transitive closure of interfaces this class implements
- this_klass->set_transitive_interfaces(transitive_interfaces());
+ this_klass->set_transitive_interfaces(transitive_interfaces);
// Fill in information needed to compute superclasses.
this_klass->initialize_supers(super_klass(), CHECK_(nullHandle));
@@ -3718,7 +3735,18 @@
// Allocate mirror and initialize static fields
java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
- ClassLoadingService::notify_class_loaded(instanceKlass::cast(this_klass()),
+ // Allocate a simple java object for locking during class initialization.
+ // This needs to be a java object because it can be held across a java call.
+ typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
+ this_klass->set_init_lock(r);
+
+ // TODO: Move these oops to the mirror
+ this_klass->set_protection_domain(protection_domain());
+
+ // Update the loader_data graph.
+ record_defined_class_dependencies(this_klass, CHECK_NULL);
+
+ ClassLoadingService::notify_class_loaded(InstanceKlass::cast(this_klass()),
false /* not shared class */);
if (TraceClassLoading) {
@@ -3728,17 +3756,17 @@
cfs->source());
} else if (class_loader.is_null()) {
if (THREAD->is_Java_thread()) {
- klassOop caller = ((JavaThread*)THREAD)->security_get_caller_class(1);
+ Klass* caller = ((JavaThread*)THREAD)->security_get_caller_class(1);
tty->print("[Loaded %s by instance of %s]\n",
this_klass->external_name(),
- instanceKlass::cast(caller)->external_name());
+ InstanceKlass::cast(caller)->external_name());
} else {
tty->print("[Loaded %s]\n", this_klass->external_name());
}
} else {
ResourceMark rm;
tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
- instanceKlass::cast(class_loader->klass())->external_name());
+ InstanceKlass::cast(class_loader->klass())->external_name());
}
}
@@ -3746,15 +3774,15 @@
// print out the superclass.
const char * from = Klass::cast(this_klass())->external_name();
if (this_klass->java_super() != NULL) {
- tty->print("RESOLVE %s %s (super)\n", from, instanceKlass::cast(this_klass->java_super())->external_name());
+ tty->print("RESOLVE %s %s (super)\n", from, InstanceKlass::cast(this_klass->java_super())->external_name());
}
// print out each of the interface classes referred to by this class.
- objArrayHandle local_interfaces(THREAD, this_klass->local_interfaces());
- if (!local_interfaces.is_null()) {
+ Array<Klass*>* local_interfaces = this_klass->local_interfaces();
+ if (local_interfaces != NULL) {
int length = local_interfaces->length();
for (int i = 0; i < length; i++) {
- klassOop k = klassOop(local_interfaces->obj_at(i));
- instanceKlass* to_class = instanceKlass::cast(k);
+ Klass* k = local_interfaces->at(i);
+ InstanceKlass* to_class = InstanceKlass::cast(k);
const char * to = to_class->external_name();
tty->print("RESOLVE %s %s (interface)\n", from, to);
}
@@ -3781,9 +3809,10 @@
preserve_this_klass = this_klass();
}
- // Create new handle outside HandleMark
+ // Create new handle outside HandleMark (might be needed for
+ // Extended Class Redefinition)
instanceKlassHandle this_klass (THREAD, preserve_this_klass);
- debug_only(this_klass->as_klassOop()->verify();)
+ debug_only(this_klass->verify();)
return this_klass;
}
@@ -3826,7 +3855,7 @@
int* nonstatic_oop_offsets,
unsigned int* nonstatic_oop_counts) {
OopMapBlock* this_oop_map = k->start_of_nonstatic_oop_maps();
- const instanceKlass* const super = k->superklass();
+ const InstanceKlass* const super = k->superklass();
const unsigned int super_count = super ? super->nonstatic_oop_map_count() : 0;
if (super_count > 0) {
// Copy maps from superklass
@@ -3861,20 +3890,20 @@
void ClassFileParser::set_precomputed_flags(instanceKlassHandle k) {
- klassOop super = k->super();
+ Klass* super = k->super();
// Check if this klass has an empty finalize method (i.e. one with return bytecode only),
// in which case we don't have to register objects as finalizable
if (!_has_empty_finalizer) {
if (_has_finalizer ||
- (super != NULL && super->klass_part()->has_finalizer())) {
+ (super != NULL && super->has_finalizer())) {
k->set_has_finalizer();
}
}
#ifdef ASSERT
bool f = false;
- methodOop m = k->lookup_method(vmSymbols::finalize_method_name(),
+ Method* m = k->lookup_method(vmSymbols::finalize_method_name(),
vmSymbols::void_method_signature());
if (m != NULL && !m->is_empty_method()) {
f = true;
@@ -3901,7 +3930,7 @@
#ifdef ASSERT
bool v = false;
if (Klass::cast(super)->has_vanilla_constructor()) {
- methodOop constructor = k->find_method(vmSymbols::object_initializer_name(
+ Method* constructor = k->find_method(vmSymbols::object_initializer_name(
), vmSymbols::void_method_signature());
if (constructor != NULL && constructor->is_vanilla_constructor()) {
v = true;
@@ -3912,12 +3941,12 @@
}
// If it cannot be fast-path allocated, set a bit in the layout helper.
- // See documentation of instanceKlass::can_be_fastpath_allocated().
+ // See documentation of InstanceKlass::can_be_fastpath_allocated().
assert(k->size_helper() > 0, "layout_helper is initialized");
if ((!RegisterFinalizersAtInit && k->has_finalizer())
|| k->is_abstract() || k->is_interface()
|| (k->name() == vmSymbols::java_lang_Class()
- && k->class_loader() == NULL)
+ && k->class_loader_data()->is_the_null_class_loader_data())
|| k->size_helper() >= FastAllocateSizeLimit) {
// Forbid fast-path allocation.
jint lh = Klass::instance_layout_helper(k->size_helper(), true);
@@ -3925,30 +3954,44 @@
}
}
-
-// utility method for appending and array with check for duplicates
-
-void append_interfaces(objArrayHandle result, int& index, objArrayOop ifs) {
- // iterate over new interfaces
- for (int i = 0; i < ifs->length(); i++) {
- oop e = ifs->obj_at(i);
- assert(e->is_klass() && instanceKlass::cast(klassOop(e))->is_interface(), "just checking");
- // check for duplicates
- bool duplicate = false;
- for (int j = 0; j < index; j++) {
- if (result->obj_at(j) == e) {
- duplicate = true;
- break;
+// Attach super classes and interface classes to class loader data
+void ClassFileParser::record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS) {
+ ClassLoaderData * defining_loader_data = defined_klass->class_loader_data();
+ if (defining_loader_data->is_the_null_class_loader_data()) {
+ // Dependencies to null class loader data are implicit.
+ return;
+ } else {
+ // add super class dependency
+ Klass* super = defined_klass->super();
+ if (super != NULL) {
+ defining_loader_data->record_dependency(super, CHECK);
+ }
+
+ // add super interface dependencies
+ Array<Klass*>* local_interfaces = defined_klass->local_interfaces();
+ if (local_interfaces != NULL) {
+ int length = local_interfaces->length();
+ for (int i = 0; i < length; i++) {
+ defining_loader_data->record_dependency(local_interfaces->at(i), CHECK);
}
}
- // add new interface
- if (!duplicate) {
- result->obj_at_put(index++, e);
- }
}
}
-objArrayHandle ClassFileParser::compute_transitive_interfaces(instanceKlassHandle super, objArrayHandle local_ifs, TRAPS) {
+// utility method for appending and array with check for duplicates
+
+void append_interfaces(GrowableArray<Klass*>* result, Array<Klass*>* ifs) {
+ // iterate over new interfaces
+ for (int i = 0; i < ifs->length(); i++) {
+ Klass* e = ifs->at(i);
+ assert(e->is_klass() && InstanceKlass::cast(e)->is_interface(), "just checking");
+ // add new interface
+ result->append_if_missing(e);
+ }
+}
+
+
+Array<Klass*>* ClassFileParser::compute_transitive_interfaces(ClassLoaderData* loader_data, instanceKlassHandle super, Array<Klass*>* local_ifs, TRAPS) {
// Compute maximum size for transitive interfaces
int max_transitive_size = 0;
int super_size = 0;
@@ -3960,66 +4003,63 @@
// Add local interfaces' super interfaces
int local_size = local_ifs->length();
for (int i = 0; i < local_size; i++) {
- klassOop l = klassOop(local_ifs->obj_at(i));
- max_transitive_size += instanceKlass::cast(l)->transitive_interfaces()->length();
+ Klass* l = local_ifs->at(i);
+ max_transitive_size += InstanceKlass::cast(l)->transitive_interfaces()->length();
}
// Finally add local interfaces
max_transitive_size += local_size;
// Construct array
- objArrayHandle result;
if (max_transitive_size == 0) {
// no interfaces, use canonicalized array
- result = objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
+ return Universe::the_empty_klass_array();
} else if (max_transitive_size == super_size) {
// no new local interfaces added, share superklass' transitive interface array
- result = objArrayHandle(THREAD, super->transitive_interfaces());
+ return super->transitive_interfaces();
} else if (max_transitive_size == local_size) {
// only local interfaces added, share local interface array
- result = local_ifs;
+ return local_ifs;
} else {
- objArrayHandle nullHandle;
- objArrayOop new_objarray = oopFactory::new_system_objArray(max_transitive_size, CHECK_(nullHandle));
- result = objArrayHandle(THREAD, new_objarray);
- int index = 0;
+ ResourceMark rm;
+ GrowableArray<Klass*>* result = new GrowableArray<Klass*>(max_transitive_size);
+
// Copy down from superclass
if (super.not_null()) {
- append_interfaces(result, index, super->transitive_interfaces());
+ append_interfaces(result, super->transitive_interfaces());
}
+
// Copy down from local interfaces' superinterfaces
for (int i = 0; i < local_ifs->length(); i++) {
- klassOop l = klassOop(local_ifs->obj_at(i));
- append_interfaces(result, index, instanceKlass::cast(l)->transitive_interfaces());
+ Klass* l = local_ifs->at(i);
+ append_interfaces(result, InstanceKlass::cast(l)->transitive_interfaces());
}
// Finally add local interfaces
- append_interfaces(result, index, local_ifs());
-
- // Check if duplicates were removed
- if (index != max_transitive_size) {
- assert(index < max_transitive_size, "just checking");
- objArrayOop new_result = oopFactory::new_system_objArray(index, CHECK_(nullHandle));
- for (int i = 0; i < index; i++) {
- oop e = result->obj_at(i);
+ append_interfaces(result, local_ifs);
+
+ // length will be less than the max_transitive_size if duplicates were removed
+ int length = result->length();
+ assert(length <= max_transitive_size, "just checking");
+ Array<Klass*>* new_result = MetadataFactory::new_array<Klass*>(loader_data, length, CHECK_NULL);
+ for (int i = 0; i < length; i++) {
+ Klass* e = result->at(i);
assert(e != NULL, "just checking");
- new_result->obj_at_put(i, e);
- }
- result = objArrayHandle(THREAD, new_result);
+ new_result->at_put(i, e);
}
+ return new_result;
}
- return result;
}
void ClassFileParser::check_super_class_access(instanceKlassHandle this_klass, TRAPS) {
- klassOop super = this_klass->super();
+ Klass* super = this_klass->super();
if ((super != NULL) &&
- (!Reflection::verify_class_access(this_klass->as_klassOop(), super, false))) {
+ (!Reflection::verify_class_access(this_klass(), super, false))) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_IllegalAccessError(),
"class %s cannot access its superclass %s",
this_klass->external_name(),
- instanceKlass::cast(super)->external_name()
+ InstanceKlass::cast(super)->external_name()
);
return;
}
@@ -4027,19 +4067,19 @@
void ClassFileParser::check_super_interface_access(instanceKlassHandle this_klass, TRAPS) {
- objArrayHandle local_interfaces (THREAD, this_klass->local_interfaces());
+ Array<Klass*>* local_interfaces = this_klass->local_interfaces();
int lng = local_interfaces->length();
for (int i = lng - 1; i >= 0; i--) {
- klassOop k = klassOop(local_interfaces->obj_at(i));
+ Klass* k = local_interfaces->at(i);
assert (k != NULL && Klass::cast(k)->is_interface(), "invalid interface");
- if (!Reflection::verify_class_access(this_klass->as_klassOop(), k, false)) {
+ if (!Reflection::verify_class_access(this_klass(), k, false)) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_IllegalAccessError(),
"class %s cannot access its superinterface %s",
this_klass->external_name(),
- instanceKlass::cast(k)->external_name()
+ InstanceKlass::cast(k)->external_name()
);
return;
}
@@ -4048,12 +4088,12 @@
void ClassFileParser::check_final_method_override(instanceKlassHandle this_klass, TRAPS) {
- objArrayHandle methods (THREAD, this_klass->methods());
+ Array<Method*>* methods = this_klass->methods();
int num_methods = methods->length();
// go thru each method and check if it overrides a final method
for (int index = 0; index < num_methods; index++) {
- methodOop m = (methodOop)methods->obj_at(index);
+ Method* m = methods->at(index);
// skip private, static and <init> methods
if ((!m->is_private()) &&
@@ -4062,20 +4102,20 @@
Symbol* name = m->name();
Symbol* signature = m->signature();
- klassOop k = this_klass->super();
- methodOop super_m = NULL;
+ Klass* k = this_klass->super();
+ Method* super_m = NULL;
while (k != NULL) {
// skip supers that don't have final methods.
- if (k->klass_part()->has_final_method()) {
+ if (k->has_final_method()) {
// lookup a matching method in the super class hierarchy
- super_m = instanceKlass::cast(k)->lookup_method(name, signature);
+ super_m = InstanceKlass::cast(k)->lookup_method(name, signature);
if (super_m == NULL) {
break; // didn't find any match; get out
}
if (super_m->is_final() &&
// matching method in super is final
- (Reflection::verify_field_access(this_klass->as_klassOop(),
+ (Reflection::verify_field_access(this_klass(),
super_m->method_holder(),
super_m->method_holder(),
super_m->access_flags(), false))
@@ -4094,11 +4134,11 @@
}
// continue to look from super_m's holder's super.
- k = instanceKlass::cast(super_m->method_holder())->super();
+ k = InstanceKlass::cast(super_m->method_holder())->super();
continue;
}
- k = k->klass_part()->super();
+ k = k->super();
}
}
}
@@ -4108,11 +4148,11 @@
// assumes that this_klass is an interface
void ClassFileParser::check_illegal_static_method(instanceKlassHandle this_klass, TRAPS) {
assert(this_klass->is_interface(), "not an interface");
- objArrayHandle methods (THREAD, this_klass->methods());
+ Array<Method*>* methods = this_klass->methods();
int num_methods = methods->length();
for (int index = 0; index < num_methods; index++) {
- methodOop m = (methodOop)methods->obj_at(index);
+ Method* m = methods->at(index);
// if m is static and not the init method, throw a verify error
if ((m->is_static()) && (m->name() != vmSymbols::class_initializer_name())) {
ResourceMark rm(THREAD);