diff --git a/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/Automatic.java b/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/Automatic.java index 571ebe02849..c74c01f1bf7 100644 --- a/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/Automatic.java +++ b/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/Automatic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ public class Automatic { public static final int MINUTES_TO_WAIT = Integer.getInteger("jdk.test.lib.jittester", 3); private static Pair generateIRTree(String name) { + ProductionLimiter.resetTimer(); SymbolTable.removeAll(); TypeList.removeAll(); @@ -117,34 +118,41 @@ public static void main(String[] args) { List generators = getTestGenerators(); do { double start = System.currentTimeMillis(); - System.out.print("[" + LocalTime.now() + "] |"); - String name = "Test_" + counter; - Pair irTree = generateIRTree(name); - System.out.printf(" %8d |", counter); - long maxWaitTime = TimeUnit.MINUTES.toMillis(MINUTES_TO_WAIT); - double generationTime = System.currentTimeMillis() - start; - System.out.printf(" %8.0f |", generationTime); - start = System.currentTimeMillis(); - Thread generatorThread = new Thread(() -> { - for (TestsGenerator generator : generators) { + try { + System.out.print("[" + LocalTime.now() + "] |"); + String name = "Test_" + counter; + Pair irTree = generateIRTree(name); + System.out.printf(" %8d |", counter); + long maxWaitTime = TimeUnit.MINUTES.toMillis(MINUTES_TO_WAIT); + double generationTime = System.currentTimeMillis() - start; + System.out.printf(" %8.0f |", generationTime); + start = System.currentTimeMillis(); + Thread generatorThread = new Thread(() -> { + for (TestsGenerator generator : generators) { generator.accept(irTree.first, irTree.second); + } + }); + generatorThread.start(); + try { + generatorThread.join(maxWaitTime); + } catch (InterruptedException ie) { + throw new Error("Test generation interrupted: " + ie, ie); } - }); - generatorThread.start(); - try { - generatorThread.join(maxWaitTime); - } catch (InterruptedException ie) { - throw new Error("Test generation interrupted: " + ie, ie); - } - if (generatorThread.isAlive()) { - // maxTime reached, so, proceed to next test generation - generatorThread.interrupt(); - } else { - double runningTime = System.currentTimeMillis() - start; - System.out.printf(" %8.0f |%n", runningTime); - if (runningTime < maxWaitTime) { - ++counter; + if (generatorThread.isAlive()) { + // maxTime reached, so, proceed to next test generation + generatorThread.interrupt(); + } else { + double runningTime = System.currentTimeMillis() - start; + System.out.printf(" %8.0f |%n", runningTime); + if (runningTime < maxWaitTime) { + ++counter; + } } + } catch (RuntimeException ignored) { + // Generation failures happen due to nature of fuzzing test generators, + // such errors are ignored. + System.out.println("Test_" + counter + " ignored, generation failed due to " + + ignored.getMessage()); } } while (counter < ProductionParams.numberOfTests.value()); } diff --git a/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionLimiter.java b/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionLimiter.java index 2d4fdbbeff7..f647b091adb 100644 --- a/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionLimiter.java +++ b/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionLimiter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,11 +22,17 @@ */ package jdk.test.lib.jittester; + +import java.time.Duration; +import java.time.Instant; + // an utility class to limit steps in the production of an expression public class ProductionLimiter { private static Integer limit = -1; + private static Instant limitInstant; + public static void setUnlimited() { limit = -1; } @@ -44,5 +50,23 @@ public static void limitProduction() throws ProductionFailedException { if (limit != -1 && limit <= 0) { throw new ProductionFailedException(); } + + if (Instant.now().isAfter(limitInstant)) { + long paramsLimitSeconds = ProductionParams.productionLimitSeconds.value(); + Duration elapsed = Duration.between(limitInstant.minusSeconds(paramsLimitSeconds), Instant.now()); + String elapsedStr = String.format("%d:%02d:%02d", + elapsed.toHoursPart(), elapsed.toMinutesPart(), elapsed.toSecondsPart()); + + Duration timeLimit = Duration.ofSeconds(paramsLimitSeconds); + String timeLimitStr = String.format("%d:%02d:%02d", + timeLimit.toHoursPart(), timeLimit.toMinutesPart(), timeLimit.toSecondsPart()); + + throw new RuntimeException(String.format("A test generation took %s while limit is %s", + elapsedStr, timeLimitStr)); + } + } + + public static void resetTimer() { + limitInstant = Instant.now().plusSeconds(ProductionParams.productionLimitSeconds.value()); } } diff --git a/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionParams.java b/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionParams.java index 7a8256f0b12..69d489bf00d 100644 --- a/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionParams.java +++ b/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionParams.java @@ -29,6 +29,7 @@ public class ProductionParams { public static Option productionLimit = null; + public static Option productionLimitSeconds = null; public static Option dataMemberLimit = null; public static Option statementLimit = null; public static Option testStatementLimit = null; @@ -81,6 +82,7 @@ public class ProductionParams { public static void register(OptionResolver optionResolver) { productionLimit = optionResolver.addIntegerOption('l', "production-limit", 100, "Limit on steps in the production of an expression"); + productionLimitSeconds = optionResolver.addIntegerOption("production-limit-seconds", 600, "Limit the time a test generation may take"); dataMemberLimit = optionResolver.addIntegerOption('v', "data-member-limit", 10, "Upper limit on data members"); statementLimit = optionResolver.addIntegerOption('s', "statement-limit", 30, "Upper limit on statements in function"); testStatementLimit = optionResolver.addIntegerOption('e', "test-statement-limit", 300, "Upper limit on statements in test() function");