Path: blob/master/test/hotspot/jtreg/vmTestbase/gc/hashcode/HCHelper.java
40948 views
/*1* Copyright (c) 2011, 2018, 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*/22package gc.hashcode;2324import java.util.ArrayList;25import java.util.Random;2627/**28* Helper class for the hash code tests.29*/30public final class HCHelper {3132/**33* Evacuation list 0 constant.34*/35public static final int EVAC_LIST_0 = 0;36/**37* Evacuation list 1 constant.38*/39public static final int EVAC_LIST_1 = 1;40/**41* Evacuation list 2 constant.42*/43public static final int EVAC_LIST_2 = 2;44/**45* Evacuation list 3 constant.46*/47public static final int EVAC_LIST_3 = 3;48/**49* Evacuation list 4 constant.50*/51public static final int EVAC_LIST_4 = 4;52/**53* Evacuation list 5 constant.54*/55public static final int EVAC_LIST_5 = 5;56/**57* Evacuation list 0 percentage constant.58*/59public static final double EVAC_SIZE_0 = 0.50;60/**61* Evacuation list 1 percentage constant.62*/63public static final double EVAC_SIZE_1 = 0.14;64/**65* Evacuation list 2 percentage constant.66*/67public static final double EVAC_SIZE_2 = 0.12;68/**69* Evacuation list 3 percentage constant.70*/71public static final double EVAC_SIZE_3 = 0.10;72/**73* Evacuation list 4 percentage constant.74*/75public static final double EVAC_SIZE_4 = 0.07;76/**77* Evacuation list 5 percentage constant.78*/79public static final double EVAC_SIZE_5 = 0.05;8081/**82* Helper class that allocates memory and also tracks the original83* as well as current hash code.84*/85final class AllocObject {86private byte[] allocatedArray;87private int hashValue;8889/**90* Create a new allocator object that allocates size bytes.91*92* @param size Number of bytes to allocate.93*/94AllocObject(int size) {95allocatedArray = new byte[size];96hashValue = allocatedArray.hashCode();97}9899/**100* Get the stored hash code value.101*102* @return Stored hash code.103*/104int getStoredHashValue() {105return hashValue;106}107108/**109* Get the current hash code value.110*111* @return Current hash code.112*/113int getCurrentHashValue() {114return allocatedArray.hashCode();115}116117/**118* Get the size of the allocated object.119*120* @return Size of allocated object.121*/122int getAllocatedSize() {123return allocatedArray.length;124}125}126127/**128* Helper class that holds all the allocation lists.129*/130final class AllocInfo {131private long allocatedSize;132private long numOfAllocedObjs;133private ArrayList safeList;134private ArrayList allocList;135private ArrayList evacList0;136private ArrayList evacList1;137private ArrayList evacList2;138private ArrayList evacList3;139private ArrayList evacList4;140private ArrayList evacList5;141142/**143* Create the helper object.144*/145AllocInfo() {146allocatedSize = 0;147numOfAllocedObjs = 0;148safeList = new ArrayList();149allocList = new ArrayList();150evacList0 = new ArrayList();151evacList1 = new ArrayList();152evacList2 = new ArrayList();153evacList3 = new ArrayList();154evacList4 = new ArrayList();155evacList5 = new ArrayList();156}157158/**159* Get the amount of memory allocated in total.160*161* @return Total allocated size.162*/163public long getAllocatedSize() {164return allocatedSize;165}166167/**168* Set the amount of memory allocated in total.169*170* @param allocatedSize Total allocated size.171*/172public void setAllocatedSize(long allocatedSize) {173this.allocatedSize = allocatedSize;174}175176/**177* Get total number of objects allocated.178*179* @return Number of objects allocated.180*/181public long getNumOfAllocedObjs() {182return numOfAllocedObjs;183}184185/**186* Set total number of objects allocated.187*188* @param numOfAllocedObjs Number of objects allocated.189*/190public void setNumOfAllocedObjs(long numOfAllocedObjs) {191this.numOfAllocedObjs = numOfAllocedObjs;192}193194/**195* Increase the number of objects allocated.196*/197public void incNumOfAllocedObjs() {198numOfAllocedObjs++;199}200201/**202* Decrease the number of objects allocated.203*/204public void decNumOfAllocedObjs() {205numOfAllocedObjs--;206}207208/**209* Get the safe list.210*211* @return ArrayList that contains the safe list.212*/213public ArrayList getSafeList() {214return safeList;215}216217/**218* Get the alloc list.219*220* @return ArrayList that contains the alloc list.221*/222public ArrayList getAllocList() {223return allocList;224}225226/**227* Get evacuation list 0.228*229* @return ArrayList that contains evacuation list 0.230*/231public ArrayList getEvacList0() {232return evacList0;233}234235/**236* Get evacuation list 1.237*238* @return ArrayList that contains evacuation list 1.239*/240public ArrayList getEvacList1() {241return evacList1;242}243244/**245* Get evacuation list 2.246*247* @return ArrayList that contains evacuation list 2.248*/249public ArrayList getEvacList2() {250return evacList2;251}252253/**254* Get evacuation list 3.255*256* @return ArrayList that contains evacuation list 3.257*/258public ArrayList getEvacList3() {259return evacList3;260}261262/**263* Get evacuation list 4.264*265* @return ArrayList that contains evacuation list 4.266*/267public ArrayList getEvacList4() {268return evacList4;269}270271/**272* Get evacuation list 5.273*274* @return ArrayList that contains evacuation list 5.275*/276public ArrayList getEvacList5() {277return evacList5;278}279}280281282private int minSize;283private int maxSize;284private double percentToFill;285private int allocTrigSize;286private AllocInfo ai;287private Random rnd;288289private long sizeLimit0;290private long sizeLimit1;291private long sizeLimit2;292private long sizeLimit3;293private long sizeLimit4;294private long sizeLimit5;295296/**297* Create the helper class.298*299* @param minSize Minimum size of objects to allocate.300* @param maxSize Maximum size of objects to allocate.301* @param seed Random seed to use.302* @param percentToFill Percentage of the heap to fill.303* @param allocTrigSize Object size to use when triggering a GC.304*/305public HCHelper(int minSize, int maxSize, long seed,306double percentToFill, int allocTrigSize) {307this.minSize = minSize;308this.maxSize = maxSize;309this.percentToFill = percentToFill;310this.allocTrigSize = allocTrigSize;311ai = new AllocInfo();312rnd = new Random(seed);313314sizeLimit0 = 0;315sizeLimit1 = 0;316sizeLimit2 = 0;317sizeLimit3 = 0;318sizeLimit4 = 0;319sizeLimit5 = 0;320}321322/**323* Setup all the evacuation lists and fill them with objects.324*/325public void setupLists() {326Runtime r = Runtime.getRuntime();327long maxMem = r.maxMemory();328long safeMaxMem = (long) (maxMem * percentToFill);329sizeLimit0 = (long) (safeMaxMem * EVAC_SIZE_0);330sizeLimit1 = (long) (safeMaxMem * EVAC_SIZE_1);331sizeLimit2 = (long) (safeMaxMem * EVAC_SIZE_2);332sizeLimit3 = (long) (safeMaxMem * EVAC_SIZE_3);333sizeLimit4 = (long) (safeMaxMem * EVAC_SIZE_4);334sizeLimit5 = (long) (safeMaxMem * EVAC_SIZE_5);335336// Fill the memory with objects337System.gc();338allocObjects(ai.getEvacList0(), sizeLimit0);339System.gc();340allocObjects(ai.getEvacList1(), sizeLimit1);341System.gc();342allocObjects(ai.getEvacList2(), sizeLimit2);343System.gc();344allocObjects(ai.getEvacList3(), sizeLimit3);345System.gc();346allocObjects(ai.getEvacList4(), sizeLimit4);347System.gc();348allocObjects(ai.getEvacList5(), sizeLimit5);349System.gc();350}351352private void allocObjects(ArrayList al, long totalSizeLimit) {353long allocedSize = 0;354int multiplier = maxSize - minSize;355356while (allocedSize < totalSizeLimit) {357int allocSize = minSize + (int) (rnd.nextDouble() * multiplier);358if (allocSize >= totalSizeLimit - allocedSize) {359allocSize = (int) (totalSizeLimit - allocedSize);360}361362al.add(new AllocObject(allocSize));363allocedSize += allocSize;364}365}366367/**368* Free all objects in a specific evacuation list.369*370* @param listNr The evacuation list to clear. Must be between 0 and 5.371*/372public void clearList(int listNr) {373if (listNr < EVAC_LIST_0 || listNr > EVAC_LIST_5) {374throw new IllegalArgumentException("List to removed bust be "375+ "between EVAC_LIST_0 and EVAC_LIST_5");376}377378switch (listNr) {379case EVAC_LIST_0:380ai.getEvacList0().clear();381break;382case EVAC_LIST_1:383ai.getEvacList1().clear();384break;385case EVAC_LIST_2:386ai.getEvacList2().clear();387break;388case EVAC_LIST_3:389ai.getEvacList3().clear();390break;391case EVAC_LIST_4:392ai.getEvacList4().clear();393break;394case EVAC_LIST_5:395ai.getEvacList5().clear();396break;397default: // Should never occur, since we test the listNr param398break;399}400}401402/**403* Verify the hash codes for a list of AllocObject:s.404*405* @param objList ArrayList containing AllocObject:s406* @return true if all hash codes are OK, otherwise false407*/408boolean verifyHashCodes(ArrayList objList) {409// Check the hash values410for (int i = 0; i < objList.size(); i++) {411AllocObject tmp = (AllocObject) objList.get(i);412if (tmp.getStoredHashValue() != tmp.getCurrentHashValue()) {413// At least one of the hash values mismatch, so the test failed414return false;415}416}417418return true;419}420421422/**423* Verify the hash codes for all objects in all the lists.424*425* @return Success if all hash codes matches the original hash codes.426*/427public boolean verifyHashCodes() {428return verifyHashCodes(ai.getAllocList())429&& verifyHashCodes(ai.getSafeList())430&& verifyHashCodes(ai.getEvacList0())431&& verifyHashCodes(ai.getEvacList1())432&& verifyHashCodes(ai.getEvacList2())433&& verifyHashCodes(ai.getEvacList3())434&& verifyHashCodes(ai.getEvacList4())435&& verifyHashCodes(ai.getEvacList5());436}437438/**439* Free all allocated objects from all the lists.440*/441public void cleanupLists() {442ai.getAllocList().clear();443ai.getSafeList().clear();444445ai.getEvacList0().clear();446ai.getEvacList1().clear();447ai.getEvacList2().clear();448ai.getEvacList3().clear();449ai.getEvacList4().clear();450ai.getEvacList5().clear();451}452453/**454* Get the size of evacuation list 0.455*456* @return Size of evacuation list 0.457*/458public long getEvac0Size() {459return sizeLimit0;460}461462/**463* Get the size of evacuation list 1.464*465* @return Size of evacuation list 1.466*/467public long getEvac1Size() {468return sizeLimit1;469}470471/**472* Get the size of evacuation list 2.473*474* @return Size of evacuation list 2.475*/476public long getEvac2Size() {477return sizeLimit2;478}479480/**481* Get the size of evacuation list 3.482*483* @return Size of evacuation list 3.484*/485public long getEvac3Size() {486return sizeLimit3;487}488489/**490* Get the size of evacuation list 4.491*492* @return Size of evacuation list 4.493*/494public long getEvac4Size() {495return sizeLimit4;496}497498/**499* Get the size of evacuation list 5.500*501* @return Size of evacuation list 5.502*/503public long getEvac5Size() {504return sizeLimit5;505}506}507508509