Mercurial > hg > truffle
comparison src/share/vm/classfile/classFileParser.cpp @ 939:9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
Reviewed-by: jmasa, iveresov
author | jcoomes |
---|---|
date | Thu, 13 Aug 2009 16:22:45 -0700 |
parents | b37c246bf7ce |
children | 26b774d693aa |
comparison
equal
deleted
inserted
replaced
938:b37c246bf7ce | 939:9eebd3ac74cf |
---|---|
764 NONSTATIC_ALIGNED_DOUBLE | 764 NONSTATIC_ALIGNED_DOUBLE |
765 }; | 765 }; |
766 | 766 |
767 | 767 |
768 struct FieldAllocationCount { | 768 struct FieldAllocationCount { |
769 int static_oop_count; | 769 unsigned int static_oop_count; |
770 int static_byte_count; | 770 unsigned int static_byte_count; |
771 int static_short_count; | 771 unsigned int static_short_count; |
772 int static_word_count; | 772 unsigned int static_word_count; |
773 int static_double_count; | 773 unsigned int static_double_count; |
774 int nonstatic_oop_count; | 774 unsigned int nonstatic_oop_count; |
775 int nonstatic_byte_count; | 775 unsigned int nonstatic_byte_count; |
776 int nonstatic_short_count; | 776 unsigned int nonstatic_short_count; |
777 int nonstatic_word_count; | 777 unsigned int nonstatic_word_count; |
778 int nonstatic_double_count; | 778 unsigned int nonstatic_double_count; |
779 }; | 779 }; |
780 | 780 |
781 typeArrayHandle ClassFileParser::parse_fields(constantPoolHandle cp, bool is_interface, | 781 typeArrayHandle ClassFileParser::parse_fields(constantPoolHandle cp, bool is_interface, |
782 struct FieldAllocationCount *fac, | 782 struct FieldAllocationCount *fac, |
783 objArrayHandle* fields_annotations, TRAPS) { | 783 objArrayHandle* fields_annotations, TRAPS) { |
2906 && class_loader.is_null()) { | 2906 && class_loader.is_null()) { |
2907 java_lang_ref_Reference_fix_pre(&fields, cp, &fac, CHECK_(nullHandle)); | 2907 java_lang_ref_Reference_fix_pre(&fields, cp, &fac, CHECK_(nullHandle)); |
2908 } | 2908 } |
2909 // end of "discovered" field compactibility fix | 2909 // end of "discovered" field compactibility fix |
2910 | 2910 |
2911 int nonstatic_double_count = fac.nonstatic_double_count; | 2911 unsigned int nonstatic_double_count = fac.nonstatic_double_count; |
2912 int nonstatic_word_count = fac.nonstatic_word_count; | 2912 unsigned int nonstatic_word_count = fac.nonstatic_word_count; |
2913 int nonstatic_short_count = fac.nonstatic_short_count; | 2913 unsigned int nonstatic_short_count = fac.nonstatic_short_count; |
2914 int nonstatic_byte_count = fac.nonstatic_byte_count; | 2914 unsigned int nonstatic_byte_count = fac.nonstatic_byte_count; |
2915 int nonstatic_oop_count = fac.nonstatic_oop_count; | 2915 unsigned int nonstatic_oop_count = fac.nonstatic_oop_count; |
2916 | 2916 |
2917 bool super_has_nonstatic_fields = | 2917 bool super_has_nonstatic_fields = |
2918 (super_klass() != NULL && super_klass->has_nonstatic_fields()); | 2918 (super_klass() != NULL && super_klass->has_nonstatic_fields()); |
2919 bool has_nonstatic_fields = super_has_nonstatic_fields || | 2919 bool has_nonstatic_fields = super_has_nonstatic_fields || |
2920 ((nonstatic_double_count + nonstatic_word_count + | 2920 ((nonstatic_double_count + nonstatic_word_count + |
2921 nonstatic_short_count + nonstatic_byte_count + | 2921 nonstatic_short_count + nonstatic_byte_count + |
2922 nonstatic_oop_count) != 0); | 2922 nonstatic_oop_count) != 0); |
2923 | 2923 |
2924 | 2924 |
2925 // Prepare list of oops for oop maps generation. | 2925 // Prepare list of oops for oop map generation. |
2926 u2* nonstatic_oop_offsets; | 2926 int* nonstatic_oop_offsets; |
2927 u2* nonstatic_oop_counts; | 2927 unsigned int* nonstatic_oop_counts; |
2928 int nonstatic_oop_map_count = 0; | 2928 unsigned int nonstatic_oop_map_count = 0; |
2929 | 2929 |
2930 nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD( | 2930 nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD( |
2931 THREAD, u2, nonstatic_oop_count+1); | 2931 THREAD, int, nonstatic_oop_count + 1); |
2932 nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD( | 2932 nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD( |
2933 THREAD, u2, nonstatic_oop_count+1); | 2933 THREAD, unsigned int, nonstatic_oop_count + 1); |
2934 | 2934 |
2935 // Add fake fields for java.lang.Class instances (also see above). | 2935 // Add fake fields for java.lang.Class instances (also see above). |
2936 // FieldsAllocationStyle and CompactFields values will be reset to default. | 2936 // FieldsAllocationStyle and CompactFields values will be reset to default. |
2937 if(class_name() == vmSymbols::java_lang_Class() && class_loader.is_null()) { | 2937 if(class_name() == vmSymbols::java_lang_Class() && class_loader.is_null()) { |
2938 java_lang_Class_fix_post(&next_nonstatic_field_offset); | 2938 java_lang_Class_fix_post(&next_nonstatic_field_offset); |
2939 nonstatic_oop_offsets[0] = (u2)first_nonstatic_field_offset; | 2939 nonstatic_oop_offsets[0] = first_nonstatic_field_offset; |
2940 int fake_oop_count = (( next_nonstatic_field_offset - | 2940 const uint fake_oop_count = (next_nonstatic_field_offset - |
2941 first_nonstatic_field_offset ) / heapOopSize); | 2941 first_nonstatic_field_offset) / heapOopSize; |
2942 nonstatic_oop_counts [0] = (u2)fake_oop_count; | 2942 nonstatic_oop_counts[0] = fake_oop_count; |
2943 nonstatic_oop_map_count = 1; | 2943 nonstatic_oop_map_count = 1; |
2944 nonstatic_oop_count -= fake_oop_count; | 2944 nonstatic_oop_count -= fake_oop_count; |
2945 first_nonstatic_oop_offset = first_nonstatic_field_offset; | 2945 first_nonstatic_oop_offset = first_nonstatic_field_offset; |
2946 } else { | 2946 } else { |
2947 first_nonstatic_oop_offset = 0; // will be set for first oop field | 2947 first_nonstatic_oop_offset = 0; // will be set for first oop field |
2948 } | 2948 } |
2949 | 2949 |
3117 next_nonstatic_oop_offset += heapOopSize; | 3117 next_nonstatic_oop_offset += heapOopSize; |
3118 } | 3118 } |
3119 // Update oop maps | 3119 // Update oop maps |
3120 if( nonstatic_oop_map_count > 0 && | 3120 if( nonstatic_oop_map_count > 0 && |
3121 nonstatic_oop_offsets[nonstatic_oop_map_count - 1] == | 3121 nonstatic_oop_offsets[nonstatic_oop_map_count - 1] == |
3122 (u2)(real_offset - nonstatic_oop_counts[nonstatic_oop_map_count - 1] * heapOopSize) ) { | 3122 real_offset - |
3123 int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) * | |
3124 heapOopSize ) { | |
3123 // Extend current oop map | 3125 // Extend current oop map |
3124 nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1; | 3126 nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1; |
3125 } else { | 3127 } else { |
3126 // Create new oop map | 3128 // Create new oop map |
3127 nonstatic_oop_offsets[nonstatic_oop_map_count] = (u2)real_offset; | 3129 nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset; |
3128 nonstatic_oop_counts [nonstatic_oop_map_count] = 1; | 3130 nonstatic_oop_counts [nonstatic_oop_map_count] = 1; |
3129 nonstatic_oop_map_count += 1; | 3131 nonstatic_oop_map_count += 1; |
3130 if( first_nonstatic_oop_offset == 0 ) { // Undefined | 3132 if( first_nonstatic_oop_offset == 0 ) { // Undefined |
3131 first_nonstatic_oop_offset = real_offset; | 3133 first_nonstatic_oop_offset = real_offset; |
3132 } | 3134 } |
3181 instance_size = align_object_size(next_nonstatic_type_offset / wordSize); | 3183 instance_size = align_object_size(next_nonstatic_type_offset / wordSize); |
3182 | 3184 |
3183 assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value"); | 3185 assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value"); |
3184 | 3186 |
3185 // Number of non-static oop map blocks allocated at end of klass. | 3187 // Number of non-static oop map blocks allocated at end of klass. |
3186 int total_oop_map_count = compute_oop_map_count(super_klass, | 3188 const unsigned int total_oop_map_count = |
3187 nonstatic_oop_map_count, | 3189 compute_oop_map_count(super_klass, nonstatic_oop_map_count, |
3188 first_nonstatic_oop_offset); | 3190 first_nonstatic_oop_offset); |
3189 | 3191 |
3190 // Compute reference type | 3192 // Compute reference type |
3191 ReferenceType rt; | 3193 ReferenceType rt; |
3192 if (super_klass() == NULL) { | 3194 if (super_klass() == NULL) { |
3193 rt = REF_NONE; | 3195 rt = REF_NONE; |
3194 } else { | 3196 } else { |
3195 rt = super_klass->reference_type(); | 3197 rt = super_klass->reference_type(); |
3196 } | 3198 } |
3197 | 3199 |
3198 // We can now create the basic klassOop for this klass | 3200 // We can now create the basic klassOop for this klass |
3199 klassOop ik = oopFactory::new_instanceKlass( | 3201 klassOop ik = oopFactory::new_instanceKlass(vtable_size, itable_size, |
3200 vtable_size, itable_size, | 3202 static_field_size, |
3201 static_field_size, total_oop_map_count, | 3203 total_oop_map_count, |
3202 rt, CHECK_(nullHandle)); | 3204 rt, CHECK_(nullHandle)); |
3203 instanceKlassHandle this_klass (THREAD, ik); | 3205 instanceKlassHandle this_klass (THREAD, ik); |
3204 | 3206 |
3205 assert(this_klass->static_field_size() == static_field_size, "sanity"); | 3207 assert(this_klass->static_field_size() == static_field_size, "sanity"); |
3206 assert(this_klass->nonstatic_oop_map_count() == total_oop_map_count, | 3208 assert(this_klass->nonstatic_oop_map_count() == total_oop_map_count, |
3207 "sanity"); | 3209 "sanity"); |
3376 | 3378 |
3377 return this_klass; | 3379 return this_klass; |
3378 } | 3380 } |
3379 | 3381 |
3380 | 3382 |
3381 int ClassFileParser::compute_oop_map_count(instanceKlassHandle super, | 3383 unsigned int |
3382 int nonstatic_oop_map_count, | 3384 ClassFileParser::compute_oop_map_count(instanceKlassHandle super, |
3383 int first_nonstatic_oop_offset) { | 3385 unsigned int nonstatic_oop_map_count, |
3384 int map_count = super.is_null() ? 0 : super->nonstatic_oop_map_count(); | 3386 int first_nonstatic_oop_offset) { |
3387 unsigned int map_count = | |
3388 super.is_null() ? 0 : super->nonstatic_oop_map_count(); | |
3385 if (nonstatic_oop_map_count > 0) { | 3389 if (nonstatic_oop_map_count > 0) { |
3386 // We have oops to add to map | 3390 // We have oops to add to map |
3387 if (map_count == 0) { | 3391 if (map_count == 0) { |
3388 map_count = nonstatic_oop_map_count; | 3392 map_count = nonstatic_oop_map_count; |
3389 } else { | 3393 } else { |
3407 return map_count; | 3411 return map_count; |
3408 } | 3412 } |
3409 | 3413 |
3410 | 3414 |
3411 void ClassFileParser::fill_oop_maps(instanceKlassHandle k, | 3415 void ClassFileParser::fill_oop_maps(instanceKlassHandle k, |
3412 int nonstatic_oop_map_count, | 3416 unsigned int nonstatic_oop_map_count, |
3413 u2* nonstatic_oop_offsets, | 3417 int* nonstatic_oop_offsets, |
3414 u2* nonstatic_oop_counts) { | 3418 unsigned int* nonstatic_oop_counts) { |
3415 OopMapBlock* this_oop_map = k->start_of_nonstatic_oop_maps(); | 3419 OopMapBlock* this_oop_map = k->start_of_nonstatic_oop_maps(); |
3416 const instanceKlass* const super = k->superklass(); | 3420 const instanceKlass* const super = k->superklass(); |
3417 const int super_count = super != NULL ? super->nonstatic_oop_map_count() : 0; | 3421 const unsigned int super_count = super ? super->nonstatic_oop_map_count() : 0; |
3418 if (super_count > 0) { | 3422 if (super_count > 0) { |
3419 // Copy maps from superklass | 3423 // Copy maps from superklass |
3420 OopMapBlock* super_oop_map = super->start_of_nonstatic_oop_maps(); | 3424 OopMapBlock* super_oop_map = super->start_of_nonstatic_oop_maps(); |
3421 for (int i = 0; i < super_count; ++i) { | 3425 for (unsigned int i = 0; i < super_count; ++i) { |
3422 *this_oop_map++ = *super_oop_map++; | 3426 *this_oop_map++ = *super_oop_map++; |
3423 } | 3427 } |
3424 } | 3428 } |
3425 | 3429 |
3426 if (nonstatic_oop_map_count > 0) { | 3430 if (nonstatic_oop_map_count > 0) { |