@@ -53,55 +53,50 @@ public class IndyInterface {
5353 private static final long INDY_FALLBACK_CUTOFF = SystemUtil .getLongSafe ("groovy.indy.fallback.cutoff" , 100L );
5454
5555 /**
56- * flags for method and property calls
56+ * Flags for method and property calls.
5757 */
58- public static final int
59- SAFE_NAVIGATION = 1 , THIS_CALL = 2 ,
60- GROOVY_OBJECT = 4 , IMPLICIT_THIS = 8 ,
61- SPREAD_CALL = 16 , UNCACHED_CALL = 32 ;
58+ public static final int SAFE_NAVIGATION =1 , THIS_CALL =2 , GROOVY_OBJECT =4 , IMPLICIT_THIS =8 , SPREAD_CALL =16 , UNCACHED_CALL =32 ;
59+
6260 private static final MethodHandleWrapper NULL_METHOD_HANDLE_WRAPPER = MethodHandleWrapper .getNullMethodHandleWrapper ();
6361
6462 /**
65- * Enum for easy differentiation between call types
63+ * Enum for easy differentiation between call types.
6664 */
6765 public enum CallType {
6866 /**
69- * Method invocation type
67+ * Method invocation type.
7068 */
71- METHOD ("invoke" , 0 ),
69+ METHOD ("invoke" ),
7270 /**
73- * Constructor invocation type
71+ * Constructor invocation type.
7472 */
75- INIT ("init" , 1 ),
73+ INIT ("init" ),
7674 /**
77- * Get property invocation type
75+ * Get property invocation type.
7876 */
79- GET ("getProperty" , 2 ),
77+ GET ("getProperty" ),
8078 /**
81- * Set property invocation type
79+ * Set property invocation type.
8280 */
83- SET ("setProperty" , 3 ),
81+ SET ("setProperty" ),
8482 /**
85- * Cast invocation type
83+ * Cast invocation type.
8684 */
87- CAST ("cast" , 4 ),
88-
85+ CAST ("cast" ),
8986 /**
90- * call to interface method
87+ * Interface method invocation type.
9188 */
92- INTERFACE ("interface" , 5 );
89+ INTERFACE ("interface" );
9390
94- private static final Map <String , CallType > NAME_CALLTYPE_MAP =
95- Stream . of ( CallType . values ()). collect (Collectors .toMap (CallType ::getCallSiteName , Function .identity ()));
91+ private static final Map <String , CallType > NAME_CALLTYPE_MAP = Stream . of ( CallType . values ())
92+ . collect (Collectors .toUnmodifiableMap (CallType ::getCallSiteName , Function .identity ()));
9693
9794 /**
98- * The name of the call site type
95+ * The call site type name.
9996 */
10097 private final String name ;
101- private final int orderNumber ;
10298
103- CallType (String callSiteName , int orderNumber ) {
104- this .orderNumber = orderNumber ;
99+ CallType (String callSiteName ) {
105100 this .name = callSiteName ;
106101 }
107102
@@ -117,16 +112,16 @@ public static CallType fromCallSiteName(String callSiteName) {
117112 }
118113
119114 public int getOrderNumber () {
120- return this . orderNumber ;
115+ return ordinal () ;
121116 }
122117 }
123118
124119 /**
125- * Logger
120+ * Logger.
126121 */
127122 protected static final Logger LOG ;
128123 /**
129- * boolean to indicate if logging for indy is enabled
124+ * Indicates if indy logging is enabled.
130125 */
131126 protected static final boolean LOG_ENABLED ;
132127
@@ -152,6 +147,11 @@ public int getOrderNumber() {
152147 */
153148 public static final MethodHandles .Lookup LOOKUP = MethodHandles .lookup ();
154149
150+ /**
151+ * shared invoker for cached method handles
152+ */
153+ private static final MethodHandle CACHED_INVOKER = MethodHandles .exactInvoker (MethodType .methodType (Object .class , Object [].class ));
154+
155155 /**
156156 * handle for the fromCacheHandle method
157157 */
@@ -162,22 +162,15 @@ public int getOrderNumber() {
162162 */
163163 private static final MethodHandle SELECT_METHOD_HANDLE_METHOD ;
164164
165- /**
166- * shared invoker for cached method handles
167- */
168- private static final MethodHandle CACHED_INVOKER ;
169-
170165 static {
171-
172166 try {
173- MethodType handleMt = MethodType .methodType (MethodHandle .class , CacheableCallSite .class , Class .class , String .class , int .class , Boolean .class , Boolean .class , Boolean .class , Object .class , Object [].class );
174- FROM_CACHE_HANDLE_METHOD = LOOKUP .findStatic (IndyInterface .class , "fromCacheHandle" , handleMt );
175- SELECT_METHOD_HANDLE_METHOD = LOOKUP .findStatic (IndyInterface .class , "selectMethodHandle" , handleMt );
167+ MethodType mt = MethodType .methodType (MethodHandle .class , CacheableCallSite .class , Class .class , String .class , int .class , Boolean .class , Boolean .class , Boolean .class , Object .class , Object [].class );
168+
169+ FROM_CACHE_HANDLE_METHOD = LOOKUP .findStatic (IndyInterface .class , "fromCacheHandle" , mt );
170+ SELECT_METHOD_HANDLE_METHOD = LOOKUP .findStatic (IndyInterface .class , "selectMethodHandle" , mt );
176171 } catch (Exception e ) {
177172 throw new GroovyBugError (e );
178173 }
179-
180- CACHED_INVOKER = MethodHandles .exactInvoker (MethodType .methodType (Object .class , Object [].class ));
181174 }
182175
183176 protected static SwitchPoint switchPoint = new SwitchPoint ();
@@ -202,41 +195,32 @@ protected static void invalidateSwitchPoints() {
202195 }
203196
204197 /**
205- * bootstrap method for method calls from Groovy compiled code with indy
206- * enabled. This method gets a flags parameter which uses the following
207- * encoding:<ul>
208- * <li>{@value #SAFE_NAVIGATION} is the flag value for safe navigation see {@link #SAFE_NAVIGATION}</li>
209- * <li>{@value #THIS_CALL} is the flag value for a call on this see {@link #THIS_CALL}</li>
210- * </ul>
198+ * Bootstrap method for method calls from Groovy-compiled code with indy.
211199 *
212200 * @param caller - the caller
213- * @param callType - the type of the call
214- * @param type - the call site type
201+ * @param callType - the type of call
202+ * @param type - the parameter(s) and return type specification
215203 * @param name - the real method name
216- * @param flags - call flags
217- * @return the produced CallSite
218- * @since Groovy 2.1.0
204+ * @param flags - call flags <ul>
205+ * <li>{@value #SAFE_NAVIGATION} is the flag value for safe navigation; see {@link #SAFE_NAVIGATION}</li>
206+ * <li>{@value #THIS_CALL} is the flag value for a call on this; see {@link #THIS_CALL}</li>
207+ * <li>{@value #SPREAD_CALL} is the flag value for a spread call; see {@link #SPREAD_CALL}</li>
208+ * </ul>
209+ * @since 2.1.0
219210 */
220- public static CallSite bootstrap (MethodHandles .Lookup caller , String callType , MethodType type , String name , int flags ) {
211+ public static CallSite bootstrap (final MethodHandles .Lookup caller , final String callType , final MethodType type , final String name , final int flags ) {
221212 CallType ct = CallType .fromCallSiteName (callType );
222213 if (null == ct ) throw new GroovyBugError ("Unknown call type: " + callType );
223214
224215 int callID = ct .getOrderNumber ();
225- boolean safe = (flags & SAFE_NAVIGATION ) != 0 ;
226- boolean thisCall = (flags & THIS_CALL ) != 0 ;
227- boolean spreadCall = (flags & SPREAD_CALL ) != 0 ;
216+ boolean safe = (flags & SAFE_NAVIGATION ) != 0 ;
217+ boolean thisCall = (flags & THIS_CALL ) != 0 ;
218+ boolean spreadCall = (flags & SPREAD_CALL ) != 0 ;
228219
229- return realBootstrap (caller , name , callID , type , safe , thisCall , spreadCall );
230- }
231-
232- /**
233- * backing bootstrap method with all parameters
234- */
235- private static CallSite realBootstrap (MethodHandles .Lookup caller , String name , int callID , MethodType type , boolean safe , boolean thisCall , boolean spreadCall ) {
236220 // first produce a dummy call site, since indy doesn't give the runtime types;
237221 // the site then changes to the target when INDY_OPTIMIZE_THRESHOLD is reached
238222 // that does the method selection including the direct call to the real method
239- CacheableCallSite mc = new CacheableCallSite (type , caller );
223+ var mc = new CacheableCallSite (type , caller );
240224 Class <?> sender = caller .lookupClass ();
241225 if (thisCall ) {
242226 while (GeneratedClosure .class .isAssignableFrom (sender )) {
@@ -252,40 +236,45 @@ private static CallSite realBootstrap(MethodHandles.Lookup caller, String name,
252236 }
253237
254238 /**
255- * Makes a fallback method for an invalidated method selection
239+ * Makes a fallback method for an invalidated method selection.
256240 */
257241 protected static MethodHandle makeFallBack (MutableCallSite mc , Class <?> sender , String name , int callID , MethodType type , boolean safeNavigation , boolean thisCall , boolean spreadCall ) {
258242 return makeBootHandle (mc , sender , name , callID , type , safeNavigation , thisCall , spreadCall , SELECT_METHOD_HANDLE_METHOD );
259243 }
260244
261245 /**
262- * Makes an adapter method for method selection, i.e. get the cached methodHandle (fast path) or fallback
246+ * Makes an adapter method for method selection, i.e. get the cached method handle (fast path) or fallback.
263247 */
264248 private static MethodHandle makeAdapter (MutableCallSite mc , Class <?> sender , String name , int callID , MethodType type , boolean safeNavigation , boolean thisCall , boolean spreadCall ) {
265249 return makeBootHandle (mc , sender , name , callID , type , safeNavigation , thisCall , spreadCall , FROM_CACHE_HANDLE_METHOD );
266250 }
267251
268- private static MethodHandle makeBootHandle (MutableCallSite mc , Class <?> sender , String name , int callID , MethodType type , boolean safeNavigation , boolean thisCall , boolean spreadCall , MethodHandle handleReturningMh ) {
269- // Step 1: bind site-constant arguments (incl dummy receiver marker)
270- MethodHandle fromCacheBound = MethodHandles .insertArguments (
271- handleReturningMh ,
272- 0 , mc , sender , name , callID ,
273- safeNavigation , thisCall , spreadCall ,
274- /*dummy receiver*/ 1
252+ private static MethodHandle makeBootHandle (MutableCallSite mc , Class <?> sender , String name , int callID , MethodType type , boolean safeNavigation , boolean thisCall , boolean spreadCall , MethodHandle fromCacheOrSelectMethod ) {
253+ final Object dummyReceiver = 1 ;
254+ // Step 1: bind site-constant arguments
255+ MethodHandle boundHandle = MethodHandles .insertArguments (
256+ fromCacheOrSelectMethod ,
257+ 0 , // insert start index
258+ mc ,
259+ sender ,
260+ name ,
261+ callID ,
262+ safeNavigation ,
263+ thisCall ,
264+ spreadCall ,
265+ dummyReceiver
275266 );
276- // fromCacheBound : (Object receiver, Object[] args ) → MethodHandle
267+ // boundHandle : (Object receiver, Object[] arguments ) → MethodHandle
277268
278269 // Step 2: fold into the shared invoker (MethodHandle, Object[]) → Object
279270 MethodHandle bootHandle = MethodHandles .foldArguments (
280271 CACHED_INVOKER , // (MethodHandle, Object[]) → Object
281- fromCacheBound // (Object, Object[]) → MethodHandle
272+ boundHandle // (Object, Object[]) → MethodHandle
282273 );
283- // bootHandle: (Object receiver, Object[] args ) → Object
274+ // bootHandle: (Object receiver, Object[] arguments ) → Object
284275
285- // Step 3: adapt to callsite type: collect all arguments into Object[] and then asType
286- bootHandle = bootHandle
287- .asCollector (Object [].class , type .parameterCount ())
288- .asType (type );
276+ // Step 3: adapt to call site type: collect all arguments into Object[] and then asType
277+ bootHandle = bootHandle .asCollector (Object [].class , type .parameterCount ()).asType (type );
289278
290279 return bootHandle ;
291280 }
0 commit comments