1 /* 2 * Copyright (c) 2013, 2018, 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 package vm.compiler.complog.uninit; 24 25 import java.util.*; 26 import java.util.regex.*; 27 import java.io.*; 28 29 import nsk.share.TestFailure; 30 import vm.compiler.complog.share.LogCompilationParser; 31 32 /** 33 * Parser that finds uninitialized traps for each method and throws 34 * and exception if there are more then 1 uninitialized trap for at least 1 method. 35 * 36 * Parser supports following options: 37 * <ul> 38 * <li>-classFilter=<comma separated list> - list of classes for which uncommon traps will be checked. If option is not presented or list is empty then all uncommon traps for all classes will be checked. 39 * <li>-methodFilter=<comma separated list> - list of methods for which uncommon traps will be checked. If option is not presented or list is empty then all uncommon traps for all methods will be checked. 40 * </ul> 41 * If compilation log contains uncommon trap with reason uninialized that was fired for method M in class K, then it will be checked only if classFilter contains K and methodFilter contains M. 42 */ 43 public class UninitializedTrapCounter extends LogCompilationParser { 44 private Map<String,Integer> methods = new LinkedHashMap<String,Integer>(); 45 46 private static final String JVMS_ELEMENT = "<jvms [^>]*>"; 47 private static final String METHOD_INFO = "method='(([^ ']+) ([^ ']+) [^']+)'.*uninitialized_traps='([0-9]+)'"; 48 private static final String CLASS_FILTER = "-classFilter=([^ ]+)"; 49 private static final String METHOD_FILTER = "-methodFilter=([^ ]+)"; 50 private static Pattern pattern = Pattern.compile(METHOD_INFO); 51 52 private List<String> classFilter = new ArrayList<String>(); 53 private List<String> methodFilter = new ArrayList<String>(); 54 setOptions(String optionString)55 public void setOptions(String optionString) { 56 if(optionString == null) return; 57 Matcher methodFilterMatcher = Pattern.compile(METHOD_FILTER).matcher(optionString); 58 Matcher classFilterMatcher = Pattern.compile(CLASS_FILTER).matcher(optionString); 59 if(methodFilterMatcher.find()) { 60 methodFilter = Arrays.asList(methodFilterMatcher.group(1).split(",")); 61 } 62 if(classFilterMatcher.find()) { 63 classFilter = Arrays.asList(classFilterMatcher.group(1).split(",")); 64 } 65 } 66 67 /** 68 * Find uninitialized traps count. 69 */ parse(File logFile)70 public void parse(File logFile) throws Throwable { 71 Scanner scanner = new Scanner(logFile); 72 String jvms = scanner.findWithinHorizon(JVMS_ELEMENT,0); 73 while(jvms != null) { 74 parseJVMSElement(jvms); 75 jvms = scanner.findWithinHorizon(JVMS_ELEMENT,0); 76 } 77 78 boolean failed = false; 79 for(Map.Entry<String,Integer> method : methods.entrySet()) { 80 if(method.getValue() > 1) { 81 failed = true; 82 log.error(method.getValue() + 83 " uninitizlied traps found for method '" + 84 method.getKey() + "'."); 85 86 } 87 } 88 if(failed) { 89 throw new TestFailure("More than 1 uncommon trap with reason 'uninitialized'"+ 90 " occurred at least for 1 method."); 91 } 92 } 93 parseJVMSElement(String jvms)94 private void parseJVMSElement(String jvms) { 95 Matcher matcher = pattern.matcher(jvms); 96 if(!matcher.find()) return; 97 98 String methodID = matcher.group(1); 99 String trapsCountStr = matcher.group(4); 100 Integer trapsCount = 0; 101 Integer oldTrapsCount = 0; 102 String className = matcher.group(2); 103 String methodName = matcher.group(3); 104 105 if((classFilter.size() > 0 && !findMatches(classFilter,className)) || 106 (methodFilter.size() > 0 && !findMatches(methodFilter,methodName))) { 107 //filtering out uncommon trap we are not interested in 108 return; 109 } 110 111 try { 112 trapsCount = Integer.valueOf(trapsCountStr); 113 } catch (NumberFormatException nfe) { 114 trapsCount = 0; 115 } 116 117 oldTrapsCount = methods.get(methodID); 118 if(oldTrapsCount == null) oldTrapsCount = -1; 119 120 methods.put(methodID, Math.max(trapsCount, oldTrapsCount)); 121 } 122 findMatches(List<String> patterns, String str)123 private static boolean findMatches(List<String> patterns, String str) { 124 for(String pattern : patterns) { 125 if(Pattern.matches(pattern,str)) { 126 return true; 127 } 128 } 129 return false; 130 } 131 132 } 133