comparison src/share/vm/classfile/classFileParser.cpp @ 113:ba764ed4b6f2

6420645: Create a vm that uses compressed oops for up to 32gb heapsizes Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author coleenp
date Sun, 13 Apr 2008 17:43:42 -0400
parents ebec5b9731e2
children 7f3a69574470
comparison
equal deleted inserted replaced
110:a49a647afe9a 113:ba764ed4b6f2
2339 // Cause the extra fake fields in java.lang.Class to show up before 2339 // Cause the extra fake fields in java.lang.Class to show up before
2340 // the Java fields for layout compatibility between 1.3 and 1.4 2340 // the Java fields for layout compatibility between 1.3 and 1.4
2341 // Incrementing next_nonstatic_oop_offset here advances the 2341 // Incrementing next_nonstatic_oop_offset here advances the
2342 // location where the real java fields are placed. 2342 // location where the real java fields are placed.
2343 const int extra = java_lang_Class::number_of_fake_oop_fields; 2343 const int extra = java_lang_Class::number_of_fake_oop_fields;
2344 (*next_nonstatic_oop_offset_ptr) += (extra * wordSize); 2344 (*next_nonstatic_oop_offset_ptr) += (extra * heapOopSize);
2345 } 2345 }
2346 2346
2347 2347
2348 instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, 2348 instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
2349 Handle class_loader, 2349 Handle class_loader,
2645 // Calculate the starting byte offsets 2645 // Calculate the starting byte offsets
2646 next_static_oop_offset = (instanceKlass::header_size() + 2646 next_static_oop_offset = (instanceKlass::header_size() +
2647 align_object_offset(vtable_size) + 2647 align_object_offset(vtable_size) +
2648 align_object_offset(itable_size)) * wordSize; 2648 align_object_offset(itable_size)) * wordSize;
2649 next_static_double_offset = next_static_oop_offset + 2649 next_static_double_offset = next_static_oop_offset +
2650 (fac.static_oop_count * oopSize); 2650 (fac.static_oop_count * heapOopSize);
2651 if ( fac.static_double_count && 2651 if ( fac.static_double_count &&
2652 (Universe::field_type_should_be_aligned(T_DOUBLE) || 2652 (Universe::field_type_should_be_aligned(T_DOUBLE) ||
2653 Universe::field_type_should_be_aligned(T_LONG)) ) { 2653 Universe::field_type_should_be_aligned(T_LONG)) ) {
2654 next_static_double_offset = align_size_up(next_static_double_offset, BytesPerLong); 2654 next_static_double_offset = align_size_up(next_static_double_offset, BytesPerLong);
2655 } 2655 }
2685 int nonstatic_word_count = fac.nonstatic_word_count; 2685 int nonstatic_word_count = fac.nonstatic_word_count;
2686 int nonstatic_short_count = fac.nonstatic_short_count; 2686 int nonstatic_short_count = fac.nonstatic_short_count;
2687 int nonstatic_byte_count = fac.nonstatic_byte_count; 2687 int nonstatic_byte_count = fac.nonstatic_byte_count;
2688 int nonstatic_oop_count = fac.nonstatic_oop_count; 2688 int nonstatic_oop_count = fac.nonstatic_oop_count;
2689 2689
2690 bool super_has_nonstatic_fields =
2691 (super_klass() != NULL && super_klass->has_nonstatic_fields());
2692 bool has_nonstatic_fields = super_has_nonstatic_fields ||
2693 ((nonstatic_double_count + nonstatic_word_count +
2694 nonstatic_short_count + nonstatic_byte_count +
2695 nonstatic_oop_count) != 0);
2696
2697
2690 // Prepare list of oops for oop maps generation. 2698 // Prepare list of oops for oop maps generation.
2691 u2* nonstatic_oop_offsets; 2699 u2* nonstatic_oop_offsets;
2692 u2* nonstatic_oop_length; 2700 u2* nonstatic_oop_length;
2693 int nonstatic_oop_map_count = 0; 2701 int nonstatic_oop_map_count = 0;
2694 2702
2701 // FieldsAllocationStyle and CompactFields values will be reset to default. 2709 // FieldsAllocationStyle and CompactFields values will be reset to default.
2702 if(class_name() == vmSymbols::java_lang_Class() && class_loader.is_null()) { 2710 if(class_name() == vmSymbols::java_lang_Class() && class_loader.is_null()) {
2703 java_lang_Class_fix_post(&next_nonstatic_field_offset); 2711 java_lang_Class_fix_post(&next_nonstatic_field_offset);
2704 nonstatic_oop_offsets[0] = (u2)first_nonstatic_field_offset; 2712 nonstatic_oop_offsets[0] = (u2)first_nonstatic_field_offset;
2705 int fake_oop_count = (( next_nonstatic_field_offset - 2713 int fake_oop_count = (( next_nonstatic_field_offset -
2706 first_nonstatic_field_offset ) / oopSize); 2714 first_nonstatic_field_offset ) / heapOopSize);
2707 nonstatic_oop_length [0] = (u2)fake_oop_count; 2715 nonstatic_oop_length [0] = (u2)fake_oop_count;
2708 nonstatic_oop_map_count = 1; 2716 nonstatic_oop_map_count = 1;
2709 nonstatic_oop_count -= fake_oop_count; 2717 nonstatic_oop_count -= fake_oop_count;
2710 first_nonstatic_oop_offset = first_nonstatic_field_offset; 2718 first_nonstatic_oop_offset = first_nonstatic_field_offset;
2711 } else { 2719 } else {
2713 } 2721 }
2714 2722
2715 #ifndef PRODUCT 2723 #ifndef PRODUCT
2716 if( PrintCompactFieldsSavings ) { 2724 if( PrintCompactFieldsSavings ) {
2717 next_nonstatic_double_offset = next_nonstatic_field_offset + 2725 next_nonstatic_double_offset = next_nonstatic_field_offset +
2718 (nonstatic_oop_count * oopSize); 2726 (nonstatic_oop_count * heapOopSize);
2719 if ( nonstatic_double_count > 0 ) { 2727 if ( nonstatic_double_count > 0 ) {
2720 next_nonstatic_double_offset = align_size_up(next_nonstatic_double_offset, BytesPerLong); 2728 next_nonstatic_double_offset = align_size_up(next_nonstatic_double_offset, BytesPerLong);
2721 } 2729 }
2722 next_nonstatic_word_offset = next_nonstatic_double_offset + 2730 next_nonstatic_word_offset = next_nonstatic_double_offset +
2723 (nonstatic_double_count * BytesPerLong); 2731 (nonstatic_double_count * BytesPerLong);
2747 class_name() == vmSymbols::java_lang_ClassLoader() || 2755 class_name() == vmSymbols::java_lang_ClassLoader() ||
2748 class_name() == vmSymbols::java_lang_ref_Reference() || 2756 class_name() == vmSymbols::java_lang_ref_Reference() ||
2749 class_name() == vmSymbols::java_lang_ref_SoftReference() || 2757 class_name() == vmSymbols::java_lang_ref_SoftReference() ||
2750 class_name() == vmSymbols::java_lang_StackTraceElement() || 2758 class_name() == vmSymbols::java_lang_StackTraceElement() ||
2751 class_name() == vmSymbols::java_lang_String() || 2759 class_name() == vmSymbols::java_lang_String() ||
2752 class_name() == vmSymbols::java_lang_Throwable()) ) { 2760 class_name() == vmSymbols::java_lang_Throwable() ||
2761 class_name() == vmSymbols::java_lang_Boolean() ||
2762 class_name() == vmSymbols::java_lang_Character() ||
2763 class_name() == vmSymbols::java_lang_Float() ||
2764 class_name() == vmSymbols::java_lang_Double() ||
2765 class_name() == vmSymbols::java_lang_Byte() ||
2766 class_name() == vmSymbols::java_lang_Short() ||
2767 class_name() == vmSymbols::java_lang_Integer() ||
2768 class_name() == vmSymbols::java_lang_Long())) {
2753 allocation_style = 0; // Allocate oops first 2769 allocation_style = 0; // Allocate oops first
2754 compact_fields = false; // Don't compact fields 2770 compact_fields = false; // Don't compact fields
2755 } 2771 }
2756 2772
2757 if( allocation_style == 0 ) { 2773 if( allocation_style == 0 ) {
2758 // Fields order: oops, longs/doubles, ints, shorts/chars, bytes 2774 // Fields order: oops, longs/doubles, ints, shorts/chars, bytes
2759 next_nonstatic_oop_offset = next_nonstatic_field_offset; 2775 next_nonstatic_oop_offset = next_nonstatic_field_offset;
2760 next_nonstatic_double_offset = next_nonstatic_oop_offset + 2776 next_nonstatic_double_offset = next_nonstatic_oop_offset +
2761 (nonstatic_oop_count * oopSize); 2777 (nonstatic_oop_count * heapOopSize);
2762 } else if( allocation_style == 1 ) { 2778 } else if( allocation_style == 1 ) {
2763 // Fields order: longs/doubles, ints, shorts/chars, bytes, oops 2779 // Fields order: longs/doubles, ints, shorts/chars, bytes, oops
2764 next_nonstatic_double_offset = next_nonstatic_field_offset; 2780 next_nonstatic_double_offset = next_nonstatic_field_offset;
2765 } else { 2781 } else {
2766 ShouldNotReachHere(); 2782 ShouldNotReachHere();
2773 int nonstatic_oop_space_offset; 2789 int nonstatic_oop_space_offset;
2774 int nonstatic_word_space_offset; 2790 int nonstatic_word_space_offset;
2775 int nonstatic_short_space_offset; 2791 int nonstatic_short_space_offset;
2776 int nonstatic_byte_space_offset; 2792 int nonstatic_byte_space_offset;
2777 2793
2778 if( nonstatic_double_count > 0 ) { 2794 bool compact_into_header = (UseCompressedOops &&
2779 int offset = next_nonstatic_double_offset; 2795 allocation_style == 1 && compact_fields &&
2796 !super_has_nonstatic_fields);
2797
2798 if( compact_into_header || nonstatic_double_count > 0 ) {
2799 int offset;
2800 // Pack something in with the header if no super klass has done so.
2801 if (compact_into_header) {
2802 offset = oopDesc::klass_gap_offset_in_bytes();
2803 } else {
2804 offset = next_nonstatic_double_offset;
2805 }
2780 next_nonstatic_double_offset = align_size_up(offset, BytesPerLong); 2806 next_nonstatic_double_offset = align_size_up(offset, BytesPerLong);
2781 if( compact_fields && offset != next_nonstatic_double_offset ) { 2807 if( compact_fields && offset != next_nonstatic_double_offset ) {
2782 // Allocate available fields into the gap before double field. 2808 // Allocate available fields into the gap before double field.
2783 int length = next_nonstatic_double_offset - offset; 2809 int length = next_nonstatic_double_offset - offset;
2784 assert(length == BytesPerInt, ""); 2810 assert(length == BytesPerInt, "");
2802 nonstatic_byte_space_count += 1; 2828 nonstatic_byte_space_count += 1;
2803 length -= 1; 2829 length -= 1;
2804 } 2830 }
2805 // Allocate oop field in the gap if there are no other fields for that. 2831 // Allocate oop field in the gap if there are no other fields for that.
2806 nonstatic_oop_space_offset = offset; 2832 nonstatic_oop_space_offset = offset;
2807 if( length >= oopSize && nonstatic_oop_count > 0 && 2833 if(!compact_into_header && length >= heapOopSize &&
2834 nonstatic_oop_count > 0 &&
2808 allocation_style != 0 ) { // when oop fields not first 2835 allocation_style != 0 ) { // when oop fields not first
2809 nonstatic_oop_count -= 1; 2836 nonstatic_oop_count -= 1;
2810 nonstatic_oop_space_count = 1; // Only one will fit 2837 nonstatic_oop_space_count = 1; // Only one will fit
2811 length -= oopSize; 2838 length -= heapOopSize;
2812 offset += oopSize; 2839 offset += heapOopSize;
2813 } 2840 }
2814 } 2841 }
2815 } 2842 }
2816 2843
2817 next_nonstatic_word_offset = next_nonstatic_double_offset + 2844 next_nonstatic_word_offset = next_nonstatic_double_offset +
2826 notaligned_offset = next_nonstatic_byte_offset + nonstatic_byte_count; 2853 notaligned_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
2827 } else { // allocation_style == 1 2854 } else { // allocation_style == 1
2828 next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count; 2855 next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
2829 if( nonstatic_oop_count > 0 ) { 2856 if( nonstatic_oop_count > 0 ) {
2830 notaligned_offset = next_nonstatic_oop_offset; 2857 notaligned_offset = next_nonstatic_oop_offset;
2831 next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, oopSize); 2858 next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize);
2832 } 2859 }
2833 notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * oopSize); 2860 notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize);
2834 } 2861 }
2835 next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize ); 2862 next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize );
2836 nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset 2863 nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset
2837 - first_nonstatic_field_offset)/wordSize); 2864 - first_nonstatic_field_offset)/wordSize);
2838 2865
2844 int real_offset; 2871 int real_offset;
2845 FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i+4); 2872 FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i+4);
2846 switch (atype) { 2873 switch (atype) {
2847 case STATIC_OOP: 2874 case STATIC_OOP:
2848 real_offset = next_static_oop_offset; 2875 real_offset = next_static_oop_offset;
2849 next_static_oop_offset += oopSize; 2876 next_static_oop_offset += heapOopSize;
2850 break; 2877 break;
2851 case STATIC_BYTE: 2878 case STATIC_BYTE:
2852 real_offset = next_static_byte_offset; 2879 real_offset = next_static_byte_offset;
2853 next_static_byte_offset += 1; 2880 next_static_byte_offset += 1;
2854 break; 2881 break;
2866 next_static_double_offset += BytesPerLong; 2893 next_static_double_offset += BytesPerLong;
2867 break; 2894 break;
2868 case NONSTATIC_OOP: 2895 case NONSTATIC_OOP:
2869 if( nonstatic_oop_space_count > 0 ) { 2896 if( nonstatic_oop_space_count > 0 ) {
2870 real_offset = nonstatic_oop_space_offset; 2897 real_offset = nonstatic_oop_space_offset;
2871 nonstatic_oop_space_offset += oopSize; 2898 nonstatic_oop_space_offset += heapOopSize;
2872 nonstatic_oop_space_count -= 1; 2899 nonstatic_oop_space_count -= 1;
2873 } else { 2900 } else {
2874 real_offset = next_nonstatic_oop_offset; 2901 real_offset = next_nonstatic_oop_offset;
2875 next_nonstatic_oop_offset += oopSize; 2902 next_nonstatic_oop_offset += heapOopSize;
2876 } 2903 }
2877 // Update oop maps 2904 // Update oop maps
2878 if( nonstatic_oop_map_count > 0 && 2905 if( nonstatic_oop_map_count > 0 &&
2879 nonstatic_oop_offsets[nonstatic_oop_map_count - 1] == 2906 nonstatic_oop_offsets[nonstatic_oop_map_count - 1] ==
2880 (u2)(real_offset - nonstatic_oop_length[nonstatic_oop_map_count - 1] * oopSize) ) { 2907 (u2)(real_offset - nonstatic_oop_length[nonstatic_oop_map_count - 1] * heapOopSize) ) {
2881 // Extend current oop map 2908 // Extend current oop map
2882 nonstatic_oop_length[nonstatic_oop_map_count - 1] += 1; 2909 nonstatic_oop_length[nonstatic_oop_map_count - 1] += 1;
2883 } else { 2910 } else {
2884 // Create new oop map 2911 // Create new oop map
2885 nonstatic_oop_offsets[nonstatic_oop_map_count] = (u2)real_offset; 2912 nonstatic_oop_offsets[nonstatic_oop_map_count] = (u2)real_offset;
2968 assert(this_klass->size_helper() == instance_size, "correct size_helper"); 2995 assert(this_klass->size_helper() == instance_size, "correct size_helper");
2969 // Not yet: supers are done below to support the new subtype-checking fields 2996 // Not yet: supers are done below to support the new subtype-checking fields
2970 //this_klass->set_super(super_klass()); 2997 //this_klass->set_super(super_klass());
2971 this_klass->set_class_loader(class_loader()); 2998 this_klass->set_class_loader(class_loader());
2972 this_klass->set_nonstatic_field_size(nonstatic_field_size); 2999 this_klass->set_nonstatic_field_size(nonstatic_field_size);
3000 this_klass->set_has_nonstatic_fields(has_nonstatic_fields);
2973 this_klass->set_static_oop_field_size(fac.static_oop_count); 3001 this_klass->set_static_oop_field_size(fac.static_oop_count);
2974 cp->set_pool_holder(this_klass()); 3002 cp->set_pool_holder(this_klass());
2975 this_klass->set_constants(cp()); 3003 this_klass->set_constants(cp());
2976 this_klass->set_local_interfaces(local_interfaces()); 3004 this_klass->set_local_interfaces(local_interfaces());
2977 this_klass->set_fields(fields()); 3005 this_klass->set_fields(fields());
3126 } else { 3154 } else {
3127 // Check whether we should add a new map block or whether the last one can be extended 3155 // Check whether we should add a new map block or whether the last one can be extended
3128 OopMapBlock* first_map = super->start_of_nonstatic_oop_maps(); 3156 OopMapBlock* first_map = super->start_of_nonstatic_oop_maps();
3129 OopMapBlock* last_map = first_map + map_size - 1; 3157 OopMapBlock* last_map = first_map + map_size - 1;
3130 3158
3131 int next_offset = last_map->offset() + (last_map->length() * oopSize); 3159 int next_offset = last_map->offset() + (last_map->length() * heapOopSize);
3132 if (next_offset == first_nonstatic_oop_offset) { 3160 if (next_offset == first_nonstatic_oop_offset) {
3133 // There is no gap bettwen superklass's last oop field and first 3161 // There is no gap bettwen superklass's last oop field and first
3134 // local oop field, merge maps. 3162 // local oop field, merge maps.
3135 nonstatic_oop_map_count -= 1; 3163 nonstatic_oop_map_count -= 1;
3136 } else { 3164 } else {