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;