1 /*
2  * Copyright (c) 2015, 2017, 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 8136421
27  * @requires vm.jvmci
28  * @library / /test/lib
29  * @library ../common/patches
30  * @modules java.base/jdk.internal.misc
31  * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot
32  * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
33  * @run driver compiler.jvmci.compilerToVM.DebugOutputTest
34  */
35 
36 package compiler.jvmci.compilerToVM;
37 
38 import jdk.test.lib.process.OutputAnalyzer;
39 import jdk.test.lib.process.ProcessTools;
40 import jdk.vm.ci.hotspot.CompilerToVMHelper;
41 
42 import java.util.Arrays;
43 import java.nio.file.Path;
44 import java.nio.file.Paths;
45 
46 public class DebugOutputTest {
47     private static final String VM_CI_MODULE = "jdk.internal.vm.ci";
main(String[] args)48     public static void main(String[] args) {
49         new DebugOutputTest().test();
50     }
51 
test()52     private void test() {
53         for (TestCaseData testCase : TestCaseData.values()) {
54             System.out.println(testCase);
55             OutputAnalyzer oa;
56             try {
57                 Path patch = Paths.get(System.getProperty("test.patch.path"));
58                 Path jvmciPath = patch.resolve(VM_CI_MODULE).toAbsolutePath();
59                 if (!jvmciPath.toFile().exists()) {
60                     throw new Error("TESTBUG: patch for " + VM_CI_MODULE + " : "
61                             + jvmciPath.toString() + " does not exist");
62                 }
63                 oa = ProcessTools.executeTestJvm(
64                         "-XX:+UnlockExperimentalVMOptions",
65                         "-XX:+EnableJVMCI",
66                         "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED",
67                         "--add-exports", "jdk.internal.vm.ci/jdk.vm.ci.hotspot=ALL-UNNAMED",
68                         "--patch-module", VM_CI_MODULE + "=" + jvmciPath.toString(),
69                         DebugOutputTest.Worker.class.getName(),
70                         testCase.name());
71                } catch (Throwable e) {
72                 e.printStackTrace();
73                 throw new Error("Problems running child process", e);
74             }
75             if (testCase.expectedException != null) {
76                 oa.shouldHaveExitValue(1);
77                 oa.shouldContain(testCase.expectedException.getName());
78             } else {
79                 oa.shouldHaveExitValue(0);
80                 oa.shouldContain(new String(testCase.getExpected()));
81             }
82         }
83     }
84 
85     /**
86      * A list of test cases that are executed in forked VM
87      */
88     private enum TestCaseData {
89         PART_ARRAY(100, 50),
90         FULL_ARRAY(0, 255),
91         EMPTY(0, 0),
92         NEGATIVE_LENGTH(0, Integer.MIN_VALUE,
93                 ArrayIndexOutOfBoundsException.class),
94         NEGATIVE_OFFSET(-1, 255,
95                 ArrayIndexOutOfBoundsException.class),
96         LEFT_BOUND(Integer.MIN_VALUE, 100,
97                 ArrayIndexOutOfBoundsException.class),
98         RIGHT_BOUND(Integer.MAX_VALUE, 100,
99                 ArrayIndexOutOfBoundsException.class),
100         BIG_LENGTH(0, Integer.MAX_VALUE,
101                 ArrayIndexOutOfBoundsException.class),
102         NULL_POINTER(0, 0,
103                 NullPointerException.class),
104         ;
105 
106         private static final int SIZE = 255;
107         private static final byte[] DATA = generate();
108         public final int offset;
109         public final int length;
110         public final Class<? extends Throwable> expectedException;
111 
TestCaseData(int offset, int length, Class<? extends Throwable> expectedException)112         private TestCaseData(int offset, int length,
113                 Class<? extends Throwable> expectedException) {
114             this.offset = offset;
115             this.length = length;
116             this.expectedException = expectedException;
117         }
118 
TestCaseData(int offset, int length)119         private TestCaseData(int offset, int length) {
120             this(offset, length, null);
121         }
122 
generate()123         private static byte[] generate() {
124             byte[] byteArray = new byte[SIZE];
125             for (int i = 0; i < SIZE; i++) {
126                 byteArray[i] = (byte) (i + 1);
127             }
128             return byteArray;
129         }
130 
getExpected()131         public byte[] getExpected() {
132             if (expectedException != null) {
133                 return new byte[0];
134             }
135             return Arrays.copyOfRange(TestCaseData.DATA, offset,
136                     offset + length);
137         }
138 
139         @Override
toString()140         public String toString() {
141             return "CASE: " + this.name();
142         }
143 
getData()144         public byte[] getData() {
145             if (equals(NULL_POINTER)) {
146                 return null;
147             } else {
148                 return DATA;
149             }
150         }
151     }
152 
153     public static class Worker {
main(String[] args)154         public static void main(String[] args) {
155             for (String arg : args) {
156                 TestCaseData tcase = TestCaseData.valueOf(arg);
157                 CompilerToVMHelper.writeDebugOutput(tcase.getData(),
158                         tcase.offset, tcase.length);
159                 CompilerToVMHelper.flushDebugOutput();
160             }
161         }
162     }
163 }
164