126 final boolean forceInline;
127 final MethodHandle customized;
128 @Stable final Name[] names;
129 final Kind kind;
130 MemberName vmentry; // low-level behavior, or null if not yet prepared
131 private boolean isCompiled;
132
133 // Either a LambdaForm cache (managed by LambdaFormEditor) or a link to uncustomized version (for customized LF)
134 volatile Object transformCache;
135
136 public static final int VOID_RESULT = -1, LAST_RESULT = -2;
137
138 enum BasicType {
139 L_TYPE('L', Object.class, Wrapper.OBJECT), // all reference types
140 I_TYPE('I', int.class, Wrapper.INT),
141 J_TYPE('J', long.class, Wrapper.LONG),
142 F_TYPE('F', float.class, Wrapper.FLOAT),
143 D_TYPE('D', double.class, Wrapper.DOUBLE), // all primitive types
144 V_TYPE('V', void.class, Wrapper.VOID); // not valid in all contexts
145
146 static final BasicType[] ALL_TYPES = BasicType.values();
147 static final BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1);
148
149 static final int ARG_TYPE_LIMIT = ARG_TYPES.length;
150 static final int TYPE_LIMIT = ALL_TYPES.length;
151
152 final char btChar;
153 final Class<?> btClass;
154 final Wrapper btWrapper;
155
156 private BasicType(char btChar, Class<?> btClass, Wrapper wrapper) {
157 this.btChar = btChar;
158 this.btClass = btClass;
159 this.btWrapper = wrapper;
160 }
161
162 char basicTypeChar() {
163 return btChar;
164 }
165 Class<?> basicTypeClass() {
166 return btClass;
167 }
168 Wrapper basicTypeWrapper() {
169 return btWrapper;
170 }
171 int basicTypeSlots() {
662 int arity = sig.indexOf('_');
663 if (arity < 0) return false; // must be of the form *_*
664 int siglen = sig.length();
665 if (siglen != arity + 2) return false; // *_X
666 for (int i = 0; i < siglen; i++) {
667 if (i == arity) continue; // skip '_'
668 char c = sig.charAt(i);
669 if (c == 'V')
670 return (i == siglen - 1 && arity == siglen - 2);
671 if (!isArgBasicTypeChar(c)) return false; // must be [LIJFD]
672 }
673 return true; // [LIJFD]*_[LIJFDV]
674 }
675 static MethodType signatureType(String sig) {
676 Class<?>[] ptypes = new Class<?>[signatureArity(sig)];
677 for (int i = 0; i < ptypes.length; i++)
678 ptypes[i] = basicType(sig.charAt(i)).btClass;
679 Class<?> rtype = signatureReturn(sig).btClass;
680 return MethodType.makeImpl(rtype, ptypes, true);
681 }
682
683 /**
684 * Check if i-th name is a call to MethodHandleImpl.selectAlternative.
685 */
686 boolean isSelectAlternative(int pos) {
687 // selectAlternative idiom:
688 // t_{n}:L=MethodHandleImpl.selectAlternative(...)
689 // t_{n+1}:?=MethodHandle.invokeBasic(t_{n}, ...)
690 if (pos+1 >= names.length) return false;
691 Name name0 = names[pos];
692 Name name1 = names[pos+1];
693 return name0.refersTo(MethodHandleImpl.class, "selectAlternative") &&
694 name1.isInvokeBasic() &&
695 name1.lastUseIndex(name0) == 0 && // t_{n+1}:?=MethodHandle.invokeBasic(t_{n}, ...)
696 lastUseIndex(name0) == pos+1; // t_{n} is local: used only in t_{n+1}
697 }
698
699 private boolean isMatchingIdiom(int pos, String idiomName, int nArgs) {
700 if (pos+2 >= names.length) return false;
701 Name name0 = names[pos];
1274 return this.equals(constantZero(returnType()));
1275 }
1276
1277 public MethodHandleImpl.Intrinsic intrinsicName() {
1278 return intrinsicName;
1279 }
1280 }
1281
1282 public static String basicTypeSignature(MethodType type) {
1283 int params = type.parameterCount();
1284 char[] sig = new char[params + 2];
1285 int sigp = 0;
1286 while (sigp < params) {
1287 sig[sigp] = basicTypeChar(type.parameterType(sigp++));
1288 }
1289 sig[sigp++] = '_';
1290 sig[sigp++] = basicTypeChar(type.returnType());
1291 assert(sigp == sig.length);
1292 return String.valueOf(sig);
1293 }
1294 public static String shortenSignature(String signature) {
1295 // Hack to make signatures more readable when they show up in method names.
1296 final int NO_CHAR = -1, MIN_RUN = 3;
1297 int c0, c1 = NO_CHAR, c1reps = 0;
1298 StringBuilder buf = null;
1299 int len = signature.length();
1300 if (len < MIN_RUN) return signature;
1301 for (int i = 0; i <= len; i++) {
1302 // shift in the next char:
1303 c0 = c1; c1 = (i == len ? NO_CHAR : signature.charAt(i));
1304 if (c1 == c0) { ++c1reps; continue; }
1305 // shift in the next count:
1306 int c0reps = c1reps; c1reps = 1;
1307 // end of a character run
1308 if (c0reps < MIN_RUN) {
1309 if (buf != null) {
1310 while (--c0reps >= 0)
1311 buf.append((char)c0);
1312 }
1313 continue;
1314 }
1315 // found three or more in a row
1316 if (buf == null)
1317 buf = new StringBuilder().append(signature, 0, i - c0reps);
1318 buf.append((char)c0).append(c0reps);
1319 }
1320 return (buf == null) ? signature : buf.toString();
1321 }
1325 @Stable short index;
1326 final NamedFunction function;
1327 final Object constraint; // additional type information, if not null
1328 @Stable final Object[] arguments;
1329
1330 private Name(int index, BasicType type, NamedFunction function, Object[] arguments) {
1331 this.index = (short)index;
1332 this.type = type;
1333 this.function = function;
1334 this.arguments = arguments;
1335 this.constraint = null;
1336 assert(this.index == index);
1337 }
1338 private Name(Name that, Object constraint) {
1339 this.index = that.index;
1340 this.type = that.type;
1341 this.function = that.function;
1342 this.arguments = that.arguments;
1343 this.constraint = constraint;
1344 assert(constraint == null || isParam()); // only params have constraints
1345 assert(constraint == null || constraint instanceof BoundMethodHandle.SpeciesData || constraint instanceof Class);
1346 }
1347 Name(MethodHandle function, Object... arguments) {
1348 this(new NamedFunction(function), arguments);
1349 }
1350 Name(MethodType functionType, Object... arguments) {
1351 this(new NamedFunction(functionType), arguments);
1352 assert(arguments[0] instanceof Name && ((Name)arguments[0]).type == L_TYPE);
1353 }
1354 Name(MemberName function, Object... arguments) {
1355 this(new NamedFunction(function), arguments);
1356 }
1357 Name(NamedFunction function, Object... arguments) {
1358 this(-1, function.returnType(), function, arguments = Arrays.copyOf(arguments, arguments.length, Object[].class));
1359 assert(typesMatch(function, arguments));
1360 }
1361 /** Create a raw parameter of the given type, with an expected index. */
1362 Name(int index, BasicType type) {
1363 this(index, type, null, null);
1364 }
1365 /** Create a raw parameter of the given type. */
|
126 final boolean forceInline;
127 final MethodHandle customized;
128 @Stable final Name[] names;
129 final Kind kind;
130 MemberName vmentry; // low-level behavior, or null if not yet prepared
131 private boolean isCompiled;
132
133 // Either a LambdaForm cache (managed by LambdaFormEditor) or a link to uncustomized version (for customized LF)
134 volatile Object transformCache;
135
136 public static final int VOID_RESULT = -1, LAST_RESULT = -2;
137
138 enum BasicType {
139 L_TYPE('L', Object.class, Wrapper.OBJECT), // all reference types
140 I_TYPE('I', int.class, Wrapper.INT),
141 J_TYPE('J', long.class, Wrapper.LONG),
142 F_TYPE('F', float.class, Wrapper.FLOAT),
143 D_TYPE('D', double.class, Wrapper.DOUBLE), // all primitive types
144 V_TYPE('V', void.class, Wrapper.VOID); // not valid in all contexts
145
146 static final @Stable BasicType[] ALL_TYPES = BasicType.values();
147 static final @Stable BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1);
148
149 static final int ARG_TYPE_LIMIT = ARG_TYPES.length;
150 static final int TYPE_LIMIT = ALL_TYPES.length;
151
152 // Derived int constants, which (unlike the enums) can be constant folded.
153 // We can remove them when JDK-8161245 is fixed.
154 static final byte
155 L_TYPE_NUM = (byte) L_TYPE.ordinal(),
156 I_TYPE_NUM = (byte) I_TYPE.ordinal(),
157 J_TYPE_NUM = (byte) J_TYPE.ordinal(),
158 F_TYPE_NUM = (byte) F_TYPE.ordinal(),
159 D_TYPE_NUM = (byte) D_TYPE.ordinal(),
160 V_TYPE_NUM = (byte) V_TYPE.ordinal();
161
162 final char btChar;
163 final Class<?> btClass;
164 final Wrapper btWrapper;
165
166 private BasicType(char btChar, Class<?> btClass, Wrapper wrapper) {
167 this.btChar = btChar;
168 this.btClass = btClass;
169 this.btWrapper = wrapper;
170 }
171
172 char basicTypeChar() {
173 return btChar;
174 }
175 Class<?> basicTypeClass() {
176 return btClass;
177 }
178 Wrapper basicTypeWrapper() {
179 return btWrapper;
180 }
181 int basicTypeSlots() {
672 int arity = sig.indexOf('_');
673 if (arity < 0) return false; // must be of the form *_*
674 int siglen = sig.length();
675 if (siglen != arity + 2) return false; // *_X
676 for (int i = 0; i < siglen; i++) {
677 if (i == arity) continue; // skip '_'
678 char c = sig.charAt(i);
679 if (c == 'V')
680 return (i == siglen - 1 && arity == siglen - 2);
681 if (!isArgBasicTypeChar(c)) return false; // must be [LIJFD]
682 }
683 return true; // [LIJFD]*_[LIJFDV]
684 }
685 static MethodType signatureType(String sig) {
686 Class<?>[] ptypes = new Class<?>[signatureArity(sig)];
687 for (int i = 0; i < ptypes.length; i++)
688 ptypes[i] = basicType(sig.charAt(i)).btClass;
689 Class<?> rtype = signatureReturn(sig).btClass;
690 return MethodType.makeImpl(rtype, ptypes, true);
691 }
692 static MethodType basicMethodType(MethodType mt) {
693 return signatureType(basicTypeSignature(mt));
694 }
695
696 /**
697 * Check if i-th name is a call to MethodHandleImpl.selectAlternative.
698 */
699 boolean isSelectAlternative(int pos) {
700 // selectAlternative idiom:
701 // t_{n}:L=MethodHandleImpl.selectAlternative(...)
702 // t_{n+1}:?=MethodHandle.invokeBasic(t_{n}, ...)
703 if (pos+1 >= names.length) return false;
704 Name name0 = names[pos];
705 Name name1 = names[pos+1];
706 return name0.refersTo(MethodHandleImpl.class, "selectAlternative") &&
707 name1.isInvokeBasic() &&
708 name1.lastUseIndex(name0) == 0 && // t_{n+1}:?=MethodHandle.invokeBasic(t_{n}, ...)
709 lastUseIndex(name0) == pos+1; // t_{n} is local: used only in t_{n+1}
710 }
711
712 private boolean isMatchingIdiom(int pos, String idiomName, int nArgs) {
713 if (pos+2 >= names.length) return false;
714 Name name0 = names[pos];
1287 return this.equals(constantZero(returnType()));
1288 }
1289
1290 public MethodHandleImpl.Intrinsic intrinsicName() {
1291 return intrinsicName;
1292 }
1293 }
1294
1295 public static String basicTypeSignature(MethodType type) {
1296 int params = type.parameterCount();
1297 char[] sig = new char[params + 2];
1298 int sigp = 0;
1299 while (sigp < params) {
1300 sig[sigp] = basicTypeChar(type.parameterType(sigp++));
1301 }
1302 sig[sigp++] = '_';
1303 sig[sigp++] = basicTypeChar(type.returnType());
1304 assert(sigp == sig.length);
1305 return String.valueOf(sig);
1306 }
1307
1308 /** Hack to make signatures more readable when they show up in method names.
1309 * Signature should start with a sequence of uppercase ASCII letters.
1310 * Runs of three or more are replaced by a single letter plus a decimal repeat count.
1311 * A tail of anything other than uppercase ASCII is passed through unchanged.
1312 * @param signature sequence of uppercase ASCII letters with possible repetitions
1313 * @return same sequence, with repetitions counted by decimal numerals
1314 */
1315 public static String shortenSignature(String signature) {
1316 final int NO_CHAR = -1, MIN_RUN = 3;
1317 int c0, c1 = NO_CHAR, c1reps = 0;
1318 StringBuilder buf = null;
1319 int len = signature.length();
1320 if (len < MIN_RUN) return signature;
1321 for (int i = 0; i <= len; i++) {
1322 if (c1 != NO_CHAR && !('A' <= c1 && c1 <= 'Z')) {
1323 // wrong kind of char; bail out here
1324 if (buf != null) {
1325 buf.append(signature.substring(i - c1reps, len));
1326 }
1327 break;
1328 }
1329 // shift in the next char:
1330 c0 = c1; c1 = (i == len ? NO_CHAR : signature.charAt(i));
1331 if (c1 == c0) { ++c1reps; continue; }
1332 // shift in the next count:
1333 int c0reps = c1reps; c1reps = 1;
1334 // end of a character run
1335 if (c0reps < MIN_RUN) {
1336 if (buf != null) {
1337 while (--c0reps >= 0)
1338 buf.append((char)c0);
1339 }
1340 continue;
1341 }
1342 // found three or more in a row
1343 if (buf == null)
1344 buf = new StringBuilder().append(signature, 0, i - c0reps);
1345 buf.append((char)c0).append(c0reps);
1346 }
1347 return (buf == null) ? signature : buf.toString();
1348 }
1352 @Stable short index;
1353 final NamedFunction function;
1354 final Object constraint; // additional type information, if not null
1355 @Stable final Object[] arguments;
1356
1357 private Name(int index, BasicType type, NamedFunction function, Object[] arguments) {
1358 this.index = (short)index;
1359 this.type = type;
1360 this.function = function;
1361 this.arguments = arguments;
1362 this.constraint = null;
1363 assert(this.index == index);
1364 }
1365 private Name(Name that, Object constraint) {
1366 this.index = that.index;
1367 this.type = that.type;
1368 this.function = that.function;
1369 this.arguments = that.arguments;
1370 this.constraint = constraint;
1371 assert(constraint == null || isParam()); // only params have constraints
1372 assert(constraint == null || constraint instanceof ClassSpecializer.SpeciesData || constraint instanceof Class);
1373 }
1374 Name(MethodHandle function, Object... arguments) {
1375 this(new NamedFunction(function), arguments);
1376 }
1377 Name(MethodType functionType, Object... arguments) {
1378 this(new NamedFunction(functionType), arguments);
1379 assert(arguments[0] instanceof Name && ((Name)arguments[0]).type == L_TYPE);
1380 }
1381 Name(MemberName function, Object... arguments) {
1382 this(new NamedFunction(function), arguments);
1383 }
1384 Name(NamedFunction function, Object... arguments) {
1385 this(-1, function.returnType(), function, arguments = Arrays.copyOf(arguments, arguments.length, Object[].class));
1386 assert(typesMatch(function, arguments));
1387 }
1388 /** Create a raw parameter of the given type, with an expected index. */
1389 Name(int index, BasicType type) {
1390 this(index, type, null, null);
1391 }
1392 /** Create a raw parameter of the given type. */
|