1 /* 2 * Copyright (c) 2017, 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 24 25 package jdk.tools.jaotc; 26 27 import java.util.HashMap; 28 import java.util.HashSet; 29 import java.util.Set; 30 31 import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin.DynamicTypeStore; 32 33 import jdk.vm.ci.hotspot.HotSpotConstantPool; 34 import jdk.vm.ci.hotspot.HotSpotConstantPoolObject; 35 import jdk.vm.ci.hotspot.HotSpotObjectConstant; 36 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; 37 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; 38 import jdk.vm.ci.meta.JavaConstant; 39 40 final class AOTDynamicTypeStore implements DynamicTypeStore { 41 42 public static class Location { 43 private HotSpotResolvedObjectType holder; 44 private int cpi; 45 46 Location(HotSpotResolvedObjectType holder, int cpi) { 47 this.holder = holder; 48 this.cpi = cpi; 49 } 50 51 public HotSpotResolvedObjectType getHolder() { 52 return holder; 53 } 54 55 public int getCpi() { 56 return cpi; 57 } 58 59 @Override 60 public String toString() { 61 return getHolder().getName() + "@" + cpi; 62 } 63 64 @Override 65 public int hashCode() { 66 return holder.hashCode() + getClass().hashCode() + cpi; 67 } 68 69 @Override 70 public boolean equals(Object o) { 71 if (this == o) { 72 return true; 73 } 74 if (getClass() != o.getClass()) { 75 return false; 76 } 77 Location l = (Location) o; 78 return cpi == l.cpi && holder.equals(l.holder); 79 } 80 } 81 82 public static class AdapterLocation extends Location { 83 private int methodId; 84 85 AdapterLocation(HotSpotResolvedObjectType holder, int cpi, int methodId) { 86 super(holder, cpi); 87 this.methodId = methodId; 88 } 89 90 public int getMethodId() { 91 return methodId; 92 } 93 94 @Override 95 public String toString() { 96 return "adapter:" + methodId + "@" + super.toString(); 97 } 98 } 99 100 public static class AppendixLocation extends Location { 101 AppendixLocation(HotSpotResolvedObjectType holder, int cpi) { 102 super(holder, cpi); 103 } 104 105 @Override 106 public String toString() { 107 return "appendix@" + super.toString(); 108 } 109 } 110 111 private HashMap<HotSpotResolvedObjectType, HashSet<Location>> typeMap = new HashMap<>(); 112 private HashMap<HotSpotResolvedObjectType, HashSet<HotSpotResolvedObjectType>> holderMap = new HashMap<>(); 113 114 public Set<HotSpotResolvedObjectType> getDynamicTypes() { 115 synchronized (typeMap) { 116 return typeMap.keySet(); 117 } 118 } 119 120 public Set<HotSpotResolvedObjectType> getDynamicHolders() { 121 synchronized (holderMap) { 122 return holderMap.keySet(); 123 } 124 } 125 126 @Override 127 public void recordAdapter(int opcode, HotSpotResolvedObjectType holder, int index, HotSpotResolvedJavaMethod adapter) { 128 int cpi = ((HotSpotConstantPool) holder.getConstantPool()).rawIndexToConstantPoolIndex(index, opcode); 129 int methodId = adapter.methodIdnum(); 130 HotSpotResolvedObjectType adapterType = adapter.getDeclaringClass(); 131 recordDynamicTypeLocation(new AdapterLocation(holder, cpi, methodId), adapterType); 132 } 133 134 @Override 135 public JavaConstant recordAppendix(int opcode, HotSpotResolvedObjectType holder, int index, JavaConstant appendix) { 136 int cpi = ((HotSpotConstantPool) holder.getConstantPool()).rawIndexToConstantPoolIndex(index, opcode); 137 HotSpotResolvedObjectType appendixType = ((HotSpotObjectConstant) appendix).getType(); 138 recordDynamicTypeLocation(new AppendixLocation(holder, cpi), appendixType); 139 // Make the constant locatable 140 return HotSpotConstantPoolObject.forObject(holder, cpi, appendix); 141 } 142 143 private static <T> void recordDynamicMapValue(HashMap<HotSpotResolvedObjectType, HashSet<T>> map, HotSpotResolvedObjectType type, T v) { 144 synchronized (map) { 145 HashSet<T> set = map.get(type); 146 if (set == null) { 147 set = new HashSet<>(); 148 map.put(type, set); 149 } 150 set.add(v); 151 } 152 } 153 154 private void recordDynamicTypeLocation(Location l, HotSpotResolvedObjectType type) { 155 recordDynamicMapValue(typeMap, type, l); 156 HotSpotResolvedObjectType holder = l.getHolder(); 157 recordDynamicMapValue(holderMap, holder, type); 158 } 159 160 public Set<Location> getDynamicClassLocationsForType(HotSpotResolvedObjectType type) { 161 synchronized (typeMap) { 162 return typeMap.get(type); 163 } 164 } 165 166 public Set<HotSpotResolvedObjectType> getDynamicTypesForHolder(HotSpotResolvedObjectType holder) { 167 synchronized (holderMap) { 168 return holderMap.get(holder); 169 } 170 } 171 172 }