[12] 8206403: ByteArrayOutputStream hugeCapacity method can return invalid capacity

Martin Buchholz martinrb at google.com
Tue Jul 24 01:04:41 UTC 2018


Latest hotspot code still has the limit.  It's dependent on element type
and VM specifics like header size, so we can't just try to see what the
limit is empirically and adjust 8 to 2.

  // Return the maximum length of an array of BasicType.  The length can
passed
  // to typeArrayOop::object_size(scale, length, header_size) without
causing an
  // overflow. We also need to make sure that this will not overflow a
size_t on
  // 32 bit platforms when we convert it to a byte size.
  static int32_t max_array_length(BasicType type) {
    assert(type >= 0 && type < T_CONFLICT, "wrong type");
    assert(type2aelembytes(type) != 0, "wrong type");

    const size_t max_element_words_per_size_t =
      align_down((SIZE_MAX/HeapWordSize - header_size(type)),
MinObjAlignment);
    const size_t max_elements_per_size_t =
      HeapWordSize * max_element_words_per_size_t / type2aelembytes(type);
    if ((size_t)max_jint < max_elements_per_size_t) {
      // It should be ok to return max_jint here, but parts of the code
      // (CollectedHeap, Klass::oop_oop_iterate(), and more) uses an int for
      // passing around the size (in words) of an object. So, we need to
avoid
      // overflowing an int when we add the header. See CRs 4718400 and
7110613.
      return align_down(max_jint - header_size(type), MinObjAlignment);
    }
    return (int32_t)max_elements_per_size_t;
  }


On Mon, Jul 23, 2018 at 5:40 PM, Brian Burkhalter <
brian.burkhalter at oracle.com> wrote:

>
> On Jul 23, 2018, at 5:26 PM, Martin Buchholz <martinrb at google.com> wrote:
>
> I'm the author of most of the MAX_ARRAY_SIZE code in the jdk.
> We should be as consistent as we can given the history.
>
>
> Thanks for the history lesson.
>
> It all looks pretty similar.
>
>
> There are in fact a number of them in java.base:
>
>     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
> src/java.base/share/classes/java/io/ByteArrayOutputStream.java
>
>     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
> src/java.base/share/classes/java/lang/AbstractStringBuilder.java
>
>     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
> src/java.base/share/classes/java/util/AbstractCollection.java
>
>     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
> src/java.base/share/classes/java/util/ArrayDeque.java
>
>     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
> src/java.base/share/classes/java/util/ArrayList.java
>
>     static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
> src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java
>
>     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
> src/java.base/share/classes/java/util/concurrent/
> PriorityBlockingQueue.java
>
>     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
> src/java.base/share/classes/java/util/Hashtable.java
>
>     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
> src/java.base/share/classes/java/util/PriorityQueue.java
>
>     static final long MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
> src/java.base/share/classes/java/util/stream/Nodes.java
>
>     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
> src/java.base/share/classes/java/util/Vector.java
>
> So unsurprisingly I prefer the status quo.
>
>
> I am wondering whether MAX_ARRAY_SIZE is even still necessary in current
> VMs? I don’t know the low level details enough to comment on that.
>
> Thanks,
>
> Brian
>


More information about the core-libs-dev mailing list