1 /*
2 * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
524 assert(form.arity == lambdaForm.arity - arrayLength + 1);
525 return form;
526 }
527 LambdaFormBuffer buf = buffer();
528 buf.startEdit();
529
530 assert(pos <= MethodType.MAX_JVM_ARITY);
531 assert(pos + arrayLength <= lambdaForm.arity);
532 assert(pos > 0); // cannot spread the MH arg itself
533
534 Name spreadParam = new Name(L_TYPE);
535 Name checkSpread = new Name(MethodHandleImpl.getFunction(MethodHandleImpl.NF_checkSpreadArgument),
536 spreadParam, arrayLength);
537
538 // insert the new expressions
539 int exprPos = lambdaForm.arity();
540 buf.insertExpression(exprPos++, checkSpread);
541 // adjust the arguments
542 MethodHandle aload = MethodHandles.arrayElementGetter(erasedArrayType);
543 for (int i = 0; i < arrayLength; i++) {
544 Name loadArgument = new Name(aload, spreadParam, i);
545 buf.insertExpression(exprPos + i, loadArgument);
546 buf.replaceParameterByCopy(pos + i, exprPos + i);
547 }
548 buf.insertParameter(pos, spreadParam);
549
550 form = buf.endEdit();
551 return putInCache(key, form);
552 }
553
554 LambdaForm collectArgumentsForm(int pos, MethodType collectorType) {
555 int collectorArity = collectorType.parameterCount();
556 boolean dropResult = (collectorType.returnType() == void.class);
557 if (collectorArity == 1 && !dropResult) {
558 return filterArgumentForm(pos, basicType(collectorType.parameterType(0)));
559 }
560 byte[] newTypes = BasicType.basicTypesOrd(collectorType.parameterArray());
561 byte kind = (dropResult
562 ? Transform.COLLECT_ARGS_TO_VOID
563 : Transform.COLLECT_ARGS);
564 if (dropResult && collectorArity == 0) pos = 1; // pure side effect
587 argTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
588 }
589 assert(collectorType.parameterList().equals(Collections.nCopies(collectorArity, elementType)));
590 byte kind = Transform.COLLECT_ARGS_TO_ARRAY;
591 Transform key = Transform.of(kind, pos, collectorArity, argTypeKey);
592 LambdaForm form = getInCache(key);
593 if (form != null) {
594 assert(form.arity == lambdaForm.arity - 1 + collectorArity);
595 return form;
596 }
597 LambdaFormBuffer buf = buffer();
598 buf.startEdit();
599
600 assert(pos + 1 <= lambdaForm.arity);
601 assert(pos > 0); // cannot filter the MH arg itself
602
603 Name[] newParams = new Name[collectorArity];
604 for (int i = 0; i < collectorArity; i++) {
605 newParams[i] = new Name(pos + i, argType);
606 }
607 Name callCombiner = new Name(arrayCollector, (Object[]) /*...*/ newParams);
608
609 // insert the new expression
610 int exprPos = lambdaForm.arity();
611 buf.insertExpression(exprPos, callCombiner);
612
613 // insert new arguments
614 int argPos = pos + 1; // skip result parameter
615 for (Name newParam : newParams) {
616 buf.insertParameter(argPos++, newParam);
617 }
618 assert(buf.lastIndexOf(callCombiner) == exprPos+newParams.length);
619 buf.replaceParameterByCopy(pos, exprPos+newParams.length);
620
621 form = buf.endEdit();
622 return putInCache(key, form);
623 }
624
625 LambdaForm filterArgumentForm(int pos, BasicType newType) {
626 Transform key = Transform.of(Transform.FILTER_ARG, pos, newType.ordinal());
627 LambdaForm form = getInCache(key);
|
1 /*
2 * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
524 assert(form.arity == lambdaForm.arity - arrayLength + 1);
525 return form;
526 }
527 LambdaFormBuffer buf = buffer();
528 buf.startEdit();
529
530 assert(pos <= MethodType.MAX_JVM_ARITY);
531 assert(pos + arrayLength <= lambdaForm.arity);
532 assert(pos > 0); // cannot spread the MH arg itself
533
534 Name spreadParam = new Name(L_TYPE);
535 Name checkSpread = new Name(MethodHandleImpl.getFunction(MethodHandleImpl.NF_checkSpreadArgument),
536 spreadParam, arrayLength);
537
538 // insert the new expressions
539 int exprPos = lambdaForm.arity();
540 buf.insertExpression(exprPos++, checkSpread);
541 // adjust the arguments
542 MethodHandle aload = MethodHandles.arrayElementGetter(erasedArrayType);
543 for (int i = 0; i < arrayLength; i++) {
544 Name loadArgument = new Name(new NamedFunction(aload, Intrinsic.ARRAY_LOAD), spreadParam, i);
545 buf.insertExpression(exprPos + i, loadArgument);
546 buf.replaceParameterByCopy(pos + i, exprPos + i);
547 }
548 buf.insertParameter(pos, spreadParam);
549
550 form = buf.endEdit();
551 return putInCache(key, form);
552 }
553
554 LambdaForm collectArgumentsForm(int pos, MethodType collectorType) {
555 int collectorArity = collectorType.parameterCount();
556 boolean dropResult = (collectorType.returnType() == void.class);
557 if (collectorArity == 1 && !dropResult) {
558 return filterArgumentForm(pos, basicType(collectorType.parameterType(0)));
559 }
560 byte[] newTypes = BasicType.basicTypesOrd(collectorType.parameterArray());
561 byte kind = (dropResult
562 ? Transform.COLLECT_ARGS_TO_VOID
563 : Transform.COLLECT_ARGS);
564 if (dropResult && collectorArity == 0) pos = 1; // pure side effect
587 argTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
588 }
589 assert(collectorType.parameterList().equals(Collections.nCopies(collectorArity, elementType)));
590 byte kind = Transform.COLLECT_ARGS_TO_ARRAY;
591 Transform key = Transform.of(kind, pos, collectorArity, argTypeKey);
592 LambdaForm form = getInCache(key);
593 if (form != null) {
594 assert(form.arity == lambdaForm.arity - 1 + collectorArity);
595 return form;
596 }
597 LambdaFormBuffer buf = buffer();
598 buf.startEdit();
599
600 assert(pos + 1 <= lambdaForm.arity);
601 assert(pos > 0); // cannot filter the MH arg itself
602
603 Name[] newParams = new Name[collectorArity];
604 for (int i = 0; i < collectorArity; i++) {
605 newParams[i] = new Name(pos + i, argType);
606 }
607 Name callCombiner = new Name(new NamedFunction(arrayCollector, Intrinsic.NEW_ARRAY),
608 (Object[]) /*...*/ newParams);
609
610 // insert the new expression
611 int exprPos = lambdaForm.arity();
612 buf.insertExpression(exprPos, callCombiner);
613
614 // insert new arguments
615 int argPos = pos + 1; // skip result parameter
616 for (Name newParam : newParams) {
617 buf.insertParameter(argPos++, newParam);
618 }
619 assert(buf.lastIndexOf(callCombiner) == exprPos+newParams.length);
620 buf.replaceParameterByCopy(pos, exprPos+newParams.length);
621
622 form = buf.endEdit();
623 return putInCache(key, form);
624 }
625
626 LambdaForm filterArgumentForm(int pos, BasicType newType) {
627 Transform key = Transform.of(Transform.FILTER_ARG, pos, newType.ordinal());
628 LambdaForm form = getInCache(key);
|