84 package jdk.internal.dynalink.support; |
84 package jdk.internal.dynalink.support; |
85 |
85 |
86 import java.lang.invoke.MethodHandles; |
86 import java.lang.invoke.MethodHandles; |
87 import java.lang.invoke.MethodHandles.Lookup; |
87 import java.lang.invoke.MethodHandles.Lookup; |
88 import java.lang.invoke.MethodType; |
88 import java.lang.invoke.MethodType; |
|
89 import java.lang.ref.Reference; |
89 import java.lang.ref.WeakReference; |
90 import java.lang.ref.WeakReference; |
90 import java.util.Arrays; |
91 import java.util.Arrays; |
91 import java.util.Collections; |
92 import java.util.Collections; |
92 import java.util.List; |
93 import java.util.List; |
93 import java.util.StringTokenizer; |
94 import java.util.StringTokenizer; |
101 * a previously created, at least softly reachable one exists. It also uses several different implementations of the |
102 * a previously created, at least softly reachable one exists. It also uses several different implementations of the |
102 * {@link CallSiteDescriptor} internally, and chooses the most space-efficient one based on the input. |
103 * {@link CallSiteDescriptor} internally, and chooses the most space-efficient one based on the input. |
103 * @author Attila Szegedi |
104 * @author Attila Szegedi |
104 */ |
105 */ |
105 public class CallSiteDescriptorFactory { |
106 public class CallSiteDescriptorFactory { |
106 private static final WeakHashMap<CallSiteDescriptor, WeakReference<CallSiteDescriptor>> publicDescs = |
107 private static final WeakHashMap<CallSiteDescriptor, Reference<CallSiteDescriptor>> publicDescs = |
107 new WeakHashMap<>(); |
108 new WeakHashMap<>(); |
108 |
109 |
109 |
110 |
110 private CallSiteDescriptorFactory() { |
111 private CallSiteDescriptorFactory() { |
111 } |
112 } |
132 return new LookupCallSiteDescriptor(tokenizedName, methodType, lookup); |
133 return new LookupCallSiteDescriptor(tokenizedName, methodType, lookup); |
133 } |
134 } |
134 |
135 |
135 static CallSiteDescriptor getCanonicalPublicDescriptor(final CallSiteDescriptor desc) { |
136 static CallSiteDescriptor getCanonicalPublicDescriptor(final CallSiteDescriptor desc) { |
136 synchronized(publicDescs) { |
137 synchronized(publicDescs) { |
137 final WeakReference<CallSiteDescriptor> ref = publicDescs.get(desc); |
138 final Reference<CallSiteDescriptor> ref = publicDescs.get(desc); |
138 if(ref != null) { |
139 if(ref != null) { |
139 final CallSiteDescriptor canonical = ref.get(); |
140 final CallSiteDescriptor canonical = ref.get(); |
140 if(canonical != null) { |
141 if(canonical != null) { |
141 return canonical; |
142 return canonical; |
142 } |
143 } |
143 } |
144 } |
144 publicDescs.put(desc, new WeakReference<>(desc)); |
145 publicDescs.put(desc, createReference(desc)); |
145 } |
146 } |
146 return desc; |
147 return desc; |
|
148 } |
|
149 |
|
150 /** |
|
151 * Override this to use a different kind of references for the cache |
|
152 * @param desc desc |
|
153 * @return reference |
|
154 */ |
|
155 protected static Reference<CallSiteDescriptor> createReference(final CallSiteDescriptor desc) { |
|
156 return new WeakReference<>(desc); |
147 } |
157 } |
148 |
158 |
149 private static CallSiteDescriptor createPublicCallSiteDescriptor(final String[] tokenizedName, final MethodType methodType) { |
159 private static CallSiteDescriptor createPublicCallSiteDescriptor(final String[] tokenizedName, final MethodType methodType) { |
150 final int l = tokenizedName.length; |
160 final int l = tokenizedName.length; |
151 if(l > 0 && tokenizedName[0] == "dyn") { |
161 if(l > 0 && tokenizedName[0] == "dyn") { |