src/share/vm/prims/jvmtiClassFileReconstituter.cpp

Print this page

        

*** 41,51 **** # include "bytes_arm.hpp" #endif #ifdef TARGET_ARCH_ppc # include "bytes_ppc.hpp" #endif ! // FIXME: add Deprecated, LVTT attributes // FIXME: fix Synthetic attribute // FIXME: per Serguei, add error return handling for constantPoolOopDesc::copy_cpool_bytes() // Write the field information portion of ClassFile structure --- 41,51 ---- # include "bytes_arm.hpp" #endif #ifdef TARGET_ARCH_ppc # include "bytes_ppc.hpp" #endif ! // FIXME: add Deprecated attribute // FIXME: fix Synthetic attribute // FIXME: per Serguei, add error return handling for constantPoolOopDesc::copy_cpool_bytes() // Write the field information portion of ClassFile structure
*** 135,144 **** --- 135,145 ---- void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) { constMethodHandle const_method(thread(), method->constMethod()); u2 line_num_cnt = 0; int stackmap_len = 0; int local_variable_table_length = 0; + int local_variable_type_table_length = 0; // compute number and length of attributes int attr_count = 0; int attr_size = 0; if (const_method->has_linenumber_table()) {
*** 171,182 **** 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; --- 172,183 ---- attr_size += 2 + 4 + stackmap_len; } } if (method->has_localvariable_table()) { local_variable_table_length = method->localvariable_table_length(); if (local_variable_table_length != 0) { + ++attr_count; // 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;
*** 186,198 **** --- 187,224 ---- // u2 name_index; // u2 descriptor_index; // u2 index; // } attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2); + + // Local variables with generic signatures must have LVTT entries + LocalVariableTableElement *elem = method->localvariable_table_start(); + for (int idx = 0; idx < local_variable_table_length; idx++) { + if (elem[idx].signature_cp_index != 0) { + local_variable_type_table_length++; } } + if (local_variable_type_table_length != 0) { + ++attr_count; + // Compute the size of the local variable type table attribute (VM stores raw): + // LocalVariableTypeTable_attribute { + // u2 attribute_name_index; + // u4 attribute_length; + // u2 local_variable_type_table_length; + // { + // u2 start_pc; + // u2 length; + // u2 name_index; + // u2 signature_index; + // u2 index; + // } + attr_size += 2 + 4 + 2 + local_variable_type_table_length * (2 + 2 + 2 + 2 + 2); + } + } + } + ExceptionTable exception_table(method()); int exception_table_length = exception_table.length(); int code_size = const_method->code_size(); int size = 2+2+4 + // max_stack, max_locals, code_length
*** 223,232 **** --- 249,261 ---- write_stackmap_table_attribute(method, stackmap_len); } if (local_variable_table_length != 0) { write_local_variable_table_attribute(method, local_variable_table_length); } + if (local_variable_type_table_length != 0) { + write_local_variable_type_table_attribute(method, local_variable_type_table_length); + } } // Write Exceptions attribute // JVMSpec| Exceptions_attribute { // JVMSpec| u2 attribute_name_index;
*** 387,397 **** write_u2(stream.bci()); write_u2(stream.line()); } } ! // 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; --- 416,426 ---- write_u2(stream.bci()); write_u2(stream.line()); } } ! // Write LocalVariableTable attribute // JVMSpec| LocalVariableTable_attribute { // JVMSpec| u2 attribute_name_index; // JVMSpec| u4 attribute_length; // JVMSpec| u2 local_variable_table_length; // JVMSpec| { u2 start_pc;
*** 417,426 **** --- 446,488 ---- write_u2(elem->slot); elem++; } } + // Write LocalVariableTypeTable attribute + // JVMSpec| LocalVariableTypeTable_attribute { + // JVMSpec| u2 attribute_name_index; + // JVMSpec| u4 attribute_length; + // JVMSpec| u2 local_variable_type_table_length; + // JVMSpec| { u2 start_pc; + // JVMSpec| u2 length; + // JVMSpec| u2 name_index; + // JVMSpec| u2 signature_index; + // JVMSpec| u2 index; + // JVMSpec| } local_variable_type_table[local_variable_type_table_length]; + // JVMSpec| } + void JvmtiClassFileReconstituter::write_local_variable_type_table_attribute(methodHandle method, u2 num_entries) { + write_attribute_name_index("LocalVariableTypeTable"); + write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2)); + write_u2(num_entries); + + LocalVariableTableElement *elem = method->localvariable_table_start(); + for (int j=0; j<method->localvariable_table_length(); j++) { + if (elem->signature_cp_index > 0) { + // Local variable has a generic signature - write LVTT attribute entry + write_u2(elem->start_bci); + write_u2(elem->length); + write_u2(elem->name_cp_index); + write_u2(elem->signature_cp_index); + write_u2(elem->slot); + num_entries--; + } + elem++; + } + assert(num_entries == 0, "just checking"); + } + // Write stack map table attribute // JSR-202| StackMapTable_attribute { // JSR-202| u2 attribute_name_index; // JSR-202| u4 attribute_length; // JSR-202| u2 number_of_entries;