1
1
/*
2
- * Copyright (c) 2008, 2018 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2008, 2019 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
46
46
* @author John Rose
47
47
*/
48
48
final class MethodTypeForm {
49
- final int [] argToSlotTable , slotToArgTable ;
50
- final long argCounts ; // packed slot & value counts
51
- final long primCounts ; // packed prim & double counts
49
+ final short parameterSlotCount ;
50
+ final short primitiveCount ;
52
51
final MethodType erasedType ; // the canonical erasure
53
52
final MethodType basicType ; // the canonical erasure, with primitives simplified
54
53
@@ -159,44 +158,33 @@ protected MethodTypeForm(MethodType erasedType) {
159
158
this .erasedType = erasedType ;
160
159
161
160
Class <?>[] ptypes = erasedType .ptypes ();
162
- int ptypeCount = ptypes .length ;
163
- int pslotCount = ptypeCount ; // temp. estimate
164
- int rtypeCount = 1 ; // temp. estimate
165
- int rslotCount = 1 ; // temp. estimate
166
-
167
- int [] argToSlotTab = null , slotToArgTab = null ;
161
+ int pslotCount = ptypes .length ;
168
162
169
163
// Walk the argument types, looking for primitives.
170
- int pac = 0 , lac = 0 , prc = 0 , lrc = 0 ;
164
+ short primitiveCount = 0 , longArgCount = 0 ;
171
165
Class <?>[] epts = ptypes ;
172
166
Class <?>[] bpts = epts ;
173
167
for (int i = 0 ; i < epts .length ; i ++) {
174
168
Class <?> pt = epts [i ];
175
169
if (pt != Object .class ) {
176
- ++pac ;
170
+ ++primitiveCount ;
177
171
Wrapper w = Wrapper .forPrimitiveType (pt );
178
- if (w .isDoubleWord ()) ++lac ;
172
+ if (w .isDoubleWord ()) ++longArgCount ;
179
173
if (w .isSubwordOrInt () && pt != int .class ) {
180
174
if (bpts == epts )
181
175
bpts = bpts .clone ();
182
176
bpts [i ] = int .class ;
183
177
}
184
178
}
185
179
}
186
- pslotCount += lac ; // #slots = #args + #longs
180
+ pslotCount += longArgCount ; // #slots = #args + #longs
187
181
Class <?> rt = erasedType .returnType ();
188
182
Class <?> bt = rt ;
189
183
if (rt != Object .class ) {
190
- ++prc ; // even void.class counts as a prim here
184
+ ++primitiveCount ; // even void.class counts as a prim here
191
185
Wrapper w = Wrapper .forPrimitiveType (rt );
192
- if (w .isDoubleWord ()) ++lrc ;
193
186
if (w .isSubwordOrInt () && rt != int .class )
194
187
bt = int .class ;
195
- // adjust #slots, #args
196
- if (rt == void .class )
197
- rtypeCount = rslotCount = 0 ;
198
- else
199
- rslotCount += lrc ;
200
188
}
201
189
if (epts == bpts && bt == rt ) {
202
190
this .basicType = erasedType ;
@@ -205,112 +193,32 @@ protected MethodTypeForm(MethodType erasedType) {
205
193
// fill in rest of data from the basic type:
206
194
MethodTypeForm that = this .basicType .form ();
207
195
assert (this != that );
208
- this .primCounts = that .primCounts ;
209
- this .argCounts = that .argCounts ;
210
- this .argToSlotTable = that .argToSlotTable ;
211
- this .slotToArgTable = that .slotToArgTable ;
196
+ this .parameterSlotCount = that .parameterSlotCount ;
197
+ this .primitiveCount = that .primitiveCount ;
212
198
this .methodHandles = null ;
213
199
this .lambdaForms = null ;
214
200
return ;
215
201
}
216
- if (lac != 0 ) {
217
- int slot = ptypeCount + lac ;
218
- slotToArgTab = new int [slot +1 ];
219
- argToSlotTab = new int [1 +ptypeCount ];
220
- argToSlotTab [0 ] = slot ; // argument "-1" is past end of slots
221
- for (int i = 0 ; i < epts .length ; i ++) {
222
- Class <?> pt = epts [i ];
223
- Wrapper w = Wrapper .forBasicType (pt );
224
- if (w .isDoubleWord ()) --slot ;
225
- --slot ;
226
- slotToArgTab [slot ] = i +1 ; // "+1" see argSlotToParameter note
227
- argToSlotTab [1 +i ] = slot ;
228
- }
229
- assert (slot == 0 ); // filled the table
230
- } else if (pac != 0 ) {
231
- // have primitives but no long primitives; share slot counts with generic
232
- assert (ptypeCount == pslotCount );
233
- MethodTypeForm that = MethodType .genericMethodType (ptypeCount ).form ();
234
- assert (this != that );
235
- slotToArgTab = that .slotToArgTable ;
236
- argToSlotTab = that .argToSlotTable ;
237
- } else {
238
- int slot = ptypeCount ; // first arg is deepest in stack
239
- slotToArgTab = new int [slot +1 ];
240
- argToSlotTab = new int [1 +ptypeCount ];
241
- argToSlotTab [0 ] = slot ; // argument "-1" is past end of slots
242
- for (int i = 0 ; i < ptypeCount ; i ++) {
243
- --slot ;
244
- slotToArgTab [slot ] = i +1 ; // "+1" see argSlotToParameter note
245
- argToSlotTab [1 +i ] = slot ;
246
- }
247
- }
248
- this .primCounts = pack (lrc , prc , lac , pac );
249
- this .argCounts = pack (rslotCount , rtypeCount , pslotCount , ptypeCount );
250
- this .argToSlotTable = argToSlotTab ;
251
- this .slotToArgTable = slotToArgTab ;
252
202
253
203
if (pslotCount >= 256 ) throw newIllegalArgumentException ("too many arguments" );
254
204
205
+ this .primitiveCount = primitiveCount ;
206
+ this .parameterSlotCount = (short )pslotCount ;
207
+
255
208
// Initialize caches, but only for basic types
256
209
assert (basicType == erasedType );
257
210
this .lambdaForms = new SoftReference [LF_LIMIT ];
258
211
this .methodHandles = new SoftReference [MH_LIMIT ];
259
212
}
260
213
261
- private static long pack (int a , int b , int c , int d ) {
262
- assert (((a |b |c |d ) & ~0xFFFF ) == 0 );
263
- long hw = ((a << 16 ) | b ), lw = ((c << 16 ) | d );
264
- return (hw << 32 ) | lw ;
265
- }
266
- private static char unpack (long packed , int word ) { // word==0 => return a, ==3 => return d
267
- assert (word <= 3 );
268
- return (char )(packed >> ((3 -word ) * 16 ));
269
- }
270
-
271
214
public int parameterCount () { // # outgoing values
272
- return unpack ( argCounts , 3 );
215
+ return erasedType . parameterCount ( );
273
216
}
274
217
public int parameterSlotCount () { // # outgoing interpreter slots
275
- return unpack (argCounts , 2 );
276
- }
277
- public int returnCount () { // = 0 (V), or 1
278
- return unpack (argCounts , 1 );
279
- }
280
- public int returnSlotCount () { // = 0 (V), 2 (J/D), or 1
281
- return unpack (argCounts , 0 );
282
- }
283
- public int primitiveParameterCount () {
284
- return unpack (primCounts , 3 );
285
- }
286
- public int longPrimitiveParameterCount () {
287
- return unpack (primCounts , 2 );
288
- }
289
- public int primitiveReturnCount () { // = 0 (obj), or 1
290
- return unpack (primCounts , 1 );
291
- }
292
- public int longPrimitiveReturnCount () { // = 1 (J/D), or 0
293
- return unpack (primCounts , 0 );
218
+ return parameterSlotCount ;
294
219
}
295
220
public boolean hasPrimitives () {
296
- return primCounts != 0 ;
297
- }
298
- public boolean hasNonVoidPrimitives () {
299
- if (primCounts == 0 ) return false ;
300
- if (primitiveParameterCount () != 0 ) return true ;
301
- return (primitiveReturnCount () != 0 && returnCount () != 0 );
302
- }
303
- public boolean hasLongPrimitives () {
304
- return (longPrimitiveParameterCount () | longPrimitiveReturnCount ()) != 0 ;
305
- }
306
- public int parameterToArgSlot (int i ) {
307
- return argToSlotTable [1 +i ];
308
- }
309
- public int argSlotToParameter (int argSlot ) {
310
- // Note: Empty slots are represented by zero in this table.
311
- // Valid arguments slots contain incremented entries, so as to be non-zero.
312
- // We return -1 the caller to mean an empty slot.
313
- return slotToArgTable [argSlot ] - 1 ;
221
+ return primitiveCount != 0 ;
314
222
}
315
223
316
224
static MethodTypeForm findForm (MethodType mt ) {
@@ -334,17 +242,17 @@ static MethodTypeForm findForm(MethodType mt) {
334
242
* (assumed to be a return type) to int if it is smaller than an int,
335
243
* or if it is void.
336
244
*/
337
- public static final int NO_CHANGE = 0 , ERASE = 1 , WRAP = 2 , UNWRAP = 3 , INTS = 4 , LONGS = 5 , RAW_RETURN = 6 ;
245
+ public static final int ERASE = 1 , WRAP = 2 , UNWRAP = 3 , INTS = 4 , LONGS = 5 , RAW_RETURN = 6 ;
338
246
339
247
/** Canonicalize the types in the given method type.
340
248
* If any types change, intern the new type, and return it.
341
249
* Otherwise return null.
342
250
*/
343
251
public static MethodType canonicalize (MethodType mt , int howRet , int howArgs ) {
344
252
Class <?>[] ptypes = mt .ptypes ();
345
- Class <?>[] ptc = MethodTypeForm . canonicalizeAll (ptypes , howArgs );
253
+ Class <?>[] ptc = canonicalizeAll (ptypes , howArgs );
346
254
Class <?> rtype = mt .returnType ();
347
- Class <?> rtc = MethodTypeForm . canonicalize (rtype , howRet );
255
+ Class <?> rtc = canonicalize (rtype , howRet );
348
256
if (ptc == null && rtc == null ) {
349
257
// It is already canonical.
350
258
return null ;
@@ -414,9 +322,8 @@ static Class<?>[] canonicalizeAll(Class<?>[] ts, int how) {
414
322
Class <?>[] cs = null ;
415
323
for (int imax = ts .length , i = 0 ; i < imax ; i ++) {
416
324
Class <?> c = canonicalize (ts [i ], how );
417
- if (c == void .class )
418
- c = null ; // a Void parameter was unwrapped to void; ignore
419
- if (c != null ) {
325
+ // Void parameters may be unwrapped to void; ignore those
326
+ if (c != null && c != void .class ) {
420
327
if (cs == null )
421
328
cs = ts .clone ();
422
329
cs [i ] = c ;
0 commit comments