1 /* 2 * Copyright (c) 2005, 2015, 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 jdk.test.lib.jittester; 25 26 import java.util.ArrayList; 27 import java.util.Collection; 28 import java.util.HashMap; 29 import java.util.Map; 30 import java.util.Stack; 31 import jdk.test.lib.jittester.types.TypeKlass; 32 33 34 public class SymbolTable { 35 36 private static final Stack<HashMap<Type, ArrayList<Symbol>>> SYMBOL_STACK 37 = new Stack<>(); 38 private static int VARIABLE_NUMBER = 0; 39 private static int FUNCTION_NUMBER = 0; 40 41 private static void initExternalSymbols() { 42 43 String classList = ProductionParams.addExternalSymbols.value(); 44 if (classList.equals("all")) { 45 for (Type type : TypeList.getReferenceTypes()) { 46 type.exportSymbols(); 47 } 48 } else { 49 String[] splittedList = classList.split(","); 50 for (Type type : TypeList.getReferenceTypes()) { 51 for (String str : splittedList) { 52 if (type.getName().equals(str)) { 53 type.exportSymbols(); 54 break; 55 } 56 } 57 } 58 } 59 60 } 61 62 static { 63 SYMBOL_STACK.push(new HashMap<>()); 64 if (!ProductionParams.disableExternalSymbols.value()) { 65 initExternalSymbols(); 66 } 67 } 68 69 public static void add(Symbol symbol) { 70 HashMap<Type, ArrayList<Symbol>> vars = SYMBOL_STACK.peek(); 71 if (!vars.containsKey(symbol.type)) { 72 vars.put(symbol.type, new ArrayList<>()); 73 } 74 vars.get(symbol.type).add(symbol); 75 } 76 77 public static void remove(Symbol symbol) { 78 HashMap<Type, ArrayList<Symbol>> vars = SYMBOL_STACK.peek(); 79 if (vars.containsKey(symbol.type)) { 80 ArrayList<Symbol> symbolsOfType = vars.get(symbol.type); 81 symbolsOfType.remove(symbol); 82 if (symbolsOfType.isEmpty()) { 83 vars.remove(symbol.type); 84 } 85 } 86 } 87 88 protected static Collection<Symbol> get(Type type) { 89 HashMap<Type, ArrayList<Symbol>> vars = SYMBOL_STACK.peek(); 90 if (vars.containsKey(type)) { 91 return vars.get(type); 92 } 93 return new ArrayList<>(); 94 } 95 96 public static Collection<Symbol> get(Type type, Class<?> classToCheck) { 97 HashMap<Type, ArrayList<Symbol>> vars = SYMBOL_STACK.peek(); 98 if (vars.containsKey(type)) { 99 ArrayList<Symbol> result = new ArrayList<>(); 100 for (Symbol symbol : vars.get(type)) { 101 if (classToCheck.isInstance(symbol)) { 102 result.add(symbol); 103 } 104 } 105 return result; 106 } 107 return new ArrayList<>(); 108 } 109 110 protected static Collection<Symbol> get(TypeKlass typeKlass, Type type, 111 Class<?> classToCheck) { 112 HashMap<Type, ArrayList<Symbol>> vars = SYMBOL_STACK.peek(); 113 if (vars.containsKey(type)) { 114 ArrayList<Symbol> result = new ArrayList<>(); 115 for (Symbol symbol : vars.get(type)) { 116 if (classToCheck.isInstance(symbol) && typeKlass.equals(symbol.klass)) { 117 result.add(symbol); 118 } 119 } 120 return result; 121 } 122 return new ArrayList<>(); 123 } 124 125 protected static HashMap<Type, ArrayList<Symbol>> getAll() { 126 return SYMBOL_STACK.peek(); 127 } 128 129 protected static HashMap<Type, ArrayList<Symbol>> getAll(Class<?> classToCheck) { 130 HashMap<Type, ArrayList<Symbol>> result = new HashMap<>(); 131 132 for (Type type : SYMBOL_STACK.peek().keySet()) { 133 ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type); 134 for (Symbol symbol : symbolsOfType) { 135 if (classToCheck.isInstance(symbol)) { 136 if (!result.containsKey(type)) { 137 result.put(type, new ArrayList<>()); 138 } 139 result.get(type).add(symbol); 140 } 141 } 142 } 143 144 return result; 145 } 146 147 protected static HashMap<Type, ArrayList<Symbol>> getAll(TypeKlass typeKlass, Class<?> classToCheck) { 148 HashMap<Type, ArrayList<Symbol>> result = new HashMap<>(); 149 150 for (Type type : SYMBOL_STACK.peek().keySet()) { 151 ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type); 152 for (Symbol symbol : symbolsOfType) { 153 if (classToCheck.isInstance(symbol) && typeKlass.equals(symbol.klass)) { 154 if (!result.containsKey(type)) { 155 result.put(type, new ArrayList<>()); 156 } 157 result.get(type).add(symbol); 158 } 159 } 160 } 161 162 return result; 163 } 164 165 protected static ArrayList<Symbol> getAllCombined() { 166 ArrayList<Symbol> result = new ArrayList<>(); 167 for (Type type : SYMBOL_STACK.peek().keySet()) { 168 ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type); 169 for (Symbol symbol : symbolsOfType) { 170 result.add(symbol); 171 } 172 } 173 174 return result; 175 } 176 177 public static ArrayList<Symbol> getAllCombined(Class<?> classToCheck) { 178 ArrayList<Symbol> result = new ArrayList<>(); 179 for (Type type : SYMBOL_STACK.peek().keySet()) { 180 ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type); 181 for (Symbol symbol : symbolsOfType) { 182 if (classToCheck.isInstance(symbol)) { 183 result.add(symbol); 184 } 185 } 186 } 187 188 return result; 189 } 190 191 public static ArrayList<Symbol> getAllCombined(TypeKlass typeKlass, Class<?> classToCheck) { 192 ArrayList<Symbol> result = new ArrayList<>(); 193 for (Type type : SYMBOL_STACK.peek().keySet()) { 194 ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type); 195 for (Symbol symbol : symbolsOfType) { 196 if (classToCheck.isInstance(symbol) && typeKlass.equals(symbol.klass)) { 197 result.add(symbol); 198 } 199 } 200 } 201 202 return result; 203 } 204 205 public static ArrayList<Symbol> getAllCombined(TypeKlass typeKlass) { 206 ArrayList<Symbol> result = new ArrayList<>(); 207 for (Type t : SYMBOL_STACK.peek().keySet()) { 208 ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(t); 209 for (Symbol symbol : symbolsOfType) { 210 if (typeKlass.equals(symbol.klass)) { 211 result.add(symbol); 212 } 213 } 214 } 215 216 return result; 217 } 218 219 protected static ArrayList<Symbol> getAllCombined(String name, Class<?> classToCheck) { 220 ArrayList<Symbol> result = new ArrayList<>(); 221 for (Type type : SYMBOL_STACK.peek().keySet()) { 222 ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type); 223 for (Symbol symbol : symbolsOfType) { 224 if (classToCheck.isInstance(symbol) && name.equals(symbol.name)) { 225 result.add(symbol); 226 } 227 } 228 } 229 230 return result; 231 } 232 233 public static Symbol get(String name, Class<?> classToCheck) { 234 for (Type type : SYMBOL_STACK.peek().keySet()) { 235 ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type); 236 for (Symbol symbol : symbolsOfType) { 237 if (classToCheck.isInstance(symbol) && name.equals(symbol.name)) { 238 return symbol; 239 } 240 } 241 } 242 return null; 243 } 244 245 public static void removeAll() { 246 SYMBOL_STACK.clear(); 247 SYMBOL_STACK.push(new HashMap<>()); 248 VARIABLE_NUMBER = 0; 249 FUNCTION_NUMBER = 0; 250 if (!ProductionParams.disableExternalSymbols.value()) { 251 initExternalSymbols(); 252 } 253 } 254 255 public static void push() { 256 // Do deep cloning.. 257 HashMap<Type, ArrayList<Symbol>> prev = SYMBOL_STACK.peek(); 258 HashMap<Type, ArrayList<Symbol>> top = new HashMap<>(prev.size()); 259 SYMBOL_STACK.push(top); 260 for (Map.Entry<Type, ArrayList<Symbol>> entry : prev.entrySet()) { 261 ArrayList<Symbol> prevArray = entry.getValue(); 262 ArrayList<Symbol> topArray = new ArrayList<>(prevArray.size()); 263 top.put(entry.getKey(), topArray); 264 for (Symbol symbol : prevArray) { 265 topArray.add(symbol.copy()); 266 } 267 } 268 } 269 270 public static void merge() { 271 // Merging means moving element at the top of stack one step down, while removing the 272 // previous element. 273 HashMap<Type, ArrayList<Symbol>> top = SYMBOL_STACK.pop(); 274 SYMBOL_STACK.pop(); 275 SYMBOL_STACK.push(top); 276 } 277 278 public static void pop() { 279 SYMBOL_STACK.pop(); 280 } 281 282 public static int getNextVariableNumber() { 283 return ++VARIABLE_NUMBER; 284 } 285 286 public static int getNextFunctionNumber() { 287 return ++FUNCTION_NUMBER; 288 } 289 290 @Override 291 public String toString() { 292 return SYMBOL_STACK.toString(); 293 } 294 }