1 /* 2 * Copyright (c) 2018, 2019, 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 package org.graalvm.compiler.hotspot.lir.test; 26 27 import static org.graalvm.compiler.test.SubprocessUtil.getVMCommandLine; 28 import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments; 29 30 import java.io.File; 31 import java.util.ArrayList; 32 import java.util.Iterator; 33 import java.util.List; 34 import java.util.regex.Matcher; 35 import java.util.regex.Pattern; 36 37 import org.graalvm.compiler.api.directives.GraalDirectives; 38 import org.graalvm.compiler.core.common.LIRKind; 39 import org.graalvm.compiler.hotspot.HotSpotBackend; 40 import org.graalvm.compiler.hotspot.debug.BenchmarkCounters; 41 import org.graalvm.compiler.lir.ConstantValue; 42 import org.graalvm.compiler.lir.gen.LIRGeneratorTool; 43 import org.graalvm.compiler.lir.jtt.LIRTest; 44 import org.graalvm.compiler.lir.jtt.LIRTestSpecification; 45 import org.graalvm.compiler.test.SubprocessUtil; 46 import org.junit.Assert; 47 import org.junit.Assume; 48 import org.junit.Before; 49 import org.junit.Test; 50 51 import jdk.vm.ci.amd64.AMD64; 52 import jdk.vm.ci.meta.JavaConstant; 53 import jdk.vm.ci.meta.JavaKind; 54 import jdk.vm.ci.meta.ResolvedJavaMethod; 55 56 public class BenchmarkCounterOverflowTest extends LIRTest { 57 private static final String SUBPROCESS_PROPERTY = BenchmarkCounterOverflowTest.class.getSimpleName() + ".subprocess.call"; 58 private static final boolean VERBOSE = Boolean.getBoolean(BenchmarkCounterOverflowTest.class.getSimpleName() + ".verbose"); 59 60 private static LIRKind intKind; 61 62 @Before 63 public void checkAMD64() { 64 Assume.assumeTrue("skipping AMD64 specific test", getTarget().arch instanceof AMD64); 65 Assume.assumeTrue("skipping HotSpot specific test", getBackend() instanceof HotSpotBackend); 66 } 67 68 @Before 69 public void setUp() { 70 intKind = LIRKind.fromJavaKind(getBackend().getTarget().arch, JavaKind.Long); 71 } 72 73 private static final LIRTestSpecification constCounterIncrement = new LIRTestSpecification() { 74 @Override 75 public void generate(LIRGeneratorTool gen) { 76 gen.append(gen.createBenchmarkCounter("counter", "test", new ConstantValue(intKind, JavaConstant.forLong(Integer.MAX_VALUE)))); 77 } 78 }; 79 80 @SuppressWarnings("unused") 81 @LIRIntrinsic 82 public static void counterInc(LIRTestSpecification spec) { 83 } 84 85 public static void test(long count) { 86 for (long i = 0; i < count; i++) { 87 counterInc(constCounterIncrement); 88 GraalDirectives.blackhole(i); 89 } 90 } 91 92 @Test 93 public void incrementCounter() { 94 Assume.assumeTrue("not a subprocess -> skip", Boolean.getBoolean(SUBPROCESS_PROPERTY)); 95 BenchmarkCounters.enabled = true; 96 97 Object[] args = new Object[]{Integer.MAX_VALUE * 4L}; 98 ResolvedJavaMethod method = getResolvedJavaMethod("test"); 99 executeActualCheckDeopt(getInitialOptions(), method, EMPTY, null, args); 100 } 101 102 @Test 103 public void spawnSubprocess() throws Throwable { 104 Assume.assumeFalse("subprocess already spawned -> skip", Boolean.getBoolean(SUBPROCESS_PROPERTY)); 105 List<String> vmArgs = withoutDebuggerArguments(getVMCommandLine()); 106 vmArgs.add("-XX:JVMCICounterSize=1"); 107 vmArgs.add("-Dgraal." + BenchmarkCounters.Options.AbortOnBenchmarkCounterOverflow.getName() + "=true"); 108 vmArgs.add("-D" + SUBPROCESS_PROPERTY + "=true"); 109 110 // Disable increment range checks (e.g. HotSpotCounterOp.checkIncrements()) 111 vmArgs.add("-dsa"); 112 vmArgs.add("-da"); 113 114 List<String> mainClassAndArgs = new ArrayList<>(); 115 mainClassAndArgs.add("com.oracle.mxtool.junit.MxJUnitWrapper"); 116 mainClassAndArgs.add(BenchmarkCounterOverflowTest.class.getName()); 117 118 SubprocessUtil.Subprocess proc = SubprocessUtil.java(vmArgs, mainClassAndArgs); 119 120 if (VERBOSE) { 121 System.out.println(proc); 122 } 123 124 Assert.assertNotEquals("Expected non-zero exit status", 0, proc.exitCode); 125 126 Iterator<String> it = proc.output.iterator(); 127 boolean foundProblematicFrame = false; 128 while (it.hasNext()) { 129 String line = it.next(); 130 if (line.contains("Problematic frame:")) { 131 if (!it.hasNext()) { 132 // no more line 133 break; 134 } 135 line = it.next(); 136 if (line.contains(BenchmarkCounterOverflowTest.class.getName() + ".test")) { 137 foundProblematicFrame = true; 138 break; 139 } 140 Assert.fail("Unexpected stack trace: " + line); 141 } 142 } 143 // find and delete hserr file 144 while (it.hasNext()) { 145 String line = it.next(); 146 if (line.contains("An error report file with more information is saved as:")) { 147 if (!it.hasNext()) { 148 // no more line 149 break; 150 } 151 line = it.next(); 152 Pattern pattern = Pattern.compile("^# (.*hs_err_pid.*log)$"); 153 Matcher matcher = pattern.matcher(line); 154 if (matcher.matches()) { 155 File hserrFile = new File(matcher.group(1)); 156 if (hserrFile.exists()) { 157 if (VERBOSE) { 158 System.out.println("Deleting error report file:" + hserrFile.getAbsolutePath()); 159 } 160 hserrFile.delete(); 161 } 162 } 163 } 164 } 165 Assert.assertTrue(String.format("Could not find method in output:%n%s", proc), foundProblematicFrame); 166 } 167 }