src/share/vm/prims/jvmtiClassFileReconstituter.cpp

Print this page




  26 #include "classfile/symbolTable.hpp"
  27 #include "interpreter/bytecodeStream.hpp"
  28 #include "oops/fieldStreams.hpp"
  29 #include "prims/jvmtiClassFileReconstituter.hpp"
  30 #include "runtime/signature.hpp"
  31 #ifdef TARGET_ARCH_x86
  32 # include "bytes_x86.hpp"
  33 #endif
  34 #ifdef TARGET_ARCH_sparc
  35 # include "bytes_sparc.hpp"
  36 #endif
  37 #ifdef TARGET_ARCH_zero
  38 # include "bytes_zero.hpp"
  39 #endif
  40 #ifdef TARGET_ARCH_arm
  41 # include "bytes_arm.hpp"
  42 #endif
  43 #ifdef TARGET_ARCH_ppc
  44 # include "bytes_ppc.hpp"
  45 #endif
  46 // FIXME: add Deprecated, LVTT attributes
  47 // FIXME: fix Synthetic attribute
  48 // FIXME: per Serguei, add error return handling for constantPoolOopDesc::copy_cpool_bytes()
  49 
  50 
  51 // Write the field information portion of ClassFile structure
  52 // JVMSpec|     u2 fields_count;
  53 // JVMSpec|     field_info fields[fields_count];
  54 void JvmtiClassFileReconstituter::write_field_infos() {
  55   HandleMark hm(thread());
  56   objArrayHandle fields_anno(thread(), ikh()->fields_annotations());
  57 
  58   // Compute the real number of Java fields
  59   int java_fields = ikh()->java_fields_count();
  60 
  61   write_u2(java_fields);
  62   for (JavaFieldStream fs(ikh()); !fs.done(); fs.next()) {
  63     AccessFlags access_flags = fs.access_flags();
  64     int name_index = fs.name_index();
  65     int signature_index = fs.signature_index();
  66     int initial_value_index = fs.initval_index();


 120 // JVMSpec|     u2 attribute_name_index;
 121 // JVMSpec|     u4 attribute_length;
 122 // JVMSpec|     u2 max_stack;
 123 // JVMSpec|     u2 max_locals;
 124 // JVMSpec|     u4 code_length;
 125 // JVMSpec|     u1 code[code_length];
 126 // JVMSpec|     u2 exception_table_length;
 127 // JVMSpec|     {       u2 start_pc;
 128 // JVMSpec|             u2 end_pc;
 129 // JVMSpec|             u2  handler_pc;
 130 // JVMSpec|             u2  catch_type;
 131 // JVMSpec|     }       exception_table[exception_table_length];
 132 // JVMSpec|     u2 attributes_count;
 133 // JVMSpec|     attribute_info attributes[attributes_count];
 134 // JVMSpec|   }
 135 void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
 136   constMethodHandle const_method(thread(), method->constMethod());
 137   u2 line_num_cnt = 0;
 138   int stackmap_len = 0;
 139   int local_variable_table_length = 0;

 140 
 141   // compute number and length of attributes
 142   int attr_count = 0;
 143   int attr_size = 0;
 144   if (const_method->has_linenumber_table()) {
 145     line_num_cnt = line_number_table_entries(method);
 146     if (line_num_cnt != 0) {
 147       ++attr_count;
 148       // Compute the complete size of the line number table attribute:
 149       //      LineNumberTable_attribute {
 150       //        u2 attribute_name_index;
 151       //        u4 attribute_length;
 152       //        u2 line_number_table_length;
 153       //        {  u2 start_pc;
 154       //           u2 line_number;
 155       //        } line_number_table[line_number_table_length];
 156       //      }
 157       attr_size += 2 + 4 + 2 + line_num_cnt * (2 + 2);
 158     }
 159   }
 160   if (method->has_stackmap_table()) {
 161     stackmap_len = method->stackmap_data()->length();
 162     if (stackmap_len != 0) {
 163       ++attr_count;
 164       // Compute the  size of the stack map table attribute (VM stores raw):
 165       //      StackMapTable_attribute {
 166       //        u2 attribute_name_index;
 167       //        u4 attribute_length;
 168       //        u2 number_of_entries;
 169       //        stack_map_frame_entries[number_of_entries];
 170       //      }
 171       attr_size += 2 + 4 + stackmap_len;
 172     }
 173   }
 174   if (method->has_localvariable_table()) {
 175     local_variable_table_length = method->localvariable_table_length();
 176     ++attr_count;
 177     if (local_variable_table_length != 0) {

 178       // Compute the size of the local variable table attribute (VM stores raw):
 179       // LocalVariableTable_attribute {
 180       //   u2 attribute_name_index;
 181       //   u4 attribute_length;
 182       //   u2 local_variable_table_length;
 183       //   {
 184       //     u2 start_pc;
 185       //     u2 length;
 186       //     u2 name_index;
 187       //     u2 descriptor_index;
 188       //     u2 index;
 189       //   }
 190       attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2);






 191     }
 192   }

 193 


















 194   ExceptionTable exception_table(method());
 195   int exception_table_length = exception_table.length();
 196   int code_size = const_method->code_size();
 197   int size =
 198     2+2+4 +                                // max_stack, max_locals, code_length
 199     code_size +                            // code
 200     2 +                                    // exception_table_length
 201     (2+2+2+2) * exception_table_length +   // exception_table
 202     2 +                                    // attributes_count
 203     attr_size;                             // attributes
 204 
 205   write_attribute_name_index("Code");
 206   write_u4(size);
 207   write_u2(method->max_stack());
 208   write_u2(method->max_locals());
 209   write_u4(code_size);
 210   copy_bytecodes(method, (unsigned char*)writeable_address(code_size));
 211   write_u2(exception_table_length);
 212   for (int index = 0; index < exception_table_length; index++) {
 213     write_u2(exception_table.start_pc(index));
 214     write_u2(exception_table.end_pc(index));
 215     write_u2(exception_table.handler_pc(index));
 216     write_u2(exception_table.catch_type_index(index));
 217   }
 218   write_u2(attr_count);
 219   if (line_num_cnt != 0) {
 220     write_line_number_table_attribute(method, line_num_cnt);
 221   }
 222   if (stackmap_len != 0) {
 223     write_stackmap_table_attribute(method, stackmap_len);
 224   }
 225   if (local_variable_table_length != 0) {
 226     write_local_variable_table_attribute(method, local_variable_table_length);
 227   }



 228 }
 229 
 230 // Write Exceptions attribute
 231 // JVMSpec|   Exceptions_attribute {
 232 // JVMSpec|     u2 attribute_name_index;
 233 // JVMSpec|     u4 attribute_length;
 234 // JVMSpec|     u2 number_of_exceptions;
 235 // JVMSpec|     u2 exception_index_table[number_of_exceptions];
 236 // JVMSpec|   }
 237 void JvmtiClassFileReconstituter::write_exceptions_attribute(constMethodHandle const_method) {
 238   CheckedExceptionElement* checked_exceptions = const_method->checked_exceptions_start();
 239   int checked_exceptions_length = const_method->checked_exceptions_length();
 240   int size =
 241     2 +                                    // number_of_exceptions
 242     2 * checked_exceptions_length;         // exception_index_table
 243 
 244   write_attribute_name_index("Exceptions");
 245   write_u4(size);
 246   write_u2(checked_exceptions_length);
 247   for (int index = 0; index < checked_exceptions_length; index++) {


 372 // JVMSpec|     u4 attribute_length;
 373 // JVMSpec|     u2 line_number_table_length;
 374 // JVMSpec|     {  u2 start_pc;
 375 // JVMSpec|        u2 line_number;
 376 // JVMSpec|     } line_number_table[line_number_table_length];
 377 // JVMSpec|   }
 378 void JvmtiClassFileReconstituter::write_line_number_table_attribute(methodHandle method,
 379                                                                     u2 num_entries) {
 380 
 381   write_attribute_name_index("LineNumberTable");
 382   write_u4(2 + num_entries * (2 + 2));
 383   write_u2(num_entries);
 384 
 385   CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
 386   while (stream.read_pair()) {
 387     write_u2(stream.bci());
 388     write_u2(stream.line());
 389   }
 390 }
 391 
 392 // Write LineNumberTable attribute
 393 // JVMSpec|   LocalVariableTable_attribute {
 394 // JVMSpec|     u2 attribute_name_index;
 395 // JVMSpec|     u4 attribute_length;
 396 // JVMSpec|     u2 local_variable_table_length;
 397 // JVMSpec|     {  u2 start_pc;
 398 // JVMSpec|       u2 length;
 399 // JVMSpec|       u2 name_index;
 400 // JVMSpec|       u2 descriptor_index;
 401 // JVMSpec|       u2 index;
 402 // JVMSpec|     } local_variable_table[local_variable_table_length];
 403 // JVMSpec|   }
 404 void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHandle method, u2 num_entries) {
 405     write_attribute_name_index("LocalVariableTable");
 406     write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
 407     write_u2(num_entries);
 408 
 409     assert(method->localvariable_table_length() == num_entries, "just checking");
 410 
 411     LocalVariableTableElement *elem = method->localvariable_table_start();
 412     for (int j=0; j<method->localvariable_table_length(); j++) {
 413       write_u2(elem->start_bci);
 414       write_u2(elem->length);
 415       write_u2(elem->name_cp_index);
 416       write_u2(elem->descriptor_cp_index);
 417       write_u2(elem->slot);
 418       elem++;
 419     }
 420 }
 421 

































 422 // Write stack map table attribute
 423 // JSR-202|   StackMapTable_attribute {
 424 // JSR-202|     u2 attribute_name_index;
 425 // JSR-202|     u4 attribute_length;
 426 // JSR-202|     u2 number_of_entries;
 427 // JSR-202|     stack_map_frame_entries[number_of_entries];
 428 // JSR-202|   }
 429 void JvmtiClassFileReconstituter::write_stackmap_table_attribute(methodHandle method,
 430                                                                  int stackmap_len) {
 431 
 432   write_attribute_name_index("StackMapTable");
 433   write_u4(stackmap_len);
 434   memcpy(
 435     writeable_address(stackmap_len),
 436     (void*)(method->stackmap_data()->byte_at_addr(0)),
 437     stackmap_len);
 438 }
 439 
 440 // Write one method_info structure
 441 // JVMSpec|   method_info {




  26 #include "classfile/symbolTable.hpp"
  27 #include "interpreter/bytecodeStream.hpp"
  28 #include "oops/fieldStreams.hpp"
  29 #include "prims/jvmtiClassFileReconstituter.hpp"
  30 #include "runtime/signature.hpp"
  31 #ifdef TARGET_ARCH_x86
  32 # include "bytes_x86.hpp"
  33 #endif
  34 #ifdef TARGET_ARCH_sparc
  35 # include "bytes_sparc.hpp"
  36 #endif
  37 #ifdef TARGET_ARCH_zero
  38 # include "bytes_zero.hpp"
  39 #endif
  40 #ifdef TARGET_ARCH_arm
  41 # include "bytes_arm.hpp"
  42 #endif
  43 #ifdef TARGET_ARCH_ppc
  44 # include "bytes_ppc.hpp"
  45 #endif
  46 // FIXME: add Deprecated attribute
  47 // FIXME: fix Synthetic attribute
  48 // FIXME: per Serguei, add error return handling for constantPoolOopDesc::copy_cpool_bytes()
  49 
  50 
  51 // Write the field information portion of ClassFile structure
  52 // JVMSpec|     u2 fields_count;
  53 // JVMSpec|     field_info fields[fields_count];
  54 void JvmtiClassFileReconstituter::write_field_infos() {
  55   HandleMark hm(thread());
  56   objArrayHandle fields_anno(thread(), ikh()->fields_annotations());
  57 
  58   // Compute the real number of Java fields
  59   int java_fields = ikh()->java_fields_count();
  60 
  61   write_u2(java_fields);
  62   for (JavaFieldStream fs(ikh()); !fs.done(); fs.next()) {
  63     AccessFlags access_flags = fs.access_flags();
  64     int name_index = fs.name_index();
  65     int signature_index = fs.signature_index();
  66     int initial_value_index = fs.initval_index();


 120 // JVMSpec|     u2 attribute_name_index;
 121 // JVMSpec|     u4 attribute_length;
 122 // JVMSpec|     u2 max_stack;
 123 // JVMSpec|     u2 max_locals;
 124 // JVMSpec|     u4 code_length;
 125 // JVMSpec|     u1 code[code_length];
 126 // JVMSpec|     u2 exception_table_length;
 127 // JVMSpec|     {       u2 start_pc;
 128 // JVMSpec|             u2 end_pc;
 129 // JVMSpec|             u2  handler_pc;
 130 // JVMSpec|             u2  catch_type;
 131 // JVMSpec|     }       exception_table[exception_table_length];
 132 // JVMSpec|     u2 attributes_count;
 133 // JVMSpec|     attribute_info attributes[attributes_count];
 134 // JVMSpec|   }
 135 void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
 136   constMethodHandle const_method(thread(), method->constMethod());
 137   u2 line_num_cnt = 0;
 138   int stackmap_len = 0;
 139   int local_variable_table_length = 0;
 140   int local_variable_type_table_length = 0;
 141 
 142   // compute number and length of attributes
 143   int attr_count = 0;
 144   int attr_size = 0;
 145   if (const_method->has_linenumber_table()) {
 146     line_num_cnt = line_number_table_entries(method);
 147     if (line_num_cnt != 0) {
 148       ++attr_count;
 149       // Compute the complete size of the line number table attribute:
 150       //      LineNumberTable_attribute {
 151       //        u2 attribute_name_index;
 152       //        u4 attribute_length;
 153       //        u2 line_number_table_length;
 154       //        {  u2 start_pc;
 155       //           u2 line_number;
 156       //        } line_number_table[line_number_table_length];
 157       //      }
 158       attr_size += 2 + 4 + 2 + line_num_cnt * (2 + 2);
 159     }
 160   }
 161   if (method->has_stackmap_table()) {
 162     stackmap_len = method->stackmap_data()->length();
 163     if (stackmap_len != 0) {
 164       ++attr_count;
 165       // Compute the  size of the stack map table attribute (VM stores raw):
 166       //      StackMapTable_attribute {
 167       //        u2 attribute_name_index;
 168       //        u4 attribute_length;
 169       //        u2 number_of_entries;
 170       //        stack_map_frame_entries[number_of_entries];
 171       //      }
 172       attr_size += 2 + 4 + stackmap_len;
 173     }
 174   }
 175   if (method->has_localvariable_table()) {
 176     local_variable_table_length = method->localvariable_table_length();

 177     if (local_variable_table_length != 0) {
 178       ++attr_count;
 179       // Compute the size of the local variable table attribute (VM stores raw):
 180       // LocalVariableTable_attribute {
 181       //   u2 attribute_name_index;
 182       //   u4 attribute_length;
 183       //   u2 local_variable_table_length;
 184       //   {
 185       //     u2 start_pc;
 186       //     u2 length;
 187       //     u2 name_index;
 188       //     u2 descriptor_index;
 189       //     u2 index;
 190       //   }
 191       attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2);
 192 
 193       // Local variables with generic signatures must have LVTT entries
 194       LocalVariableTableElement *elem = method->localvariable_table_start();
 195       for (int idx = 0; idx < local_variable_table_length; idx++) {
 196         if (elem[idx].signature_cp_index > 0) {
 197           local_variable_type_table_length++;
 198         }
 199       }
 200     }
 201 
 202     if (local_variable_type_table_length != 0) {
 203       ++attr_count;
 204       // Compute the size of the local variable type table attribute (VM stores raw):
 205       // LocalVariableTypeTable_attribute {
 206       //   u2 attribute_name_index;
 207       //   u4 attribute_length;
 208       //   u2 local_variable_type_table_length;
 209       //   {
 210       //     u2 start_pc;
 211       //     u2 length;
 212       //     u2 name_index;
 213       //     u2 signature_index;
 214       //     u2 index;
 215       //   }
 216       attr_size += 2 + 4 + 2 + local_variable_type_table_length * (2 + 2 + 2 + 2 + 2);
 217     }
 218   }
 219 
 220   ExceptionTable exception_table(method());
 221   int exception_table_length = exception_table.length();
 222   int code_size = const_method->code_size();
 223   int size =
 224     2+2+4 +                                // max_stack, max_locals, code_length
 225     code_size +                            // code
 226     2 +                                    // exception_table_length
 227     (2+2+2+2) * exception_table_length +   // exception_table
 228     2 +                                    // attributes_count
 229     attr_size;                             // attributes
 230 
 231   write_attribute_name_index("Code");
 232   write_u4(size);
 233   write_u2(method->max_stack());
 234   write_u2(method->max_locals());
 235   write_u4(code_size);
 236   copy_bytecodes(method, (unsigned char*)writeable_address(code_size));
 237   write_u2(exception_table_length);
 238   for (int index = 0; index < exception_table_length; index++) {
 239     write_u2(exception_table.start_pc(index));
 240     write_u2(exception_table.end_pc(index));
 241     write_u2(exception_table.handler_pc(index));
 242     write_u2(exception_table.catch_type_index(index));
 243   }
 244   write_u2(attr_count);
 245   if (line_num_cnt != 0) {
 246     write_line_number_table_attribute(method, line_num_cnt);
 247   }
 248   if (stackmap_len != 0) {
 249     write_stackmap_table_attribute(method, stackmap_len);
 250   }
 251   if (local_variable_table_length != 0) {
 252     write_local_variable_table_attribute(method, local_variable_table_length);
 253   }
 254   if (local_variable_type_table_length != 0) {
 255     write_local_variable_type_table_attribute(method, local_variable_type_table_length);
 256   }
 257 }
 258 
 259 // Write Exceptions attribute
 260 // JVMSpec|   Exceptions_attribute {
 261 // JVMSpec|     u2 attribute_name_index;
 262 // JVMSpec|     u4 attribute_length;
 263 // JVMSpec|     u2 number_of_exceptions;
 264 // JVMSpec|     u2 exception_index_table[number_of_exceptions];
 265 // JVMSpec|   }
 266 void JvmtiClassFileReconstituter::write_exceptions_attribute(constMethodHandle const_method) {
 267   CheckedExceptionElement* checked_exceptions = const_method->checked_exceptions_start();
 268   int checked_exceptions_length = const_method->checked_exceptions_length();
 269   int size =
 270     2 +                                    // number_of_exceptions
 271     2 * checked_exceptions_length;         // exception_index_table
 272 
 273   write_attribute_name_index("Exceptions");
 274   write_u4(size);
 275   write_u2(checked_exceptions_length);
 276   for (int index = 0; index < checked_exceptions_length; index++) {


 401 // JVMSpec|     u4 attribute_length;
 402 // JVMSpec|     u2 line_number_table_length;
 403 // JVMSpec|     {  u2 start_pc;
 404 // JVMSpec|        u2 line_number;
 405 // JVMSpec|     } line_number_table[line_number_table_length];
 406 // JVMSpec|   }
 407 void JvmtiClassFileReconstituter::write_line_number_table_attribute(methodHandle method,
 408                                                                     u2 num_entries) {
 409 
 410   write_attribute_name_index("LineNumberTable");
 411   write_u4(2 + num_entries * (2 + 2));
 412   write_u2(num_entries);
 413 
 414   CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
 415   while (stream.read_pair()) {
 416     write_u2(stream.bci());
 417     write_u2(stream.line());
 418   }
 419 }
 420 
 421 // Write LocalVariableTable attribute
 422 // JVMSpec|   LocalVariableTable_attribute {
 423 // JVMSpec|     u2 attribute_name_index;
 424 // JVMSpec|     u4 attribute_length;
 425 // JVMSpec|     u2 local_variable_table_length;
 426 // JVMSpec|     {  u2 start_pc;
 427 // JVMSpec|       u2 length;
 428 // JVMSpec|       u2 name_index;
 429 // JVMSpec|       u2 descriptor_index;
 430 // JVMSpec|       u2 index;
 431 // JVMSpec|     } local_variable_table[local_variable_table_length];
 432 // JVMSpec|   }
 433 void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHandle method, u2 num_entries) {
 434     write_attribute_name_index("LocalVariableTable");
 435     write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
 436     write_u2(num_entries);
 437 
 438     assert(method->localvariable_table_length() == num_entries, "just checking");
 439 
 440     LocalVariableTableElement *elem = method->localvariable_table_start();
 441     for (int j=0; j<method->localvariable_table_length(); j++) {
 442       write_u2(elem->start_bci);
 443       write_u2(elem->length);
 444       write_u2(elem->name_cp_index);
 445       write_u2(elem->descriptor_cp_index);
 446       write_u2(elem->slot);
 447       elem++;
 448     }
 449 }
 450 
 451 // Write LocalVariableTypeTable attribute
 452 // JVMSpec|   LocalVariableTypeTable_attribute {
 453 // JVMSpec|     u2 attribute_name_index;
 454 // JVMSpec|     u4 attribute_length;
 455 // JVMSpec|     u2 local_variable_type_table_length;
 456 // JVMSpec|     { u2 start_pc;
 457 // JVMSpec|       u2 length;
 458 // JVMSpec|       u2 name_index;
 459 // JVMSpec|       u2 signature_index;
 460 // JVMSpec|       u2 index;
 461 // JVMSpec|     } local_variable_type_table[local_variable_type_table_length];
 462 // JVMSpec|   }
 463 void JvmtiClassFileReconstituter::write_local_variable_type_table_attribute(methodHandle method, u2 num_entries) {
 464     write_attribute_name_index("LocalVariableTypeTable");
 465     write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
 466     write_u2(num_entries);
 467 
 468     LocalVariableTableElement *elem = method->localvariable_table_start();
 469     for (int j=0; j<method->localvariable_table_length(); j++) {
 470       if (elem->signature_cp_index > 0) {
 471         // Local variable has a generic signature - write LVTT attribute entry
 472         write_u2(elem->start_bci);
 473         write_u2(elem->length);
 474         write_u2(elem->name_cp_index);
 475         write_u2(elem->signature_cp_index);
 476         write_u2(elem->slot);
 477         num_entries--;
 478       }
 479       elem++;
 480     }
 481     assert(num_entries == 0, "just checking");
 482 }
 483 
 484 // Write stack map table attribute
 485 // JSR-202|   StackMapTable_attribute {
 486 // JSR-202|     u2 attribute_name_index;
 487 // JSR-202|     u4 attribute_length;
 488 // JSR-202|     u2 number_of_entries;
 489 // JSR-202|     stack_map_frame_entries[number_of_entries];
 490 // JSR-202|   }
 491 void JvmtiClassFileReconstituter::write_stackmap_table_attribute(methodHandle method,
 492                                                                  int stackmap_len) {
 493 
 494   write_attribute_name_index("StackMapTable");
 495   write_u4(stackmap_len);
 496   memcpy(
 497     writeable_address(stackmap_len),
 498     (void*)(method->stackmap_data()->byte_at_addr(0)),
 499     stackmap_len);
 500 }
 501 
 502 // Write one method_info structure
 503 // JVMSpec|   method_info {