1 /*
  2  * Copyright (c) 2006, 2026, 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 5045582
 27  * @summary arrays larger than 1<<30
 28  * @author Martin Buchholz
 29  * @library /test/lib
 30  */
 31 
 32 // A proper regression test for 5045582 requires too much memory.
 33 // If you have a really big machine, run like this:
 34 // java -Xms25g -Xmx25g Big 30
 35 
 36 import java.util.*;
 37 
 38 import jdk.test.lib.valueclass.AsValueClass;
 39 
 40 public class Big {
 41 
 42     @AsValueClass
 43     record Point(int x, int y) implements Comparable<Point> {
 44         public int compareTo(Point o) {
 45             int c = Integer.compare(x, o.x);
 46             return c != 0 ? c : Integer.compare(y, o.y);
 47         }
 48     }
 49 
 50     private static void realMain(String[] args) throws Throwable {
 51         final int shift = intArg(args, 0, 10); // "30" is real test
 52         final int tasks = intArg(args, 1, ~0); // all tasks
 53         final int n = (1<<shift) + 47;
 54 
 55         // To test byte arrays larger than 1<<30, you need 1600MB. Run like:
 56         // java -Xms1600m -Xmx1600m Big 30 1
 57         if ((tasks & 0x1) != 0) {
 58             System.out.println("byte[]");
 59             System.gc();
 60             byte[] a = new byte[n];
 61             a[0]   = (byte) -44;
 62             a[1]   = (byte) -43;
 63             a[n-2] = (byte) +43;
 64             a[n-1] = (byte) +44;
 65             for (int i : new int[] { 0, 1, n-2, n-1 })
 66                 try { equal(i, Arrays.binarySearch(a, a[i])); }
 67                 catch (Throwable t) { unexpected(t); }
 68             for (int i : new int[] { n-2, n-1 })
 69                 try { equal(i, Arrays.binarySearch(a, n-5, n, a[i])); }
 70                 catch (Throwable t) { unexpected(t); }
 71 
 72             a[n-19] = (byte) 45;
 73             try { Arrays.sort(a, n-29, n); }
 74             catch (Throwable t) { unexpected(t); }
 75             equal(a[n-1], (byte) 45);
 76             equal(a[n-2], (byte) 44);
 77             equal(a[n-3], (byte) 43);
 78             equal(a[n-4], (byte)  0);
 79         }
 80 
 81         // To test Object arrays larger than 1<<30, you need 13GB. Run like:
 82         // java -Xms13g -Xmx13g Big 30 2
 83         if ((tasks & 0x2) != 0) {
 84             System.out.println("Integer[]");
 85             System.gc();
 86             Integer[] a = new Integer[n];
 87             Integer ZERO = 0;
 88             Arrays.fill(a, ZERO);
 89             a[0]   =  -44;
 90             a[1]   =  -43;
 91             a[n-2] =  +43;
 92             a[n-1] =  +44;
 93             for (int i : new int[] { 0, 1, n-2, n-1 })
 94                 try { equal(i, Arrays.binarySearch(a, a[i])); }
 95                 catch (Throwable t) { unexpected(t); }
 96             for (int i : new int[] { n-2, n-1 })
 97                 try { equal(i, Arrays.binarySearch(a, n-5, n, a[i])); }
 98                 catch (Throwable t) { unexpected(t); }
 99 
100             a[n-19] = 45;
101             try { Arrays.sort(a, n-29, n); }
102             catch (Throwable t) { unexpected(t); }
103             equal(a[n-1],  45);
104             equal(a[n-2],  44);
105             equal(a[n-3],  43);
106             equal(a[n-4],   0);
107         }
108 
109         // To test value record arrays larger than 1<<30, you need ~25GB. Run like:
110         // java --enable-preview -Xms25g -Xmx25g Big 30 4
111         if ((tasks & 0x4) != 0) {
112             System.out.println("Point[]");
113             System.gc();
114             Point[] a = new Point[n];
115             Point ZERO = new Point(0, 0);
116             Arrays.fill(a, ZERO);
117             a[0]   = new Point(-44, -44);
118             a[1]   = new Point(-43, -43);
119             a[n-2] = new Point(+43, +43);
120             a[n-1] = new Point(+44, +44);
121             for (int i : new int[] { 0, 1, n-2, n-1 })
122                 try { equal(i, Arrays.binarySearch(a, a[i])); }
123                 catch (Throwable t) { unexpected(t); }
124             for (int i : new int[] { n-2, n-1 })
125                 try { equal(i, Arrays.binarySearch(a, n-5, n, a[i])); }
126                 catch (Throwable t) { unexpected(t); }
127 
128             a[n-19] = new Point(45, 45);
129             try { Arrays.sort(a, n-29, n); }
130             catch (Throwable t) { unexpected(t); }
131             equal(a[n-1], new Point(45, 45));
132             equal(a[n-2], new Point(44, 44));
133             equal(a[n-3], new Point(43, 43));
134             equal(a[n-4], new Point(0, 0));
135         }
136     }
137 
138     //--------------------- Infrastructure ---------------------------
139     static volatile int passed = 0, failed = 0;
140     static void pass() {passed++;}
141     static void fail() {failed++; Thread.dumpStack();}
142     static void fail(String msg) {System.out.println(msg); fail();}
143     static void unexpected(Throwable t) {failed++; t.printStackTrace();}
144     static void check(boolean cond) {if (cond) pass(); else fail();}
145     static void equal(Object x, Object y) {
146         if (x == null ? y == null : x.equals(y)) pass();
147         else fail(x + " not equal to " + y);}
148     public static void main(String[] args) throws Throwable {
149         try {realMain(args);} catch (Throwable t) {unexpected(t);}
150         System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
151         if (failed > 0) throw new AssertionError("Some tests failed");}
152     static int intArg(String[] args, int i, int defaultValue) {
153         return args.length > i ? Integer.parseInt(args[i]) : defaultValue;}
154 }