From d3d8a0d90410f7dd0ced55fe719af04c93d46431 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Fri, 10 Apr 2026 17:55:02 +0000 Subject: [PATCH] 8381636: Add built-in AOT support to GrowableArray Co-authored-by: Stefan Karlsson Reviewed-by: matsaave, kvn, coleenp --- src/hotspot/share/cds/aotGrowableArray.cpp | 34 --------- src/hotspot/share/cds/aotGrowableArray.hpp | 76 ------------------- .../share/cds/aotGrowableArray.inline.hpp | 37 --------- src/hotspot/share/cds/cppVtables.cpp | 6 +- src/hotspot/share/classfile/moduleEntry.cpp | 3 +- src/hotspot/share/classfile/moduleEntry.hpp | 7 +- src/hotspot/share/classfile/packageEntry.cpp | 3 +- src/hotspot/share/classfile/packageEntry.hpp | 3 +- src/hotspot/share/memory/metaspaceClosure.cpp | 4 +- src/hotspot/share/memory/metaspaceClosure.hpp | 55 +++++++++++--- src/hotspot/share/utilities/growableArray.cpp | 7 +- src/hotspot/share/utilities/growableArray.hpp | 13 ++-- .../gtest/utilities/test_metaspaceClosure.cpp | 13 ++-- 13 files changed, 72 insertions(+), 189 deletions(-) delete mode 100644 src/hotspot/share/cds/aotGrowableArray.cpp delete mode 100644 src/hotspot/share/cds/aotGrowableArray.hpp delete mode 100644 src/hotspot/share/cds/aotGrowableArray.inline.hpp diff --git a/src/hotspot/share/cds/aotGrowableArray.cpp b/src/hotspot/share/cds/aotGrowableArray.cpp deleted file mode 100644 index ec63e7aa57f..00000000000 --- a/src/hotspot/share/cds/aotGrowableArray.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "cds/aotGrowableArray.hpp" -#include "cds/aotMetaspace.hpp" -#include "memory/allocation.inline.hpp" -#include "utilities/growableArray.hpp" - -void AOTGrowableArrayHelper::deallocate(void* mem) { - if (!AOTMetaspace::in_aot_cache(mem)) { - GrowableArrayCHeapAllocator::deallocate(mem); - } -} diff --git a/src/hotspot/share/cds/aotGrowableArray.hpp b/src/hotspot/share/cds/aotGrowableArray.hpp deleted file mode 100644 index 0a0c137ed07..00000000000 --- a/src/hotspot/share/cds/aotGrowableArray.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_AOT_AOTGROWABLEARRAY_HPP -#define SHARE_AOT_AOTGROWABLEARRAY_HPP - -#include -#include - -class AOTGrowableArrayHelper { -public: - static void deallocate(void* mem); -}; - -// An AOTGrowableArray provides the same functionality as a GrowableArray that -// uses the C heap allocator. In addition, AOTGrowableArray can be iterated with -// MetaspaceClosure. This type should be used for growable arrays that need to be -// stored in the AOT cache. See ModuleEntry::_reads for an example. -template -class AOTGrowableArray : public GrowableArrayWithAllocator> { - friend class VMStructs; - friend class GrowableArrayWithAllocator; - - static E* allocate(int max, MemTag mem_tag) { - return (E*)GrowableArrayCHeapAllocator::allocate(max, sizeof(E), mem_tag); - } - - E* allocate() { - return allocate(this->_capacity, mtClass); - } - - void deallocate(E* mem) { -#if INCLUDE_CDS - AOTGrowableArrayHelper::deallocate(mem); -#else - GrowableArrayCHeapAllocator::deallocate(mem); -#endif - } - -public: - AOTGrowableArray(int initial_capacity, MemTag mem_tag) : - GrowableArrayWithAllocator( - allocate(initial_capacity, mem_tag), - initial_capacity) {} - - AOTGrowableArray() : AOTGrowableArray(0, mtClassShared) {} - - // methods required by MetaspaceClosure - void metaspace_pointers_do(MetaspaceClosure* it); - int size_in_heapwords() const { return (int)heap_word_size(sizeof(*this)); } - MetaspaceClosureType type() const { return MetaspaceClosureType::GrowableArrayType; } - static bool is_read_only_by_default() { return false; } -}; - -#endif // SHARE_AOT_AOTGROWABLEARRAY_HPP diff --git a/src/hotspot/share/cds/aotGrowableArray.inline.hpp b/src/hotspot/share/cds/aotGrowableArray.inline.hpp deleted file mode 100644 index 8c6e8cb6503..00000000000 --- a/src/hotspot/share/cds/aotGrowableArray.inline.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_CDS_AOTGROWABLEARRAY_INLINE_HPP -#define SHARE_CDS_AOTGROWABLEARRAY_INLINE_HPP - -#include "cds/aotGrowableArray.hpp" - -#include "memory/metaspaceClosure.hpp" - -template -void AOTGrowableArray::metaspace_pointers_do(MetaspaceClosure* it) { - it->push_c_array(AOTGrowableArray::data_addr(), AOTGrowableArray::capacity()); -} - -#endif // SHARE_CDS_AOTGROWABLEARRAY_INLINE_HPP diff --git a/src/hotspot/share/cds/cppVtables.cpp b/src/hotspot/share/cds/cppVtables.cpp index dc5a777d7b1..57da12dee48 100644 --- a/src/hotspot/share/cds/cppVtables.cpp +++ b/src/hotspot/share/cds/cppVtables.cpp @@ -22,7 +22,6 @@ * */ -#include "cds/aotGrowableArray.hpp" #include "cds/aotMetaspace.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveUtils.hpp" @@ -41,6 +40,7 @@ #include "oops/typeArrayKlass.hpp" #include "runtime/arguments.hpp" #include "utilities/globalDefinitions.hpp" +#include "utilities/growableArray.hpp" // Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables. // (In GCC this is the field ::_vptr, i.e., first word in the object.) @@ -58,10 +58,10 @@ #ifndef PRODUCT -// AOTGrowableArray has a vtable only when in non-product builds (due to +// GrowableArray has a vtable only when in non-product builds (due to // the virtual printing functions in AnyObj). -using GrowableArray_ModuleEntry_ptr = AOTGrowableArray; +using GrowableArray_ModuleEntry_ptr = GrowableArray; #define DEBUG_CPP_VTABLE_TYPES_DO(f) \ f(GrowableArray_ModuleEntry_ptr) \ diff --git a/src/hotspot/share/classfile/moduleEntry.cpp b/src/hotspot/share/classfile/moduleEntry.cpp index b5b8aa4ef55..c7fadeaea9b 100644 --- a/src/hotspot/share/classfile/moduleEntry.cpp +++ b/src/hotspot/share/classfile/moduleEntry.cpp @@ -23,7 +23,6 @@ */ #include "cds/aotClassLocation.hpp" -#include "cds/aotGrowableArray.inline.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveUtils.hpp" #include "cds/cdsConfig.hpp" @@ -168,7 +167,7 @@ void ModuleEntry::add_read(ModuleEntry* m) { } else { if (reads() == nullptr) { // Lazily create a module's reads list - AOTGrowableArray* new_reads = new (mtModule) AOTGrowableArray(MODULE_READS_SIZE, mtModule); + GrowableArray* new_reads = new (mtModule) GrowableArray(MODULE_READS_SIZE, mtModule); set_reads(new_reads); } diff --git a/src/hotspot/share/classfile/moduleEntry.hpp b/src/hotspot/share/classfile/moduleEntry.hpp index 1a0251a2c2a..10dec73e9fa 100644 --- a/src/hotspot/share/classfile/moduleEntry.hpp +++ b/src/hotspot/share/classfile/moduleEntry.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_CLASSFILE_MODULEENTRY_HPP #define SHARE_CLASSFILE_MODULEENTRY_HPP -#include "cds/aotGrowableArray.hpp" #include "jni.h" #include "memory/metaspaceClosureType.hpp" #include "oops/oopHandle.hpp" @@ -70,7 +69,7 @@ private: // for shared classes from this module Symbol* _name; // name of this module ClassLoaderData* _loader_data; - AOTGrowableArray* _reads; // list of modules that are readable by this module + GrowableArray* _reads; // list of modules that are readable by this module Symbol* _version; // module version number Symbol* _location; // module location @@ -118,10 +117,10 @@ public: bool can_read(ModuleEntry* m) const; bool has_reads_list() const; - AOTGrowableArray* reads() const { + GrowableArray* reads() const { return _reads; } - void set_reads(AOTGrowableArray* r) { + void set_reads(GrowableArray* r) { _reads = r; } void pack_reads() { diff --git a/src/hotspot/share/classfile/packageEntry.cpp b/src/hotspot/share/classfile/packageEntry.cpp index 3e61f2e3a3e..3eb50fcb5a7 100644 --- a/src/hotspot/share/classfile/packageEntry.cpp +++ b/src/hotspot/share/classfile/packageEntry.cpp @@ -22,7 +22,6 @@ * */ -#include "cds/aotGrowableArray.inline.hpp" #include "cds/aotMetaspace.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveUtils.hpp" @@ -83,7 +82,7 @@ void PackageEntry::add_qexport(ModuleEntry* m) { if (!has_qual_exports_list()) { // Lazily create a package's qualified exports list. // Initial size is small, do not anticipate export lists to be large. - _qualified_exports = new (mtModule) AOTGrowableArray(QUAL_EXP_SIZE, mtModule); + _qualified_exports = new (mtModule) GrowableArray(QUAL_EXP_SIZE, mtModule); } // Determine, based on this newly established export to module m, diff --git a/src/hotspot/share/classfile/packageEntry.hpp b/src/hotspot/share/classfile/packageEntry.hpp index 7b174a92287..e064e53b263 100644 --- a/src/hotspot/share/classfile/packageEntry.hpp +++ b/src/hotspot/share/classfile/packageEntry.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_CLASSFILE_PACKAGEENTRY_HPP #define SHARE_CLASSFILE_PACKAGEENTRY_HPP -#include "cds/aotGrowableArray.hpp" #include "classfile/moduleEntry.hpp" #include "memory/metaspaceClosureType.hpp" #include "oops/symbol.hpp" @@ -116,7 +115,7 @@ private: bool _must_walk_exports; // Contains list of modules this package is qualifiedly exported to. Access // to this list is protected by the Module_lock. - AOTGrowableArray* _qualified_exports; + GrowableArray* _qualified_exports; JFR_ONLY(DEFINE_TRACE_ID_FIELD;) // Initial size of a package entry's list of qualified exports. diff --git a/src/hotspot/share/memory/metaspaceClosure.cpp b/src/hotspot/share/memory/metaspaceClosure.cpp index 0239eadf692..0926b55b9a3 100644 --- a/src/hotspot/share/memory/metaspaceClosure.cpp +++ b/src/hotspot/share/memory/metaspaceClosure.cpp @@ -22,11 +22,11 @@ * */ -#include "cds/aotGrowableArray.hpp" #include "classfile/packageEntry.hpp" #include "memory/metaspaceClosure.hpp" #include "oops/array.hpp" #include "oops/instanceKlass.hpp" +#include "utilities/growableArray.hpp" // Sanity checks static_assert(!HAS_METASPACE_POINTERS_DO(int)); @@ -35,8 +35,6 @@ static_assert(HAS_METASPACE_POINTERS_DO(Array)); static_assert(HAS_METASPACE_POINTERS_DO(Array)); static_assert(HAS_METASPACE_POINTERS_DO(InstanceKlass)); static_assert(HAS_METASPACE_POINTERS_DO(PackageEntry)); -static_assert(HAS_METASPACE_POINTERS_DO(AOTGrowableArray)); -static_assert(HAS_METASPACE_POINTERS_DO(AOTGrowableArray)); void MetaspaceClosure::push_impl(MetaspaceClosure::Ref* ref) { if (_enclosing_ref != nullptr) { diff --git a/src/hotspot/share/memory/metaspaceClosure.hpp b/src/hotspot/share/memory/metaspaceClosure.hpp index b6ba69d6f63..ac42dd13c6c 100644 --- a/src/hotspot/share/memory/metaspaceClosure.hpp +++ b/src/hotspot/share/memory/metaspaceClosure.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_MEMORY_METASPACECLOSURE_HPP #define SHARE_MEMORY_METASPACECLOSURE_HPP -#include "cds/aotGrowableArray.hpp" #include "cppstdlib/type_traits.hpp" #include "logging/log.hpp" #include "memory/allocation.hpp" @@ -90,7 +89,9 @@ public: // int size_in_heapwords() const; // // Currently, the iterable types include all subtypes of MetsapceObj, as well - // as GrowableArray, ModuleEntry and PackageEntry. + // as GrowableArray (C-heap allocated only), ModuleEntry, and PackageEntry. + // + // (Note that GrowableArray is supported specially and does not require the above functions.) // // Calling these functions would be trivial if these were virtual functions. // However, to save space, MetaspaceObj has NO vtable. The vtable is introduced @@ -303,11 +304,38 @@ private: }; //-------------------------------- - // Support for AOTGrowableArray + // Support for GrowableArray //-------------------------------- + // GrowableArrayRef -- iterate an instance of GrowableArray. + template class GrowableArrayRef : public Ref { + GrowableArray** _mpp; + GrowableArray* dereference() const { + return *_mpp; + } + + public: + GrowableArrayRef(GrowableArray** mpp, Writability w) : Ref(w), _mpp(mpp) {} + + virtual void** mpp() const { + return (void**)_mpp; + } + + virtual void metaspace_pointers_do(MetaspaceClosure *it) const { + GrowableArray* array = dereference(); + log_trace(aot)("Iter(GrowableArray): %p [%d]", array, array->length()); + array->assert_on_C_heap(); + it->push_c_array(array->data_addr(), array->capacity()); + } + + virtual bool is_read_only_by_default() const { return false; } + virtual bool not_null() const { return dereference() != nullptr; } + virtual int size() const { return (int)heap_word_size(sizeof(*dereference())); } + virtual MetaspaceClosureType type() const { return MetaspaceClosureType::GrowableArrayType; } + }; + // Abstract base class for MSOCArrayRef, MSOPointerCArrayRef and OtherCArrayRef. - // These are used for iterating the buffer held by AOTGrowableArray. + // These are used for iterating the buffer held by GrowableArray. template class CArrayRef : public Ref { T** _mpp; int _num_elems; // Number of elements @@ -354,7 +382,7 @@ private: // MSOCArrayRef -- iterate a C array of type T, where T has metaspace_pointer_do(). // We recursively call T::metaspace_pointers_do() for each element in this array. - // This is for supporting AOTGrowableArray. + // This is for supporting GrowableArray. // // E.g., PackageEntry* _pkg_entry_pointers[2]; // a buffer that has 2 PackageEntry objects // ... @@ -377,7 +405,7 @@ private: // MSOPointerCArrayRef -- iterate a C array of type T*, where T has metaspace_pointer_do(). // We recursively call MetaspaceClosure::push() for each pointer in this array. - // This is for supporting AOTGrowableArray. + // This is for supporting GrowableArray. // // E.g., PackageEntry** _pkg_entry_pointers[2]; // a buffer that has 2 PackageEntry pointers // ... @@ -440,11 +468,11 @@ public: // Array*>* a4 = ...; it->push(&a4); => MSOPointerArrayRef // Array* a5 = ...; it->push(&a5); => MSOPointerArrayRef // - // AOTGrowableArrays have a separate "C array" buffer, so they are scanned in two steps: + // GrowableArrays have a separate "C array" buffer, so they are scanned in two steps: // - // AOTGrowableArray* ga1 = ...; it->push(&ga1); => MSORef => OtherCArrayRef - // AOTGrowableArray* ga2 = ...; it->push(&ga2); => MSORef => MSOCArrayRef - // AOTGrowableArray* ga3 = ...; it->push(&ga3); => MSORef => MSOPointerCArrayRef + // GrowableArray* ga1 = ...; it->push(&ga1); => GrowableArrayRef => OtherCArrayRef + // GrowableArray* ga2 = ...; it->push(&ga2); => GrowableArrayRef => MSOCArrayRef + // GrowableArray* ga3 = ...; it->push(&ga3); => GrowableArrayRef => MSOPointerCArrayRef // // Note that the following will fail to compile: // @@ -476,7 +504,12 @@ public: push_with_ref>(mpp, w); } - // --- The buffer of AOTGrowableArray + template + void push(GrowableArray** mpp, Writability w = _default) { + push_with_ref>(mpp, w); + } + + // --- The buffer of GrowableArray template void push_c_array(T** mpp, int num_elems, Writability w = _default) { push_impl(new OtherCArrayRef(mpp, num_elems, w)); diff --git a/src/hotspot/share/utilities/growableArray.cpp b/src/hotspot/share/utilities/growableArray.cpp index 6a1cb0b0414..9cc0813a1f6 100644 --- a/src/hotspot/share/utilities/growableArray.cpp +++ b/src/hotspot/share/utilities/growableArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ * */ +#include "cds/aotMetaspace.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "runtime/javaThread.hpp" @@ -56,7 +57,9 @@ void* GrowableArrayCHeapAllocator::allocate(int max, int element_size, MemTag me } void GrowableArrayCHeapAllocator::deallocate(void* elements) { - FreeHeap(elements); + if (!AOTMetaspace::in_aot_cache(elements)) { + FreeHeap(elements); + } } #ifdef ASSERT diff --git a/src/hotspot/share/utilities/growableArray.hpp b/src/hotspot/share/utilities/growableArray.hpp index e300bea6993..14b54cfc4ea 100644 --- a/src/hotspot/share/utilities/growableArray.hpp +++ b/src/hotspot/share/utilities/growableArray.hpp @@ -116,12 +116,6 @@ protected: ~GrowableArrayView() {} -protected: - // Used by AOTGrowableArray for MetaspaceClosure support. - E** data_addr() { - return &_data; - } - public: bool operator==(const GrowableArrayView& rhs) const { if (_len != rhs._len) @@ -303,6 +297,11 @@ public: } tty->print("}\n"); } + + // MetaspaceClosure support + E** data_addr() { + return &_data; + } }; template @@ -821,6 +820,8 @@ public: this->clear_and_deallocate(); } } + + void assert_on_C_heap() { assert(on_C_heap(), "must be on C heap"); } }; // Leaner GrowableArray for CHeap backed data arrays, with compile-time decided MemTag. diff --git a/test/hotspot/gtest/utilities/test_metaspaceClosure.cpp b/test/hotspot/gtest/utilities/test_metaspaceClosure.cpp index c98b38b8c3c..091767cc273 100644 --- a/test/hotspot/gtest/utilities/test_metaspaceClosure.cpp +++ b/test/hotspot/gtest/utilities/test_metaspaceClosure.cpp @@ -21,7 +21,6 @@ * questions. */ -#include "cds/aotGrowableArray.inline.hpp" #include "memory/allocation.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" @@ -168,9 +167,9 @@ TEST_VM(MetaspaceClosure, OtherArrayRef) { EXPECT_TRUE(closure.has_visited(array)) << "must be"; } -// iterate an AOTGrowableArray +// iterate an GrowableArray TEST_VM(MetaspaceClosure, GrowableArray_MSOPointer) { - AOTGrowableArray* array = new(mtClass) AOTGrowableArray(2, mtClass); + GrowableArray* array = new(mtClass) GrowableArray(2, mtClass); MyMetaData x; MyMetaData y; @@ -190,9 +189,9 @@ TEST_VM(MetaspaceClosure, GrowableArray_MSOPointer) { EXPECT_TRUE(closure.has_visited(&z)) << "must be"; } -// iterate an AOTGrowableArray +// iterate an GrowableArray TEST_VM(MetaspaceClosure, GrowableArray_MSO) { - AOTGrowableArray* array = new(mtClass) AOTGrowableArray(4, mtClass); + GrowableArray* array = new(mtClass) GrowableArray(4, mtClass); for (int i = 0; i < array->length(); i++) { EXPECT_TRUE(array->at(i)._a == nullptr) << "should be initialized to null"; @@ -218,9 +217,9 @@ TEST_VM(MetaspaceClosure, GrowableArray_MSO) { EXPECT_TRUE(closure.has_visited(&z)) << "must be"; } -// iterate an AOTGrowableArray +// iterate an GrowableArray TEST_VM(MetaspaceClosure, GrowableArray_jlong) { - AOTGrowableArray* array = new(mtClass) AOTGrowableArray(4, mtClass); + GrowableArray* array = new(mtClass) GrowableArray(4, mtClass); MyUniqueMetaspaceClosure closure; closure.push(&array);