371 length += sizeof(u2); // bootstrap_method_ref
372 length += sizeof(u2); // num_bootstrap_arguments
373 length += sizeof(u2) * num_bootstrap_arguments; // bootstrap_arguments[num_bootstrap_arguments]
374 }
375 write_u4(length);
376
377 // write attribute
378 write_u2(num_bootstrap_methods);
379 for (int n = 0; n < num_bootstrap_methods; n++) {
380 u2 bootstrap_method_ref = cpool()->operand_bootstrap_method_ref_index_at(n);
381 u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);
382 write_u2(bootstrap_method_ref);
383 write_u2(num_bootstrap_arguments);
384 for (int arg = 0; arg < num_bootstrap_arguments; arg++) {
385 u2 bootstrap_argument = cpool()->operand_argument_index_at(n, arg);
386 write_u2(bootstrap_argument);
387 }
388 }
389 }
390
391
392 // Write InnerClasses attribute
393 // JVMSpec| InnerClasses_attribute {
394 // JVMSpec| u2 attribute_name_index;
395 // JVMSpec| u4 attribute_length;
396 // JVMSpec| u2 number_of_classes;
397 // JVMSpec| { u2 inner_class_info_index;
398 // JVMSpec| u2 outer_class_info_index;
399 // JVMSpec| u2 inner_name_index;
400 // JVMSpec| u2 inner_class_access_flags;
401 // JVMSpec| } classes[number_of_classes];
402 // JVMSpec| }
403 void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) {
404 InnerClassesIterator iter(ik());
405 guarantee(iter.length() != 0 && iter.length() == length,
406 "caller must check");
407 u2 entry_count = length / InstanceKlass::inner_class_next_offset;
408 u4 size = 2 + entry_count * (2+2+2+2);
409
410 write_attribute_name_index("InnerClasses");
641 ++attr_count;
642 }
643 if (ik()->source_file_name() != NULL) {
644 ++attr_count;
645 }
646 if (ik()->source_debug_extension() != NULL) {
647 ++attr_count;
648 }
649 if (inner_classes_length > 0) {
650 ++attr_count;
651 }
652 if (anno != NULL) {
653 ++attr_count; // has RuntimeVisibleAnnotations attribute
654 }
655 if (type_anno != NULL) {
656 ++attr_count; // has RuntimeVisibleTypeAnnotations attribute
657 }
658 if (cpool()->operands() != NULL) {
659 ++attr_count;
660 }
661
662 write_u2(attr_count);
663
664 if (generic_signature != NULL) {
665 write_signature_attribute(symbol_to_cpool_index(generic_signature));
666 }
667 if (ik()->source_file_name() != NULL) {
668 write_source_file_attribute();
669 }
670 if (ik()->source_debug_extension() != NULL) {
671 write_source_debug_extension_attribute();
672 }
673 if (inner_classes_length > 0) {
674 write_inner_classes_attribute(inner_classes_length);
675 }
676 if (anno != NULL) {
677 write_annotations_attribute("RuntimeVisibleAnnotations", anno);
678 }
679 if (type_anno != NULL) {
680 write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
681 }
682 if (cpool()->operands() != NULL) {
683 write_bootstrapmethod_attribute();
684 }
685 }
686
687 // Write the method information portion of ClassFile structure
688 // JVMSpec| u2 methods_count;
689 // JVMSpec| method_info methods[methods_count];
690 void JvmtiClassFileReconstituter::write_method_infos() {
691 HandleMark hm(thread());
692 Array<Method*>* methods = ik()->methods();
693 int num_methods = methods->length();
694 int num_overpass = 0;
695
696 // count the generated default interface methods
697 // these will not be re-created by write_method_info
698 // and should not be included in the total count
699 for (int index = 0; index < num_methods; index++) {
700 Method* method = methods->at(index);
701 if (method->is_overpass()) {
702 num_overpass++;
703 }
|
371 length += sizeof(u2); // bootstrap_method_ref
372 length += sizeof(u2); // num_bootstrap_arguments
373 length += sizeof(u2) * num_bootstrap_arguments; // bootstrap_arguments[num_bootstrap_arguments]
374 }
375 write_u4(length);
376
377 // write attribute
378 write_u2(num_bootstrap_methods);
379 for (int n = 0; n < num_bootstrap_methods; n++) {
380 u2 bootstrap_method_ref = cpool()->operand_bootstrap_method_ref_index_at(n);
381 u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);
382 write_u2(bootstrap_method_ref);
383 write_u2(num_bootstrap_arguments);
384 for (int arg = 0; arg < num_bootstrap_arguments; arg++) {
385 u2 bootstrap_argument = cpool()->operand_argument_index_at(n, arg);
386 write_u2(bootstrap_argument);
387 }
388 }
389 }
390
391 // NestHost_attribute {
392 // u2 attribute_name_index;
393 // u4 attribute_length;
394 // u2 host_class_index;
395 // }
396 void JvmtiClassFileReconstituter::write_nest_host_attribute() {
397 int length = sizeof(u2);
398 int host_class_index = ik()->nest_host_index();
399
400 write_attribute_name_index("NestHost");
401 write_u4(length);
402 write_u2(host_class_index);
403 }
404
405 // NestMembers_attribute {
406 // u2 attribute_name_index;
407 // u4 attribute_length;
408 // u2 number_of_classes;
409 // u2 classes[number_of_classes];
410 // }
411 void JvmtiClassFileReconstituter::write_nest_members_attribute() {
412 Array<u2>* nest_members = ik()->nest_members();
413 int number_of_classes = nest_members->length();
414 int length = sizeof(u2) * (1 + number_of_classes);
415
416 write_attribute_name_index("NestMembers");
417 write_u4(length);
418 write_u2(number_of_classes);
419 for (int i = 0; i < number_of_classes; i++) {
420 u2 class_cp_index = nest_members->at(i);
421 write_u2(class_cp_index);
422 }
423 }
424
425
426 // Write InnerClasses attribute
427 // JVMSpec| InnerClasses_attribute {
428 // JVMSpec| u2 attribute_name_index;
429 // JVMSpec| u4 attribute_length;
430 // JVMSpec| u2 number_of_classes;
431 // JVMSpec| { u2 inner_class_info_index;
432 // JVMSpec| u2 outer_class_info_index;
433 // JVMSpec| u2 inner_name_index;
434 // JVMSpec| u2 inner_class_access_flags;
435 // JVMSpec| } classes[number_of_classes];
436 // JVMSpec| }
437 void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) {
438 InnerClassesIterator iter(ik());
439 guarantee(iter.length() != 0 && iter.length() == length,
440 "caller must check");
441 u2 entry_count = length / InstanceKlass::inner_class_next_offset;
442 u4 size = 2 + entry_count * (2+2+2+2);
443
444 write_attribute_name_index("InnerClasses");
675 ++attr_count;
676 }
677 if (ik()->source_file_name() != NULL) {
678 ++attr_count;
679 }
680 if (ik()->source_debug_extension() != NULL) {
681 ++attr_count;
682 }
683 if (inner_classes_length > 0) {
684 ++attr_count;
685 }
686 if (anno != NULL) {
687 ++attr_count; // has RuntimeVisibleAnnotations attribute
688 }
689 if (type_anno != NULL) {
690 ++attr_count; // has RuntimeVisibleTypeAnnotations attribute
691 }
692 if (cpool()->operands() != NULL) {
693 ++attr_count;
694 }
695 if (ik()->nest_host_index() != 0) {
696 ++attr_count;
697 }
698 if (ik()->nest_members() != Universe::the_empty_short_array()) {
699 ++attr_count;
700 }
701
702 write_u2(attr_count);
703
704 if (generic_signature != NULL) {
705 write_signature_attribute(symbol_to_cpool_index(generic_signature));
706 }
707 if (ik()->source_file_name() != NULL) {
708 write_source_file_attribute();
709 }
710 if (ik()->source_debug_extension() != NULL) {
711 write_source_debug_extension_attribute();
712 }
713 if (inner_classes_length > 0) {
714 write_inner_classes_attribute(inner_classes_length);
715 }
716 if (anno != NULL) {
717 write_annotations_attribute("RuntimeVisibleAnnotations", anno);
718 }
719 if (type_anno != NULL) {
720 write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
721 }
722 if (cpool()->operands() != NULL) {
723 write_bootstrapmethod_attribute();
724 }
725 if (ik()->nest_host_index() != 0) {
726 write_nest_host_attribute();
727 }
728 if (ik()->nest_members() != Universe::the_empty_short_array()) {
729 write_nest_members_attribute();
730 }
731 }
732
733 // Write the method information portion of ClassFile structure
734 // JVMSpec| u2 methods_count;
735 // JVMSpec| method_info methods[methods_count];
736 void JvmtiClassFileReconstituter::write_method_infos() {
737 HandleMark hm(thread());
738 Array<Method*>* methods = ik()->methods();
739 int num_methods = methods->length();
740 int num_overpass = 0;
741
742 // count the generated default interface methods
743 // these will not be re-created by write_method_info
744 // and should not be included in the total count
745 for (int index = 0; index < num_methods; index++) {
746 Method* method = methods->at(index);
747 if (method->is_overpass()) {
748 num_overpass++;
749 }
|