diff src/share/vm/prims/jvmtiClassFileReconstituter.cpp @ 10408:836a62f43af9

Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author Doug Simon <doug.simon@oracle.com>
date Wed, 19 Jun 2013 10:45:56 +0200
parents b5fef8013a95
children de6a9e811145
line wrap: on
line diff
--- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp	Tue Jun 18 14:23:29 2013 -0700
+++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp	Wed Jun 19 10:45:56 2013 +0200
@@ -341,6 +341,44 @@
   memcpy(writeable_address(length), annos->adr_at(0), length);
 }
 
+//  BootstrapMethods_attribute {
+//    u2 attribute_name_index;
+//    u4 attribute_length;
+//    u2 num_bootstrap_methods;
+//    {   u2 bootstrap_method_ref;
+//        u2 num_bootstrap_arguments;
+//        u2 bootstrap_arguments[num_bootstrap_arguments];
+//    } bootstrap_methods[num_bootstrap_methods];
+//  }
+void JvmtiClassFileReconstituter::write_bootstrapmethod_attribute() {
+  Array<u2>* operands = cpool()->operands();
+  write_attribute_name_index("BootstrapMethods");
+  int num_bootstrap_methods = ConstantPool::operand_array_length(operands);
+
+  // calculate length of attribute
+  int length = sizeof(u2); // num_bootstrap_methods
+  for (int n = 0; n < num_bootstrap_methods; n++) {
+    u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);
+    length += sizeof(u2); // bootstrap_method_ref
+    length += sizeof(u2); // num_bootstrap_arguments
+    length += sizeof(u2) * num_bootstrap_arguments; // bootstrap_arguments[num_bootstrap_arguments]
+  }
+  write_u4(length);
+
+  // write attribute
+  write_u2(num_bootstrap_methods);
+  for (int n = 0; n < num_bootstrap_methods; n++) {
+    u2 bootstrap_method_ref = cpool()->operand_bootstrap_method_ref_index_at(n);
+    u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);
+    write_u2(bootstrap_method_ref);
+    write_u2(num_bootstrap_arguments);
+    for (int arg = 0; arg < num_bootstrap_arguments; arg++) {
+      u2 bootstrap_argument = cpool()->operand_argument_index_at(n, arg);
+      write_u2(bootstrap_argument);
+    }
+  }
+}
+
 
 // Write InnerClasses attribute
 // JVMSpec|   InnerClasses_attribute {
@@ -513,6 +551,11 @@
   AnnotationArray* param_anno = method->parameter_annotations();
   AnnotationArray* default_anno = method->annotation_default();
 
+  // skip generated default interface methods
+  if (method->is_overpass()) {
+    return;
+  }
+
   write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS);
   write_u2(const_method->name_index());
   write_u2(const_method->signature_index());
@@ -592,6 +635,9 @@
   if (anno != NULL) {
     ++attr_count;     // has RuntimeVisibleAnnotations attribute
   }
+  if (cpool()->operands() != NULL) {
+    ++attr_count;
+  }
 
   write_u2(attr_count);
 
@@ -610,6 +656,9 @@
   if (anno != NULL) {
     write_annotations_attribute("RuntimeVisibleAnnotations", anno);
   }
+  if (cpool()->operands() != NULL) {
+    write_bootstrapmethod_attribute();
+  }
 }
 
 // Write the method information portion of ClassFile structure
@@ -619,8 +668,19 @@
   HandleMark hm(thread());
   Array<Method*>* methods = ikh()->methods();
   int num_methods = methods->length();
+  int num_overpass = 0;
 
-  write_u2(num_methods);
+  // count the generated default interface methods
+  // these will not be re-created by write_method_info
+  // and should not be included in the total count
+  for (int index = 0; index < num_methods; index++) {
+    Method* method = methods->at(index);
+    if (method->is_overpass()) {
+      num_overpass++;
+    }
+  }
+
+  write_u2(num_methods - num_overpass);
   if (JvmtiExport::can_maintain_original_method_order()) {
     int index;
     int original_index;