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