comparison src/share/vm/prims/jvmtiClassFileReconstituter.cpp @ 6772:1cb8583c3da8

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
author minqi
date Tue, 18 Sep 2012 10:10:43 -0700
parents da91efe96a93
children 18fb7da42534 64812523d72e
comparison
equal deleted inserted replaced
6769:c088e2e95e69 6772:1cb8583c3da8
41 # include "bytes_arm.hpp" 41 # include "bytes_arm.hpp"
42 #endif 42 #endif
43 #ifdef TARGET_ARCH_ppc 43 #ifdef TARGET_ARCH_ppc
44 # include "bytes_ppc.hpp" 44 # include "bytes_ppc.hpp"
45 #endif 45 #endif
46 // FIXME: add Deprecated, LVTT attributes 46 // FIXME: add Deprecated attribute
47 // FIXME: fix Synthetic attribute 47 // FIXME: fix Synthetic attribute
48 // FIXME: per Serguei, add error return handling for ConstantPool::copy_cpool_bytes() 48 // FIXME: per Serguei, add error return handling for ConstantPool::copy_cpool_bytes()
49 49
50 50
51 // Write the field information portion of ClassFile structure 51 // Write the field information portion of ClassFile structure
133 void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) { 133 void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
134 ConstMethod* const_method = method->constMethod(); 134 ConstMethod* const_method = method->constMethod();
135 u2 line_num_cnt = 0; 135 u2 line_num_cnt = 0;
136 int stackmap_len = 0; 136 int stackmap_len = 0;
137 int local_variable_table_length = 0; 137 int local_variable_table_length = 0;
138 int local_variable_type_table_length = 0;
138 139
139 // compute number and length of attributes 140 // compute number and length of attributes
140 int attr_count = 0; 141 int attr_count = 0;
141 int attr_size = 0; 142 int attr_size = 0;
142 if (const_method->has_linenumber_table()) { 143 if (const_method->has_linenumber_table()) {
169 attr_size += 2 + 4 + stackmap_len; 170 attr_size += 2 + 4 + stackmap_len;
170 } 171 }
171 } 172 }
172 if (method->has_localvariable_table()) { 173 if (method->has_localvariable_table()) {
173 local_variable_table_length = method->localvariable_table_length(); 174 local_variable_table_length = method->localvariable_table_length();
174 ++attr_count;
175 if (local_variable_table_length != 0) { 175 if (local_variable_table_length != 0) {
176 ++attr_count;
176 // Compute the size of the local variable table attribute (VM stores raw): 177 // Compute the size of the local variable table attribute (VM stores raw):
177 // LocalVariableTable_attribute { 178 // LocalVariableTable_attribute {
178 // u2 attribute_name_index; 179 // u2 attribute_name_index;
179 // u4 attribute_length; 180 // u4 attribute_length;
180 // u2 local_variable_table_length; 181 // u2 local_variable_table_length;
184 // u2 name_index; 185 // u2 name_index;
185 // u2 descriptor_index; 186 // u2 descriptor_index;
186 // u2 index; 187 // u2 index;
187 // } 188 // }
188 attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2); 189 attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2);
190
191 // Local variables with generic signatures must have LVTT entries
192 LocalVariableTableElement *elem = method->localvariable_table_start();
193 for (int idx = 0; idx < local_variable_table_length; idx++) {
194 if (elem[idx].signature_cp_index != 0) {
195 local_variable_type_table_length++;
196 }
197 }
198
199 if (local_variable_type_table_length != 0) {
200 ++attr_count;
201 // Compute the size of the local variable type table attribute (VM stores raw):
202 // LocalVariableTypeTable_attribute {
203 // u2 attribute_name_index;
204 // u4 attribute_length;
205 // u2 local_variable_type_table_length;
206 // {
207 // u2 start_pc;
208 // u2 length;
209 // u2 name_index;
210 // u2 signature_index;
211 // u2 index;
212 // }
213 attr_size += 2 + 4 + 2 + local_variable_type_table_length * (2 + 2 + 2 + 2 + 2);
214 }
189 } 215 }
190 } 216 }
191 217
192 ExceptionTable exception_table(method()); 218 ExceptionTable exception_table(method());
193 int exception_table_length = exception_table.length(); 219 int exception_table_length = exception_table.length();
220 if (stackmap_len != 0) { 246 if (stackmap_len != 0) {
221 write_stackmap_table_attribute(method, stackmap_len); 247 write_stackmap_table_attribute(method, stackmap_len);
222 } 248 }
223 if (local_variable_table_length != 0) { 249 if (local_variable_table_length != 0) {
224 write_local_variable_table_attribute(method, local_variable_table_length); 250 write_local_variable_table_attribute(method, local_variable_table_length);
251 }
252 if (local_variable_type_table_length != 0) {
253 write_local_variable_type_table_attribute(method, local_variable_type_table_length);
225 } 254 }
226 } 255 }
227 256
228 // Write Exceptions attribute 257 // Write Exceptions attribute
229 // JVMSpec| Exceptions_attribute { 258 // JVMSpec| Exceptions_attribute {
385 write_u2(stream.bci()); 414 write_u2(stream.bci());
386 write_u2(stream.line()); 415 write_u2(stream.line());
387 } 416 }
388 } 417 }
389 418
390 // Write LineNumberTable attribute 419 // Write LocalVariableTable attribute
391 // JVMSpec| LocalVariableTable_attribute { 420 // JVMSpec| LocalVariableTable_attribute {
392 // JVMSpec| u2 attribute_name_index; 421 // JVMSpec| u2 attribute_name_index;
393 // JVMSpec| u4 attribute_length; 422 // JVMSpec| u4 attribute_length;
394 // JVMSpec| u2 local_variable_table_length; 423 // JVMSpec| u2 local_variable_table_length;
395 // JVMSpec| { u2 start_pc; 424 // JVMSpec| { u2 start_pc;
413 write_u2(elem->name_cp_index); 442 write_u2(elem->name_cp_index);
414 write_u2(elem->descriptor_cp_index); 443 write_u2(elem->descriptor_cp_index);
415 write_u2(elem->slot); 444 write_u2(elem->slot);
416 elem++; 445 elem++;
417 } 446 }
447 }
448
449 // Write LocalVariableTypeTable attribute
450 // JVMSpec| LocalVariableTypeTable_attribute {
451 // JVMSpec| u2 attribute_name_index;
452 // JVMSpec| u4 attribute_length;
453 // JVMSpec| u2 local_variable_type_table_length;
454 // JVMSpec| { u2 start_pc;
455 // JVMSpec| u2 length;
456 // JVMSpec| u2 name_index;
457 // JVMSpec| u2 signature_index;
458 // JVMSpec| u2 index;
459 // JVMSpec| } local_variable_type_table[local_variable_type_table_length];
460 // JVMSpec| }
461 void JvmtiClassFileReconstituter::write_local_variable_type_table_attribute(methodHandle method, u2 num_entries) {
462 write_attribute_name_index("LocalVariableTypeTable");
463 write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
464 write_u2(num_entries);
465
466 LocalVariableTableElement *elem = method->localvariable_table_start();
467 for (int j=0; j<method->localvariable_table_length(); j++) {
468 if (elem->signature_cp_index > 0) {
469 // Local variable has a generic signature - write LVTT attribute entry
470 write_u2(elem->start_bci);
471 write_u2(elem->length);
472 write_u2(elem->name_cp_index);
473 write_u2(elem->signature_cp_index);
474 write_u2(elem->slot);
475 num_entries--;
476 }
477 elem++;
478 }
479 assert(num_entries == 0, "just checking");
418 } 480 }
419 481
420 // Write stack map table attribute 482 // Write stack map table attribute
421 // JSR-202| StackMapTable_attribute { 483 // JSR-202| StackMapTable_attribute {
422 // JSR-202| u2 attribute_name_index; 484 // JSR-202| u2 attribute_name_index;