Path: blob/master/test/hotspot/jtreg/vmTestbase/gc/gctests/RememberedSet/RememberedSet.java
41159 views
/*1* Copyright (c) 2010, 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*/22/*23* This test stress RememberetSet procerssing in the G1 by creation of references24* between different 1MB blocks.25* Test is specific for G1, for other GCs it should just pass.26*/272829/*30* @test31* @modules java.base/jdk.internal.misc:+open java.base/jdk.internal.vm.annotation:+open java.base/sun.reflect.annotation:+open32* @key stress33*34* @summary converted from VM Testbase gc/gctests/RememberedSet.35* VM Testbase keywords: [gc, stress, stressopt, feature_g1, nonconcurrent]36*37* @library /vmTestbase38* /test/lib39* @run main/othervm -XX:-UseGCOverheadLimit gc.gctests.RememberedSet.RememberedSet40*/4142package gc.gctests.RememberedSet;4344import java.lang.reflect.Field;45import java.util.ArrayList;46import java.util.List;47import nsk.share.gc.GC;48import nsk.share.gc.MemoryObject;49import nsk.share.gc.ThreadedGCTest;50import nsk.share.test.ExecutionController;51import jdk.internal.misc.Unsafe;5253public class RememberedSet extends ThreadedGCTest {5455static class PointerUtils {56private static Unsafe unsafe;57private static long fieldOffset;58private static PointerUtils instance = new PointerUtils();59private static boolean compressedRef = false;6061static {62try {63unsafe = Unsafe.getUnsafe();64fieldOffset = unsafe.objectFieldOffset(PointerUtils.class.getDeclaredField("obj"));65long fieldOffset0 = unsafe.objectFieldOffset(PointerUtils.class.getDeclaredField("obj0"));66int oopSize = (int)Math.abs(fieldOffset - fieldOffset0);6768if (oopSize != unsafe.addressSize()) {69System.out.println("Compressed oops detected");70compressedRef = true;71}72} catch (Exception ex) {73throw new RuntimeException(ex);74}75}7677private Object obj;78private Object obj0;7980public synchronized static long toAddress(Object o) {81long address;82instance.obj = o;8384if (compressedRef || unsafe.addressSize() == 4) {85address = unsafe.getInt(instance, fieldOffset);86}87else {88address = unsafe.getLong(instance, fieldOffset);89}9091return address;92}9394}95private ExecutionController stresser;9697@Override98protected Runnable createRunnable(int i) {99return new Worker();100}101102class Worker implements Runnable {103104static final long BLOCK_SIZE = 1024 * 1024;105106107// this method tries to allocate a new MemoryObject108// which is in another 1MB block109MemoryObject getOutOfTheBlockObject(int size, Object obj) {110long address = PointerUtils.toAddress(obj);111MemoryObject ref = new MemoryObject(size);112int attempt = (int) (BLOCK_SIZE / size);113while (attempt != 0 && Math.abs(address - PointerUtils.toAddress(ref)) < BLOCK_SIZE) {114ref = new MemoryObject(size);115attempt--;116}117return ref;118}119120@Override121public void run() {122123int size = (int) Math.sqrt(BLOCK_SIZE);124int refsCount = (int) (runParams.getTestMemory() / BLOCK_SIZE);125int count = (int) (runParams.getTestMemory() / runParams.getNumberOfThreads() / (refsCount * size));126// Each cycle 10% of references and 10% of arrays are reallocated127int step = 10;128129List<List<MemoryObject>> objs = new ArrayList<List<MemoryObject>>(count);130for (int i = 0; i < count; i++) {131List<MemoryObject> obj = new ArrayList<MemoryObject>();132objs.add(obj);133for (int j = 0; j < refsCount; j++) {134obj.add(getOutOfTheBlockObject(size, obj));135}136}137if (stresser == null) {138stresser = getExecutionController();139}140int shift = 0;141while (stresser.continueExecution()) {142for (int j = shift; j < refsCount; j += step) {143for (int i = 0; i < count; i ++) {144// update each 10th reference to allow GC previous one145List<MemoryObject> obj = objs.get(i);146obj.set(j, getOutOfTheBlockObject(size, obj));147}148}149for (int i = step - shift; i < count; i += step) {150// update each 10th array of references151// to allocate it in the another 1MB block (as new young object)152List<MemoryObject> obj = new ArrayList<MemoryObject>();153objs.set(i, obj);154for (int j = 0; j < refsCount; j++) {155obj.add(getOutOfTheBlockObject(size, obj));156}157}158// shift is changed from 0 to step - 1159log.debug("shift = " + shift);160shift = (shift + 1) % step;161}162}163}164165public static void main(String[] args) {166GC.runTest(new RememberedSet(), args);167}168}169170171