jvmtiClassFileReconstituter.cpp revision 0:a61af66fc99e
1/* 2 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 * 23 */ 24# include "incls/_precompiled.incl" 25# include "incls/_jvmtiClassFileReconstituter.cpp.incl" 26 27// FIXME: add Deprecated, LVT, LVTT attributes 28// FIXME: fix Synthetic attribute 29// FIXME: per Serguei, add error return handling for constantPoolOopDesc::copy_cpool_bytes() 30 31 32// Write the field information portion of ClassFile structure 33// JVMSpec| u2 fields_count; 34// JVMSpec| field_info fields[fields_count]; 35void JvmtiClassFileReconstituter::write_field_infos() { 36 HandleMark hm(thread()); 37 typeArrayHandle fields(thread(), ikh()->fields()); 38 int fields_length = fields->length(); 39 int num_fields = fields_length / instanceKlass::next_offset; 40 objArrayHandle fields_anno(thread(), ikh()->fields_annotations()); 41 42 write_u2(num_fields); 43 for (int index = 0; index < fields_length; index += instanceKlass::next_offset) { 44 AccessFlags access_flags; 45 int flags = fields->ushort_at(index + instanceKlass::access_flags_offset); 46 access_flags.set_flags(flags); 47 int name_index = fields->ushort_at(index + instanceKlass::name_index_offset); 48 int signature_index = fields->ushort_at(index + instanceKlass::signature_index_offset); 49 int initial_value_index = fields->ushort_at(index + instanceKlass::initval_index_offset); 50 guarantee(name_index != 0 && signature_index != 0, "bad constant pool index for field"); 51 int offset = ikh()->offset_from_fields( index ); 52 int generic_signature_index = 53 fields->ushort_at(index + instanceKlass::generic_signature_offset); 54 typeArrayHandle anno(thread(), fields_anno.not_null() ? 55 (typeArrayOop)(fields_anno->obj_at(index / instanceKlass::next_offset)) : 56 (typeArrayOop)NULL); 57 58 // JVMSpec| field_info { 59 // JVMSpec| u2 access_flags; 60 // JVMSpec| u2 name_index; 61 // JVMSpec| u2 descriptor_index; 62 // JVMSpec| u2 attributes_count; 63 // JVMSpec| attribute_info attributes[attributes_count]; 64 // JVMSpec| } 65 66 write_u2(flags & JVM_RECOGNIZED_FIELD_MODIFIERS); 67 write_u2(name_index); 68 write_u2(signature_index); 69 int attr_count = 0; 70 if (initial_value_index != 0) { 71 ++attr_count; 72 } 73 if (access_flags.is_synthetic()) { 74 // ++attr_count; 75 } 76 if (generic_signature_index != 0) { 77 ++attr_count; 78 } 79 if (anno.not_null()) { 80 ++attr_count; // has RuntimeVisibleAnnotations attribute 81 } 82 83 write_u2(attr_count); 84 85 if (initial_value_index != 0) { 86 write_attribute_name_index("ConstantValue"); 87 write_u4(2); //length always 2 88 write_u2(initial_value_index); 89 } 90 if (access_flags.is_synthetic()) { 91 // write_synthetic_attribute(); 92 } 93 if (generic_signature_index != 0) { 94 write_signature_attribute(generic_signature_index); 95 } 96 if (anno.not_null()) { 97 write_annotations_attribute("RuntimeVisibleAnnotations", anno); 98 } 99 } 100} 101 102// Write Code attribute 103// JVMSpec| Code_attribute { 104// JVMSpec| u2 attribute_name_index; 105// JVMSpec| u4 attribute_length; 106// JVMSpec| u2 max_stack; 107// JVMSpec| u2 max_locals; 108// JVMSpec| u4 code_length; 109// JVMSpec| u1 code[code_length]; 110// JVMSpec| u2 exception_table_length; 111// JVMSpec| { u2 start_pc; 112// JVMSpec| u2 end_pc; 113// JVMSpec| u2 handler_pc; 114// JVMSpec| u2 catch_type; 115// JVMSpec| } exception_table[exception_table_length]; 116// JVMSpec| u2 attributes_count; 117// JVMSpec| attribute_info attributes[attributes_count]; 118// JVMSpec| } 119void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) { 120 constMethodHandle const_method(thread(), method->constMethod()); 121 u2 line_num_cnt = 0; 122 int stackmap_len = 0; 123 124 // compute number and length of attributes -- FIXME: for now no LVT 125 int attr_count = 0; 126 int attr_size = 0; 127 if (const_method->has_linenumber_table()) { 128 line_num_cnt = line_number_table_entries(method); 129 if (line_num_cnt != 0) { 130 ++attr_count; 131 // Compute the complete size of the line number table attribute: 132 // LineNumberTable_attribute { 133 // u2 attribute_name_index; 134 // u4 attribute_length; 135 // u2 line_number_table_length; 136 // { u2 start_pc; 137 // u2 line_number; 138 // } line_number_table[line_number_table_length]; 139 // } 140 attr_size += 2 + 4 + 2 + line_num_cnt * (2 + 2); 141 } 142 } 143 if (method->has_stackmap_table()) { 144 stackmap_len = method->stackmap_data()->length(); 145 if (stackmap_len != 0) { 146 ++attr_count; 147 // Compute the size of the stack map table attribute (VM stores raw): 148 // StackMapTable_attribute { 149 // u2 attribute_name_index; 150 // u4 attribute_length; 151 // u2 number_of_entries; 152 // stack_map_frame_entries[number_of_entries]; 153 // } 154 attr_size += 2 + 4 + stackmap_len; 155 } 156 } 157 158 typeArrayHandle exception_table(thread(), const_method->exception_table()); 159 int exception_table_length = exception_table->length(); 160 int exception_table_entries = exception_table_length / 4; 161 int code_size = const_method->code_size(); 162 int size = 163 2+2+4 + // max_stack, max_locals, code_length 164 code_size + // code 165 2 + // exception_table_length 166 (2+2+2+2) * exception_table_entries + // exception_table 167 2 + // attributes_count 168 attr_size; // attributes 169 170 write_attribute_name_index("Code"); 171 write_u4(size); 172 write_u2(method->max_stack()); 173 write_u2(method->max_locals()); 174 write_u4(code_size); 175 copy_bytecodes(method, (unsigned char*)writeable_address(code_size)); 176 write_u2(exception_table_entries); 177 for (int index = 0; index < exception_table_length; ) { 178 write_u2(exception_table->int_at(index++)); 179 write_u2(exception_table->int_at(index++)); 180 write_u2(exception_table->int_at(index++)); 181 write_u2(exception_table->int_at(index++)); 182 } 183 write_u2(attr_count); 184 if (line_num_cnt != 0) { 185 write_line_number_table_attribute(method, line_num_cnt); 186 } 187 if (stackmap_len != 0) { 188 write_stackmap_table_attribute(method, stackmap_len); 189 } 190 191 // FIXME: write LVT attribute 192} 193 194// Write Exceptions attribute 195// JVMSpec| Exceptions_attribute { 196// JVMSpec| u2 attribute_name_index; 197// JVMSpec| u4 attribute_length; 198// JVMSpec| u2 number_of_exceptions; 199// JVMSpec| u2 exception_index_table[number_of_exceptions]; 200// JVMSpec| } 201void JvmtiClassFileReconstituter::write_exceptions_attribute(constMethodHandle const_method) { 202 CheckedExceptionElement* checked_exceptions = const_method->checked_exceptions_start(); 203 int checked_exceptions_length = const_method->checked_exceptions_length(); 204 int size = 205 2 + // number_of_exceptions 206 2 * checked_exceptions_length; // exception_index_table 207 208 write_attribute_name_index("Exceptions"); 209 write_u4(size); 210 write_u2(checked_exceptions_length); 211 for (int index = 0; index < checked_exceptions_length; index++) { 212 write_u2(checked_exceptions[index].class_cp_index); 213 } 214} 215 216// Write SourceFile attribute 217// JVMSpec| SourceFile_attribute { 218// JVMSpec| u2 attribute_name_index; 219// JVMSpec| u4 attribute_length; 220// JVMSpec| u2 sourcefile_index; 221// JVMSpec| } 222void JvmtiClassFileReconstituter::write_source_file_attribute() { 223 assert(ikh()->source_file_name() != NULL, "caller must check"); 224 225 write_attribute_name_index("SourceFile"); 226 write_u4(2); // always length 2 227 write_u2(symbol_to_cpool_index(ikh()->source_file_name())); 228} 229 230// Write SourceDebugExtension attribute 231// JSR45| SourceDebugExtension_attribute { 232// JSR45| u2 attribute_name_index; 233// JSR45| u4 attribute_length; 234// JSR45| u2 sourcefile_index; 235// JSR45| } 236void JvmtiClassFileReconstituter::write_source_debug_extension_attribute() { 237 assert(ikh()->source_debug_extension() != NULL, "caller must check"); 238 239 write_attribute_name_index("SourceDebugExtension"); 240 write_u4(2); // always length 2 241 write_u2(symbol_to_cpool_index(ikh()->source_debug_extension())); 242} 243 244// Write (generic) Signature attribute 245// JVMSpec| Signature_attribute { 246// JVMSpec| u2 attribute_name_index; 247// JVMSpec| u4 attribute_length; 248// JVMSpec| u2 signature_index; 249// JVMSpec| } 250void JvmtiClassFileReconstituter::write_signature_attribute(u2 generic_signature_index) { 251 write_attribute_name_index("Signature"); 252 write_u4(2); // always length 2 253 write_u2(generic_signature_index); 254} 255 256// Compute the number of entries in the InnerClasses attribute 257u2 JvmtiClassFileReconstituter::inner_classes_attribute_length() { 258 typeArrayOop inner_class_list = ikh()->inner_classes(); 259 return (inner_class_list == NULL) ? 0 : inner_class_list->length(); 260} 261 262// Write an annotation attribute. The VM stores them in raw form, so all we need 263// to do is add the attrubute name and fill in the length. 264// JSR202| *Annotations_attribute { 265// JSR202| u2 attribute_name_index; 266// JSR202| u4 attribute_length; 267// JSR202| ... 268// JSR202| } 269void JvmtiClassFileReconstituter::write_annotations_attribute(const char* attr_name, 270 typeArrayHandle annos) { 271 u4 length = annos->length(); 272 write_attribute_name_index(attr_name); 273 write_u4(length); 274 memcpy(writeable_address(length), annos->byte_at_addr(0), length); 275} 276 277 278// Write InnerClasses attribute 279// JVMSpec| InnerClasses_attribute { 280// JVMSpec| u2 attribute_name_index; 281// JVMSpec| u4 attribute_length; 282// JVMSpec| u2 number_of_classes; 283// JVMSpec| { u2 inner_class_info_index; 284// JVMSpec| u2 outer_class_info_index; 285// JVMSpec| u2 inner_name_index; 286// JVMSpec| u2 inner_class_access_flags; 287// JVMSpec| } classes[number_of_classes]; 288// JVMSpec| } 289void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) { 290 typeArrayOop inner_class_list = ikh()->inner_classes(); 291 guarantee(inner_class_list != NULL && inner_class_list->length() == length, 292 "caller must check"); 293 typeArrayHandle inner_class_list_h(thread(), inner_class_list); 294 assert (length % instanceKlass::inner_class_next_offset == 0, "just checking"); 295 u2 entry_count = length / instanceKlass::inner_class_next_offset; 296 u4 size = 2 + entry_count * (2+2+2+2); 297 298 write_attribute_name_index("InnerClasses"); 299 write_u4(size); 300 write_u2(entry_count); 301 for (int i = 0; i < length; i += instanceKlass::inner_class_next_offset) { 302 write_u2(inner_class_list_h->ushort_at( 303 i + instanceKlass::inner_class_inner_class_info_offset)); 304 write_u2(inner_class_list_h->ushort_at( 305 i + instanceKlass::inner_class_outer_class_info_offset)); 306 write_u2(inner_class_list_h->ushort_at( 307 i + instanceKlass::inner_class_inner_name_offset)); 308 write_u2(inner_class_list_h->ushort_at( 309 i + instanceKlass::inner_class_access_flags_offset)); 310 } 311} 312 313// Write Synthetic attribute 314// JVMSpec| Synthetic_attribute { 315// JVMSpec| u2 attribute_name_index; 316// JVMSpec| u4 attribute_length; 317// JVMSpec| } 318void JvmtiClassFileReconstituter::write_synthetic_attribute() { 319 write_attribute_name_index("Synthetic"); 320 write_u4(0); //length always zero 321} 322 323// Compute size of LineNumberTable 324u2 JvmtiClassFileReconstituter::line_number_table_entries(methodHandle method) { 325 // The line number table is compressed so we don't know how big it is until decompressed. 326 // Decompression is really fast so we just do it twice. 327 u2 num_entries = 0; 328 CompressedLineNumberReadStream stream(method->compressed_linenumber_table()); 329 while (stream.read_pair()) { 330 num_entries++; 331 } 332 return num_entries; 333} 334 335// Write LineNumberTable attribute 336// JVMSpec| LineNumberTable_attribute { 337// JVMSpec| u2 attribute_name_index; 338// JVMSpec| u4 attribute_length; 339// JVMSpec| u2 line_number_table_length; 340// JVMSpec| { u2 start_pc; 341// JVMSpec| u2 line_number; 342// JVMSpec| } line_number_table[line_number_table_length]; 343// JVMSpec| } 344void JvmtiClassFileReconstituter::write_line_number_table_attribute(methodHandle method, 345 u2 num_entries) { 346 347 write_attribute_name_index("LineNumberTable"); 348 write_u4(2 + num_entries * (2 + 2)); 349 write_u2(num_entries); 350 351 CompressedLineNumberReadStream stream(method->compressed_linenumber_table()); 352 while (stream.read_pair()) { 353 write_u2(stream.bci()); 354 write_u2(stream.line()); 355 } 356} 357 358// Write stack map table attribute 359// JSR-202| StackMapTable_attribute { 360// JSR-202| u2 attribute_name_index; 361// JSR-202| u4 attribute_length; 362// JSR-202| u2 number_of_entries; 363// JSR-202| stack_map_frame_entries[number_of_entries]; 364// JSR-202| } 365void JvmtiClassFileReconstituter::write_stackmap_table_attribute(methodHandle method, 366 int stackmap_len) { 367 368 write_attribute_name_index("StackMapTable"); 369 write_u4(stackmap_len); 370 memcpy( 371 writeable_address(stackmap_len), 372 (void*)(method->stackmap_data()->byte_at_addr(0)), 373 stackmap_len); 374} 375 376// Write one method_info structure 377// JVMSpec| method_info { 378// JVMSpec| u2 access_flags; 379// JVMSpec| u2 name_index; 380// JVMSpec| u2 descriptor_index; 381// JVMSpec| u2 attributes_count; 382// JVMSpec| attribute_info attributes[attributes_count]; 383// JVMSpec| } 384void JvmtiClassFileReconstituter::write_method_info(methodHandle method) { 385 AccessFlags access_flags = method->access_flags(); 386 constMethodHandle const_method(thread(), method->constMethod()); 387 u2 generic_signature_index = const_method->generic_signature_index(); 388 typeArrayHandle anno(thread(), method->annotations()); 389 typeArrayHandle param_anno(thread(), method->parameter_annotations()); 390 typeArrayHandle default_anno(thread(), method->annotation_default()); 391 392 write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS); 393 write_u2(const_method->name_index()); 394 write_u2(const_method->signature_index()); 395 396 // write attributes in the same order javac does, so we can test with byte for 397 // byte comparison 398 int attr_count = 0; 399 if (const_method->code_size() != 0) { 400 ++attr_count; // has Code attribute 401 } 402 if (const_method->has_checked_exceptions()) { 403 ++attr_count; // has Exceptions attribute 404 } 405 if (default_anno.not_null()) { 406 ++attr_count; // has AnnotationDefault attribute 407 } 408 // Deprecated attribute would go here 409 if (access_flags.is_synthetic()) { // FIXME 410 // ++attr_count; 411 } 412 if (generic_signature_index != 0) { 413 ++attr_count; 414 } 415 if (anno.not_null()) { 416 ++attr_count; // has RuntimeVisibleAnnotations attribute 417 } 418 if (param_anno.not_null()) { 419 ++attr_count; // has RuntimeVisibleParameterAnnotations attribute 420 } 421 422 write_u2(attr_count); 423 if (const_method->code_size() > 0) { 424 write_code_attribute(method); 425 } 426 if (const_method->has_checked_exceptions()) { 427 write_exceptions_attribute(const_method); 428 } 429 if (default_anno.not_null()) { 430 write_annotations_attribute("AnnotationDefault", default_anno); 431 } 432 // Deprecated attribute would go here 433 if (access_flags.is_synthetic()) { 434 // write_synthetic_attribute(); 435 } 436 if (generic_signature_index != 0) { 437 write_signature_attribute(generic_signature_index); 438 } 439 if (anno.not_null()) { 440 write_annotations_attribute("RuntimeVisibleAnnotations", anno); 441 } 442 if (param_anno.not_null()) { 443 write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno); 444 } 445} 446 447// Write the class attributes portion of ClassFile structure 448// JVMSpec| u2 attributes_count; 449// JVMSpec| attribute_info attributes[attributes_count]; 450void JvmtiClassFileReconstituter::write_class_attributes() { 451 u2 inner_classes_length = inner_classes_attribute_length(); 452 symbolHandle generic_signature(thread(), ikh()->generic_signature()); 453 typeArrayHandle anno(thread(), ikh()->class_annotations()); 454 455 int attr_count = 0; 456 if (generic_signature() != NULL) { 457 ++attr_count; 458 } 459 if (ikh()->source_file_name() != NULL) { 460 ++attr_count; 461 } 462 if (ikh()->source_debug_extension() != NULL) { 463 ++attr_count; 464 } 465 if (inner_classes_length > 0) { 466 ++attr_count; 467 } 468 if (anno.not_null()) { 469 ++attr_count; // has RuntimeVisibleAnnotations attribute 470 } 471 472 write_u2(attr_count); 473 474 if (generic_signature() != NULL) { 475 write_signature_attribute(symbol_to_cpool_index(generic_signature())); 476 } 477 if (ikh()->source_file_name() != NULL) { 478 write_source_file_attribute(); 479 } 480 if (ikh()->source_debug_extension() != NULL) { 481 write_source_debug_extension_attribute(); 482 } 483 if (inner_classes_length > 0) { 484 write_inner_classes_attribute(inner_classes_length); 485 } 486 if (anno.not_null()) { 487 write_annotations_attribute("RuntimeVisibleAnnotations", anno); 488 } 489} 490 491// Write the method information portion of ClassFile structure 492// JVMSpec| u2 methods_count; 493// JVMSpec| method_info methods[methods_count]; 494void JvmtiClassFileReconstituter::write_method_infos() { 495 HandleMark hm(thread()); 496 objArrayHandle methods(thread(), ikh()->methods()); 497 int num_methods = methods->length(); 498 499 write_u2(num_methods); 500 if (JvmtiExport::can_maintain_original_method_order()) { 501 int index; 502 int original_index; 503 int* method_order = NEW_RESOURCE_ARRAY(int, num_methods); 504 505 // invert the method order mapping 506 for (index = 0; index < num_methods; index++) { 507 original_index = ikh()->method_ordering()->int_at(index); 508 assert(original_index >= 0 && original_index < num_methods, 509 "invalid original method index"); 510 method_order[original_index] = index; 511 } 512 513 // write in original order 514 for (original_index = 0; original_index < num_methods; original_index++) { 515 index = method_order[original_index]; 516 methodHandle method(thread(), (methodOop)(ikh()->methods()->obj_at(index))); 517 write_method_info(method); 518 } 519 } else { 520 // method order not preserved just dump the method infos 521 for (int index = 0; index < num_methods; index++) { 522 methodHandle method(thread(), (methodOop)(ikh()->methods()->obj_at(index))); 523 write_method_info(method); 524 } 525 } 526} 527 528void JvmtiClassFileReconstituter::write_class_file_format() { 529 ReallocMark(); 530 531 // JVMSpec| ClassFile { 532 // JVMSpec| u4 magic; 533 write_u4(0xCAFEBABE); 534 535 // JVMSpec| u2 minor_version; 536 // JVMSpec| u2 major_version; 537 write_u2(ikh()->minor_version()); 538 u2 major = ikh()->major_version(); 539 write_u2(major); 540 541 // JVMSpec| u2 constant_pool_count; 542 // JVMSpec| cp_info constant_pool[constant_pool_count-1]; 543 write_u2(cpool()->length()); 544 copy_cpool_bytes(writeable_address(cpool_size())); 545 546 // JVMSpec| u2 access_flags; 547 write_u2(ikh()->access_flags().get_flags() & JVM_RECOGNIZED_CLASS_MODIFIERS); 548 549 // JVMSpec| u2 this_class; 550 // JVMSpec| u2 super_class; 551 write_u2(class_symbol_to_cpool_index(ikh()->name())); 552 klassOop super_class = ikh()->super(); 553 write_u2(super_class == NULL? 0 : // zero for java.lang.Object 554 class_symbol_to_cpool_index(super_class->klass_part()->name())); 555 556 // JVMSpec| u2 interfaces_count; 557 // JVMSpec| u2 interfaces[interfaces_count]; 558 objArrayHandle interfaces(thread(), ikh()->local_interfaces()); 559 int num_interfaces = interfaces->length(); 560 write_u2(num_interfaces); 561 for (int index = 0; index < num_interfaces; index++) { 562 HandleMark hm(thread()); 563 instanceKlassHandle iikh(thread(), klassOop(interfaces->obj_at(index))); 564 write_u2(class_symbol_to_cpool_index(iikh->name())); 565 } 566 567 // JVMSpec| u2 fields_count; 568 // JVMSpec| field_info fields[fields_count]; 569 write_field_infos(); 570 571 // JVMSpec| u2 methods_count; 572 // JVMSpec| method_info methods[methods_count]; 573 write_method_infos(); 574 575 // JVMSpec| u2 attributes_count; 576 // JVMSpec| attribute_info attributes[attributes_count]; 577 // JVMSpec| } /* end ClassFile 8? 578 write_class_attributes(); 579} 580 581address JvmtiClassFileReconstituter::writeable_address(size_t size) { 582 size_t used_size = _buffer_ptr - _buffer; 583 if (size + used_size >= _buffer_size) { 584 // compute the new buffer size: must be at least twice as big as before 585 // plus whatever new is being used; then convert to nice clean block boundary 586 size_t new_buffer_size = (size + _buffer_size*2 + 1) / initial_buffer_size 587 * initial_buffer_size; 588 589 // VM goes belly-up if the memory isn't available, so cannot do OOM processing 590 _buffer = REALLOC_RESOURCE_ARRAY(u1, _buffer, _buffer_size, new_buffer_size); 591 _buffer_size = new_buffer_size; 592 _buffer_ptr = _buffer + used_size; 593 } 594 u1* ret_ptr = _buffer_ptr; 595 _buffer_ptr += size; 596 return ret_ptr; 597} 598 599void JvmtiClassFileReconstituter::write_attribute_name_index(const char* name) { 600 unsigned int hash_ignored; 601 symbolOop sym = SymbolTable::lookup_only(name, (int)strlen(name), hash_ignored); 602 assert(sym != NULL, "attribute name symbol not found"); 603 u2 attr_name_index = symbol_to_cpool_index(sym); 604 assert(attr_name_index != 0, "attribute name symbol not in constant pool"); 605 write_u2(attr_name_index); 606} 607 608void JvmtiClassFileReconstituter::write_u1(u1 x) { 609 *writeable_address(1) = x; 610} 611 612void JvmtiClassFileReconstituter::write_u2(u2 x) { 613 Bytes::put_Java_u2(writeable_address(2), x); 614} 615 616void JvmtiClassFileReconstituter::write_u4(u4 x) { 617 Bytes::put_Java_u4(writeable_address(4), x); 618} 619 620void JvmtiClassFileReconstituter::write_u8(u8 x) { 621 Bytes::put_Java_u8(writeable_address(8), x); 622} 623 624void JvmtiClassFileReconstituter::copy_bytecodes(methodHandle mh, 625 unsigned char* bytecodes) { 626 // use a BytecodeStream to iterate over the bytecodes. JVM/fast bytecodes 627 // and the breakpoint bytecode are converted to their original bytecodes. 628 629 BytecodeStream bs(mh); 630 631 unsigned char* p = bytecodes; 632 Bytecodes::Code code; 633 bool is_rewritten = instanceKlass::cast(mh->method_holder())->is_rewritten(); 634 635 while ((code = bs.next()) >= 0) { 636 assert(Bytecodes::is_java_code(code), "sanity check"); 637 assert(code != Bytecodes::_breakpoint, "sanity check"); 638 639 // length of bytecode (mnemonic + operands) 640 address bcp = bs.bcp(); 641 int len = bs.next_bcp() - bcp; 642 assert(len > 0, "length must be > 0"); 643 644 // copy the bytecodes 645 *p = (unsigned char) (bs.is_wide()? Bytecodes::_wide : code); 646 if (len > 1) { 647 memcpy(p+1, bcp+1, len-1); 648 } 649 650 // During linking the get/put and invoke instructions are rewritten 651 // with an index into the constant pool cache. The original constant 652 // pool index must be returned to caller. Rewrite the index. 653 if (is_rewritten && len >= 3) { 654 switch (code) { 655 case Bytecodes::_getstatic : // fall through 656 case Bytecodes::_putstatic : // fall through 657 case Bytecodes::_getfield : // fall through 658 case Bytecodes::_putfield : // fall through 659 case Bytecodes::_invokevirtual : // fall through 660 case Bytecodes::_invokespecial : // fall through 661 case Bytecodes::_invokestatic : // fall through 662 case Bytecodes::_invokeinterface : 663 assert(len == 3 || (code == Bytecodes::_invokeinterface && len ==5), 664 "sanity check"); 665 // cache cannot be pre-fetched since some classes won't have it yet 666 ConstantPoolCacheEntry* entry = 667 mh->constants()->cache()->entry_at(Bytes::get_native_u2(bcp+1)); 668 int i = entry->constant_pool_index(); 669 assert(i < mh->constants()->length(), "sanity check"); 670 Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering 671 break; 672 } 673 } 674 675 p += len; 676 } 677} 678