提交 5b3c38a8 编写于 作者: M minqi

7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method

Summary: JVMTI REtruncformClasses must support LocalVariableTypeTable attribute
Reviewed-by: dcubed, dsamersoff, rbackman
Contributed-by: serguei.spitsyn@oracle.com
上级 c151d2ae
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#ifdef TARGET_ARCH_ppc #ifdef TARGET_ARCH_ppc
# include "bytes_ppc.hpp" # include "bytes_ppc.hpp"
#endif #endif
// FIXME: add Deprecated, LVTT attributes // FIXME: add Deprecated attribute
// FIXME: fix Synthetic attribute // FIXME: fix Synthetic attribute
// FIXME: per Serguei, add error return handling for ConstantPool::copy_cpool_bytes() // FIXME: per Serguei, add error return handling for ConstantPool::copy_cpool_bytes()
...@@ -135,6 +135,7 @@ void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) { ...@@ -135,6 +135,7 @@ void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
u2 line_num_cnt = 0; u2 line_num_cnt = 0;
int stackmap_len = 0; int stackmap_len = 0;
int local_variable_table_length = 0; int local_variable_table_length = 0;
int local_variable_type_table_length = 0;
// compute number and length of attributes // compute number and length of attributes
int attr_count = 0; int attr_count = 0;
...@@ -171,8 +172,8 @@ void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) { ...@@ -171,8 +172,8 @@ void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
} }
if (method->has_localvariable_table()) { if (method->has_localvariable_table()) {
local_variable_table_length = method->localvariable_table_length(); local_variable_table_length = method->localvariable_table_length();
++attr_count;
if (local_variable_table_length != 0) { if (local_variable_table_length != 0) {
++attr_count;
// Compute the size of the local variable table attribute (VM stores raw): // Compute the size of the local variable table attribute (VM stores raw):
// LocalVariableTable_attribute { // LocalVariableTable_attribute {
// u2 attribute_name_index; // u2 attribute_name_index;
...@@ -186,6 +187,31 @@ void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) { ...@@ -186,6 +187,31 @@ void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
// u2 index; // u2 index;
// } // }
attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2); 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);
}
} }
} }
...@@ -223,6 +249,9 @@ void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) { ...@@ -223,6 +249,9 @@ void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
if (local_variable_table_length != 0) { if (local_variable_table_length != 0) {
write_local_variable_table_attribute(method, local_variable_table_length); 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 // Write Exceptions attribute
...@@ -387,7 +416,7 @@ void JvmtiClassFileReconstituter::write_line_number_table_attribute(methodHandle ...@@ -387,7 +416,7 @@ void JvmtiClassFileReconstituter::write_line_number_table_attribute(methodHandle
} }
} }
// Write LineNumberTable attribute // Write LocalVariableTable attribute
// JVMSpec| LocalVariableTable_attribute { // JVMSpec| LocalVariableTable_attribute {
// JVMSpec| u2 attribute_name_index; // JVMSpec| u2 attribute_name_index;
// JVMSpec| u4 attribute_length; // JVMSpec| u4 attribute_length;
...@@ -417,6 +446,39 @@ void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHan ...@@ -417,6 +446,39 @@ void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHan
} }
} }
// 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 // Write stack map table attribute
// JSR-202| StackMapTable_attribute { // JSR-202| StackMapTable_attribute {
// JSR-202| u2 attribute_name_index; // JSR-202| u2 attribute_name_index;
......
...@@ -120,6 +120,7 @@ class JvmtiClassFileReconstituter : public JvmtiConstantPoolReconstituter { ...@@ -120,6 +120,7 @@ class JvmtiClassFileReconstituter : public JvmtiConstantPoolReconstituter {
u2 line_number_table_entries(methodHandle method); u2 line_number_table_entries(methodHandle method);
void write_line_number_table_attribute(methodHandle method, u2 num_entries); void write_line_number_table_attribute(methodHandle method, u2 num_entries);
void write_local_variable_table_attribute(methodHandle method, u2 num_entries); void write_local_variable_table_attribute(methodHandle method, u2 num_entries);
void write_local_variable_type_table_attribute(methodHandle method, u2 num_entries);
void write_stackmap_table_attribute(methodHandle method, int stackmap_table_len); void write_stackmap_table_attribute(methodHandle method, int stackmap_table_len);
u2 inner_classes_attribute_length(); u2 inner_classes_attribute_length();
void write_inner_classes_attribute(int length); void write_inner_classes_attribute(int length);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册