comparison src/share/vm/prims/jvmtiClassFileReconstituter.cpp @ 4718:c01e115b095e

7064927: retransformClasses() does not pass in LocalVariableTable of a method Summary: Handle LVT attribute in the class file reconstitutor. Reviewed-by: phh, coleenp Contributed-by: thomaswue <thomas.wuerthinger@oracle.com>
author coleenp
date Wed, 21 Dec 2011 16:41:15 -0500
parents 35c656d0b685
children ff29ce866f23
comparison
equal deleted inserted replaced
4716:4502fd5c7698 4718:c01e115b095e
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, LVT, LVTT attributes 46 // FIXME: add Deprecated, LVTT attributes
47 // FIXME: fix Synthetic attribute 47 // FIXME: fix Synthetic attribute
48 // FIXME: per Serguei, add error return handling for constantPoolOopDesc::copy_cpool_bytes() 48 // FIXME: per Serguei, add error return handling for constantPoolOopDesc::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
134 // JVMSpec| } 134 // JVMSpec| }
135 void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) { 135 void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
136 constMethodHandle const_method(thread(), method->constMethod()); 136 constMethodHandle const_method(thread(), method->constMethod());
137 u2 line_num_cnt = 0; 137 u2 line_num_cnt = 0;
138 int stackmap_len = 0; 138 int stackmap_len = 0;
139 139 int local_variable_table_length = 0;
140 // compute number and length of attributes -- FIXME: for now no LVT 140
141 // compute number and length of attributes
141 int attr_count = 0; 142 int attr_count = 0;
142 int attr_size = 0; 143 int attr_size = 0;
143 if (const_method->has_linenumber_table()) { 144 if (const_method->has_linenumber_table()) {
144 line_num_cnt = line_number_table_entries(method); 145 line_num_cnt = line_number_table_entries(method);
145 if (line_num_cnt != 0) { 146 if (line_num_cnt != 0) {
168 // stack_map_frame_entries[number_of_entries]; 169 // stack_map_frame_entries[number_of_entries];
169 // } 170 // }
170 attr_size += 2 + 4 + stackmap_len; 171 attr_size += 2 + 4 + stackmap_len;
171 } 172 }
172 } 173 }
174 if (method->has_localvariable_table()) {
175 local_variable_table_length = method->localvariable_table_length();
176 ++attr_count;
177 if (local_variable_table_length != 0) {
178 // Compute the size of the local variable table attribute (VM stores raw):
179 // LocalVariableTable_attribute {
180 // u2 attribute_name_index;
181 // u4 attribute_length;
182 // u2 local_variable_table_length;
183 // {
184 // u2 start_pc;
185 // u2 length;
186 // u2 name_index;
187 // u2 descriptor_index;
188 // u2 index;
189 // }
190 attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2);
191 }
192 }
173 193
174 typeArrayHandle exception_table(thread(), const_method->exception_table()); 194 typeArrayHandle exception_table(thread(), const_method->exception_table());
175 int exception_table_length = exception_table->length(); 195 int exception_table_length = exception_table->length();
176 int exception_table_entries = exception_table_length / 4; 196 int exception_table_entries = exception_table_length / 4;
177 int code_size = const_method->code_size(); 197 int code_size = const_method->code_size();
201 write_line_number_table_attribute(method, line_num_cnt); 221 write_line_number_table_attribute(method, line_num_cnt);
202 } 222 }
203 if (stackmap_len != 0) { 223 if (stackmap_len != 0) {
204 write_stackmap_table_attribute(method, stackmap_len); 224 write_stackmap_table_attribute(method, stackmap_len);
205 } 225 }
206 226 if (local_variable_table_length != 0) {
207 // FIXME: write LVT attribute 227 write_local_variable_table_attribute(method, local_variable_table_length);
228 }
208 } 229 }
209 230
210 // Write Exceptions attribute 231 // Write Exceptions attribute
211 // JVMSpec| Exceptions_attribute { 232 // JVMSpec| Exceptions_attribute {
212 // JVMSpec| u2 attribute_name_index; 233 // JVMSpec| u2 attribute_name_index;
367 CompressedLineNumberReadStream stream(method->compressed_linenumber_table()); 388 CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
368 while (stream.read_pair()) { 389 while (stream.read_pair()) {
369 write_u2(stream.bci()); 390 write_u2(stream.bci());
370 write_u2(stream.line()); 391 write_u2(stream.line());
371 } 392 }
393 }
394
395 // Write LineNumberTable attribute
396 // JVMSpec| LocalVariableTable_attribute {
397 // JVMSpec| u2 attribute_name_index;
398 // JVMSpec| u4 attribute_length;
399 // JVMSpec| u2 local_variable_table_length;
400 // JVMSpec| { u2 start_pc;
401 // JVMSpec| u2 length;
402 // JVMSpec| u2 name_index;
403 // JVMSpec| u2 descriptor_index;
404 // JVMSpec| u2 index;
405 // JVMSpec| } local_variable_table[local_variable_table_length];
406 // JVMSpec| }
407 void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHandle method, u2 num_entries) {
408 write_attribute_name_index("LocalVariableTable");
409 write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
410 write_u2(num_entries);
411
412 assert(method->localvariable_table_length() == num_entries, "just checking");
413
414 LocalVariableTableElement *elem = method->localvariable_table_start();
415 for (int j=0; j<method->localvariable_table_length(); j++) {
416 write_u2(elem->start_bci);
417 write_u2(elem->length);
418 write_u2(elem->name_cp_index);
419 write_u2(elem->descriptor_cp_index);
420 write_u2(elem->slot);
421 elem++;
422 }
372 } 423 }
373 424
374 // Write stack map table attribute 425 // Write stack map table attribute
375 // JSR-202| StackMapTable_attribute { 426 // JSR-202| StackMapTable_attribute {
376 // JSR-202| u2 attribute_name_index; 427 // JSR-202| u2 attribute_name_index;