Request for review: 7110152 assert(size_in_words <= (julong)max_jint) failed: no overflow
Bengt Rutisson
bengt.rutisson at oracle.com
Thu Nov 10 15:24:28 UTC 2011
Vladimir,
This change turns out to propagate to all kinds of places. In fact,
Klass:: oop_oop_iterate() returns an int for the object size. This seems
wrong to me, but it will become a very large change to correct it.
How about just limiting the maximum array length to be "max_jint -
headersize"? That will be a very small change and hopefully it will not
have such a huge impact on "real" applications. The difference between
the allowed maximum array length and the theoretical maximum will only
be a few elements.
Here is a webrev of what I think that would look like:
http://cr.openjdk.java.net/~brutisso/7110152/webrev.03/
Thanks,
Bengt
On 2011-11-10 01:30, Vladimir Kozlov wrote:
> Sorry, my last comment is incorrect. Yes, max_array_length() returns
> max_jint in 64 bit VM.
>
> Removing assert from object_size() is not enough. You need to change
> returned type to size_t. Otherwise the size will be cut incorrectly.
> Yes, it become messy.
>
> I all cases it would be nice to keep the assert (maybe changed) to
> catch incorrect size in 32 bit VM. And move the assert in
> object_size() after size alignment.
>
> Thanks,
> Vladimir
>
> Vladimir Kozlov wrote:
>> Bengt Rutisson wrote:
>>> On 2011-11-10 00:14, Vladimir Kozlov wrote:
>>>> Bengt Rutisson wrote:
>>>>>
>>>>> ...except that I just saw that
>>>>> CollectedHeap::array_allocate_nozero() uses int.
>>>>
>>>> Yes, this is what I tried to tell you :)
>>>
>>> Right. Thanks. :-)
>>>
>>>> You also missed code in typeArrayKlass::allocate_permanent() and
>>>> nozero code in typeArrayKlass::allocate_common(). May be also other
>>>> places where CollectedHeap::array_allocate is called.
>>>
>>> Yes, unfortunately this propagates to
>>> typeArrayOopDesc::object_size() that returns an int. So, this really
>>> propagates.
>>
>> I surprise that c++ compilers does not complain about returning int
>> from typeArrayOopDesc::object_size() in 64 bit VM when
>> align_object_size() returns intptr_t value.
>>
>>>
>>> I'll dig in to it a bit, but if the change is getting too large, I
>>> guess an alternative is to go back to limiting
>>> arrayOopDesc::max_array_length() to return max_jint - headersize.
>>> Seems like there is a lot of code that relize on that an object size
>>> will fit into an int.
>>
>> Your new code does substruct headersize in max_array_length(). And it
>> rounds size down to MinObjAlignment. So we should not overflow int in
>> object_size().
>> One note, in object_size() we need to move assert after
>> align_object_size():
>>
>> assert(size_in_words <= (julong)max_jint, "no overflow");
>>
>> return align_object_size((intptr_t)size_in_words);
>> ---
>> size_t aligned_size =
>> (size_t)align_object_size((intptr_t)size_in_words);
>> assert(aligned_size <= (size_t)max_jint, "no overflow");
>> return aligned_size;
>>
>> Thanks,
>> Vladimir
>>
>>>
>>>> Could you also remove 'size' argument in
>>>> post_allocation_install_obj_klass() which does not use it?
>>>
>>> Sure. Done.
>>>
>>> Bengt
>>>
>>>>
>>>> Thanks,
>>>> Vladimir
>>>>
>>>>>
>>>>> I'll fix that and update the webrev.
>>>>>
>>>>> Bengt
>>>>>
>>>>> On 2011-11-09 23:47, Bengt Rutisson wrote:
>>>>>>
>>>>>> Vladimir,
>>>>>>
>>>>>> Thanks for looking at this!
>>>>>>
>>>>>> On 2011-11-09 23:06, Vladimir Kozlov wrote:
>>>>>>> Why not change it in all CollectedHeap methods?
>>>>>>
>>>>>> The other methods in CollectedHeap that use int for size are
>>>>>> handling objects. Those should not have been affected by my other
>>>>>> change (since it only changed the maximum array length).
>>>>>>
>>>>>> I have not investigated whether or not it is possible to create
>>>>>> an object (that is not an array) that will have a size larger
>>>>>> than int. I assume that there is some limit to how many fields an
>>>>>> object can have. But I don't know what that limit is and whether
>>>>>> it will guarantee that the largest object fits into an int. It
>>>>>> also seems much more unlikely that anyone would actually create
>>>>>> such a large object.
>>>>>>
>>>>>> I'd like to only change this for arrays now since we have
>>>>>> failures in the nightlies. If you think it is ok I could create a
>>>>>> separate CR to investigate whether or not the int object sizes in
>>>>>> CollectedHeap are safe.
>>>>>>
>>>>>> Bengt
>>>>>>
>>>>>>>
>>>>>>> Vladimir
>>>>>>>
>>>>>>> Bengt Rutisson wrote:
>>>>>>>>
>>>>>>>> Hi all,
>>>>>>>>
>>>>>>>> Could I have a couple of reviews for this small change?
>>>>>>>> http://cr.openjdk.java.net/~brutisso/7110152/webrev.01/
>>>>>>>>
>>>>>>>> The problem is that CollectedHeap::array_allocate() takes its
>>>>>>>> size as an int instead of a size_t. This was exposed by the fix
>>>>>>>> I made to 7102044 recently.
>>>>>>>>
>>>>>>>> That change allows arrays to be max_jint long on 64 bit
>>>>>>>> systems. This is correct since we can handle this size in a 64
>>>>>>>> bit size_t even when we add the object header. However, it will
>>>>>>>> overflow an int.
>>>>>>>>
>>>>>>>> Here is a small reproducer that will trigger the assert
>>>>>>>> mentioned in 7110152 when it is run on a 64 bit VM:
>>>>>>>>
>>>>>>>> public class MaxJIntArray {
>>>>>>>> public static void main(String[] args) {
>>>>>>>> final int MAX_JINT = 2147483647;
>>>>>>>> double[] a = new double[MAX_JINT];
>>>>>>>> System.out.println("Allocated a[" + a.length + "]");
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>> The fix is to remove the assert (since it is too strict) and
>>>>>>>> changing CollectedHeap::array_allocate() to take a size_t
>>>>>>>> instead of an int.
>>>>>>>>
>>>>>>>> CR:
>>>>>>>> 7110152 assert(size_in_words <= (julong)max_jint) failed: no
>>>>>>>> overflow
>>>>>>>> http://monaco.sfbay.sun.com/detail.jsf?cr=7110152
>>>>>>>>
>>>>>>>> Bengt
>>>>>>
>>>>>
>>>
More information about the hotspot-gc-dev
mailing list