1 /*
  2  * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_UTILITIES_GROWABLEARRAY_HPP
 26 #define SHARE_UTILITIES_GROWABLEARRAY_HPP
 27 
 28 #include "memory/allocation.hpp"
 29 #include "memory/iterator.hpp"
 30 #include "utilities/debug.hpp"
 31 #include "utilities/globalDefinitions.hpp"
 32 #include "utilities/ostream.hpp"
 33 #include "utilities/powerOfTwo.hpp"
 34 
 35 // A growable array.
 36 
 37 /*************************************************************************/
 38 /*                                                                       */
 39 /*     WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING   */
 40 /*                                                                       */
 41 /* Should you use GrowableArrays to contain handles you must be certain  */
 42 /* that the GrowableArray does not outlive the HandleMark that contains  */
 43 /* the handles. Since GrowableArrays are typically resource allocated    */
 44 /* the following is an example of INCORRECT CODE,                        */
 45 /*                                                                       */
 46 /* ResourceMark rm;                                                      */
 47 /* GrowableArray<Handle>* arr = new GrowableArray<Handle>(size);         */
 48 /* if (blah) {                                                           */
 49 /*    while (...) {                                                      */
 50 /*      HandleMark hm;                                                   */
 51 /*      ...                                                              */
 52 /*      Handle h(THREAD, some_oop);                                      */
 53 /*      arr->append(h);                                                  */
 54 /*    }                                                                  */
 55 /* }                                                                     */
 56 /* if (arr->length() != 0 ) {                                            */
 57 /*    oop bad_oop = arr->at(0)(); // Handle is BAD HERE.                 */
 58 /*    ...                                                                */
 59 /* }                                                                     */
 60 /*                                                                       */
 61 /* If the GrowableArrays you are creating is C_Heap allocated then it    */
 62 /* should not hold handles since the handles could trivially try and     */
 63 /* outlive their HandleMark. In some situations you might need to do     */
 64 /* this and it would be legal but be very careful and see if you can do  */
 65 /* the code in some other manner.                                        */
 66 /*                                                                       */
 67 /*************************************************************************/
 68 
 69 // Non-template base class responsible for handling the length and max.
 70 
 71 
 72 class GrowableArrayBase : public AnyObj {
 73   friend class VMStructs;
 74 
 75 protected:
 76   // Current number of accessible elements
 77   int _len;
 78   // Current number of allocated elements
 79   int _capacity;
 80 
 81   GrowableArrayBase(int capacity, int initial_len) :
 82       _len(initial_len),
 83       _capacity(capacity) {
 84     assert(_len >= 0 && _len <= _capacity, "initial_len too big");
 85   }
 86 
 87   ~GrowableArrayBase() {}
 88 
 89 public:
 90   int   length() const          { return _len; }
 91   int   capacity() const        { return _capacity; }
 92 
 93   bool  is_empty() const        { return _len == 0; }
 94   bool  is_nonempty() const     { return _len != 0; }
 95   bool  is_full() const         { return _len == _capacity; }
 96 };
 97 
 98 template <typename E> class GrowableArrayIterator;
 99 
100 // Extends GrowableArrayBase with a typed data array.
101 //
102 // E: Element type
103 //
104 // The "view" adds function that don't grow or deallocate
105 // the _data array, so there's no need for an allocator.
106 //
107 // The "view" can be used to type erase the allocator classes
108 // of GrowableArrayWithAllocator.
109 template <typename E>
110 class GrowableArrayView : public GrowableArrayBase {
111 protected:
112   E* _data; // data array
113 
114   GrowableArrayView(E* data, int capacity, int initial_len) :
115       GrowableArrayBase(capacity, initial_len), _data(data) {}
116 
117   ~GrowableArrayView() {}
118 
119 public:
120   bool operator==(const GrowableArrayView& rhs) const {
121     if (_len != rhs._len)
122       return false;
123     for (int i = 0; i < _len; i++) {
124       if (at(i) != rhs.at(i)) {
125         return false;
126       }
127     }
128     return true;
129   }
130 
131   bool operator!=(const GrowableArrayView& rhs) const {
132     return !(*this == rhs);
133   }
134 
135   E& at(int i) {
136     assert(0 <= i && i < _len, "illegal index %d for length %d", i, _len);
137     return _data[i];
138   }
139 
140   E const& at(int i) const {
141     assert(0 <= i && i < _len, "illegal index %d for length %d", i, _len);
142     return _data[i];
143   }
144 
145   E* adr_at(int i) const {
146     assert(0 <= i && i < _len, "illegal index %d for length %d", i, _len);
147     return &_data[i];
148   }
149 
150   E& first() {
151     assert(_len > 0, "empty");
152     return _data[0];
153   }
154 
155   E const& first() const {
156     assert(_len > 0, "empty");
157     return _data[0];
158   }
159 
160   E& top() {
161     assert(_len > 0, "empty");
162     return _data[_len - 1];
163   }
164 
165   E const& top() const {
166     assert(_len > 0, "empty");
167     return _data[_len - 1];
168   }
169 
170   E& last() {
171     return top();
172   }
173 
174   E const& last() const {
175     return top();
176   }
177 
178   GrowableArrayIterator<E> begin() const {
179     return GrowableArrayIterator<E>(this, 0);
180   }
181 
182   GrowableArrayIterator<E> end() const {
183     return GrowableArrayIterator<E>(this, length());
184   }
185 
186   void at_put(int i, const E& elem) {
187     assert(0 <= i && i < _len, "illegal index %d for length %d", i, _len);
188     _data[i] = elem;
189   }
190 
191   bool contains(const E& elem) const {
192     for (int i = 0; i < _len; i++) {
193       if (_data[i] == elem) return true;
194     }
195     return false;
196   }
197 
198   int  find(const E& elem) const {
199     for (int i = 0; i < _len; i++) {
200       if (_data[i] == elem) return i;
201     }
202     return -1;
203   }
204 
205   int  find_from_end(const E& elem) const {
206     for (int i = _len-1; i >= 0; i--) {
207       if (_data[i] == elem) return i;
208     }
209     return -1;
210   }
211 
212   // Find first element that matches the given predicate.
213   //
214   // Predicate: bool predicate(const E& elem)
215   //
216   // Returns the index of the element or -1 if no element matches the predicate
217   template<typename Predicate>
218   int find_if(Predicate predicate) const {
219     for (int i = 0; i < _len; i++) {
220       if (predicate(_data[i])) return i;
221     }
222     return -1;
223   }
224 
225   // Find last element that matches the given predicate.
226   //
227   // Predicate: bool predicate(const E& elem)
228   //
229   // Returns the index of the element or -1 if no element matches the predicate
230   template<typename Predicate>
231   int find_from_end_if(Predicate predicate) const {
232     // start at the end of the array
233     for (int i = _len-1; i >= 0; i--) {
234       if (predicate(_data[i])) return i;
235     }
236     return -1;
237   }
238 
239   void sort(int f(E*, E*)) {
240     if (_data == nullptr) return;
241     qsort(_data, length(), sizeof(E), (_sort_Fn)f);
242   }
243   // sort by fixed-stride sub arrays:
244   void sort(int f(E*, E*), int stride) {
245     if (_data == nullptr) return;
246     qsort(_data, length() / stride, sizeof(E) * stride, (_sort_Fn)f);
247   }
248 
249   template <typename K, int compare(const K&, const E&)> int find_sorted(const K& key, bool& found) const {
250     found = false;
251     int min = 0;
252     int max = length() - 1;
253 
254     while (max >= min) {
255       int mid = (int)(((uint)max + min) / 2);
256       E value = at(mid);
257       int diff = compare(key, value);
258       if (diff > 0) {
259         min = mid + 1;
260       } else if (diff < 0) {
261         max = mid - 1;
262       } else {
263         found = true;
264         return mid;
265       }
266     }
267     return min;
268   }
269 
270   template <typename K>
271   int find_sorted(CompareClosure<E>* cc, const K& key, bool& found) {
272     found = false;
273     int min = 0;
274     int max = length() - 1;
275 
276     while (max >= min) {
277       int mid = (int)(((uint)max + min) / 2);
278       E value = at(mid);
279       int diff = cc->do_compare(key, value);
280       if (diff > 0) {
281         min = mid + 1;
282       } else if (diff < 0) {
283         max = mid - 1;
284       } else {
285         found = true;
286         return mid;
287       }
288     }
289     return min;
290   }
291 
292   void print() const {
293     tty->print("Growable Array " PTR_FORMAT, p2i(this));
294     tty->print(": length %d (capacity %d) { ", _len, _capacity);
295     for (int i = 0; i < _len; i++) {
296       tty->print(INTPTR_FORMAT " ", *(intptr_t*)&(_data[i]));
297     }
298     tty->print("}\n");
299   }
300 
301   // MetaspaceClosure support
302   E** data_addr() {
303     return &_data;
304   }
305 };
306 
307 template <typename E>
308 class GrowableArrayFromArray : public GrowableArrayView<E> {
309 public:
310 
311   GrowableArrayFromArray(E* data, int len) :
312     GrowableArrayView<E>(data, len, len) {}
313 };
314 
315 // GrowableArrayWithAllocator extends the "view" with
316 // the capability to grow and deallocate the data array.
317 //
318 // The allocator responsibility is delegated to the sub-class.
319 //
320 // Derived: The sub-class responsible for allocation / deallocation
321 //  - E* Derived::allocate()       - member function responsible for allocation
322 //  - void Derived::deallocate(E*) - member function responsible for deallocation
323 template <typename E, typename Derived>
324 class GrowableArrayWithAllocator : public GrowableArrayView<E> {
325   void expand_to(int j);
326   void grow(int j);
327 
328 protected:
329   GrowableArrayWithAllocator(E* data, int capacity) :
330       GrowableArrayView<E>(data, capacity, 0) {
331     for (int i = 0; i < capacity; i++) {
332       ::new ((void*)&data[i]) E();
333     }
334   }
335 
336   GrowableArrayWithAllocator(E* data, int capacity, int initial_len, const E& filler) :
337       GrowableArrayView<E>(data, capacity, initial_len) {
338     int i = 0;
339     for (; i < initial_len; i++) {
340       ::new ((void*)&data[i]) E(filler);
341     }
342     for (; i < capacity; i++) {
343       ::new ((void*)&data[i]) E();
344     }
345   }
346 
347   GrowableArrayWithAllocator(E* data, int capacity, int initial_len) :
348     GrowableArrayView<E>(data, capacity, initial_len) {}
349 
350   ~GrowableArrayWithAllocator() {}
351 
352 public:
353   int append(const E& elem) {
354     if (this->_len == this->_capacity) grow(this->_len);
355     int idx = this->_len++;
356     this->_data[idx] = elem;
357     return idx;
358   }
359 
360   bool append_if_missing(const E& elem) {
361     // Returns TRUE if elem is added.
362     bool missed = !this->contains(elem);
363     if (missed) append(elem);
364     return missed;
365   }
366 
367   void push(const E& elem) { append(elem); }
368 
369   E pop() {
370     assert(this->_len > 0, "empty list");
371     return this->_data[--this->_len];
372   }
373 
374   E& at_grow(int i, const E& fill = E()) {
375     assert(0 <= i, "negative index %d", i);
376     if (i >= this->_len) {
377       if (i >= this->_capacity) grow(i);
378       for (int j = this->_len; j <= i; j++)
379         this->_data[j] = fill;
380       this->_len = i+1;
381     }
382     return this->_data[i];
383   }
384 
385   void at_put_grow(int i, const E& elem, const E& fill = E()) {
386     assert(0 <= i, "negative index %d", i);
387     if (i >= this->_len) {
388       if (i >= this->_capacity) grow(i);
389       for (int j = this->_len; j < i; j++)
390         this->_data[j] = fill;
391       this->_len = i+1;
392     }
393     this->_data[i] = elem;
394   }
395 
396   // inserts the given element before the element at index i
397   void insert_before(const int idx, const E& elem) {
398     assert(0 <= idx && idx <= this->_len, "illegal index %d for length %d", idx, this->_len);
399     if (this->_len == this->_capacity) grow(this->_len);
400     for (int j = this->_len - 1; j >= idx; j--) {
401       this->_data[j + 1] = this->_data[j];
402     }
403     this->_len++;
404     this->_data[idx] = elem;
405   }
406 
407   void insert_before(const int idx, const GrowableArrayView<E>* array) {
408     assert(0 <= idx && idx <= this->_len, "illegal index %d for length %d", idx, this->_len);
409     int array_len = array->length();
410     int new_len = this->_len + array_len;
411     if (new_len >= this->_capacity) grow(new_len);
412 
413     for (int j = this->_len - 1; j >= idx; j--) {
414       this->_data[j + array_len] = this->_data[j];
415     }
416 
417     for (int j = 0; j < array_len; j++) {
418       this->_data[idx + j] = array->at(j);
419     }
420 
421     this->_len += array_len;
422   }
423 
424   void appendAll(const GrowableArrayView<E>* l) {
425     for (int i = 0; i < l->length(); i++) {
426       this->at_put_grow(this->_len, l->at(i), E());
427     }
428   }
429 
430   // Binary search and insertion utility.  Search array for element
431   // matching key according to the static compare function.  Insert
432   // that element if not already in the list.  Assumes the list is
433   // already sorted according to compare function.
434   template <int compare(const E&, const E&)> E insert_sorted(const E& key) {
435     bool found;
436     int location = GrowableArrayView<E>::template find_sorted<E, compare>(key, found);
437     if (!found) {
438       insert_before(location, key);
439     }
440     return this->at(location);
441   }
442 
443   E insert_sorted(CompareClosure<E>* cc, const E& key) {
444     bool found;
445     int location = find_sorted(cc, key, found);
446     if (!found) {
447       insert_before(location, key);
448     }
449     return this->at(location);
450   }
451 
452   void swap(GrowableArrayWithAllocator* other) {
453     ::swap(this->_data, other->_data);
454     ::swap(this->_len, other->_len);
455     ::swap(this->_capacity, other->_capacity);
456   }
457 
458   // Ensure capacity is at least new_capacity.
459   void reserve(int new_capacity);
460 
461   void trunc_to(int length) {
462     assert(length <= this->_len,"cannot increase length");
463     this->_len = length;
464   }
465 
466   // Order preserving remove operations.
467 
468   void remove_at(int index) {
469     assert(0 <= index && index < this->_len,
470            "illegal index %d for length %d", index, this->_len);
471     for (int j = index + 1; j < this->_len; j++) {
472       this->_data[j-1] = this->_data[j];
473     }
474     this->_len--;
475   }
476 
477   void remove(const E& elem) {
478     // Assuming that element does exist.
479     bool removed = this->remove_if_existing(elem);
480     if (removed) return;
481     ShouldNotReachHere();
482   }
483 
484   bool remove_if_existing(const E& elem) {
485     // Returns TRUE if elem is removed.
486     for (int i = 0; i < this->_len; i++) {
487       if (this->_data[i] == elem) {
488         this->remove_at(i);
489         return true;
490       }
491     }
492     return false;
493   }
494 
495   // Remove all elements in the range [0; end). The order is preserved.
496   void remove_till(int end) {
497     remove_range(0, end);
498   }
499 
500   // Remove all elements in the range [start; end). The order is preserved.
501   void remove_range(int start, int end) {
502     assert(0 <= start, "illegal start index %d", start);
503     assert(start <= end && end <= this->_len,
504            "erase called with invalid range [%d, %d) for length %d",
505            start, end, this->_len);
506 
507     for (int i = start, j = end; j < this->length(); i++, j++) {
508       this->at_put(i, this->at(j));
509     }
510     this->_len -= (end - start);
511   }
512 
513   // Replaces the designated element with the last element and shrinks by 1.
514   void delete_at(int index) {
515     assert(0 <= index && index < this->_len, "illegal index %d for length %d", index, this->_len);
516     if (index < --this->_len) {
517       // Replace removed element with last one.
518       this->_data[index] = this->_data[this->_len];
519     }
520   }
521 
522   // Reduce capacity to length.
523   void shrink_to_fit();
524 
525   void clear() { this->_len = 0; }
526   void clear_and_deallocate();
527 };
528 
529 template <typename E, typename Derived>
530 void GrowableArrayWithAllocator<E, Derived>::expand_to(int new_capacity) {
531   int old_capacity = this->_capacity;
532   assert(new_capacity > old_capacity,
533          "expected growth but %d <= %d", new_capacity, old_capacity);
534   this->_capacity = new_capacity;
535   E* newData = static_cast<Derived*>(this)->allocate();
536   int i = 0;
537   for (     ; i < this->_len; i++) ::new ((void*)&newData[i]) E(this->_data[i]);
538   for (     ; i < this->_capacity; i++) ::new ((void*)&newData[i]) E();
539   for (i = 0; i < old_capacity; i++) this->_data[i].~E();
540   if (this->_data != nullptr) {
541     static_cast<Derived*>(this)->deallocate(this->_data);
542   }
543   this->_data = newData;
544 }
545 
546 template <typename E, typename Derived>
547 void GrowableArrayWithAllocator<E, Derived>::grow(int j) {
548   // grow the array by increasing _capacity to the first power of two larger than the size we need
549   expand_to(next_power_of_2(j));
550 }
551 
552 template <typename E, typename Derived>
553 void GrowableArrayWithAllocator<E, Derived>::reserve(int new_capacity) {
554   if (new_capacity > this->_capacity) {
555     expand_to(new_capacity);
556   }
557 }
558 
559 template <typename E, typename Derived>
560 void GrowableArrayWithAllocator<E, Derived>::shrink_to_fit() {
561   int old_capacity = this->_capacity;
562   int len = this->_len;
563   assert(len <= old_capacity, "invariant");
564 
565   // If already at full capacity, nothing to do.
566   if (len == old_capacity) {
567     return;
568   }
569 
570   // If not empty, allocate new, smaller, data, and copy old data to it.
571   E* old_data = this->_data;
572   E* new_data = nullptr;
573   this->_capacity = len;        // Must preceed allocate().
574   if (len > 0) {
575     new_data = static_cast<Derived*>(this)->allocate();
576     for (int i = 0; i < len; ++i) ::new (&new_data[i]) E(old_data[i]);
577   }
578   // Destroy contents of old data, and deallocate it.
579   for (int i = 0; i < old_capacity; ++i) old_data[i].~E();
580   if (old_data != nullptr) {
581     static_cast<Derived*>(this)->deallocate(old_data);
582   }
583   // Install new data, which might be nullptr.
584   this->_data = new_data;
585 }
586 
587 template <typename E, typename Derived>
588 void GrowableArrayWithAllocator<E, Derived>::clear_and_deallocate() {
589   this->clear();
590   this->shrink_to_fit();
591 }
592 
593 class GrowableArrayResourceAllocator {
594 public:
595   static void* allocate(int max, int element_size);
596 };
597 
598 // Arena allocator
599 class GrowableArrayArenaAllocator {
600 public:
601   static void* allocate(int max, int element_size, Arena* arena);
602 };
603 
604 // CHeap allocator
605 class GrowableArrayCHeapAllocator {
606 public:
607   static void* allocate(int max, int element_size, MemTag mem_tag);
608   static void deallocate(void* mem);
609 };
610 
611 #ifdef ASSERT
612 
613 // Checks resource allocation nesting
614 class GrowableArrayNestingCheck {
615   // resource area nesting at creation
616   int _nesting;
617 
618 public:
619   GrowableArrayNestingCheck(bool on_resource_area);
620   GrowableArrayNestingCheck(Arena* arena);
621 
622   void on_resource_area_alloc() const;
623   void on_arena_alloc(Arena* arena) const;
624 };
625 
626 #endif // ASSERT
627 
628 // Encodes where the backing array is allocated
629 // and performs necessary checks.
630 class GrowableArrayMetadata {
631   uintptr_t _bits;
632 
633   // resource area nesting at creation
634   DEBUG_ONLY(GrowableArrayNestingCheck _nesting_check;)
635 
636   // Resource allocation
637   static uintptr_t bits() {
638     return 0;
639   }
640 
641   // CHeap allocation
642   static uintptr_t bits(MemTag mem_tag) {
643     assert(mem_tag != mtNone, "Must provide a proper MemTag");
644     return (uintptr_t(mem_tag) << 1) | 1;
645   }
646 
647   // Arena allocation
648   static uintptr_t bits(Arena* arena) {
649     assert((uintptr_t(arena) & 1) == 0, "Required for on_C_heap() to work");
650     return uintptr_t(arena);
651   }
652 
653 public:
654   // Resource allocation
655   GrowableArrayMetadata() :
656       _bits(bits())
657       DEBUG_ONLY(COMMA _nesting_check(true)) {
658   }
659 
660   // Arena allocation
661   GrowableArrayMetadata(Arena* arena) :
662       _bits(bits(arena))
663       DEBUG_ONLY(COMMA _nesting_check(arena)) {
664   }
665 
666   // CHeap allocation
667   GrowableArrayMetadata(MemTag mem_tag) :
668       _bits(bits(mem_tag))
669       DEBUG_ONLY(COMMA _nesting_check(false)) {
670   }
671 
672 #ifdef ASSERT
673   GrowableArrayMetadata(const GrowableArrayMetadata& other) :
674       _bits(other._bits),
675       _nesting_check(other._nesting_check) {
676     assert(!on_C_heap(), "Copying of CHeap arrays not supported");
677     assert(!other.on_C_heap(), "Copying of CHeap arrays not supported");
678   }
679 
680   GrowableArrayMetadata& operator=(const GrowableArrayMetadata& other) {
681     _bits = other._bits;
682     _nesting_check = other._nesting_check;
683     assert(!on_C_heap(), "Assignment of CHeap arrays not supported");
684     assert(!other.on_C_heap(), "Assignment of CHeap arrays not supported");
685     return *this;
686   }
687 
688   void init_checks(const GrowableArrayBase* array) const;
689   void on_resource_area_alloc_check() const;
690   void on_arena_alloc_check() const;
691 #endif // ASSERT
692 
693   bool on_C_heap() const        { return (_bits & 1) == 1; }
694   bool on_resource_area() const { return _bits == 0; }
695   bool on_arena() const         { return (_bits & 1) == 0 && _bits != 0; }
696 
697   Arena* arena() const      { return (Arena*)_bits; }
698   MemTag mem_tag() const { return MemTag(_bits >> 1); }
699 };
700 
701 // THE GrowableArray.
702 //
703 // Supports multiple allocation strategies:
704 //  - Resource stack allocation: if no extra argument is provided
705 //  - CHeap allocation: if mem_tag is provided
706 //  - Arena allocation: if an arena is provided
707 //
708 // There are some drawbacks of using GrowableArray, that are removed in some
709 // of the other implementations of GrowableArrayWithAllocator sub-classes:
710 //
711 // Memory overhead: The multiple allocation strategies uses extra metadata
712 //  embedded in the instance.
713 //
714 // Strict allocation locations: There are rules about where the GrowableArray
715 //  instance is allocated, that depends on where the data array is allocated.
716 //  See: init_checks.
717 
718 template <typename E>
719 class GrowableArray : public GrowableArrayWithAllocator<E, GrowableArray<E>> {
720   friend class VMStructs;
721   friend class GrowableArrayWithAllocator<E, GrowableArray>;
722   friend class GrowableArrayTest;
723 
724   static E* allocate(int max) {
725     return (E*)GrowableArrayResourceAllocator::allocate(max, sizeof(E));
726   }
727 
728   static E* allocate(int max, MemTag mem_tag) {
729     return (E*)GrowableArrayCHeapAllocator::allocate(max, sizeof(E), mem_tag);
730   }
731 
732   static E* allocate(int max, Arena* arena) {
733     return (E*)GrowableArrayArenaAllocator::allocate(max, sizeof(E), arena);
734   }
735 
736   GrowableArrayMetadata _metadata;
737 
738   void init_checks() const { DEBUG_ONLY(_metadata.init_checks(this);) }
739 
740   // Where are we going to allocate memory?
741   bool on_C_heap() const        { return _metadata.on_C_heap(); }
742   bool on_resource_area() const { return _metadata.on_resource_area(); }
743   bool on_arena() const         { return _metadata.on_arena(); }
744 
745   E* allocate() {
746     if (on_resource_area()) {
747       DEBUG_ONLY(_metadata.on_resource_area_alloc_check());
748       return allocate(this->_capacity);
749     }
750 
751     if (on_C_heap()) {
752       return allocate(this->_capacity, _metadata.mem_tag());
753     }
754 
755     assert(on_arena(), "Sanity");
756     DEBUG_ONLY(_metadata.on_arena_alloc_check());
757     return allocate(this->_capacity, _metadata.arena());
758   }
759 
760   void deallocate(E* mem) {
761     if (on_C_heap()) {
762       GrowableArrayCHeapAllocator::deallocate(mem);
763     }
764   }
765 
766 public:
767   GrowableArray() : GrowableArray(2 /* initial_capacity */) {}
768 
769   explicit GrowableArray(int initial_capacity) :
770       GrowableArrayWithAllocator<E, GrowableArray>(
771           allocate(initial_capacity),
772           initial_capacity),
773       _metadata() {
774     init_checks();
775   }
776 
777   GrowableArray(int initial_capacity, MemTag mem_tag) :
778       GrowableArrayWithAllocator<E, GrowableArray>(
779           allocate(initial_capacity, mem_tag),
780           initial_capacity),
781       _metadata(mem_tag) {
782     init_checks();
783   }
784 
785   GrowableArray(int initial_capacity, int initial_len, const E& filler) :
786       GrowableArrayWithAllocator<E, GrowableArray>(
787           allocate(initial_capacity),
788           initial_capacity, initial_len, filler),
789       _metadata() {
790     init_checks();
791   }
792 
793   // This constructor performs no default initialization, so be careful.
794   GrowableArray(int initial_capacity, int initial_len, MemTag mem_tag) :
795     GrowableArrayWithAllocator<E, GrowableArray>(
796       allocate(initial_capacity, mem_tag),
797       initial_capacity, initial_len),
798     _metadata(mem_tag) {
799     init_checks();
800   }
801 
802   GrowableArray(int initial_capacity, int initial_len, const E& filler, MemTag mem_tag) :
803       GrowableArrayWithAllocator<E, GrowableArray>(
804           allocate(initial_capacity, mem_tag),
805           initial_capacity, initial_len, filler),
806       _metadata(mem_tag) {
807     init_checks();
808   }
809 
810   GrowableArray(Arena* arena, int initial_capacity, int initial_len, const E& filler) :
811       GrowableArrayWithAllocator<E, GrowableArray>(
812           allocate(initial_capacity, arena),
813           initial_capacity, initial_len, filler),
814       _metadata(arena) {
815     init_checks();
816   }
817 
818   ~GrowableArray() {
819     if (on_C_heap()) {
820       this->clear_and_deallocate();
821     }
822   }
823 
824   void assert_on_C_heap() { assert(on_C_heap(), "must be on C heap"); }
825 };
826 
827 // Leaner GrowableArray for CHeap backed data arrays, with compile-time decided MemTag.
828 template <typename E, MemTag MT>
829 class GrowableArrayCHeap : public GrowableArrayWithAllocator<E, GrowableArrayCHeap<E, MT> > {
830   friend class GrowableArrayWithAllocator<E, GrowableArrayCHeap<E, MT> >;
831 
832   STATIC_ASSERT(MT != mtNone);
833 
834   static E* allocate(int max, MemTag mem_tag) {
835     return (E*)GrowableArrayCHeapAllocator::allocate(max, sizeof(E), mem_tag);
836   }
837 
838   NONCOPYABLE(GrowableArrayCHeap);
839 
840   E* allocate() {
841     return allocate(this->_capacity, MT);
842   }
843 
844   void deallocate(E* mem) {
845     GrowableArrayCHeapAllocator::deallocate(mem);
846   }
847 
848 public:
849   GrowableArrayCHeap(int initial_capacity = 0) :
850       GrowableArrayWithAllocator<E, GrowableArrayCHeap<E, MT> >(
851           allocate(initial_capacity, MT),
852           initial_capacity) {}
853 
854   GrowableArrayCHeap(int initial_capacity, int initial_len, const E& filler) :
855       GrowableArrayWithAllocator<E, GrowableArrayCHeap<E, MT> >(
856           allocate(initial_capacity, MT),
857           initial_capacity, initial_len, filler) {}
858 
859   ~GrowableArrayCHeap() {
860     this->clear_and_deallocate();
861   }
862 
863   void* operator new(size_t size) {
864     return AnyObj::operator new(size, MT);
865   }
866 
867   void* operator new(size_t size, const std::nothrow_t&  nothrow_constant) throw() {
868     return AnyObj::operator new(size, nothrow_constant, MT);
869   }
870   void operator delete(void *p) {
871     AnyObj::operator delete(p);
872   }
873 };
874 
875 // Custom STL-style iterator to iterate over GrowableArrays
876 // It is constructed by invoking GrowableArray::begin() and GrowableArray::end()
877 template <typename E>
878 class GrowableArrayIterator : public StackObj {
879   friend class GrowableArrayView<E>;
880 
881  private:
882   const GrowableArrayView<E>* _array; // GrowableArray we iterate over
883   int _position;                      // The current position in the GrowableArray
884 
885   // Private constructor used in GrowableArray::begin() and GrowableArray::end()
886   GrowableArrayIterator(const GrowableArrayView<E>* array, int position) : _array(array), _position(position) {
887     assert(0 <= position && position <= _array->length(), "illegal position");
888   }
889 
890  public:
891   GrowableArrayIterator() : _array(nullptr), _position(0) { }
892   GrowableArrayIterator& operator++() { ++_position; return *this; }
893   E operator*()                       { return _array->at(_position); }
894 
895   bool operator==(const GrowableArrayIterator& rhs)  {
896     assert(_array == rhs._array, "iterator belongs to different array");
897     return _position == rhs._position;
898   }
899 
900   bool operator!=(const GrowableArrayIterator& rhs)  {
901     assert(_array == rhs._array, "iterator belongs to different array");
902     return _position != rhs._position;
903   }
904 };
905 
906 // Arrays for basic types
907 typedef GrowableArray<int> intArray;
908 typedef GrowableArray<int> intStack;
909 typedef GrowableArray<bool> boolArray;
910 
911 #endif // SHARE_UTILITIES_GROWABLEARRAY_HPP