7064927: retransformClasses() does not pass in LocalVariableTable of a method
authorcoleenp
Wed, 21 Dec 2011 16:41:15 -0500
changeset 11257 b98dfa12a8f7
parent 11255 7d28e253b4b0
child 11258 ec59f88eb330
7064927: retransformClasses() does not pass in LocalVariableTable of a method Summary: Handle LVT attribute in the class file reconstitutor. Reviewed-by: phh, coleenp Contributed-by: thomaswue <thomas.wuerthinger@oracle.com>
hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp	Mon Dec 19 21:38:51 2011 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp	Wed Dec 21 16:41:15 2011 -0500
@@ -43,7 +43,7 @@
 #ifdef TARGET_ARCH_ppc
 # include "bytes_ppc.hpp"
 #endif
-// FIXME: add Deprecated, LVT, LVTT attributes
+// FIXME: add Deprecated, LVTT attributes
 // FIXME: fix Synthetic attribute
 // FIXME: per Serguei, add error return handling for constantPoolOopDesc::copy_cpool_bytes()
 
@@ -136,8 +136,9 @@
   constMethodHandle const_method(thread(), method->constMethod());
   u2 line_num_cnt = 0;
   int stackmap_len = 0;
+  int local_variable_table_length = 0;
 
-  // compute number and length of attributes -- FIXME: for now no LVT
+  // compute number and length of attributes
   int attr_count = 0;
   int attr_size = 0;
   if (const_method->has_linenumber_table()) {
@@ -170,6 +171,25 @@
       attr_size += 2 + 4 + stackmap_len;
     }
   }
+  if (method->has_localvariable_table()) {
+    local_variable_table_length = method->localvariable_table_length();
+    ++attr_count;
+    if (local_variable_table_length != 0) {
+      // Compute the size of the local variable table attribute (VM stores raw):
+      // LocalVariableTable_attribute {
+      //   u2 attribute_name_index;
+      //   u4 attribute_length;
+      //   u2 local_variable_table_length;
+      //   {
+      //     u2 start_pc;
+      //     u2 length;
+      //     u2 name_index;
+      //     u2 descriptor_index;
+      //     u2 index;
+      //   }
+      attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2);
+    }
+  }
 
   typeArrayHandle exception_table(thread(), const_method->exception_table());
   int exception_table_length = exception_table->length();
@@ -203,8 +223,9 @@
   if (stackmap_len != 0) {
     write_stackmap_table_attribute(method, stackmap_len);
   }
-
-  // FIXME: write LVT attribute
+  if (local_variable_table_length != 0) {
+    write_local_variable_table_attribute(method, local_variable_table_length);
+  }
 }
 
 // Write Exceptions attribute
@@ -371,6 +392,36 @@
   }
 }
 
+// Write LineNumberTable attribute
+// JVMSpec|   LocalVariableTable_attribute {
+// JVMSpec|     u2 attribute_name_index;
+// JVMSpec|     u4 attribute_length;
+// JVMSpec|     u2 local_variable_table_length;
+// JVMSpec|     {  u2 start_pc;
+// JVMSpec|       u2 length;
+// JVMSpec|       u2 name_index;
+// JVMSpec|       u2 descriptor_index;
+// JVMSpec|       u2 index;
+// JVMSpec|     } local_variable_table[local_variable_table_length];
+// JVMSpec|   }
+void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHandle method, u2 num_entries) {
+    write_attribute_name_index("LocalVariableTable");
+    write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
+    write_u2(num_entries);
+
+    assert(method->localvariable_table_length() == num_entries, "just checking");
+
+    LocalVariableTableElement *elem = method->localvariable_table_start();
+    for (int j=0; j<method->localvariable_table_length(); j++) {
+      write_u2(elem->start_bci);
+      write_u2(elem->length);
+      write_u2(elem->name_cp_index);
+      write_u2(elem->descriptor_cp_index);
+      write_u2(elem->slot);
+      elem++;
+    }
+}
+
 // Write stack map table attribute
 // JSR-202|   StackMapTable_attribute {
 // JSR-202|     u2 attribute_name_index;
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp	Mon Dec 19 21:38:51 2011 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp	Wed Dec 21 16:41:15 2011 -0500
@@ -119,6 +119,7 @@
   void write_source_debug_extension_attribute();
   u2 line_number_table_entries(methodHandle method);
   void write_line_number_table_attribute(methodHandle method, u2 num_entries);
+  void write_local_variable_table_attribute(methodHandle method, u2 num_entries);
   void write_stackmap_table_attribute(methodHandle method, int stackmap_table_len);
   u2 inner_classes_attribute_length();
   void write_inner_classes_attribute(int length);