Mercurial > hg > graal-jvmci-8
diff src/share/vm/prims/jvmtiClassFileReconstituter.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | e74da3c2b827 |
children | 1cb8583c3da8 |
line wrap: on
line diff
--- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Fri Aug 31 16:39:35 2012 -0700 +++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Sat Sep 01 13:25:18 2012 -0400 @@ -45,7 +45,7 @@ #endif // FIXME: add Deprecated, LVTT attributes // FIXME: fix Synthetic attribute -// FIXME: per Serguei, add error return handling for constantPoolOopDesc::copy_cpool_bytes() +// FIXME: per Serguei, add error return handling for ConstantPool::copy_cpool_bytes() // Write the field information portion of ClassFile structure @@ -53,7 +53,7 @@ // JVMSpec| field_info fields[fields_count]; void JvmtiClassFileReconstituter::write_field_infos() { HandleMark hm(thread()); - objArrayHandle fields_anno(thread(), ikh()->fields_annotations()); + Array<AnnotationArray*>* fields_anno = ikh()->fields_annotations(); // Compute the real number of Java fields int java_fields = ikh()->java_fields_count(); @@ -67,9 +67,7 @@ guarantee(name_index != 0 && signature_index != 0, "bad constant pool index for field"); // int offset = ikh()->field_offset( index ); int generic_signature_index = fs.generic_signature_index(); - typeArrayHandle anno(thread(), fields_anno.not_null() ? - (typeArrayOop)(fields_anno->obj_at(fs.index())) : - (typeArrayOop)NULL); + AnnotationArray* anno = fields_anno == NULL ? NULL : fields_anno->at(fs.index()); // JVMSpec| field_info { // JVMSpec| u2 access_flags; @@ -92,7 +90,7 @@ if (generic_signature_index != 0) { ++attr_count; } - if (anno.not_null()) { + if (anno != NULL) { ++attr_count; // has RuntimeVisibleAnnotations attribute } @@ -109,7 +107,7 @@ if (generic_signature_index != 0) { write_signature_attribute(generic_signature_index); } - if (anno.not_null()) { + if (anno != NULL) { write_annotations_attribute("RuntimeVisibleAnnotations", anno); } } @@ -133,7 +131,7 @@ // JVMSpec| attribute_info attributes[attributes_count]; // JVMSpec| } void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) { - constMethodHandle const_method(thread(), method->constMethod()); + ConstMethod* const_method = method->constMethod(); u2 line_num_cnt = 0; int stackmap_len = 0; int local_variable_table_length = 0; @@ -234,7 +232,7 @@ // JVMSpec| u2 number_of_exceptions; // JVMSpec| u2 exception_index_table[number_of_exceptions]; // JVMSpec| } -void JvmtiClassFileReconstituter::write_exceptions_attribute(constMethodHandle const_method) { +void JvmtiClassFileReconstituter::write_exceptions_attribute(ConstMethod* const_method) { CheckedExceptionElement* checked_exceptions = const_method->checked_exceptions_start(); int checked_exceptions_length = const_method->checked_exceptions_length(); int size = @@ -307,11 +305,11 @@ // JSR202| ... // JSR202| } void JvmtiClassFileReconstituter::write_annotations_attribute(const char* attr_name, - typeArrayHandle annos) { + AnnotationArray* annos) { u4 length = annos->length(); write_attribute_name_index(attr_name); write_u4(length); - memcpy(writeable_address(length), annos->byte_at_addr(0), length); + memcpy(writeable_address(length), annos->adr_at(0), length); } @@ -330,7 +328,7 @@ InnerClassesIterator iter(ikh()); guarantee(iter.length() != 0 && iter.length() == length, "caller must check"); - u2 entry_count = length / instanceKlass::inner_class_next_offset; + u2 entry_count = length / InstanceKlass::inner_class_next_offset; u4 size = 2 + entry_count * (2+2+2+2); write_attribute_name_index("InnerClasses"); @@ -433,7 +431,7 @@ write_u4(stackmap_len); memcpy( writeable_address(stackmap_len), - (void*)(method->stackmap_data()->byte_at_addr(0)), + (void*)(method->stackmap_data()->adr_at(0)), stackmap_len); } @@ -447,11 +445,11 @@ // JVMSpec| } void JvmtiClassFileReconstituter::write_method_info(methodHandle method) { AccessFlags access_flags = method->access_flags(); - constMethodHandle const_method(thread(), method->constMethod()); + ConstMethod* const_method = method->constMethod(); u2 generic_signature_index = const_method->generic_signature_index(); - typeArrayHandle anno(thread(), method->annotations()); - typeArrayHandle param_anno(thread(), method->parameter_annotations()); - typeArrayHandle default_anno(thread(), method->annotation_default()); + AnnotationArray* anno = method->annotations(); + AnnotationArray* param_anno = method->parameter_annotations(); + AnnotationArray* default_anno = method->annotation_default(); write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS); write_u2(const_method->name_index()); @@ -466,7 +464,7 @@ if (const_method->has_checked_exceptions()) { ++attr_count; // has Exceptions attribute } - if (default_anno.not_null()) { + if (default_anno != NULL) { ++attr_count; // has AnnotationDefault attribute } // Deprecated attribute would go here @@ -476,10 +474,10 @@ if (generic_signature_index != 0) { ++attr_count; } - if (anno.not_null()) { + if (anno != NULL) { ++attr_count; // has RuntimeVisibleAnnotations attribute } - if (param_anno.not_null()) { + if (param_anno != NULL) { ++attr_count; // has RuntimeVisibleParameterAnnotations attribute } @@ -490,7 +488,7 @@ if (const_method->has_checked_exceptions()) { write_exceptions_attribute(const_method); } - if (default_anno.not_null()) { + if (default_anno != NULL) { write_annotations_attribute("AnnotationDefault", default_anno); } // Deprecated attribute would go here @@ -500,10 +498,10 @@ if (generic_signature_index != 0) { write_signature_attribute(generic_signature_index); } - if (anno.not_null()) { + if (anno != NULL) { write_annotations_attribute("RuntimeVisibleAnnotations", anno); } - if (param_anno.not_null()) { + if (param_anno != NULL) { write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno); } } @@ -514,7 +512,7 @@ void JvmtiClassFileReconstituter::write_class_attributes() { u2 inner_classes_length = inner_classes_attribute_length(); Symbol* generic_signature = ikh()->generic_signature(); - typeArrayHandle anno(thread(), ikh()->class_annotations()); + AnnotationArray* anno = ikh()->class_annotations(); int attr_count = 0; if (generic_signature != NULL) { @@ -529,7 +527,7 @@ if (inner_classes_length > 0) { ++attr_count; } - if (anno.not_null()) { + if (anno != NULL) { ++attr_count; // has RuntimeVisibleAnnotations attribute } @@ -547,7 +545,7 @@ if (inner_classes_length > 0) { write_inner_classes_attribute(inner_classes_length); } - if (anno.not_null()) { + if (anno != NULL) { write_annotations_attribute("RuntimeVisibleAnnotations", anno); } } @@ -557,33 +555,33 @@ // JVMSpec| method_info methods[methods_count]; void JvmtiClassFileReconstituter::write_method_infos() { HandleMark hm(thread()); - objArrayHandle methods(thread(), ikh()->methods()); + Array<Method*>* methods = ikh()->methods(); int num_methods = methods->length(); write_u2(num_methods); if (JvmtiExport::can_maintain_original_method_order()) { int index; int original_index; - int* method_order = NEW_RESOURCE_ARRAY(int, num_methods); + intArray method_order(num_methods, 0); // invert the method order mapping for (index = 0; index < num_methods; index++) { - original_index = ikh()->method_ordering()->int_at(index); + original_index = ikh()->method_ordering()->at(index); assert(original_index >= 0 && original_index < num_methods, "invalid original method index"); - method_order[original_index] = index; + method_order.at_put(original_index, index); } // write in original order for (original_index = 0; original_index < num_methods; original_index++) { - index = method_order[original_index]; - methodHandle method(thread(), (methodOop)(ikh()->methods()->obj_at(index))); + index = method_order.at(original_index); + methodHandle method(thread(), methods->at(index)); write_method_info(method); } } else { // method order not preserved just dump the method infos for (int index = 0; index < num_methods; index++) { - methodHandle method(thread(), (methodOop)(ikh()->methods()->obj_at(index))); + methodHandle method(thread(), methods->at(index)); write_method_info(method); } } @@ -613,18 +611,18 @@ // JVMSpec| u2 this_class; // JVMSpec| u2 super_class; write_u2(class_symbol_to_cpool_index(ikh()->name())); - klassOop super_class = ikh()->super(); + Klass* super_class = ikh()->super(); write_u2(super_class == NULL? 0 : // zero for java.lang.Object - class_symbol_to_cpool_index(super_class->klass_part()->name())); + class_symbol_to_cpool_index(super_class->name())); // JVMSpec| u2 interfaces_count; // JVMSpec| u2 interfaces[interfaces_count]; - objArrayHandle interfaces(thread(), ikh()->local_interfaces()); + Array<Klass*>* interfaces = ikh()->local_interfaces(); int num_interfaces = interfaces->length(); write_u2(num_interfaces); for (int index = 0; index < num_interfaces; index++) { HandleMark hm(thread()); - instanceKlassHandle iikh(thread(), klassOop(interfaces->obj_at(index))); + instanceKlassHandle iikh(thread(), interfaces->at(index)); write_u2(class_symbol_to_cpool_index(iikh->name())); } @@ -693,7 +691,7 @@ unsigned char* p = bytecodes; Bytecodes::Code code; - bool is_rewritten = instanceKlass::cast(mh->method_holder())->is_rewritten(); + bool is_rewritten = InstanceKlass::cast(mh->method_holder())->is_rewritten(); while ((code = bs.next()) >= 0) { assert(Bytecodes::is_java_code(code), "sanity check"); @@ -713,7 +711,8 @@ // During linking the get/put and invoke instructions are rewritten // with an index into the constant pool cache. The original constant // pool index must be returned to caller. Rewrite the index. - if (is_rewritten && len >= 3) { + if (is_rewritten && len > 1) { + bool is_wide = false; switch (code) { case Bytecodes::_getstatic : // fall through case Bytecodes::_putstatic : // fall through @@ -723,7 +722,7 @@ case Bytecodes::_invokespecial : // fall through case Bytecodes::_invokestatic : // fall through case Bytecodes::_invokedynamic : // fall through - case Bytecodes::_invokeinterface : + case Bytecodes::_invokeinterface : { assert(len == 3 || (code == Bytecodes::_invokeinterface && len == 5) || (code == Bytecodes::_invokedynamic && len == 5), @@ -731,17 +730,36 @@ int cpci = Bytes::get_native_u2(bcp+1); bool is_invokedynamic = (EnableInvokeDynamic && code == Bytecodes::_invokedynamic); - if (is_invokedynamic) + ConstantPoolCacheEntry* entry; + if (is_invokedynamic) { cpci = Bytes::get_native_u4(bcp+1); + entry = mh->constants()->invokedynamic_cp_cache_entry_at(cpci); + } else { // cache cannot be pre-fetched since some classes won't have it yet - ConstantPoolCacheEntry* entry = - mh->constants()->cache()->main_entry_at(cpci); + entry = mh->constants()->cache()->entry_at(cpci); + } int i = entry->constant_pool_index(); assert(i < mh->constants()->length(), "sanity check"); Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering if (is_invokedynamic) *(p+3) = *(p+4) = 0; break; } + case Bytecodes::_ldc_w: + is_wide = true; // fall through + case Bytecodes::_ldc: { + if (bs.raw_code() == Bytecodes::_fast_aldc || bs.raw_code() == Bytecodes::_fast_aldc_w) { + int cpci = is_wide ? Bytes::get_native_u2(bcp+1) : (u1)(*(bcp+1)); + int i = mh->constants()->object_to_cp_index(cpci); + assert(i < mh->constants()->length(), "sanity check"); + if (is_wide) { + Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering + } else { + *(p+1) = (u1)i; + } + } + break; + } + } } p += len;