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