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 package test.java.lang.invoke.lib; 25 26 // Android-added: import of Function for filterException 27 import java.util.function.Function; 28 29 /** 30 * Helper class used to catch and process VirtualMachineError with message "Out 31 * of space in CodeCache". Some JSR292 tests run out of code cache size, so code 32 * cache overflows and VME is thrown. This VME is considered as non-critical in 33 * some JSR292 tests, so it should be processed to prevent test failure. 34 */ 35 public class CodeCacheOverflowProcessor { 36 37 /** 38 * Checks if an instance of Throwable is caused by VirtualMachineError with 39 * message "Out of space in CodeCache". May be used as filter in method 40 * {@code jdk.testlibrary.Utils.filterException}. 41 * 42 * @param t - Throwable to check. 43 * @return true if Throwable is caused by VME, false otherwise. 44 */ isThrowableCausedByVME(Throwable t)45 public static Boolean isThrowableCausedByVME(Throwable t) { 46 Throwable causeOfT = t; 47 do { 48 if (causeOfT instanceof VirtualMachineError 49 && causeOfT.getMessage().matches(".*[Oo]ut of space" 50 + " in CodeCache.*")) { 51 return true; 52 } 53 causeOfT = causeOfT != null ? causeOfT.getCause() : null; 54 } while (causeOfT != null && causeOfT != t); 55 return false; 56 } 57 58 /** 59 * Checks if the given test throws an exception caused by 60 * VirtualMachineError with message "Out of space in CodeCache", and, if VME 61 * takes place, processes it so that no exception is thrown, and prints its 62 * stack trace. If test throws exception not caused by VME, this method just 63 * re-throws this exception. 64 * 65 * @param test - test to check for and process VirtualMachineError. 66 * @return - an exception caused by VME or null 67 * if test has thrown no exception. 68 * @throws Throwable - if test has thrown an exception 69 * that is not caused by VME. 70 */ runMHTest(ThrowingRunnable test)71 public static Throwable runMHTest(ThrowingRunnable test) throws Throwable { 72 Throwable t = filterException(test::run, 73 CodeCacheOverflowProcessor::isThrowableCausedByVME); 74 if (t != null) { 75 System.err.printf("%nNon-critical exception caught becuse of" 76 + " code cache size is not enough to run all test cases.%n%n"); 77 } 78 return t; 79 } 80 81 // BEGIN Android-changed: these interfaces methods taken from jdk.testlibrary 82 /** 83 * Interface same as java.lang.Runnable but with 84 * method {@code run()} able to throw any Throwable. 85 */ 86 public static interface ThrowingRunnable { run()87 void run() throws Throwable; 88 } 89 90 /** 91 * Filters out an exception that may be thrown by the given 92 * test according to the given filter. 93 * 94 * @param test - method that is invoked and checked for exception. 95 * @param filter - function that checks if the thrown exception matches 96 * criteria given in the filter's implementation. 97 * @return - exception that matches the filter if it has been thrown or 98 * {@code null} otherwise. 99 * @throws Throwable - if test has thrown an exception that does not 100 * match the filter. 101 */ filterException(ThrowingRunnable test, Function<Throwable, Boolean> filter)102 public static Throwable filterException(ThrowingRunnable test, 103 Function<Throwable, Boolean> filter) throws Throwable { 104 try { 105 test.run(); 106 } catch (Throwable t) { 107 if (filter.apply(t)) { 108 return t; 109 } else { 110 throw t; 111 } 112 } 113 return null; 114 } 115 // END Android-changed: these interfaces methods taken from jdk.testlibrary 116 } 117