472
473 @Override
474 public MethodHandle asFixedArity() {
475 return target;
476 }
477
478 @Override
479 MethodHandle setVarargs(MemberName member) {
480 if (member.isVarargs()) return this;
481 return asFixedArity();
482 }
483
484 @Override
485 public MethodHandle asTypeUncached(MethodType newType) {
486 MethodType type = this.type();
487 int collectArg = type.parameterCount() - 1;
488 int newArity = newType.parameterCount();
489 if (newArity == collectArg+1 &&
490 type.parameterType(collectArg).isAssignableFrom(newType.parameterType(collectArg))) {
491 // if arity and trailing parameter are compatible, do normal thing
492 return asTypeCache = asFixedArity().asType(newType);
493 }
494 // check cache
495 MethodHandle acc = asCollectorCache;
496 if (acc != null && acc.type().parameterCount() == newArity)
497 return asTypeCache = acc.asType(newType);
498 // build and cache a collector
499 int arrayLength = newArity - collectArg;
500 MethodHandle collector;
501 try {
502 collector = asFixedArity().asCollector(arrayType, arrayLength);
503 assert(collector.type().parameterCount() == newArity) : "newArity="+newArity+" but collector="+collector;
504 } catch (IllegalArgumentException ex) {
505 throw new WrongMethodTypeException("cannot build collector", ex);
506 }
507 asCollectorCache = collector;
508 return asTypeCache = collector.asType(newType);
509 }
510
511 @Override
512 boolean viewAsTypeChecks(MethodType newType, boolean strict) {
513 super.viewAsTypeChecks(newType, true);
514 if (strict) return true;
515 // extra assertion for non-strict checks:
516 assert (type().lastParameterType().getComponentType()
517 .isAssignableFrom(
518 newType.lastParameterType().getComponentType()))
519 : Arrays.asList(this, newType);
520 return true;
521 }
522 }
523
524 /** Factory method: Spread selected argument. */
525 static MethodHandle makeSpreadArguments(MethodHandle target,
526 Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) {
527 MethodType targetType = target.type();
528
820 this.isCounting = (count > 0);
821 }
822
823 @Hidden
824 @Override
825 protected MethodHandle getTarget() {
826 return target;
827 }
828
829 @Override
830 public MethodHandle asTypeUncached(MethodType newType) {
831 MethodHandle newTarget = target.asType(newType);
832 MethodHandle wrapper;
833 if (isCounting) {
834 LambdaForm lform;
835 lform = countingFormProducer.apply(newTarget);
836 wrapper = new CountingWrapper(newTarget, lform, countingFormProducer, nonCountingFormProducer, DONT_INLINE_THRESHOLD);
837 } else {
838 wrapper = newTarget; // no need for a counting wrapper anymore
839 }
840 return (asTypeCache = wrapper);
841 }
842
843 boolean countDown() {
844 int c = count;
845 if (c <= 1) {
846 // Try to limit number of updates. MethodHandle.updateForm() doesn't guarantee LF update visibility.
847 if (isCounting) {
848 isCounting = false;
849 return true;
850 } else {
851 return false;
852 }
853 } else {
854 count = c - 1;
855 return false;
856 }
857 }
858
859 @Hidden
860 static void maybeStopCounting(Object o1) {
1287 @Override
1288 MemberName internalMemberName() {
1289 return member;
1290 }
1291 @Override
1292 Class<?> internalCallerClass() {
1293 return callerClass;
1294 }
1295 @Override
1296 boolean isInvokeSpecial() {
1297 return isInvokeSpecial;
1298 }
1299 @Override
1300 protected MethodHandle getTarget() {
1301 return target;
1302 }
1303 @Override
1304 public MethodHandle asTypeUncached(MethodType newType) {
1305 // This MH is an alias for target, except for the MemberName
1306 // Drop the MemberName if there is any conversion.
1307 return asTypeCache = target.asType(newType);
1308 }
1309 }
1310
1311 static MethodHandle makeWrappedMember(MethodHandle target, MemberName member, boolean isInvokeSpecial) {
1312 if (member.equals(target.internalMemberName()) && isInvokeSpecial == target.isInvokeSpecial())
1313 return target;
1314 return new WrappedMember(target, target.type(), member, isInvokeSpecial, null);
1315 }
1316
1317 /** Intrinsic IDs */
1318 /*non-public*/
1319 enum Intrinsic {
1320 SELECT_ALTERNATIVE,
1321 GUARD_WITH_CATCH,
1322 NEW_ARRAY,
1323 ARRAY_LOAD,
1324 ARRAY_STORE,
1325 IDENTITY,
1326 ZERO,
1327 NONE // no intrinsic associated
1336 IntrinsicMethodHandle(MethodHandle target, Intrinsic intrinsicName) {
1337 super(target.type(), target);
1338 this.target = target;
1339 this.intrinsicName = intrinsicName;
1340 }
1341
1342 @Override
1343 protected MethodHandle getTarget() {
1344 return target;
1345 }
1346
1347 @Override
1348 Intrinsic intrinsicName() {
1349 return intrinsicName;
1350 }
1351
1352 @Override
1353 public MethodHandle asTypeUncached(MethodType newType) {
1354 // This MH is an alias for target, except for the intrinsic name
1355 // Drop the name if there is any conversion.
1356 return asTypeCache = target.asType(newType);
1357 }
1358
1359 @Override
1360 String internalProperties() {
1361 return super.internalProperties() +
1362 "\n& Intrinsic="+intrinsicName;
1363 }
1364
1365 @Override
1366 public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
1367 if (intrinsicName == Intrinsic.IDENTITY) {
1368 MethodType resultType = type().asCollectorType(arrayType, arrayLength);
1369 MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
1370 return newArray.asType(resultType);
1371 }
1372 return super.asCollector(arrayType, arrayLength);
1373 }
1374 }
1375
1376 static MethodHandle makeIntrinsic(MethodHandle target, Intrinsic intrinsicName) {
|
472
473 @Override
474 public MethodHandle asFixedArity() {
475 return target;
476 }
477
478 @Override
479 MethodHandle setVarargs(MemberName member) {
480 if (member.isVarargs()) return this;
481 return asFixedArity();
482 }
483
484 @Override
485 public MethodHandle asTypeUncached(MethodType newType) {
486 MethodType type = this.type();
487 int collectArg = type.parameterCount() - 1;
488 int newArity = newType.parameterCount();
489 if (newArity == collectArg+1 &&
490 type.parameterType(collectArg).isAssignableFrom(newType.parameterType(collectArg))) {
491 // if arity and trailing parameter are compatible, do normal thing
492 return asFixedArity().asType(newType);
493 }
494 // check cache
495 MethodHandle acc = asCollectorCache;
496 if (acc != null && acc.type().parameterCount() == newArity)
497 return acc.asType(newType);
498 // build and cache a collector
499 int arrayLength = newArity - collectArg;
500 MethodHandle collector;
501 try {
502 collector = asFixedArity().asCollector(arrayType, arrayLength);
503 assert(collector.type().parameterCount() == newArity) : "newArity="+newArity+" but collector="+collector;
504 } catch (IllegalArgumentException ex) {
505 throw new WrongMethodTypeException("cannot build collector", ex);
506 }
507 asCollectorCache = collector;
508 return collector.asType(newType);
509 }
510
511 @Override
512 boolean viewAsTypeChecks(MethodType newType, boolean strict) {
513 super.viewAsTypeChecks(newType, true);
514 if (strict) return true;
515 // extra assertion for non-strict checks:
516 assert (type().lastParameterType().getComponentType()
517 .isAssignableFrom(
518 newType.lastParameterType().getComponentType()))
519 : Arrays.asList(this, newType);
520 return true;
521 }
522 }
523
524 /** Factory method: Spread selected argument. */
525 static MethodHandle makeSpreadArguments(MethodHandle target,
526 Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) {
527 MethodType targetType = target.type();
528
820 this.isCounting = (count > 0);
821 }
822
823 @Hidden
824 @Override
825 protected MethodHandle getTarget() {
826 return target;
827 }
828
829 @Override
830 public MethodHandle asTypeUncached(MethodType newType) {
831 MethodHandle newTarget = target.asType(newType);
832 MethodHandle wrapper;
833 if (isCounting) {
834 LambdaForm lform;
835 lform = countingFormProducer.apply(newTarget);
836 wrapper = new CountingWrapper(newTarget, lform, countingFormProducer, nonCountingFormProducer, DONT_INLINE_THRESHOLD);
837 } else {
838 wrapper = newTarget; // no need for a counting wrapper anymore
839 }
840 return wrapper;
841 }
842
843 boolean countDown() {
844 int c = count;
845 if (c <= 1) {
846 // Try to limit number of updates. MethodHandle.updateForm() doesn't guarantee LF update visibility.
847 if (isCounting) {
848 isCounting = false;
849 return true;
850 } else {
851 return false;
852 }
853 } else {
854 count = c - 1;
855 return false;
856 }
857 }
858
859 @Hidden
860 static void maybeStopCounting(Object o1) {
1287 @Override
1288 MemberName internalMemberName() {
1289 return member;
1290 }
1291 @Override
1292 Class<?> internalCallerClass() {
1293 return callerClass;
1294 }
1295 @Override
1296 boolean isInvokeSpecial() {
1297 return isInvokeSpecial;
1298 }
1299 @Override
1300 protected MethodHandle getTarget() {
1301 return target;
1302 }
1303 @Override
1304 public MethodHandle asTypeUncached(MethodType newType) {
1305 // This MH is an alias for target, except for the MemberName
1306 // Drop the MemberName if there is any conversion.
1307 return target.asType(newType);
1308 }
1309 }
1310
1311 static MethodHandle makeWrappedMember(MethodHandle target, MemberName member, boolean isInvokeSpecial) {
1312 if (member.equals(target.internalMemberName()) && isInvokeSpecial == target.isInvokeSpecial())
1313 return target;
1314 return new WrappedMember(target, target.type(), member, isInvokeSpecial, null);
1315 }
1316
1317 /** Intrinsic IDs */
1318 /*non-public*/
1319 enum Intrinsic {
1320 SELECT_ALTERNATIVE,
1321 GUARD_WITH_CATCH,
1322 NEW_ARRAY,
1323 ARRAY_LOAD,
1324 ARRAY_STORE,
1325 IDENTITY,
1326 ZERO,
1327 NONE // no intrinsic associated
1336 IntrinsicMethodHandle(MethodHandle target, Intrinsic intrinsicName) {
1337 super(target.type(), target);
1338 this.target = target;
1339 this.intrinsicName = intrinsicName;
1340 }
1341
1342 @Override
1343 protected MethodHandle getTarget() {
1344 return target;
1345 }
1346
1347 @Override
1348 Intrinsic intrinsicName() {
1349 return intrinsicName;
1350 }
1351
1352 @Override
1353 public MethodHandle asTypeUncached(MethodType newType) {
1354 // This MH is an alias for target, except for the intrinsic name
1355 // Drop the name if there is any conversion.
1356 return target.asType(newType);
1357 }
1358
1359 @Override
1360 String internalProperties() {
1361 return super.internalProperties() +
1362 "\n& Intrinsic="+intrinsicName;
1363 }
1364
1365 @Override
1366 public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
1367 if (intrinsicName == Intrinsic.IDENTITY) {
1368 MethodType resultType = type().asCollectorType(arrayType, arrayLength);
1369 MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
1370 return newArray.asType(resultType);
1371 }
1372 return super.asCollector(arrayType, arrayLength);
1373 }
1374 }
1375
1376 static MethodHandle makeIntrinsic(MethodHandle target, Intrinsic intrinsicName) {
|