1 /*
2 * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /**
25 * @test
26 * @bug 8059510
27 * @summary Test SharedSymbolTableBucketSize option
28 * @requires vm.cds
29 * @library /test/lib
30 * @modules java.base/jdk.internal.misc
31 * java.management
32 */
33
34 import java.util.regex.Matcher;
35 import java.util.regex.Pattern;
36 import jdk.test.lib.cds.CDSTestUtils;
37 import jdk.test.lib.process.OutputAnalyzer;
38
39 public class SharedSymbolTableBucketSize {
40 public static void main(String[] args) throws Exception {
41 int bucket_size = 8;
42
43 OutputAnalyzer output =
44 CDSTestUtils.createArchiveAndCheck("-XX:SharedSymbolTableBucketSize="
45 + Integer.valueOf(bucket_size));
46 CDSTestUtils.checkMappingFailure(output);
47
48 /* [1] There may be other table stats that precede the symbol tabble.
49 Skip all thse until we find this:
50
51 [0.677s][info][aot,hashtables] Shared symbol table stats -------- base: 0x0000000800000000
52 [0.677s][info][aot,hashtables] Number of entries : 46244
53 [0.677s][info][aot,hashtables] Total bytes used : 393792
54 [0.677s][info][aot,hashtables] Average bytes per entry : 8.516
55 [0.677s][info][aot,hashtables] Average bucket size : 7.734
56 [0.677s][info][aot,hashtables] Variance of bucket size : 7.513
57 [0.677s][info][aot,hashtables] Std. dev. of bucket size: 2.741
58 [0.677s][info][aot,hashtables] Maximum bucket size : 20
59 [0.677s][info][aot,hashtables] Empty buckets : 2
60 [0.677s][info][aot,hashtables] Value_Only buckets : 24
61 [0.677s][info][aot,hashtables] Other buckets : 5953
62 ....
63 */
64 Pattern pattern0 = Pattern.compile("Shared symbol table stats.*", Pattern.DOTALL);
65 Matcher matcher0 = pattern0.matcher(output.getStdout());
66 String stat = null;
67 if (matcher0.find()) {
68 stat = matcher0.group(0);
69 }
70 if (stat == null) {
71 throw new Exception("FAILED: pattern \"" + pattern0 + "\" not found");
72 }
73
74 /* (2) The first "Average bucket size" line in the remaining output is for the
75 shared symbol table */
76 Pattern pattern = Pattern.compile("Average bucket size *: *([0-9]+\\.[0-9]+).*", Pattern.MULTILINE);
77 Matcher matcher = pattern.matcher(stat);
78 String s = null;
79 if (matcher.find()) {
80 s = matcher.group(1);
81 }
82 if (s == null) {
83 throw new Exception("FAILED: pattern \"" + pattern + "\" not found");
84 }
85
86 Float f = Float.parseFloat(s);
87 int size = Math.round(f);
88 if (size != bucket_size && size != bucket_size + 1) {
89 throw new Exception("FAILED: incorrect bucket size " + size +
90 ", expect " + bucket_size + ", or " + (bucket_size + 1));
91 }
92
93 // Invalid SharedSymbolTableBucketSize input
94 String input[] = {"-XX:SharedSymbolTableBucketSize=-1",
95 "-XX:SharedSymbolTableBucketSize=2.5"};
96 for (int i = 0; i < input.length; i++) {
97 CDSTestUtils.createArchive(input[i])
98 .shouldContain("Improperly specified VM option")
99 .shouldHaveExitValue(1);
100 }
101 }
102 }