hotspot/test/gc/g1/TestStringDeduplicationTools.java
author pliden
Tue, 18 Mar 2014 19:07:22 +0100
changeset 23472 35e93890ed88
child 23852 b1d6f9920924
permissions -rw-r--r--
8029075: String deduplication in G1 Summary: Implementation of JEP 192, http://openjdk.java.net/jeps/192 Reviewed-by: brutisso, tschatzl, coleenp
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
23472
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
     1
/*
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
     2
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
     4
 *
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
     7
 * published by the Free Software Foundation.
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
     8
 *
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    13
 * accompanied this code).
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    14
 *
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    18
 *
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    21
 * questions.
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    22
 */
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    23
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    24
/*
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    25
 * Common code for string deduplication tests
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    26
 */
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    27
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    28
import java.lang.management.*;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    29
import java.lang.reflect.*;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    30
import java.security.*;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    31
import java.util.*;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    32
import com.oracle.java.testlibrary.*;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    33
import sun.misc.*;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    34
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    35
class TestStringDeduplicationTools {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    36
    private static final String YoungGC = "YoungGC";
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    37
    private static final String FullGC  = "FullGC";
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    38
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    39
    private static final int Xmn = 50;  // MB
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    40
    private static final int Xms = 100; // MB
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    41
    private static final int Xmx = 100; // MB
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    42
    private static final int MB = 1024 * 1024;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    43
    private static final int StringLength = 50;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    44
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    45
    private static Field valueField;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    46
    private static Unsafe unsafe;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    47
    private static byte[] dummy;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    48
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    49
    static {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    50
        try {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    51
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    52
            field.setAccessible(true);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    53
            unsafe = (Unsafe)field.get(null);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    54
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    55
            valueField = String.class.getDeclaredField("value");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    56
            valueField.setAccessible(true);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    57
        } catch (Exception e) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    58
            throw new RuntimeException(e);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    59
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    60
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    61
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    62
    private static Object getValue(String string) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    63
        try {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    64
            return valueField.get(string);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    65
        } catch (Exception e) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    66
            throw new RuntimeException(e);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    67
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    68
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    69
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    70
    private static void doFullGc(int numberOfTimes) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    71
        for (int i = 0; i < numberOfTimes; i++) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    72
            System.out.println("Begin: Full GC " + (i + 1) + "/" + numberOfTimes);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    73
            System.gc();
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    74
            System.out.println("End: Full GC " + (i + 1) + "/" + numberOfTimes);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    75
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    76
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    77
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    78
    private static void doYoungGc(int numberOfTimes) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    79
        // Provoke at least numberOfTimes young GCs
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    80
        final int objectSize = 128;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    81
        final int maxObjectInYoung = (Xmn * MB) / objectSize;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    82
        for (int i = 0; i < numberOfTimes; i++) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    83
            System.out.println("Begin: Young GC " + (i + 1) + "/" + numberOfTimes);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    84
            for (int j = 0; j < maxObjectInYoung + 1; j++) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    85
                dummy = new byte[objectSize];
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    86
            }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    87
            System.out.println("End: Young GC " + (i + 1) + "/" + numberOfTimes);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    88
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    89
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    90
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    91
    private static void forceDeduplication(int ageThreshold, String gcType) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    92
        // Force deduplication to happen by either causing a FullGC or a YoungGC.
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    93
        // We do several collections to also provoke a situation where the the
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    94
        // deduplication thread needs to yield while processing the queue. This
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    95
        // also tests that the references in the deduplication queue are adjusted
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    96
        // accordingly.
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    97
        if (gcType.equals(FullGC)) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    98
            doFullGc(3);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
    99
        } else {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   100
            doYoungGc(ageThreshold + 3);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   101
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   102
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   103
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   104
    private static String generateString(int id) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   105
        StringBuilder builder = new StringBuilder(StringLength);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   106
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   107
        builder.append("DeduplicationTestString:" + id + ":");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   108
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   109
        while (builder.length() < StringLength) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   110
            builder.append('X');
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   111
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   112
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   113
        return builder.toString();
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   114
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   115
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   116
    private static ArrayList<String> createStrings(int total, int unique) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   117
        System.out.println("Creating strings: total=" + total + ", unique=" + unique);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   118
        if (total % unique != 0) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   119
            throw new RuntimeException("Total must be divisible by unique");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   120
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   121
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   122
        ArrayList<String> list = new ArrayList<String>(total);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   123
        for (int j = 0; j < total / unique; j++) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   124
            for (int i = 0; i < unique; i++) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   125
                list.add(generateString(i));
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   126
            }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   127
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   128
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   129
        return list;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   130
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   131
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   132
    private static void verifyStrings(ArrayList<String> list, int uniqueExpected) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   133
        for (;;) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   134
            // Check number of deduplicated strings
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   135
            ArrayList<Object> unique = new ArrayList<Object>(uniqueExpected);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   136
            for (String string: list) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   137
                Object value = getValue(string);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   138
                boolean uniqueValue = true;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   139
                for (Object obj: unique) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   140
                    if (obj == value) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   141
                        uniqueValue = false;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   142
                        break;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   143
                    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   144
                }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   145
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   146
                if (uniqueValue) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   147
                    unique.add(value);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   148
                }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   149
            }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   150
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   151
            System.out.println("Verifying strings: total=" + list.size() +
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   152
                               ", uniqueFound=" + unique.size() +
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   153
                               ", uniqueExpected=" + uniqueExpected);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   154
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   155
            if (unique.size() == uniqueExpected) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   156
                System.out.println("Deduplication completed");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   157
                break;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   158
            } else {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   159
                System.out.println("Deduplication not completed, waiting...");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   160
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   161
                // Give the deduplication thread time to complete
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   162
                try {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   163
                    Thread.sleep(1000);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   164
                } catch (Exception e) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   165
                    throw new RuntimeException(e);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   166
                }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   167
            }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   168
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   169
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   170
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   171
    private static OutputAnalyzer runTest(String... extraArgs) throws Exception {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   172
        String[] defaultArgs = new String[] {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   173
            "-Xmn" + Xmn + "m",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   174
            "-Xms" + Xms + "m",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   175
            "-Xmx" + Xmx + "m",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   176
            "-XX:+UseG1GC",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   177
            "-XX:+UnlockDiagnosticVMOptions",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   178
            "-XX:+VerifyAfterGC" // Always verify after GC
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   179
        };
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   180
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   181
        ArrayList<String> args = new ArrayList<String>();
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   182
        args.addAll(Arrays.asList(defaultArgs));
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   183
        args.addAll(Arrays.asList(extraArgs));
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   184
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   185
        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args.toArray(new String[args.size()]));
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   186
        OutputAnalyzer output = new OutputAnalyzer(pb.start());
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   187
        System.err.println(output.getStderr());
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   188
        System.out.println(output.getStdout());
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   189
        return output;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   190
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   191
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   192
    private static class DeduplicationTest {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   193
        public static void main(String[] args) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   194
            System.out.println("Begin: DeduplicationTest");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   195
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   196
            final int numberOfStrings = Integer.parseUnsignedInt(args[0]);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   197
            final int numberOfUniqueStrings = Integer.parseUnsignedInt(args[1]);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   198
            final int ageThreshold = Integer.parseUnsignedInt(args[2]);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   199
            final String gcType = args[3];
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   200
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   201
            ArrayList<String> list = createStrings(numberOfStrings, numberOfUniqueStrings);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   202
            forceDeduplication(ageThreshold, gcType);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   203
            verifyStrings(list, numberOfUniqueStrings);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   204
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   205
            System.out.println("End: DeduplicationTest");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   206
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   207
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   208
        public static OutputAnalyzer run(int numberOfStrings, int ageThreshold, String gcType, String... extraArgs) throws Exception {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   209
            String[] defaultArgs = new String[] {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   210
                "-XX:+UseStringDeduplication",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   211
                "-XX:StringDeduplicationAgeThreshold=" + ageThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   212
                DeduplicationTest.class.getName(),
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   213
                "" + numberOfStrings,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   214
                "" + numberOfStrings / 2,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   215
                "" + ageThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   216
                gcType
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   217
            };
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   218
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   219
            ArrayList<String> args = new ArrayList<String>();
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   220
            args.addAll(Arrays.asList(extraArgs));
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   221
            args.addAll(Arrays.asList(defaultArgs));
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   222
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   223
            return runTest(args.toArray(new String[args.size()]));
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   224
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   225
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   226
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   227
    private static class InternedTest {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   228
        public static void main(String[] args) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   229
            // This test verifies that interned strings are always
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   230
            // deduplicated when being interned, and never after
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   231
            // being interned.
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   232
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   233
            System.out.println("Begin: InternedTest");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   234
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   235
            final int ageThreshold = Integer.parseUnsignedInt(args[0]);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   236
            final String baseString = "DeduplicationTestString:" + InternedTest.class.getName();
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   237
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   238
            // Create duplicate of baseString
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   239
            StringBuilder sb1 = new StringBuilder(baseString);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   240
            String dupString1 = sb1.toString();
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   241
            if (getValue(dupString1) == getValue(baseString)) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   242
                throw new RuntimeException("Values should not match");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   243
            }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   244
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   245
            // Force baseString to be inspected for deduplication
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   246
            // and be inserted into the deduplication hashtable.
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   247
            forceDeduplication(ageThreshold, FullGC);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   248
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   249
            // Wait for deduplication to occur
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   250
            while (getValue(dupString1) != getValue(baseString)) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   251
                System.out.println("Waiting...");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   252
                try {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   253
                    Thread.sleep(100);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   254
                } catch (Exception e) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   255
                    throw new RuntimeException(e);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   256
                }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   257
            }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   258
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   259
            // Create a new duplicate of baseString
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   260
            StringBuilder sb2 = new StringBuilder(baseString);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   261
            String dupString2 = sb2.toString();
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   262
            if (getValue(dupString2) == getValue(baseString)) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   263
                throw new RuntimeException("Values should not match");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   264
            }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   265
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   266
            // Intern the new duplicate
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   267
            Object beforeInternedValue = getValue(dupString2);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   268
            String internedString = dupString2.intern();
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   269
            if (internedString != dupString2) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   270
                throw new RuntimeException("String should match");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   271
            }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   272
            if (getValue(internedString) != getValue(baseString)) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   273
                throw new RuntimeException("Values should match");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   274
            }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   275
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   276
            // Check original value of interned string, to make sure
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   277
            // deduplication happened on the interned string and not
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   278
            // on the base string
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   279
            if (beforeInternedValue == getValue(baseString)) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   280
                throw new RuntimeException("Values should not match");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   281
            }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   282
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   283
            System.out.println("End: InternedTest");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   284
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   285
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   286
        public static OutputAnalyzer run() throws Exception {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   287
            return runTest("-XX:+PrintGC",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   288
                           "-XX:+PrintGCDetails",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   289
                           "-XX:+UseStringDeduplication",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   290
                           "-XX:+PrintStringDeduplicationStatistics",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   291
                           "-XX:StringDeduplicationAgeThreshold=" + DefaultAgeThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   292
                           InternedTest.class.getName(),
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   293
                           "" + DefaultAgeThreshold);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   294
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   295
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   296
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   297
    private static class MemoryUsageTest {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   298
        public static void main(String[] args) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   299
            System.out.println("Begin: MemoryUsageTest");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   300
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   301
            final boolean useStringDeduplication = Boolean.parseBoolean(args[0]);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   302
            final int numberOfStrings = LargeNumberOfStrings;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   303
            final int numberOfUniqueStrings = 1;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   304
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   305
            ArrayList<String> list = createStrings(numberOfStrings, numberOfUniqueStrings);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   306
            forceDeduplication(DefaultAgeThreshold, FullGC);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   307
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   308
            if (useStringDeduplication) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   309
                verifyStrings(list, numberOfUniqueStrings);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   310
            }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   311
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   312
            System.gc();
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   313
            System.out.println("Heap Memory Usage: " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed());
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   314
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   315
            System.out.println("End: MemoryUsageTest");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   316
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   317
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   318
        public static OutputAnalyzer run(boolean useStringDeduplication) throws Exception {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   319
            String[] extraArgs = new String[0];
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   320
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   321
            if (useStringDeduplication) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   322
                extraArgs = new String[] {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   323
                    "-XX:+UseStringDeduplication",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   324
                    "-XX:+PrintStringDeduplicationStatistics",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   325
                    "-XX:StringDeduplicationAgeThreshold=" + DefaultAgeThreshold
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   326
                };
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   327
            }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   328
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   329
            String[] defaultArgs = new String[] {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   330
                "-XX:+PrintGC",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   331
                "-XX:+PrintGCDetails",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   332
                MemoryUsageTest.class.getName(),
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   333
                "" + useStringDeduplication
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   334
            };
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   335
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   336
            ArrayList<String> args = new ArrayList<String>();
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   337
            args.addAll(Arrays.asList(extraArgs));
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   338
            args.addAll(Arrays.asList(defaultArgs));
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   339
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   340
            return runTest(args.toArray(new String[args.size()]));
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   341
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   342
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   343
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   344
    /*
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   345
     * Tests
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   346
     */
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   347
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   348
    private static final int LargeNumberOfStrings = 10000;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   349
    private static final int SmallNumberOfStrings = 10;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   350
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   351
    private static final int MaxAgeThreshold      = 15;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   352
    private static final int DefaultAgeThreshold  = 3;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   353
    private static final int MinAgeThreshold      = 1;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   354
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   355
    private static final int TooLowAgeThreshold   = MinAgeThreshold - 1;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   356
    private static final int TooHighAgeThreshold  = MaxAgeThreshold + 1;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   357
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   358
    public static void testYoungGC() throws Exception {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   359
        // Do young GC to age strings to provoke deduplication
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   360
        OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   361
                                                      DefaultAgeThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   362
                                                      YoungGC,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   363
                                                      "-XX:+PrintGC",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   364
                                                      "-XX:+PrintStringDeduplicationStatistics");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   365
        output.shouldNotContain("Full GC");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   366
        output.shouldContain("GC pause (G1 Evacuation Pause) (young)");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   367
        output.shouldContain("GC concurrent-string-deduplication");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   368
        output.shouldContain("Deduplicated:");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   369
        output.shouldHaveExitValue(0);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   370
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   371
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   372
    public static void testFullGC() throws Exception {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   373
        // Do full GC to age strings to provoke deduplication
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   374
        OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   375
                                                      DefaultAgeThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   376
                                                      FullGC,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   377
                                                      "-XX:+PrintGC",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   378
                                                      "-XX:+PrintStringDeduplicationStatistics");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   379
        output.shouldNotContain("GC pause (G1 Evacuation Pause) (young)");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   380
        output.shouldContain("Full GC");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   381
        output.shouldContain("GC concurrent-string-deduplication");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   382
        output.shouldContain("Deduplicated:");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   383
        output.shouldHaveExitValue(0);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   384
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   385
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   386
    public static void testTableResize() throws Exception {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   387
        // Test with StringDeduplicationResizeALot
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   388
        OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   389
                                                      DefaultAgeThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   390
                                                      YoungGC,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   391
                                                      "-XX:+PrintGC",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   392
                                                      "-XX:+PrintStringDeduplicationStatistics",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   393
                                                      "-XX:+StringDeduplicationResizeALot");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   394
        output.shouldContain("GC concurrent-string-deduplication");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   395
        output.shouldContain("Deduplicated:");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   396
        output.shouldNotContain("Resize Count: 0");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   397
        output.shouldHaveExitValue(0);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   398
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   399
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   400
    public static void testTableRehash() throws Exception {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   401
        // Test with StringDeduplicationRehashALot
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   402
        OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   403
                                                      DefaultAgeThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   404
                                                      YoungGC,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   405
                                                      "-XX:+PrintGC",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   406
                                                      "-XX:+PrintStringDeduplicationStatistics",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   407
                                                      "-XX:+StringDeduplicationRehashALot");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   408
        output.shouldContain("GC concurrent-string-deduplication");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   409
        output.shouldContain("Deduplicated:");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   410
        output.shouldNotContain("Rehash Count: 0");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   411
        output.shouldNotContain("Hash Seed: 0x0");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   412
        output.shouldHaveExitValue(0);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   413
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   414
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   415
    public static void testAgeThreshold() throws Exception {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   416
        OutputAnalyzer output;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   417
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   418
        // Test with max age theshold
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   419
        output = DeduplicationTest.run(SmallNumberOfStrings,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   420
                                       MaxAgeThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   421
                                       YoungGC,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   422
                                       "-XX:+PrintGC",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   423
                                       "-XX:+PrintStringDeduplicationStatistics");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   424
        output.shouldContain("GC concurrent-string-deduplication");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   425
        output.shouldContain("Deduplicated:");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   426
        output.shouldHaveExitValue(0);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   427
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   428
        // Test with min age theshold
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   429
        output = DeduplicationTest.run(SmallNumberOfStrings,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   430
                                       MinAgeThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   431
                                       YoungGC,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   432
                                       "-XX:+PrintGC",
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   433
                                       "-XX:+PrintStringDeduplicationStatistics");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   434
        output.shouldContain("GC concurrent-string-deduplication");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   435
        output.shouldContain("Deduplicated:");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   436
        output.shouldHaveExitValue(0);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   437
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   438
        // Test with too low age threshold
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   439
        output = DeduplicationTest.run(SmallNumberOfStrings,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   440
                                       TooLowAgeThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   441
                                       YoungGC);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   442
        output.shouldContain("StringDeduplicationAgeThreshold of " + TooLowAgeThreshold +
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   443
                             " is invalid; must be between " + MinAgeThreshold + " and " + MaxAgeThreshold);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   444
        output.shouldHaveExitValue(1);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   445
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   446
        // Test with too high age threshold
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   447
        output = DeduplicationTest.run(SmallNumberOfStrings,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   448
                                       TooHighAgeThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   449
                                       YoungGC);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   450
        output.shouldContain("StringDeduplicationAgeThreshold of " + TooHighAgeThreshold +
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   451
                             " is invalid; must be between " + MinAgeThreshold + " and " + MaxAgeThreshold);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   452
        output.shouldHaveExitValue(1);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   453
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   454
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   455
    public static void testPrintOptions() throws Exception {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   456
        OutputAnalyzer output;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   457
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   458
        // Test without PrintGC and without PrintStringDeduplicationStatistics
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   459
        output = DeduplicationTest.run(SmallNumberOfStrings,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   460
                                       DefaultAgeThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   461
                                       YoungGC);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   462
        output.shouldNotContain("GC concurrent-string-deduplication");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   463
        output.shouldNotContain("Deduplicated:");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   464
        output.shouldHaveExitValue(0);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   465
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   466
        // Test with PrintGC but without PrintStringDeduplicationStatistics
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   467
        output = DeduplicationTest.run(SmallNumberOfStrings,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   468
                                       DefaultAgeThreshold,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   469
                                       YoungGC,
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   470
                                       "-XX:+PrintGC");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   471
        output.shouldContain("GC concurrent-string-deduplication");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   472
        output.shouldNotContain("Deduplicated:");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   473
        output.shouldHaveExitValue(0);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   474
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   475
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   476
    public static void testInterned() throws Exception {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   477
        // Test that interned strings are deduplicated before being interned
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   478
        OutputAnalyzer output = InternedTest.run();
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   479
        output.shouldHaveExitValue(0);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   480
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   481
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   482
    public static void testMemoryUsage() throws Exception {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   483
        // Test that memory usage is reduced after deduplication
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   484
        OutputAnalyzer output;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   485
        final String usagePattern = "Heap Memory Usage: (\\d+)";
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   486
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   487
        // Run without deduplication
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   488
        output = MemoryUsageTest.run(false);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   489
        output.shouldHaveExitValue(0);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   490
        final long memoryUsageWithoutDedup = Long.parseLong(output.firstMatch(usagePattern, 1));
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   491
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   492
        // Run with deduplication
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   493
        output = MemoryUsageTest.run(true);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   494
        output.shouldHaveExitValue(0);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   495
        final long memoryUsageWithDedup = Long.parseLong(output.firstMatch(usagePattern, 1));
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   496
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   497
        // Calculate expected memory usage with deduplication enabled. This calculation does
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   498
        // not take alignment and padding into account, so it's a conservative estimate.
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   499
        final long sizeOfChar = 2; // bytes
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   500
        final long bytesSaved = (LargeNumberOfStrings - 1) * (StringLength * sizeOfChar + unsafe.ARRAY_CHAR_BASE_OFFSET);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   501
        final long memoryUsageWithDedupExpected = memoryUsageWithoutDedup - bytesSaved;
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   502
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   503
        System.out.println("Memory usage summary:");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   504
        System.out.println("   memoryUsageWithoutDedup:      " + memoryUsageWithoutDedup);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   505
        System.out.println("   memoryUsageWithDedup:         " + memoryUsageWithDedup);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   506
        System.out.println("   memoryUsageWithDedupExpected: " + memoryUsageWithDedupExpected);
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   507
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   508
        if (memoryUsageWithDedup > memoryUsageWithDedupExpected) {
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   509
            throw new Exception("Unexpected memory usage, memoryUsageWithDedup should less or equal to memoryUsageWithDedupExpected");
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   510
        }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   511
    }
35e93890ed88 8029075: String deduplication in G1
pliden
parents:
diff changeset
   512
}