Path: blob/master/test/hotspot/gtest/utilities/test_growableArray.cpp
41145 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include "precompiled.hpp"24#include "memory/resourceArea.hpp"25#include "utilities/growableArray.hpp"26#include "unittest.hpp"2728struct WithEmbeddedArray {29// Array embedded in another class30GrowableArray<int> _a;3132// Resource allocated data array33WithEmbeddedArray(int initial_max) : _a(initial_max) {}34// Arena allocated data array35WithEmbeddedArray(Arena* arena, int initial_max) : _a(arena, initial_max, 0, 0) {}36// CHeap allocated data array37WithEmbeddedArray(int initial_max, MEMFLAGS memflags) : _a(initial_max, memflags) {38assert(memflags != mtNone, "test requirement");39}40WithEmbeddedArray(const GrowableArray<int>& other) : _a(other) {}41};4243// Test fixture to work with TEST_VM_F44class GrowableArrayTest : public ::testing::Test {45protected:46// friend -> private accessors47template <typename E>48static bool elements_on_C_heap(const GrowableArray<E>* array) {49return array->on_C_heap();50}51template <typename E>52static bool elements_on_stack(const GrowableArray<E>* array) {53return array->on_stack();54}55template <typename E>56static bool elements_on_arena(const GrowableArray<E>* array) {57return array->on_arena();58}5960template <typename ArrayClass>61static void test_append(ArrayClass* a) {62// Add elements63for (int i = 0; i < 10; i++) {64a->append(i);65}6667// Check size68ASSERT_EQ(a->length(), 10);6970// Check elements71for (int i = 0; i < 10; i++) {72EXPECT_EQ(a->at(i), i);73}74}7576template <typename ArrayClass>77static void test_clear(ArrayClass* a) {78// Add elements79for (int i = 0; i < 10; i++) {80a->append(i);81}8283// Check size84ASSERT_EQ(a->length(), 10);85ASSERT_EQ(a->is_empty(), false);8687// Clear elements88a->clear();8990// Check size91ASSERT_EQ(a->length(), 0);92ASSERT_EQ(a->is_empty(), true);9394// Add element95a->append(11);9697// Check size98ASSERT_EQ(a->length(), 1);99ASSERT_EQ(a->is_empty(), false);100101// Clear elements102a->clear();103104// Check size105ASSERT_EQ(a->length(), 0);106ASSERT_EQ(a->is_empty(), true);107}108109template <typename ArrayClass>110static void test_iterator(ArrayClass* a) {111// Add elements112for (int i = 0; i < 10; i++) {113a->append(i);114}115116// Iterate117int counter = 0;118for (GrowableArrayIterator<int> i = a->begin(); i != a->end(); ++i) {119ASSERT_EQ(*i, counter++);120}121122// Check count123ASSERT_EQ(counter, 10);124}125126template <typename ArrayClass>127static void test_copy1(ArrayClass* a) {128ASSERT_EQ(a->length(), 1);129ASSERT_EQ(a->at(0), 1);130131// Only allowed to copy to stack and embedded ResourceObjs132133// Copy to stack134{135GrowableArray<int> c(*a);136137ASSERT_EQ(c.length(), 1);138ASSERT_EQ(c.at(0), 1);139}140141// Copy to embedded142{143WithEmbeddedArray c(*a);144145ASSERT_EQ(c._a.length(), 1);146ASSERT_EQ(c._a.at(0), 1);147}148}149150template <typename ArrayClass>151static void test_assignment1(ArrayClass* a) {152ASSERT_EQ(a->length(), 1);153ASSERT_EQ(a->at(0), 1);154155// Only allowed to assign to stack and embedded ResourceObjs156157// Copy to embedded/resource158{159ResourceMark rm;160GrowableArray<int> c(1);161c = *a;162163ASSERT_EQ(c.length(), 1);164ASSERT_EQ(c.at(0), 1);165}166167// Copy to embedded/arena168{169Arena arena(mtTest);170GrowableArray<int> c(&arena, 1, 0, 0);171c = *a;172173ASSERT_EQ(c.length(), 1);174ASSERT_EQ(c.at(0), 1);175}176177// Copy to embedded/resource178{179ResourceMark rm;180WithEmbeddedArray c(1);181c._a = *a;182183ASSERT_EQ(c._a.length(), 1);184ASSERT_EQ(c._a.at(0), 1);185}186187// Copy to embedded/arena188{189Arena arena(mtTest);190WithEmbeddedArray c(&arena, 1);191c._a = *a;192193ASSERT_EQ(c._a.length(), 1);194ASSERT_EQ(c._a.at(0), 1);195}196}197198// Supported by all GrowableArrays199enum TestEnum {200Append,201Clear,202Iterator,203};204205template <typename ArrayClass>206static void do_test(ArrayClass* a, TestEnum test) {207switch (test) {208case Append:209test_append(a);210break;211212case Clear:213test_clear(a);214break;215216case Iterator:217test_iterator(a);218break;219220default:221fatal("Missing dispatch");222break;223}224}225226// Only supported by GrowableArrays without CHeap data arrays227enum TestNoCHeapEnum {228Copy1,229Assignment1,230};231232template <typename ArrayClass>233static void do_test(ArrayClass* a, TestNoCHeapEnum test) {234switch (test) {235case Copy1:236test_copy1(a);237break;238239case Assignment1:240test_assignment1(a);241break;242243default:244fatal("Missing dispatch");245break;246}247}248249enum ModifyEnum {250Append1,251Append1Clear,252Append1ClearAndDeallocate,253NoModify254};255256template <typename ArrayClass>257static void do_modify(ArrayClass* a, ModifyEnum modify) {258switch (modify) {259case Append1:260a->append(1);261break;262263case Append1Clear:264a->append(1);265a->clear();266break;267268case Append1ClearAndDeallocate:269a->append(1);270a->clear_and_deallocate();271break;272273case NoModify:274// Nothing to do275break;276277default:278fatal("Missing dispatch");279break;280}281}282283static const int Max0 = 0;284static const int Max1 = 1;285286template <typename ArrayClass, typename T>287static void modify_and_test(ArrayClass* array, ModifyEnum modify, T test) {288do_modify(array, modify);289do_test(array, test);290}291292template <typename T>293static void with_no_cheap_array(int max, ModifyEnum modify, T test) {294// Resource/Resource allocated295{296ResourceMark rm;297GrowableArray<int>* a = new GrowableArray<int>(max);298modify_and_test(a, modify, test);299}300301// Resource/Arena allocated302// Combination not supported303304// CHeap/Resource allocated305// Combination not supported306307// CHeap/Arena allocated308// Combination not supported309310// Stack/Resource allocated311{312ResourceMark rm;313GrowableArray<int> a(max);314modify_and_test(&a, modify, test);315}316317// Stack/Arena allocated318{319Arena arena(mtTest);320GrowableArray<int> a(&arena, max, 0, 0);321modify_and_test(&a, modify, test);322}323324// Embedded/Resource allocated325{326ResourceMark rm;327WithEmbeddedArray w(max);328modify_and_test(&w._a, modify, test);329}330331// Embedded/Arena allocated332{333Arena arena(mtTest);334WithEmbeddedArray w(&arena, max);335modify_and_test(&w._a, modify, test);336}337}338339static void with_cheap_array(int max, ModifyEnum modify, TestEnum test) {340// Resource/CHeap allocated341// Combination not supported342343// CHeap/CHeap allocated344{345GrowableArray<int>* a = new (ResourceObj::C_HEAP, mtTest) GrowableArray<int>(max, mtTest);346modify_and_test(a, modify, test);347delete a;348}349350// Stack/CHeap allocated351{352GrowableArray<int> a(max, mtTest);353modify_and_test(&a, modify, test);354}355356// Embedded/CHeap allocated357{358WithEmbeddedArray w(max, mtTest);359modify_and_test(&w._a, modify, test);360}361}362363static void with_all_types(int max, ModifyEnum modify, TestEnum test) {364with_no_cheap_array(max, modify, test);365with_cheap_array(max, modify, test);366}367368static void with_all_types_empty(TestEnum test) {369with_all_types(Max0, NoModify, test);370}371372static void with_all_types_max_set(TestEnum test) {373with_all_types(Max1, NoModify, test);374}375376static void with_all_types_cleared(TestEnum test) {377with_all_types(Max1, Append1Clear, test);378}379380static void with_all_types_clear_and_deallocated(TestEnum test) {381with_all_types(Max1, Append1ClearAndDeallocate, test);382}383384static void with_all_types_all_0(TestEnum test) {385with_all_types_empty(test);386with_all_types_max_set(test);387with_all_types_cleared(test);388with_all_types_clear_and_deallocated(test);389}390391static void with_no_cheap_array_append1(TestNoCHeapEnum test) {392with_no_cheap_array(Max0, Append1, test);393}394};395396TEST_VM_F(GrowableArrayTest, append) {397with_all_types_all_0(Append);398}399400TEST_VM_F(GrowableArrayTest, clear) {401with_all_types_all_0(Clear);402}403404TEST_VM_F(GrowableArrayTest, iterator) {405with_all_types_all_0(Iterator);406}407408TEST_VM_F(GrowableArrayTest, copy) {409with_no_cheap_array_append1(Copy1);410}411412TEST_VM_F(GrowableArrayTest, assignment) {413with_no_cheap_array_append1(Assignment1);414}415416#ifdef ASSERT417TEST_VM_F(GrowableArrayTest, where) {418WithEmbeddedArray s(1, mtTest);419ASSERT_FALSE(s._a.allocated_on_C_heap());420ASSERT_TRUE(elements_on_C_heap(&s._a));421422// Resource/Resource allocated423{424ResourceMark rm;425GrowableArray<int>* a = new GrowableArray<int>();426ASSERT_TRUE(a->allocated_on_res_area());427ASSERT_TRUE(elements_on_stack(a));428}429430// Resource/CHeap allocated431// Combination not supported432433// Resource/Arena allocated434// Combination not supported435436// CHeap/Resource allocated437// Combination not supported438439// CHeap/CHeap allocated440{441GrowableArray<int>* a = new (ResourceObj::C_HEAP, mtTest) GrowableArray<int>(0, mtTest);442ASSERT_TRUE(a->allocated_on_C_heap());443ASSERT_TRUE(elements_on_C_heap(a));444delete a;445}446447// CHeap/Arena allocated448// Combination not supported449450// Stack/Resource allocated451{452ResourceMark rm;453GrowableArray<int> a(0);454ASSERT_TRUE(a.allocated_on_stack());455ASSERT_TRUE(elements_on_stack(&a));456}457458// Stack/CHeap allocated459{460GrowableArray<int> a(0, mtTest);461ASSERT_TRUE(a.allocated_on_stack());462ASSERT_TRUE(elements_on_C_heap(&a));463}464465// Stack/Arena allocated466{467Arena arena(mtTest);468GrowableArray<int> a(&arena, 0, 0, 0);469ASSERT_TRUE(a.allocated_on_stack());470ASSERT_TRUE(elements_on_arena(&a));471}472473// Embedded/Resource allocated474{475ResourceMark rm;476WithEmbeddedArray w(0);477ASSERT_TRUE(w._a.allocated_on_stack());478ASSERT_TRUE(elements_on_stack(&w._a));479}480481// Embedded/CHeap allocated482{483WithEmbeddedArray w(0, mtTest);484ASSERT_TRUE(w._a.allocated_on_stack());485ASSERT_TRUE(elements_on_C_heap(&w._a));486}487488// Embedded/Arena allocated489{490Arena arena(mtTest);491WithEmbeddedArray w(&arena, 0);492ASSERT_TRUE(w._a.allocated_on_stack());493ASSERT_TRUE(elements_on_arena(&w._a));494}495}496497TEST_VM_ASSERT_MSG(GrowableArrayAssertingTest, copy_with_embedded_cheap,498"assert.!on_C_heap... failed: Copying of CHeap arrays not supported") {499WithEmbeddedArray s(1, mtTest);500// Intentionally asserts that copy of CHeap arrays are not allowed501WithEmbeddedArray c(s);502}503504TEST_VM_ASSERT_MSG(GrowableArrayAssertingTest, assignment_with_embedded_cheap,505"assert.!on_C_heap... failed: Assignment of CHeap arrays not supported") {506WithEmbeddedArray s(1, mtTest);507WithEmbeddedArray c(1, mtTest);508509// Intentionally asserts that assignment of CHeap arrays are not allowed510c = s;511}512513#endif514515TEST(GrowableArrayCHeap, sanity) {516// Stack/CHeap517{518GrowableArrayCHeap<int, mtTest> a(0);519#ifdef ASSERT520ASSERT_TRUE(a.allocated_on_stack());521#endif522ASSERT_TRUE(a.is_empty());523524a.append(1);525ASSERT_FALSE(a.is_empty());526ASSERT_EQ(a.at(0), 1);527}528529// CHeap/CHeap530{531GrowableArrayCHeap<int, mtTest>* a = new GrowableArrayCHeap<int, mtTest>(0);532#ifdef ASSERT533ASSERT_TRUE(a->allocated_on_C_heap());534#endif535ASSERT_TRUE(a->is_empty());536537a->append(1);538ASSERT_FALSE(a->is_empty());539ASSERT_EQ(a->at(0), 1);540delete a;541}542543// CHeap/CHeap - nothrow new operator544{545GrowableArrayCHeap<int, mtTest>* a = new (std::nothrow) GrowableArrayCHeap<int, mtTest>(0);546#ifdef ASSERT547ASSERT_TRUE(a->allocated_on_C_heap());548#endif549ASSERT_TRUE(a->is_empty());550551a->append(1);552ASSERT_FALSE(a->is_empty());553ASSERT_EQ(a->at(0), 1);554delete a;555}556}557558559