1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,889 @@ 1.4 +/* 1.5 + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "classfile/symbolTable.hpp" 1.30 +#include "interpreter/bytecodeStream.hpp" 1.31 +#include "oops/fieldStreams.hpp" 1.32 +#include "prims/jvmtiClassFileReconstituter.hpp" 1.33 +#include "runtime/signature.hpp" 1.34 +#ifdef TARGET_ARCH_x86 1.35 +# include "bytes_x86.hpp" 1.36 +#endif 1.37 +#ifdef TARGET_ARCH_sparc 1.38 +# include "bytes_sparc.hpp" 1.39 +#endif 1.40 +#ifdef TARGET_ARCH_zero 1.41 +# include "bytes_zero.hpp" 1.42 +#endif 1.43 +#ifdef TARGET_ARCH_arm 1.44 +# include "bytes_arm.hpp" 1.45 +#endif 1.46 +#ifdef TARGET_ARCH_ppc 1.47 +# include "bytes_ppc.hpp" 1.48 +#endif 1.49 +// FIXME: add Deprecated attribute 1.50 +// FIXME: fix Synthetic attribute 1.51 +// FIXME: per Serguei, add error return handling for ConstantPool::copy_cpool_bytes() 1.52 + 1.53 + 1.54 +// Write the field information portion of ClassFile structure 1.55 +// JVMSpec| u2 fields_count; 1.56 +// JVMSpec| field_info fields[fields_count]; 1.57 +void JvmtiClassFileReconstituter::write_field_infos() { 1.58 + HandleMark hm(thread()); 1.59 + Array<AnnotationArray*>* fields_anno = ikh()->fields_annotations(); 1.60 + 1.61 + // Compute the real number of Java fields 1.62 + int java_fields = ikh()->java_fields_count(); 1.63 + 1.64 + write_u2(java_fields); 1.65 + for (JavaFieldStream fs(ikh()); !fs.done(); fs.next()) { 1.66 + AccessFlags access_flags = fs.access_flags(); 1.67 + int name_index = fs.name_index(); 1.68 + int signature_index = fs.signature_index(); 1.69 + int initial_value_index = fs.initval_index(); 1.70 + guarantee(name_index != 0 && signature_index != 0, "bad constant pool index for field"); 1.71 + // int offset = ikh()->field_offset( index ); 1.72 + int generic_signature_index = fs.generic_signature_index(); 1.73 + AnnotationArray* anno = fields_anno == NULL ? NULL : fields_anno->at(fs.index()); 1.74 + 1.75 + // JVMSpec| field_info { 1.76 + // JVMSpec| u2 access_flags; 1.77 + // JVMSpec| u2 name_index; 1.78 + // JVMSpec| u2 descriptor_index; 1.79 + // JVMSpec| u2 attributes_count; 1.80 + // JVMSpec| attribute_info attributes[attributes_count]; 1.81 + // JVMSpec| } 1.82 + 1.83 + write_u2(access_flags.as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS); 1.84 + write_u2(name_index); 1.85 + write_u2(signature_index); 1.86 + int attr_count = 0; 1.87 + if (initial_value_index != 0) { 1.88 + ++attr_count; 1.89 + } 1.90 + if (access_flags.is_synthetic()) { 1.91 + // ++attr_count; 1.92 + } 1.93 + if (generic_signature_index != 0) { 1.94 + ++attr_count; 1.95 + } 1.96 + if (anno != NULL) { 1.97 + ++attr_count; // has RuntimeVisibleAnnotations attribute 1.98 + } 1.99 + 1.100 + write_u2(attr_count); 1.101 + 1.102 + if (initial_value_index != 0) { 1.103 + write_attribute_name_index("ConstantValue"); 1.104 + write_u4(2); //length always 2 1.105 + write_u2(initial_value_index); 1.106 + } 1.107 + if (access_flags.is_synthetic()) { 1.108 + // write_synthetic_attribute(); 1.109 + } 1.110 + if (generic_signature_index != 0) { 1.111 + write_signature_attribute(generic_signature_index); 1.112 + } 1.113 + if (anno != NULL) { 1.114 + write_annotations_attribute("RuntimeVisibleAnnotations", anno); 1.115 + } 1.116 + } 1.117 +} 1.118 + 1.119 +// Write Code attribute 1.120 +// JVMSpec| Code_attribute { 1.121 +// JVMSpec| u2 attribute_name_index; 1.122 +// JVMSpec| u4 attribute_length; 1.123 +// JVMSpec| u2 max_stack; 1.124 +// JVMSpec| u2 max_locals; 1.125 +// JVMSpec| u4 code_length; 1.126 +// JVMSpec| u1 code[code_length]; 1.127 +// JVMSpec| u2 exception_table_length; 1.128 +// JVMSpec| { u2 start_pc; 1.129 +// JVMSpec| u2 end_pc; 1.130 +// JVMSpec| u2 handler_pc; 1.131 +// JVMSpec| u2 catch_type; 1.132 +// JVMSpec| } exception_table[exception_table_length]; 1.133 +// JVMSpec| u2 attributes_count; 1.134 +// JVMSpec| attribute_info attributes[attributes_count]; 1.135 +// JVMSpec| } 1.136 +void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) { 1.137 + ConstMethod* const_method = method->constMethod(); 1.138 + u2 line_num_cnt = 0; 1.139 + int stackmap_len = 0; 1.140 + int local_variable_table_length = 0; 1.141 + int local_variable_type_table_length = 0; 1.142 + 1.143 + // compute number and length of attributes 1.144 + int attr_count = 0; 1.145 + int attr_size = 0; 1.146 + if (const_method->has_linenumber_table()) { 1.147 + line_num_cnt = line_number_table_entries(method); 1.148 + if (line_num_cnt != 0) { 1.149 + ++attr_count; 1.150 + // Compute the complete size of the line number table attribute: 1.151 + // LineNumberTable_attribute { 1.152 + // u2 attribute_name_index; 1.153 + // u4 attribute_length; 1.154 + // u2 line_number_table_length; 1.155 + // { u2 start_pc; 1.156 + // u2 line_number; 1.157 + // } line_number_table[line_number_table_length]; 1.158 + // } 1.159 + attr_size += 2 + 4 + 2 + line_num_cnt * (2 + 2); 1.160 + } 1.161 + } 1.162 + if (method->has_stackmap_table()) { 1.163 + stackmap_len = method->stackmap_data()->length(); 1.164 + if (stackmap_len != 0) { 1.165 + ++attr_count; 1.166 + // Compute the size of the stack map table attribute (VM stores raw): 1.167 + // StackMapTable_attribute { 1.168 + // u2 attribute_name_index; 1.169 + // u4 attribute_length; 1.170 + // u2 number_of_entries; 1.171 + // stack_map_frame_entries[number_of_entries]; 1.172 + // } 1.173 + attr_size += 2 + 4 + stackmap_len; 1.174 + } 1.175 + } 1.176 + if (method->has_localvariable_table()) { 1.177 + local_variable_table_length = method->localvariable_table_length(); 1.178 + if (local_variable_table_length != 0) { 1.179 + ++attr_count; 1.180 + // Compute the size of the local variable table attribute (VM stores raw): 1.181 + // LocalVariableTable_attribute { 1.182 + // u2 attribute_name_index; 1.183 + // u4 attribute_length; 1.184 + // u2 local_variable_table_length; 1.185 + // { 1.186 + // u2 start_pc; 1.187 + // u2 length; 1.188 + // u2 name_index; 1.189 + // u2 descriptor_index; 1.190 + // u2 index; 1.191 + // } 1.192 + attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2); 1.193 + 1.194 + // Local variables with generic signatures must have LVTT entries 1.195 + LocalVariableTableElement *elem = method->localvariable_table_start(); 1.196 + for (int idx = 0; idx < local_variable_table_length; idx++) { 1.197 + if (elem[idx].signature_cp_index != 0) { 1.198 + local_variable_type_table_length++; 1.199 + } 1.200 + } 1.201 + 1.202 + if (local_variable_type_table_length != 0) { 1.203 + ++attr_count; 1.204 + // Compute the size of the local variable type table attribute (VM stores raw): 1.205 + // LocalVariableTypeTable_attribute { 1.206 + // u2 attribute_name_index; 1.207 + // u4 attribute_length; 1.208 + // u2 local_variable_type_table_length; 1.209 + // { 1.210 + // u2 start_pc; 1.211 + // u2 length; 1.212 + // u2 name_index; 1.213 + // u2 signature_index; 1.214 + // u2 index; 1.215 + // } 1.216 + attr_size += 2 + 4 + 2 + local_variable_type_table_length * (2 + 2 + 2 + 2 + 2); 1.217 + } 1.218 + } 1.219 + } 1.220 + 1.221 + ExceptionTable exception_table(method()); 1.222 + int exception_table_length = exception_table.length(); 1.223 + int code_size = const_method->code_size(); 1.224 + int size = 1.225 + 2+2+4 + // max_stack, max_locals, code_length 1.226 + code_size + // code 1.227 + 2 + // exception_table_length 1.228 + (2+2+2+2) * exception_table_length + // exception_table 1.229 + 2 + // attributes_count 1.230 + attr_size; // attributes 1.231 + 1.232 + write_attribute_name_index("Code"); 1.233 + write_u4(size); 1.234 + write_u2(method->verifier_max_stack()); 1.235 + write_u2(method->max_locals()); 1.236 + write_u4(code_size); 1.237 + copy_bytecodes(method, (unsigned char*)writeable_address(code_size)); 1.238 + write_u2(exception_table_length); 1.239 + for (int index = 0; index < exception_table_length; index++) { 1.240 + write_u2(exception_table.start_pc(index)); 1.241 + write_u2(exception_table.end_pc(index)); 1.242 + write_u2(exception_table.handler_pc(index)); 1.243 + write_u2(exception_table.catch_type_index(index)); 1.244 + } 1.245 + write_u2(attr_count); 1.246 + if (line_num_cnt != 0) { 1.247 + write_line_number_table_attribute(method, line_num_cnt); 1.248 + } 1.249 + if (stackmap_len != 0) { 1.250 + write_stackmap_table_attribute(method, stackmap_len); 1.251 + } 1.252 + if (local_variable_table_length != 0) { 1.253 + write_local_variable_table_attribute(method, local_variable_table_length); 1.254 + } 1.255 + if (local_variable_type_table_length != 0) { 1.256 + write_local_variable_type_table_attribute(method, local_variable_type_table_length); 1.257 + } 1.258 +} 1.259 + 1.260 +// Write Exceptions attribute 1.261 +// JVMSpec| Exceptions_attribute { 1.262 +// JVMSpec| u2 attribute_name_index; 1.263 +// JVMSpec| u4 attribute_length; 1.264 +// JVMSpec| u2 number_of_exceptions; 1.265 +// JVMSpec| u2 exception_index_table[number_of_exceptions]; 1.266 +// JVMSpec| } 1.267 +void JvmtiClassFileReconstituter::write_exceptions_attribute(ConstMethod* const_method) { 1.268 + CheckedExceptionElement* checked_exceptions = const_method->checked_exceptions_start(); 1.269 + int checked_exceptions_length = const_method->checked_exceptions_length(); 1.270 + int size = 1.271 + 2 + // number_of_exceptions 1.272 + 2 * checked_exceptions_length; // exception_index_table 1.273 + 1.274 + write_attribute_name_index("Exceptions"); 1.275 + write_u4(size); 1.276 + write_u2(checked_exceptions_length); 1.277 + for (int index = 0; index < checked_exceptions_length; index++) { 1.278 + write_u2(checked_exceptions[index].class_cp_index); 1.279 + } 1.280 +} 1.281 + 1.282 +// Write SourceFile attribute 1.283 +// JVMSpec| SourceFile_attribute { 1.284 +// JVMSpec| u2 attribute_name_index; 1.285 +// JVMSpec| u4 attribute_length; 1.286 +// JVMSpec| u2 sourcefile_index; 1.287 +// JVMSpec| } 1.288 +void JvmtiClassFileReconstituter::write_source_file_attribute() { 1.289 + assert(ikh()->source_file_name() != NULL, "caller must check"); 1.290 + 1.291 + write_attribute_name_index("SourceFile"); 1.292 + write_u4(2); // always length 2 1.293 + write_u2(symbol_to_cpool_index(ikh()->source_file_name())); 1.294 +} 1.295 + 1.296 +// Write SourceDebugExtension attribute 1.297 +// JSR45| SourceDebugExtension_attribute { 1.298 +// JSR45| u2 attribute_name_index; 1.299 +// JSR45| u4 attribute_length; 1.300 +// JSR45| u1 debug_extension[attribute_length]; 1.301 +// JSR45| } 1.302 +void JvmtiClassFileReconstituter::write_source_debug_extension_attribute() { 1.303 + assert(ikh()->source_debug_extension() != NULL, "caller must check"); 1.304 + 1.305 + write_attribute_name_index("SourceDebugExtension"); 1.306 + int len = (int)strlen(ikh()->source_debug_extension()); 1.307 + write_u4(len); 1.308 + u1* ext = (u1*)ikh()->source_debug_extension(); 1.309 + for (int i=0; i<len; i++) { 1.310 + write_u1(ext[i]); 1.311 + } 1.312 +} 1.313 + 1.314 +// Write (generic) Signature attribute 1.315 +// JVMSpec| Signature_attribute { 1.316 +// JVMSpec| u2 attribute_name_index; 1.317 +// JVMSpec| u4 attribute_length; 1.318 +// JVMSpec| u2 signature_index; 1.319 +// JVMSpec| } 1.320 +void JvmtiClassFileReconstituter::write_signature_attribute(u2 generic_signature_index) { 1.321 + write_attribute_name_index("Signature"); 1.322 + write_u4(2); // always length 2 1.323 + write_u2(generic_signature_index); 1.324 +} 1.325 + 1.326 +// Compute the number of entries in the InnerClasses attribute 1.327 +u2 JvmtiClassFileReconstituter::inner_classes_attribute_length() { 1.328 + InnerClassesIterator iter(ikh()); 1.329 + return iter.length(); 1.330 +} 1.331 + 1.332 +// Write an annotation attribute. The VM stores them in raw form, so all we need 1.333 +// to do is add the attrubute name and fill in the length. 1.334 +// JSR202| *Annotations_attribute { 1.335 +// JSR202| u2 attribute_name_index; 1.336 +// JSR202| u4 attribute_length; 1.337 +// JSR202| ... 1.338 +// JSR202| } 1.339 +void JvmtiClassFileReconstituter::write_annotations_attribute(const char* attr_name, 1.340 + AnnotationArray* annos) { 1.341 + u4 length = annos->length(); 1.342 + write_attribute_name_index(attr_name); 1.343 + write_u4(length); 1.344 + memcpy(writeable_address(length), annos->adr_at(0), length); 1.345 +} 1.346 + 1.347 +// BootstrapMethods_attribute { 1.348 +// u2 attribute_name_index; 1.349 +// u4 attribute_length; 1.350 +// u2 num_bootstrap_methods; 1.351 +// { u2 bootstrap_method_ref; 1.352 +// u2 num_bootstrap_arguments; 1.353 +// u2 bootstrap_arguments[num_bootstrap_arguments]; 1.354 +// } bootstrap_methods[num_bootstrap_methods]; 1.355 +// } 1.356 +void JvmtiClassFileReconstituter::write_bootstrapmethod_attribute() { 1.357 + Array<u2>* operands = cpool()->operands(); 1.358 + write_attribute_name_index("BootstrapMethods"); 1.359 + int num_bootstrap_methods = ConstantPool::operand_array_length(operands); 1.360 + 1.361 + // calculate length of attribute 1.362 + int length = sizeof(u2); // num_bootstrap_methods 1.363 + for (int n = 0; n < num_bootstrap_methods; n++) { 1.364 + u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n); 1.365 + length += sizeof(u2); // bootstrap_method_ref 1.366 + length += sizeof(u2); // num_bootstrap_arguments 1.367 + length += sizeof(u2) * num_bootstrap_arguments; // bootstrap_arguments[num_bootstrap_arguments] 1.368 + } 1.369 + write_u4(length); 1.370 + 1.371 + // write attribute 1.372 + write_u2(num_bootstrap_methods); 1.373 + for (int n = 0; n < num_bootstrap_methods; n++) { 1.374 + u2 bootstrap_method_ref = cpool()->operand_bootstrap_method_ref_index_at(n); 1.375 + u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n); 1.376 + write_u2(bootstrap_method_ref); 1.377 + write_u2(num_bootstrap_arguments); 1.378 + for (int arg = 0; arg < num_bootstrap_arguments; arg++) { 1.379 + u2 bootstrap_argument = cpool()->operand_argument_index_at(n, arg); 1.380 + write_u2(bootstrap_argument); 1.381 + } 1.382 + } 1.383 +} 1.384 + 1.385 + 1.386 +// Write InnerClasses attribute 1.387 +// JVMSpec| InnerClasses_attribute { 1.388 +// JVMSpec| u2 attribute_name_index; 1.389 +// JVMSpec| u4 attribute_length; 1.390 +// JVMSpec| u2 number_of_classes; 1.391 +// JVMSpec| { u2 inner_class_info_index; 1.392 +// JVMSpec| u2 outer_class_info_index; 1.393 +// JVMSpec| u2 inner_name_index; 1.394 +// JVMSpec| u2 inner_class_access_flags; 1.395 +// JVMSpec| } classes[number_of_classes]; 1.396 +// JVMSpec| } 1.397 +void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) { 1.398 + InnerClassesIterator iter(ikh()); 1.399 + guarantee(iter.length() != 0 && iter.length() == length, 1.400 + "caller must check"); 1.401 + u2 entry_count = length / InstanceKlass::inner_class_next_offset; 1.402 + u4 size = 2 + entry_count * (2+2+2+2); 1.403 + 1.404 + write_attribute_name_index("InnerClasses"); 1.405 + write_u4(size); 1.406 + write_u2(entry_count); 1.407 + for (; !iter.done(); iter.next()) { 1.408 + write_u2(iter.inner_class_info_index()); 1.409 + write_u2(iter.outer_class_info_index()); 1.410 + write_u2(iter.inner_name_index()); 1.411 + write_u2(iter.inner_access_flags()); 1.412 + } 1.413 +} 1.414 + 1.415 +// Write Synthetic attribute 1.416 +// JVMSpec| Synthetic_attribute { 1.417 +// JVMSpec| u2 attribute_name_index; 1.418 +// JVMSpec| u4 attribute_length; 1.419 +// JVMSpec| } 1.420 +void JvmtiClassFileReconstituter::write_synthetic_attribute() { 1.421 + write_attribute_name_index("Synthetic"); 1.422 + write_u4(0); //length always zero 1.423 +} 1.424 + 1.425 +// Compute size of LineNumberTable 1.426 +u2 JvmtiClassFileReconstituter::line_number_table_entries(methodHandle method) { 1.427 + // The line number table is compressed so we don't know how big it is until decompressed. 1.428 + // Decompression is really fast so we just do it twice. 1.429 + u2 num_entries = 0; 1.430 + CompressedLineNumberReadStream stream(method->compressed_linenumber_table()); 1.431 + while (stream.read_pair()) { 1.432 + num_entries++; 1.433 + } 1.434 + return num_entries; 1.435 +} 1.436 + 1.437 +// Write LineNumberTable attribute 1.438 +// JVMSpec| LineNumberTable_attribute { 1.439 +// JVMSpec| u2 attribute_name_index; 1.440 +// JVMSpec| u4 attribute_length; 1.441 +// JVMSpec| u2 line_number_table_length; 1.442 +// JVMSpec| { u2 start_pc; 1.443 +// JVMSpec| u2 line_number; 1.444 +// JVMSpec| } line_number_table[line_number_table_length]; 1.445 +// JVMSpec| } 1.446 +void JvmtiClassFileReconstituter::write_line_number_table_attribute(methodHandle method, 1.447 + u2 num_entries) { 1.448 + 1.449 + write_attribute_name_index("LineNumberTable"); 1.450 + write_u4(2 + num_entries * (2 + 2)); 1.451 + write_u2(num_entries); 1.452 + 1.453 + CompressedLineNumberReadStream stream(method->compressed_linenumber_table()); 1.454 + while (stream.read_pair()) { 1.455 + write_u2(stream.bci()); 1.456 + write_u2(stream.line()); 1.457 + } 1.458 +} 1.459 + 1.460 +// Write LocalVariableTable attribute 1.461 +// JVMSpec| LocalVariableTable_attribute { 1.462 +// JVMSpec| u2 attribute_name_index; 1.463 +// JVMSpec| u4 attribute_length; 1.464 +// JVMSpec| u2 local_variable_table_length; 1.465 +// JVMSpec| { u2 start_pc; 1.466 +// JVMSpec| u2 length; 1.467 +// JVMSpec| u2 name_index; 1.468 +// JVMSpec| u2 descriptor_index; 1.469 +// JVMSpec| u2 index; 1.470 +// JVMSpec| } local_variable_table[local_variable_table_length]; 1.471 +// JVMSpec| } 1.472 +void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHandle method, u2 num_entries) { 1.473 + write_attribute_name_index("LocalVariableTable"); 1.474 + write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2)); 1.475 + write_u2(num_entries); 1.476 + 1.477 + assert(method->localvariable_table_length() == num_entries, "just checking"); 1.478 + 1.479 + LocalVariableTableElement *elem = method->localvariable_table_start(); 1.480 + for (int j=0; j<method->localvariable_table_length(); j++) { 1.481 + write_u2(elem->start_bci); 1.482 + write_u2(elem->length); 1.483 + write_u2(elem->name_cp_index); 1.484 + write_u2(elem->descriptor_cp_index); 1.485 + write_u2(elem->slot); 1.486 + elem++; 1.487 + } 1.488 +} 1.489 + 1.490 +// Write LocalVariableTypeTable attribute 1.491 +// JVMSpec| LocalVariableTypeTable_attribute { 1.492 +// JVMSpec| u2 attribute_name_index; 1.493 +// JVMSpec| u4 attribute_length; 1.494 +// JVMSpec| u2 local_variable_type_table_length; 1.495 +// JVMSpec| { u2 start_pc; 1.496 +// JVMSpec| u2 length; 1.497 +// JVMSpec| u2 name_index; 1.498 +// JVMSpec| u2 signature_index; 1.499 +// JVMSpec| u2 index; 1.500 +// JVMSpec| } local_variable_type_table[local_variable_type_table_length]; 1.501 +// JVMSpec| } 1.502 +void JvmtiClassFileReconstituter::write_local_variable_type_table_attribute(methodHandle method, u2 num_entries) { 1.503 + write_attribute_name_index("LocalVariableTypeTable"); 1.504 + write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2)); 1.505 + write_u2(num_entries); 1.506 + 1.507 + LocalVariableTableElement *elem = method->localvariable_table_start(); 1.508 + for (int j=0; j<method->localvariable_table_length(); j++) { 1.509 + if (elem->signature_cp_index > 0) { 1.510 + // Local variable has a generic signature - write LVTT attribute entry 1.511 + write_u2(elem->start_bci); 1.512 + write_u2(elem->length); 1.513 + write_u2(elem->name_cp_index); 1.514 + write_u2(elem->signature_cp_index); 1.515 + write_u2(elem->slot); 1.516 + num_entries--; 1.517 + } 1.518 + elem++; 1.519 + } 1.520 + assert(num_entries == 0, "just checking"); 1.521 +} 1.522 + 1.523 +// Write stack map table attribute 1.524 +// JSR-202| StackMapTable_attribute { 1.525 +// JSR-202| u2 attribute_name_index; 1.526 +// JSR-202| u4 attribute_length; 1.527 +// JSR-202| u2 number_of_entries; 1.528 +// JSR-202| stack_map_frame_entries[number_of_entries]; 1.529 +// JSR-202| } 1.530 +void JvmtiClassFileReconstituter::write_stackmap_table_attribute(methodHandle method, 1.531 + int stackmap_len) { 1.532 + 1.533 + write_attribute_name_index("StackMapTable"); 1.534 + write_u4(stackmap_len); 1.535 + memcpy( 1.536 + writeable_address(stackmap_len), 1.537 + (void*)(method->stackmap_data()->adr_at(0)), 1.538 + stackmap_len); 1.539 +} 1.540 + 1.541 +// Write one method_info structure 1.542 +// JVMSpec| method_info { 1.543 +// JVMSpec| u2 access_flags; 1.544 +// JVMSpec| u2 name_index; 1.545 +// JVMSpec| u2 descriptor_index; 1.546 +// JVMSpec| u2 attributes_count; 1.547 +// JVMSpec| attribute_info attributes[attributes_count]; 1.548 +// JVMSpec| } 1.549 +void JvmtiClassFileReconstituter::write_method_info(methodHandle method) { 1.550 + AccessFlags access_flags = method->access_flags(); 1.551 + ConstMethod* const_method = method->constMethod(); 1.552 + u2 generic_signature_index = const_method->generic_signature_index(); 1.553 + AnnotationArray* anno = method->annotations(); 1.554 + AnnotationArray* param_anno = method->parameter_annotations(); 1.555 + AnnotationArray* default_anno = method->annotation_default(); 1.556 + 1.557 + // skip generated default interface methods 1.558 + if (method->is_overpass()) { 1.559 + return; 1.560 + } 1.561 + 1.562 + write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS); 1.563 + write_u2(const_method->name_index()); 1.564 + write_u2(const_method->signature_index()); 1.565 + 1.566 + // write attributes in the same order javac does, so we can test with byte for 1.567 + // byte comparison 1.568 + int attr_count = 0; 1.569 + if (const_method->code_size() != 0) { 1.570 + ++attr_count; // has Code attribute 1.571 + } 1.572 + if (const_method->has_checked_exceptions()) { 1.573 + ++attr_count; // has Exceptions attribute 1.574 + } 1.575 + if (default_anno != NULL) { 1.576 + ++attr_count; // has AnnotationDefault attribute 1.577 + } 1.578 + // Deprecated attribute would go here 1.579 + if (access_flags.is_synthetic()) { // FIXME 1.580 + // ++attr_count; 1.581 + } 1.582 + if (generic_signature_index != 0) { 1.583 + ++attr_count; 1.584 + } 1.585 + if (anno != NULL) { 1.586 + ++attr_count; // has RuntimeVisibleAnnotations attribute 1.587 + } 1.588 + if (param_anno != NULL) { 1.589 + ++attr_count; // has RuntimeVisibleParameterAnnotations attribute 1.590 + } 1.591 + 1.592 + write_u2(attr_count); 1.593 + if (const_method->code_size() > 0) { 1.594 + write_code_attribute(method); 1.595 + } 1.596 + if (const_method->has_checked_exceptions()) { 1.597 + write_exceptions_attribute(const_method); 1.598 + } 1.599 + if (default_anno != NULL) { 1.600 + write_annotations_attribute("AnnotationDefault", default_anno); 1.601 + } 1.602 + // Deprecated attribute would go here 1.603 + if (access_flags.is_synthetic()) { 1.604 + // write_synthetic_attribute(); 1.605 + } 1.606 + if (generic_signature_index != 0) { 1.607 + write_signature_attribute(generic_signature_index); 1.608 + } 1.609 + if (anno != NULL) { 1.610 + write_annotations_attribute("RuntimeVisibleAnnotations", anno); 1.611 + } 1.612 + if (param_anno != NULL) { 1.613 + write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno); 1.614 + } 1.615 +} 1.616 + 1.617 +// Write the class attributes portion of ClassFile structure 1.618 +// JVMSpec| u2 attributes_count; 1.619 +// JVMSpec| attribute_info attributes[attributes_count]; 1.620 +void JvmtiClassFileReconstituter::write_class_attributes() { 1.621 + u2 inner_classes_length = inner_classes_attribute_length(); 1.622 + Symbol* generic_signature = ikh()->generic_signature(); 1.623 + AnnotationArray* anno = ikh()->class_annotations(); 1.624 + 1.625 + int attr_count = 0; 1.626 + if (generic_signature != NULL) { 1.627 + ++attr_count; 1.628 + } 1.629 + if (ikh()->source_file_name() != NULL) { 1.630 + ++attr_count; 1.631 + } 1.632 + if (ikh()->source_debug_extension() != NULL) { 1.633 + ++attr_count; 1.634 + } 1.635 + if (inner_classes_length > 0) { 1.636 + ++attr_count; 1.637 + } 1.638 + if (anno != NULL) { 1.639 + ++attr_count; // has RuntimeVisibleAnnotations attribute 1.640 + } 1.641 + if (cpool()->operands() != NULL) { 1.642 + ++attr_count; 1.643 + } 1.644 + 1.645 + write_u2(attr_count); 1.646 + 1.647 + if (generic_signature != NULL) { 1.648 + write_signature_attribute(symbol_to_cpool_index(generic_signature)); 1.649 + } 1.650 + if (ikh()->source_file_name() != NULL) { 1.651 + write_source_file_attribute(); 1.652 + } 1.653 + if (ikh()->source_debug_extension() != NULL) { 1.654 + write_source_debug_extension_attribute(); 1.655 + } 1.656 + if (inner_classes_length > 0) { 1.657 + write_inner_classes_attribute(inner_classes_length); 1.658 + } 1.659 + if (anno != NULL) { 1.660 + write_annotations_attribute("RuntimeVisibleAnnotations", anno); 1.661 + } 1.662 + if (cpool()->operands() != NULL) { 1.663 + write_bootstrapmethod_attribute(); 1.664 + } 1.665 +} 1.666 + 1.667 +// Write the method information portion of ClassFile structure 1.668 +// JVMSpec| u2 methods_count; 1.669 +// JVMSpec| method_info methods[methods_count]; 1.670 +void JvmtiClassFileReconstituter::write_method_infos() { 1.671 + HandleMark hm(thread()); 1.672 + Array<Method*>* methods = ikh()->methods(); 1.673 + int num_methods = methods->length(); 1.674 + int num_overpass = 0; 1.675 + 1.676 + // count the generated default interface methods 1.677 + // these will not be re-created by write_method_info 1.678 + // and should not be included in the total count 1.679 + for (int index = 0; index < num_methods; index++) { 1.680 + Method* method = methods->at(index); 1.681 + if (method->is_overpass()) { 1.682 + num_overpass++; 1.683 + } 1.684 + } 1.685 + 1.686 + write_u2(num_methods - num_overpass); 1.687 + if (JvmtiExport::can_maintain_original_method_order()) { 1.688 + int index; 1.689 + int original_index; 1.690 + intArray method_order(num_methods, 0); 1.691 + 1.692 + // invert the method order mapping 1.693 + for (index = 0; index < num_methods; index++) { 1.694 + original_index = ikh()->method_ordering()->at(index); 1.695 + assert(original_index >= 0 && original_index < num_methods, 1.696 + "invalid original method index"); 1.697 + method_order.at_put(original_index, index); 1.698 + } 1.699 + 1.700 + // write in original order 1.701 + for (original_index = 0; original_index < num_methods; original_index++) { 1.702 + index = method_order.at(original_index); 1.703 + methodHandle method(thread(), methods->at(index)); 1.704 + write_method_info(method); 1.705 + } 1.706 + } else { 1.707 + // method order not preserved just dump the method infos 1.708 + for (int index = 0; index < num_methods; index++) { 1.709 + methodHandle method(thread(), methods->at(index)); 1.710 + write_method_info(method); 1.711 + } 1.712 + } 1.713 +} 1.714 + 1.715 +void JvmtiClassFileReconstituter::write_class_file_format() { 1.716 + ReallocMark(); 1.717 + 1.718 + // JVMSpec| ClassFile { 1.719 + // JVMSpec| u4 magic; 1.720 + write_u4(0xCAFEBABE); 1.721 + 1.722 + // JVMSpec| u2 minor_version; 1.723 + // JVMSpec| u2 major_version; 1.724 + write_u2(ikh()->minor_version()); 1.725 + u2 major = ikh()->major_version(); 1.726 + write_u2(major); 1.727 + 1.728 + // JVMSpec| u2 constant_pool_count; 1.729 + // JVMSpec| cp_info constant_pool[constant_pool_count-1]; 1.730 + write_u2(cpool()->length()); 1.731 + copy_cpool_bytes(writeable_address(cpool_size())); 1.732 + 1.733 + // JVMSpec| u2 access_flags; 1.734 + write_u2(ikh()->access_flags().get_flags() & JVM_RECOGNIZED_CLASS_MODIFIERS); 1.735 + 1.736 + // JVMSpec| u2 this_class; 1.737 + // JVMSpec| u2 super_class; 1.738 + write_u2(class_symbol_to_cpool_index(ikh()->name())); 1.739 + Klass* super_class = ikh()->super(); 1.740 + write_u2(super_class == NULL? 0 : // zero for java.lang.Object 1.741 + class_symbol_to_cpool_index(super_class->name())); 1.742 + 1.743 + // JVMSpec| u2 interfaces_count; 1.744 + // JVMSpec| u2 interfaces[interfaces_count]; 1.745 + Array<Klass*>* interfaces = ikh()->local_interfaces(); 1.746 + int num_interfaces = interfaces->length(); 1.747 + write_u2(num_interfaces); 1.748 + for (int index = 0; index < num_interfaces; index++) { 1.749 + HandleMark hm(thread()); 1.750 + instanceKlassHandle iikh(thread(), interfaces->at(index)); 1.751 + write_u2(class_symbol_to_cpool_index(iikh->name())); 1.752 + } 1.753 + 1.754 + // JVMSpec| u2 fields_count; 1.755 + // JVMSpec| field_info fields[fields_count]; 1.756 + write_field_infos(); 1.757 + 1.758 + // JVMSpec| u2 methods_count; 1.759 + // JVMSpec| method_info methods[methods_count]; 1.760 + write_method_infos(); 1.761 + 1.762 + // JVMSpec| u2 attributes_count; 1.763 + // JVMSpec| attribute_info attributes[attributes_count]; 1.764 + // JVMSpec| } /* end ClassFile 8? 1.765 + write_class_attributes(); 1.766 +} 1.767 + 1.768 +address JvmtiClassFileReconstituter::writeable_address(size_t size) { 1.769 + size_t used_size = _buffer_ptr - _buffer; 1.770 + if (size + used_size >= _buffer_size) { 1.771 + // compute the new buffer size: must be at least twice as big as before 1.772 + // plus whatever new is being used; then convert to nice clean block boundary 1.773 + size_t new_buffer_size = (size + _buffer_size*2 + 1) / initial_buffer_size 1.774 + * initial_buffer_size; 1.775 + 1.776 + // VM goes belly-up if the memory isn't available, so cannot do OOM processing 1.777 + _buffer = REALLOC_RESOURCE_ARRAY(u1, _buffer, _buffer_size, new_buffer_size); 1.778 + _buffer_size = new_buffer_size; 1.779 + _buffer_ptr = _buffer + used_size; 1.780 + } 1.781 + u1* ret_ptr = _buffer_ptr; 1.782 + _buffer_ptr += size; 1.783 + return ret_ptr; 1.784 +} 1.785 + 1.786 +void JvmtiClassFileReconstituter::write_attribute_name_index(const char* name) { 1.787 + TempNewSymbol sym = SymbolTable::probe(name, (int)strlen(name)); 1.788 + assert(sym != NULL, "attribute name symbol not found"); 1.789 + u2 attr_name_index = symbol_to_cpool_index(sym); 1.790 + assert(attr_name_index != 0, "attribute name symbol not in constant pool"); 1.791 + write_u2(attr_name_index); 1.792 +} 1.793 + 1.794 +void JvmtiClassFileReconstituter::write_u1(u1 x) { 1.795 + *writeable_address(1) = x; 1.796 +} 1.797 + 1.798 +void JvmtiClassFileReconstituter::write_u2(u2 x) { 1.799 + Bytes::put_Java_u2(writeable_address(2), x); 1.800 +} 1.801 + 1.802 +void JvmtiClassFileReconstituter::write_u4(u4 x) { 1.803 + Bytes::put_Java_u4(writeable_address(4), x); 1.804 +} 1.805 + 1.806 +void JvmtiClassFileReconstituter::write_u8(u8 x) { 1.807 + Bytes::put_Java_u8(writeable_address(8), x); 1.808 +} 1.809 + 1.810 +void JvmtiClassFileReconstituter::copy_bytecodes(methodHandle mh, 1.811 + unsigned char* bytecodes) { 1.812 + // use a BytecodeStream to iterate over the bytecodes. JVM/fast bytecodes 1.813 + // and the breakpoint bytecode are converted to their original bytecodes. 1.814 + 1.815 + BytecodeStream bs(mh); 1.816 + 1.817 + unsigned char* p = bytecodes; 1.818 + Bytecodes::Code code; 1.819 + bool is_rewritten = mh->method_holder()->is_rewritten(); 1.820 + 1.821 + while ((code = bs.next()) >= 0) { 1.822 + assert(Bytecodes::is_java_code(code), "sanity check"); 1.823 + assert(code != Bytecodes::_breakpoint, "sanity check"); 1.824 + 1.825 + // length of bytecode (mnemonic + operands) 1.826 + address bcp = bs.bcp(); 1.827 + int len = bs.instruction_size(); 1.828 + assert(len > 0, "length must be > 0"); 1.829 + 1.830 + // copy the bytecodes 1.831 + *p = (unsigned char) (bs.is_wide()? Bytecodes::_wide : code); 1.832 + if (len > 1) { 1.833 + memcpy(p+1, bcp+1, len-1); 1.834 + } 1.835 + 1.836 + // During linking the get/put and invoke instructions are rewritten 1.837 + // with an index into the constant pool cache. The original constant 1.838 + // pool index must be returned to caller. Rewrite the index. 1.839 + if (is_rewritten && len > 1) { 1.840 + bool is_wide = false; 1.841 + switch (code) { 1.842 + case Bytecodes::_getstatic : // fall through 1.843 + case Bytecodes::_putstatic : // fall through 1.844 + case Bytecodes::_getfield : // fall through 1.845 + case Bytecodes::_putfield : // fall through 1.846 + case Bytecodes::_invokevirtual : // fall through 1.847 + case Bytecodes::_invokespecial : // fall through 1.848 + case Bytecodes::_invokestatic : // fall through 1.849 + case Bytecodes::_invokedynamic : // fall through 1.850 + case Bytecodes::_invokeinterface : { 1.851 + assert(len == 3 || 1.852 + (code == Bytecodes::_invokeinterface && len == 5) || 1.853 + (code == Bytecodes::_invokedynamic && len == 5), 1.854 + "sanity check"); 1.855 + 1.856 + int cpci = Bytes::get_native_u2(bcp+1); 1.857 + bool is_invokedynamic = (EnableInvokeDynamic && code == Bytecodes::_invokedynamic); 1.858 + ConstantPoolCacheEntry* entry; 1.859 + if (is_invokedynamic) { 1.860 + cpci = Bytes::get_native_u4(bcp+1); 1.861 + entry = mh->constants()->invokedynamic_cp_cache_entry_at(cpci); 1.862 + } else { 1.863 + // cache cannot be pre-fetched since some classes won't have it yet 1.864 + entry = mh->constants()->cache()->entry_at(cpci); 1.865 + } 1.866 + int i = entry->constant_pool_index(); 1.867 + assert(i < mh->constants()->length(), "sanity check"); 1.868 + Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering 1.869 + if (is_invokedynamic) *(p+3) = *(p+4) = 0; 1.870 + break; 1.871 + } 1.872 + case Bytecodes::_ldc_w: 1.873 + is_wide = true; // fall through 1.874 + case Bytecodes::_ldc: { 1.875 + if (bs.raw_code() == Bytecodes::_fast_aldc || bs.raw_code() == Bytecodes::_fast_aldc_w) { 1.876 + int cpci = is_wide ? Bytes::get_native_u2(bcp+1) : (u1)(*(bcp+1)); 1.877 + int i = mh->constants()->object_to_cp_index(cpci); 1.878 + assert(i < mh->constants()->length(), "sanity check"); 1.879 + if (is_wide) { 1.880 + Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering 1.881 + } else { 1.882 + *(p+1) = (u1)i; 1.883 + } 1.884 + } 1.885 + break; 1.886 + } 1.887 + } 1.888 + } 1.889 + 1.890 + p += len; 1.891 + } 1.892 +}