Mercurial > hg > graal-jvmci-8
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; |