8166790: Add stress test GCBasher
Reviewed-by: dfazunen, dholmes, erikj, tschatzl, lmesnik
--- a/hotspot/test/TEST.groups Mon Oct 17 05:44:43 2016 -0700
+++ b/hotspot/test/TEST.groups Thu Oct 06 16:32:46 2016 +0200
@@ -349,6 +349,12 @@
hotspot_fast_gc_gcold = \
gc/stress/TestGCOld.java
+hotspot_fast_gc_gcbasher = \
+ gc/stress/gcbasher/TestGCBasherWithG1.java \
+ gc/stress/gcbasher/TestGCBasherWithCMS.java \
+ gc/stress/gcbasher/TestGCBasherWithSerial.java \
+ gc/stress/gcbasher/TestGCBasherWithParallel.java
+
hotspot_fast_runtime = \
runtime/ \
-runtime/6626217/Test6626217.sh \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/ByteCursor.java Thu Oct 06 16:32:46 2016 +0200
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+class ByteCursor {
+ private int offset;
+ private byte[] data;
+
+ public ByteCursor(byte[] data) {
+ this.offset = 0;
+ this.data = data;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public void skipBytes(int n) {
+ offset += n;
+ }
+
+ public int readUnsignedByte() {
+ int val = readUnsignedByteAt(offset);
+ offset += 1;
+ return val;
+ }
+
+ public int readUnsignedByteAt(int offset) {
+ return data[offset++] & 0xff;
+ }
+
+ public int readUnsignedShort() {
+ int val = readUnsignedShortAt(offset);
+ offset += 2;
+ return val;
+ }
+
+ public int readInt() {
+ int val = readIntAt(offset);
+ offset += 4;
+ return val;
+ }
+
+ public int readUnsignedShortAt(int offset) {
+ int b1 = data[offset++] & 0xff;
+ int b2 = data[offset] & 0xff;
+
+ return (b1 << 8) + b2;
+ }
+
+ public int readIntAt(int offset) {
+ int s1 = readUnsignedShortAt(offset);
+ int s2 = readUnsignedShortAt(offset + 2);
+ return (s1 << 16) + s2;
+ }
+
+ public String readUtf8(int length) throws IllegalStateException {
+ char str[] = new char[length];
+ int count = 0;
+ int pos = 0;
+ while (count < length) {
+ int c = readUnsignedByte();
+ switch (c >> 4) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
+ // 0xxxxxxx
+ count++;
+ if(c == '/') {
+ str[pos++] = '.';
+ } else {
+ str[pos++] = (char) c;
+ }
+ break;
+ } case 12: case 13: {
+ // 110x xxxx 10xx xxxx
+ count += 2;
+ int c2 = readUnsignedByte();
+ if ((c2 & 0xC0) != 0x80) {
+ throw new IllegalStateException();
+ }
+ str[pos++] = (char) (((c & 0x1F) << 6) | (c2 & 0x3F));
+ break;
+ } case 14: {
+ // 1110 xxxx 10xx xxxx 10xx xxxx
+ count += 3;
+ int c2 = readUnsignedByte();
+ int c3 = readUnsignedByte();
+ if ((c2 & 0xC0) != 0x80 || (c3 & 0xC0) != 0x80) {
+ throw new IllegalStateException();
+ }
+ str[pos++] = (char)(((c & 0x0F) << 12) |
+ ((c2 & 0x3F) << 6) |
+ ((c3 & 0x3F) << 0));
+ break;
+ } default:
+ // 10xx xxxx, 1111 xxxx
+ throw new IllegalStateException();
+ }
+ }
+ return new String(str);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/Bytecode.java Thu Oct 06 16:32:46 2016 +0200
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+class Bytecode {
+ public static final int IINC = 132;
+ public static final int TABLESWITCH = 170;
+ public static final int LOOKUPSWITCH = 171;
+ public static final int GETSTATIC = 178;
+ public static final int PUTSTATIC = 179;
+ public static final int GETFIELD = 180;
+ public static final int PUTFIELD = 181;
+ public static final int INVOKEVIRTUAL = 182;
+ public static final int INVOKESPECIAL = 183;
+ public static final int INVOKESTATIC = 184;
+ public static final int INVOKEINTERFACE = 185;
+ public static final int NEW = 187;
+ public static final int ANEWARRAY = 189;
+ public static final int CHECKCAST = 192;
+ public static final int INSTANCEOF = 193;
+ public static final int MULTIANEWARRAY = 197;
+ public static final int WIDE = 196;
+
+ private static final int lengths[] = {
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2,
+ 3,
+ 2,
+ 3,
+ 3,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 3,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 2,
+ 99,
+ 99,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 5,
+ 5,
+ 3,
+ 2,
+ 3,
+ 1,
+ 1,
+ 3,
+ 3,
+ 1,
+ 1,
+ 0,
+ 4,
+ 3,
+ 3,
+ 5,
+ 5,
+ 1
+ };
+
+ public static int getLength(int bc) throws IllegalArgumentException {
+ if ((bc < 0) || (bc >= lengths.length)) {
+ throw new IllegalArgumentException("Unknown bytecode " + bc);
+ }
+ return lengths[bc];
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/ClassInfo.java Thu Oct 06 16:32:46 2016 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+import java.util.HashSet;
+import java.util.Set;
+
+class ClassInfo {
+ private String name;
+
+ private Set<Dependency> staticResolution;
+ private Set<Dependency> staticInitialization;
+ private Set<Dependency> constructorResolution;
+ private Set<Dependency> constructorInitialization;
+ private Set<Dependency> methodResolution;
+ private Set<Dependency> methodInitialization;
+
+ public ClassInfo(String name) {
+ this.name = name;
+
+ staticResolution = new HashSet<>();
+ staticInitialization = new HashSet<>();
+ constructorResolution = new HashSet<>();
+ constructorInitialization = new HashSet<>();
+ methodResolution = new HashSet<>();
+ methodInitialization = new HashSet<>();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void addResolutionDep(Dependency d) {
+ if(d.getMethodName().equals("<clinit>")) {
+ staticResolution.add(d);
+ } else if(d.getMethodName().equals("<init>")) {
+ constructorResolution.add(d);
+ } else {
+ methodResolution.add(d);
+ }
+ }
+
+ public void addInitializationDep(Dependency d) {
+ if(d.getMethodName().equals("<clinit>")) {
+ staticInitialization.add(d);
+ } else if(d.getMethodName().equals("<init>")) {
+ constructorInitialization.add(d);
+ } else {
+ methodInitialization.add(d);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/ConstantPoolEntry.java Thu Oct 06 16:32:46 2016 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+class ConstantPoolEntry {
+ private int index;
+ private String value;
+
+ public ConstantPoolEntry(int index) {
+ this.index = index;
+ value = null;
+ }
+
+ public ConstantPoolEntry(String value) {
+ this.index = -1;
+ this.value = value;
+ }
+
+ public String getValue() throws IllegalStateException {
+ if (index != -1) {
+ throw new IllegalStateException();
+ }
+ return value;
+ }
+
+ public int getNameIndex() throws IllegalStateException {
+ if (value != null) {
+ throw new IllegalStateException();
+ }
+ return index;
+ }
+
+ public int getClassIndex() throws IllegalStateException {
+ if (value != null) {
+ throw new IllegalStateException();
+ }
+ return index;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/Decompiler.java Thu Oct 06 16:32:46 2016 +0200
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+class Decompiler {
+ private ByteCursor cursor;
+ private ClassInfo ci;
+
+ public Decompiler(byte[] classData) {
+ cursor = new ByteCursor(classData);
+
+ int magicNumber = cursor.readInt();
+ if (magicNumber != 0xCAFEBABE) {
+ throw new IllegalArgumentException("Bad magic number " + magicNumber);
+ }
+
+ cursor.readUnsignedShort(); // Minor version
+ cursor.readUnsignedShort(); // Major version
+
+ ConstantPoolEntry[] constantPool = decodeConstantPool();
+
+ cursor.readUnsignedShort(); // Access flags
+
+ // this class index in constant pool;
+ int classInfo = cursor.readUnsignedShort();
+ int classInfoNameIndex = constantPool[classInfo].getNameIndex();
+ ci = new ClassInfo(constantPool[classInfoNameIndex].getValue());
+
+ cursor.readUnsignedShort(); // superclass
+
+ int numInterfaces = cursor.readUnsignedShort();
+ for (int i = 0; i < numInterfaces; i++) {
+ cursor.readUnsignedShort(); // interface
+ }
+
+ decodeFields();
+ MethodInfo[] methods = decodeMethods(constantPool);
+ decodeMethodDependencies(methods, constantPool);
+ }
+
+ public ClassInfo getClassInfo() {
+ return ci;
+ }
+
+ private boolean isDependency(String name, String className) {
+ return !name.equals(className) && !name.startsWith("[");
+ }
+
+ private void addDependency(MethodInfo m, String name) {
+ Dependency d = new Dependency(m.getName(), m.getDescriptor(), name);
+ ci.addResolutionDep(d);
+ }
+
+ private String resolveName(ConstantPoolEntry[] constantPool, int cpi) {
+ int nameIndex = constantPool[cpi].getNameIndex();
+ return constantPool[nameIndex].getValue();
+ }
+
+ private void decodeMethodDependencies(MethodInfo[] methods, ConstantPoolEntry[] constantPool) {
+ for (int i = 0; i < methods.length; i++) {
+ MethodInfo m = methods[i];
+ final int stopCheck = m.getCodeStart() + m.getCodeLength();
+
+ int byteCodeIndex = m.getCodeStart();
+ while (byteCodeIndex < stopCheck) {
+ int bc = cursor.readUnsignedByteAt(byteCodeIndex);
+
+ switch (bc) {
+ // These opcodes cause name resolution or initialization
+ // Their index bytes all point to a CONSTANT_Class (4.4.1)
+ case Bytecode.ANEWARRAY:
+ case Bytecode.CHECKCAST:
+ case Bytecode.INSTANCEOF:
+ case Bytecode.MULTIANEWARRAY:
+ case Bytecode.NEW: {
+ int cpi = cursor.readUnsignedShortAt(byteCodeIndex + 1);
+ String name = resolveName(constantPool, cpi);
+
+ if (isDependency(name, ci.getName())) {
+ addDependency(m, name);
+ }
+ break;
+ }
+
+ // These opcodes cause name resolution or initialization
+ // Their index bytes all point to a CONSTANT_Field/Methodref (4.4.2)
+ case Bytecode.GETFIELD:
+ case Bytecode.INVOKEINTERFACE:
+ case Bytecode.INVOKESPECIAL:
+ case Bytecode.INVOKEVIRTUAL:
+ case Bytecode.PUTFIELD:
+ case Bytecode.PUTSTATIC:
+ case Bytecode.GETSTATIC:
+ case Bytecode.INVOKESTATIC: {
+ int cpi = cursor.readUnsignedShortAt(byteCodeIndex + 1);
+ int classIndex = constantPool[cpi].getClassIndex();
+ String name = resolveName(constantPool, classIndex);
+
+ if (isDependency(name, ci.getName())) {
+ addDependency(m, name);
+ }
+ break;
+ }
+
+ case Bytecode.LOOKUPSWITCH: {
+ byteCodeIndex++;
+ int offset = byteCodeIndex - m.getCodeStart();
+ while (offset % 4 != 0) {
+ offset++;
+ byteCodeIndex++;
+ }
+
+ int def = cursor.readIntAt(byteCodeIndex);
+ byteCodeIndex +=4;
+
+ int npairs = cursor.readIntAt(byteCodeIndex);
+ byteCodeIndex +=4;
+ byteCodeIndex += (8 * npairs);
+ continue;
+ }
+
+ case Bytecode.TABLESWITCH: {
+ byteCodeIndex++;
+ int offset = byteCodeIndex - m.getCodeStart();
+ while (offset % 4 != 0) {
+ offset++;
+ byteCodeIndex++;
+ }
+
+ int def = cursor.readIntAt(byteCodeIndex);
+ byteCodeIndex +=4;
+
+ int low = cursor.readIntAt(byteCodeIndex);
+ byteCodeIndex +=4;
+ int high = cursor.readIntAt(byteCodeIndex);
+ byteCodeIndex +=4;
+ byteCodeIndex += (4 * (high - low + 1));
+ continue;
+ }
+
+ case Bytecode.WIDE: {
+ bc = cursor.readUnsignedByteAt(++byteCodeIndex);
+ if (bc == Bytecode.IINC) {
+ byteCodeIndex += 5;
+ } else {
+ byteCodeIndex += 3;
+ }
+ continue;
+ }
+ }
+
+ byteCodeIndex += Bytecode.getLength(bc);
+ }
+
+ if (byteCodeIndex - stopCheck > 1) {
+ String err = "bad finish for method " + m.getName() +
+ "End + " + (byteCodeIndex - stopCheck);
+ throw new IllegalArgumentException(err);
+ }
+ }
+ }
+
+ private MethodInfo[] decodeMethods(ConstantPoolEntry[] constantPool) {
+ MethodInfo[] methods = new MethodInfo[cursor.readUnsignedShort()];
+
+ for (int i = 0; i < methods.length; i++) {
+ cursor.readUnsignedShort(); // access flags
+
+ String name = constantPool[cursor.readUnsignedShort()].getValue();
+ String descriptor = constantPool[cursor.readUnsignedShort()].getValue();
+
+ int codeLength = 0;
+ int codeStart = 0;
+
+ int numAttributes = cursor.readUnsignedShort(); // attributes count
+ for (int j = 0; j < numAttributes; j++) {
+ int type = cursor.readUnsignedShort(); // attrib nameIndex
+ int aLen = cursor.readInt(); // attrib length
+
+ if (constantPool[type].getValue().equals("Code")) {
+ cursor.readUnsignedShort(); // Max stack
+ cursor.readUnsignedShort(); // Max locals
+
+ codeLength = cursor.readInt();
+ codeStart = cursor.getOffset();
+
+ cursor.skipBytes(codeLength); // Need to skip the code bytes
+ cursor.skipBytes(cursor.readUnsignedShort() * 8); // Skip exception table
+
+ int numSubAttributes = cursor.readUnsignedShort();
+ for (int k = 0; k < numSubAttributes; k++) {
+ cursor.readUnsignedShort(); // sub name
+ cursor.skipBytes(cursor.readInt()); // sub attrib data
+ }
+ } else {
+ cursor.skipBytes(aLen); // unknown attrib data
+ }
+ }
+
+ methods[i] = new MethodInfo(name, descriptor, codeLength, codeStart);
+ }
+
+ return methods;
+ }
+
+ private void decodeFields() {
+ // Looks like we dont need any field info, throw it away!
+ int numFields = cursor.readUnsignedShort();
+
+ for (int i = 0; i < numFields; i++) {
+ cursor.readUnsignedShort(); // access flags
+ cursor.readUnsignedShort(); // nameIndex
+ cursor.readUnsignedShort(); // descriptorIndex
+
+ int numAttributes = cursor.readUnsignedShort();
+ for (int j = 0; j < numAttributes; j++) {
+ cursor.readUnsignedShort(); // nameIndex
+ int length = cursor.readInt();
+ cursor.skipBytes(length); // data
+ }
+ }
+ }
+
+ private ConstantPoolEntry[] decodeConstantPool() {
+ final int CONSTANT_Utf8 = 1;
+ final int CONSTANT_Unicode = 2;
+ final int CONSTANT_Integer = 3;
+ final int CONSTANT_Float = 4;
+ final int CONSTANT_Long = 5;
+ final int CONSTANT_Double = 6;
+ final int CONSTANT_Class = 7;
+ final int CONSTANT_String = 8;
+ final int CONSTANT_Fieldref = 9;
+ final int CONSTANT_Methodref = 10;
+ final int CONSTANT_InterfaceMethodref = 11;
+ final int CONSTANT_NameAndType = 12;
+ final int CONSTANT_MethodHandle = 15;
+ final int CONSTANT_MethodType = 16;
+ final int CONSTANT_InvokeDynamic = 18;
+
+ ConstantPoolEntry[] constantPool = new ConstantPoolEntry[cursor.readUnsignedShort()];
+
+ // The constant pool starts at index 1
+ for (int i = 1; i < constantPool.length; i++) {
+ int type = cursor.readUnsignedByte();
+
+ switch (type) {
+ case CONSTANT_Class:
+ constantPool[i] = new ConstantPoolEntry(cursor.readUnsignedShort()); // name_index
+ break;
+
+ case CONSTANT_Fieldref: case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref:
+ constantPool[i] = new ConstantPoolEntry(cursor.readUnsignedShort()); // class_index
+ cursor.readUnsignedShort(); // name_and_type_index
+ break;
+
+ case CONSTANT_String:
+ cursor.readUnsignedShort(); // string_index
+ break;
+
+ case CONSTANT_Integer:
+ cursor.readInt(); // bytes
+ break;
+
+ case CONSTANT_Float:
+ cursor.readInt(); // bytes
+ break;
+
+ case CONSTANT_Long:
+ cursor.readInt(); // high_bytes
+ cursor.readInt(); // low_bytes
+ i++; // 8 byte constants use 2 constant pool slots.
+ break;
+
+ case CONSTANT_Double:
+ cursor.readInt(); // high_bytes
+ cursor.readInt(); // low_bytes
+ i++; // 8 byte constants use 2 constant pool slots.
+ break;
+
+ case CONSTANT_NameAndType:
+ constantPool[i] = new ConstantPoolEntry(cursor.readUnsignedShort()); // name_index
+ cursor.readUnsignedShort(); // descriptor_index
+ break;
+
+ case CONSTANT_Utf8:
+ int length = cursor.readUnsignedShort(); // length
+ constantPool[i] = new ConstantPoolEntry(cursor.readUtf8(length)); // bytes[length]
+ break;
+
+ case CONSTANT_MethodHandle:
+ cursor.readUnsignedByte(); // reference_kind
+ cursor.readUnsignedShort(); // reference_index
+ break;
+
+ case CONSTANT_MethodType:
+ cursor.readUnsignedShort(); // descriptor_index
+ break;
+
+ case CONSTANT_InvokeDynamic:
+ cursor.readUnsignedShort(); // bootstrap_method_attr_index
+ cursor.readUnsignedShort(); // name_and_type_index
+ break;
+
+ default:
+ String err = "Unknown constant pool type " + String.valueOf(type) + "\n" +
+ "CPE " + i + " of " + constantPool.length + "\n" +
+ "Byte offset " + Integer.toHexString(cursor.getOffset());
+ throw new IllegalArgumentException(err);
+ }
+ }
+ return constantPool;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/Dependency.java Thu Oct 06 16:32:46 2016 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+class Dependency {
+ private String methodName;
+ private String methodDescriptor;
+ private String target;
+
+ public Dependency(String methodName, String methodDescriptor, String target) {
+ this.methodName = methodName;
+ this.methodDescriptor = methodDescriptor;
+ this.target = target;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof Dependency)) {
+ return false;
+ }
+
+ Dependency other = (Dependency)o;
+ return target.equals(other.target) &&
+ methodName.equals(other.methodName) &&
+ methodDescriptor.equals(other.methodDescriptor);
+ }
+
+ @Override
+ public int hashCode() {
+ return methodName.hashCode() ^ methodDescriptor.hashCode() ^ target.hashCode();
+ }
+
+ public String getMethodName() {
+ return methodName;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/MethodInfo.java Thu Oct 06 16:32:46 2016 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+class MethodInfo {
+ private String name;
+ private String descriptor;
+ private int codeLength;
+ private int codeStart;
+
+ public MethodInfo(String name, String descriptor, int codeLength, int codeStart) {
+ this.name = name;
+ this.descriptor = descriptor;
+ this.codeLength = codeLength;
+ this.codeStart = codeStart;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDescriptor() {
+ return descriptor;
+ }
+
+ public int getCodeLength() {
+ return codeLength;
+ }
+
+ public int getCodeStart() {
+ return codeStart;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasher.java Thu Oct 06 16:32:46 2016 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.FileSystems;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.stream.Stream;
+
+public class TestGCBasher {
+ private static void parseClassFiles() throws IOException {
+ HashMap<String, ClassInfo> deps = new HashMap<>();
+
+ FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
+ Stream<Path> s = Files.walk(fs.getPath("/"));
+ for (Path p : (Iterable<Path>)s::iterator) {
+ if (p.toString().endsWith(".class")) {
+ byte[] data = Files.readAllBytes(p);
+ Decompiler d = new Decompiler(data);
+ ClassInfo ci = d.getClassInfo();
+ deps.put(ci.getName(), ci);
+ }
+ }
+ }
+
+ public static void run(String[] args) throws IOException {
+ if (args.length != 1) {
+ System.err.println("Usage: TestGCBasher <duration-ms>");
+ return;
+ }
+
+ long durationMillis = Long.valueOf(args[0]);
+ long start = System.currentTimeMillis();
+ while (System.currentTimeMillis() - start < durationMillis) {
+ parseClassFiles();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasherWithCMS.java Thu Oct 06 16:32:46 2016 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+import java.io.IOException;
+
+/*
+ * @test TestGCBasherWithCMS
+ * @key gc
+ * @key stress
+ * @requires vm.gc.ConcMarkSweep
+ * @requires vm.flavor == "server"
+ * @summary Stress the CMS GC by trying to make old objects more likely to be garbage than young objects.
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx128m -server -XX:+UseConcMarkSweepGC TestGCBasherWithCMS 120000
+ */
+public class TestGCBasherWithCMS {
+ public static void main(String[] args) throws IOException {
+ TestGCBasher.run(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasherWithG1.java Thu Oct 06 16:32:46 2016 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+import java.io.IOException;
+
+/*
+ * @test TestGCBasherWithG1
+ * @key gc
+ * @key stress
+ * @requires vm.gc.G1
+ * @requires vm.flavor == "server"
+ * @summary Stress the G1 GC by trying to make old objects more likely to be garbage than young objects.
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx128m -server -XX:+UseG1GC TestGCBasherWithG1 120000
+ */
+public class TestGCBasherWithG1 {
+ public static void main(String[] args) throws IOException {
+ TestGCBasher.run(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasherWithParallel.java Thu Oct 06 16:32:46 2016 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+import java.io.IOException;
+
+/*
+ * @test TestGCBasherWithParallel
+ * @key gc
+ * @key stress
+ * @requires vm.gc.Parallel
+ * @requires vm.flavor == "server"
+ * @summary Stress the Parallel GC by trying to make old objects more likely to be garbage than young objects.
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx256m -server -XX:+UseParallelGC -XX:-UseGCOverheadLimit TestGCBasherWithParallel 120000
+ */
+public class TestGCBasherWithParallel {
+ public static void main(String[] args) throws IOException {
+ TestGCBasher.run(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasherWithSerial.java Thu Oct 06 16:32:46 2016 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+import java.io.IOException;
+
+/*
+ * @test TestGCBasherWithSerial
+ * @key gc
+ * @key stress
+ * @requires vm.gc.Serial
+ * @requires vm.flavor == "server"
+ * @summary Stress the Serial GC by trying to make old objects more likely to be garbage than young objects.
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx128m -server -XX:+UseSerialGC TestGCBasherWithSerial 120000
+ */
+public class TestGCBasherWithSerial {
+ public static void main(String[] args) throws IOException {
+ TestGCBasher.run(args);
+ }
+}