85 |
85 |
86 import java.io.Serializable; |
86 import java.io.Serializable; |
87 import java.util.Collections; |
87 import java.util.Collections; |
88 import java.util.LinkedList; |
88 import java.util.LinkedList; |
89 import java.util.List; |
89 import java.util.List; |
|
90 import java.util.Objects; |
90 import jdk.internal.dynalink.linker.GuardedInvocation; |
91 import jdk.internal.dynalink.linker.GuardedInvocation; |
91 import jdk.internal.dynalink.linker.GuardingDynamicLinker; |
92 import jdk.internal.dynalink.linker.GuardingDynamicLinker; |
92 import jdk.internal.dynalink.linker.LinkRequest; |
93 import jdk.internal.dynalink.linker.LinkRequest; |
93 import jdk.internal.dynalink.linker.LinkerServices; |
94 import jdk.internal.dynalink.linker.LinkerServices; |
94 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; |
95 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; |
95 |
96 |
96 /** |
97 /** |
97 * A composite type-based guarding dynamic linker. When a receiver of a not yet seen class is encountered, all linkers |
98 * A composite type-based guarding dynamic linker. When a receiver of a not yet |
98 * are queried sequentially on their {@link TypeBasedGuardingDynamicLinker#canLinkType(Class)} method. The linkers |
99 * seen class is encountered, all linkers are queried sequentially on their |
99 * returning true are then bound to the class, and next time a receiver of same type is encountered, the linking is |
100 * {@link TypeBasedGuardingDynamicLinker#canLinkType(Class)} method. The linkers |
100 * delegated to those linkers only, speeding up dispatch. |
101 * returning true are then bound to the class, and next time a receiver of same |
|
102 * type is encountered, the linking is delegated to those linkers only, speeding |
|
103 * up dispatch. |
101 */ |
104 */ |
102 public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardingDynamicLinker, Serializable { |
105 public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardingDynamicLinker, Serializable { |
103 private static final long serialVersionUID = 1L; |
106 private static final long serialVersionUID = 1L; |
104 |
107 |
105 // Using a separate static class instance so there's no strong reference from the class value back to the composite |
108 // Using a separate static class instance so there's no strong reference from the class value back to the composite |
147 |
150 |
148 /** |
151 /** |
149 * Creates a new composite type-based linker. |
152 * Creates a new composite type-based linker. |
150 * |
153 * |
151 * @param linkers the component linkers |
154 * @param linkers the component linkers |
|
155 * @throws NullPointerException if {@code linkers} or any of its elements |
|
156 * are null. |
152 */ |
157 */ |
153 public CompositeTypeBasedGuardingDynamicLinker(final Iterable<? extends TypeBasedGuardingDynamicLinker> linkers) { |
158 public CompositeTypeBasedGuardingDynamicLinker(final Iterable<? extends TypeBasedGuardingDynamicLinker> linkers) { |
154 final List<TypeBasedGuardingDynamicLinker> l = new LinkedList<>(); |
159 final List<TypeBasedGuardingDynamicLinker> l = new LinkedList<>(); |
155 for(final TypeBasedGuardingDynamicLinker linker: linkers) { |
160 for(final TypeBasedGuardingDynamicLinker linker: linkers) { |
156 l.add(linker); |
161 l.add(Objects.requireNonNull(linker)); |
157 } |
162 } |
158 this.classToLinker = new ClassToLinker(l.toArray(new TypeBasedGuardingDynamicLinker[l.size()])); |
163 this.classToLinker = new ClassToLinker(l.toArray(new TypeBasedGuardingDynamicLinker[l.size()])); |
159 } |
164 } |
160 |
165 |
|
166 /** |
|
167 * Returns true if any of the composite linkers return true from |
|
168 * {@link TypeBasedGuardingDynamicLinker#canLinkType(Class)} for the type. |
|
169 * @param type the type to link |
|
170 * @return true if any of the composite linkers can link calls for the |
|
171 * receiver type, false otherwise. |
|
172 */ |
161 @Override |
173 @Override |
162 public boolean canLinkType(final Class<?> type) { |
174 public boolean canLinkType(final Class<?> type) { |
163 return !classToLinker.get(type).isEmpty(); |
175 return !classToLinker.get(type).isEmpty(); |
164 } |
176 } |
165 |
177 |
178 } |
190 } |
179 return null; |
191 return null; |
180 } |
192 } |
181 |
193 |
182 /** |
194 /** |
183 * Optimizes a list of type-based linkers. If a group of adjacent linkers in the list all implement |
195 * Optimizes a list of type-based linkers. If a group of adjacent linkers in |
184 * {@link TypeBasedGuardingDynamicLinker}, they will be replaced with a single instance of |
196 * the list all implement {@link TypeBasedGuardingDynamicLinker}, they will |
|
197 * be replaced with a single instance of |
185 * {@link CompositeTypeBasedGuardingDynamicLinker} that contains them. |
198 * {@link CompositeTypeBasedGuardingDynamicLinker} that contains them. |
186 * |
199 * |
187 * @param linkers the list of linkers to optimize |
200 * @param linkers the list of linkers to optimize |
188 * @return the optimized list |
201 * @return the optimized list |
|
202 * @throws NullPointerException if {@code linkers} or any of its elements |
|
203 * are null. |
189 */ |
204 */ |
190 public static List<GuardingDynamicLinker> optimize(final Iterable<? extends GuardingDynamicLinker> linkers) { |
205 public static List<GuardingDynamicLinker> optimize(final Iterable<? extends GuardingDynamicLinker> linkers) { |
191 final List<GuardingDynamicLinker> llinkers = new LinkedList<>(); |
206 final List<GuardingDynamicLinker> llinkers = new LinkedList<>(); |
192 final List<TypeBasedGuardingDynamicLinker> tblinkers = new LinkedList<>(); |
207 final List<TypeBasedGuardingDynamicLinker> tblinkers = new LinkedList<>(); |
193 for(final GuardingDynamicLinker linker: linkers) { |
208 for(final GuardingDynamicLinker linker: linkers) { |
|
209 Objects.requireNonNull(linker); |
194 if(linker instanceof TypeBasedGuardingDynamicLinker) { |
210 if(linker instanceof TypeBasedGuardingDynamicLinker) { |
195 tblinkers.add((TypeBasedGuardingDynamicLinker)linker); |
211 tblinkers.add((TypeBasedGuardingDynamicLinker)linker); |
196 } else { |
212 } else { |
197 addTypeBased(llinkers, tblinkers); |
213 addTypeBased(llinkers, tblinkers); |
198 llinkers.add(linker); |
214 llinkers.add(linker); |