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