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