1 /*
  2  * Copyright (c) 2021, Amazon, Inc. 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 package gc.shenandoah.generational;
 26 
 27 import sun.hotspot.WhiteBox;
 28 import java.util.Random;
 29 
 30 /*
 31  * @test TestSimpleGenerational
 32  * @requires vm.gc.Shenandoah
 33  * @summary Confirm that card marking and remembered set scanning do not crash.
 34  * @library /testlibrary /test/lib /
 35  * @build sun.hotspot.WhiteBox
 36  * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox
 37  * @run main/othervm -Xbootclasspath/a:.
 38  *      -XX:+IgnoreUnrecognizedVMOptions
 39  *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 40  *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational
 41  *      gc.shenandoah.generational.TestSimpleGenerational
 42  */
 43 public class TestSimpleGenerational {
 44   private static WhiteBox wb = WhiteBox.getWhiteBox();
 45   static private final int SeedForRandom = 46;
 46   // Sequence of random numbers should end with same value
 47   private static int ExpectedLastRandom = 272454100;
 48 
 49 
 50   public static class Node {
 51     static private final int NeighborCount = 5;
 52     static private final int IntArraySize = 8;
 53     static private Random random = new Random(SeedForRandom);
 54 
 55     private int val;
 56     private Object field_o;
 57 
 58     // Each Node instance holds references to two "private" arrays.
 59     // One array holds raw seething bits (primitive integers) and the
 60     // holds references.
 61 
 62     private int[] field_ints;
 63     private Node [] neighbors;
 64 
 65     public Node(int val) {
 66       this.val = val;
 67       this.field_o = new Object();
 68       this.field_ints = new int[IntArraySize];
 69       this.field_ints[0] = 0xca;
 70       this.field_ints[1] = 0xfe;
 71       this.field_ints[2] = 0xba;
 72       this.field_ints[3] = 0xbe;
 73       this.field_ints[4] = 0xba;
 74       this.field_ints[5] = 0xad;
 75       this.field_ints[6] = 0xba;
 76       this.field_ints[7] = 0xbe;
 77 
 78       this.neighbors = new Node[NeighborCount];
 79     }
 80 
 81     public int value() {
 82       return val;
 83     }
 84 
 85     // Copy each neighbor of n into a new node's neighbor array.
 86     // Then overwrite arbitrarily selected neighbor with newly allocated
 87     // leaf node.
 88     public static Node upheaval(Node n) {
 89       int first_val = random.nextInt();
 90       if (first_val < 0) first_val = -first_val;
 91       if (first_val < 0) first_val = 0;
 92       Node result = new Node(first_val);
 93       if (n != null) {
 94         for (int i = 0; i < NeighborCount; i++)
 95           result.neighbors[i] = n.neighbors[i];
 96       }
 97       int second_val = random.nextInt();
 98       if (second_val < 0) second_val = -second_val;
 99       if (second_val < 0) second_val = 0;
100 
101       int overwrite_index = first_val % NeighborCount;
102       result.neighbors[overwrite_index] = new Node(second_val);
103       return result;
104     }
105   }
106 
107   public static void main(String args[]) throws Exception {
108     Node n = null;
109 
110     if (!wb.getBooleanVMFlag("UseShenandoahGC") ||
111         !wb.getStringVMFlag("ShenandoahGCMode").equals("generational"))
112       throw new IllegalStateException("Command-line options not honored!");
113 
114     for (int count = 10000; count > 0; count--) {
115       n = Node.upheaval(n);
116     }
117 
118     if (n.value() != ExpectedLastRandom)
119       throw new IllegalStateException("Random number sequence ended badly!");
120 
121   }
122 
123 }
124