src/java.base/share/classes/java/lang/invoke/LambdaFormBuffer.java
author redestad
Thu, 16 Nov 2017 00:58:50 +0100
changeset 47753 a2008587c13f
parent 47216 71c04702a3d5
child 47857 13415772f06a
permissions -rw-r--r--
8184777: Factor out species generation logic from BoundMethodHandle Reviewed-by: vlivanov Contributed-by: john.r.rose@oracle.com, claes.redestad@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
     1
/*
39342
f66a89ed6fca 8143211: provide bytecode intrinsics for loop and try/finally executors
mhaupt
parents: 27803
diff changeset
     2
 * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
     4
 *
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    10
 *
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    15
 * accompanied this code).
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    16
 *
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    20
 *
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    23
 * questions.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    24
 */
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    25
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    26
package java.lang.invoke;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    27
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    28
import java.util.ArrayList;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    29
import java.util.Arrays;
47753
a2008587c13f 8184777: Factor out species generation logic from BoundMethodHandle
redestad
parents: 47216
diff changeset
    30
import java.util.List;
a2008587c13f 8184777: Factor out species generation logic from BoundMethodHandle
redestad
parents: 47216
diff changeset
    31
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    32
import static java.lang.invoke.LambdaForm.*;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    33
import static java.lang.invoke.LambdaForm.BasicType.*;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    34
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    35
/** Working storage for an LF that is being transformed.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    36
 *  Similarly to a StringBuffer, the editing can take place in multiple steps.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    37
 */
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    38
final class LambdaFormBuffer {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    39
    private int arity, length;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    40
    private Name[] names;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    41
    private Name[] originalNames;  // snapshot of pre-transaction names
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    42
    private byte flags;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    43
    private int firstChange;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    44
    private Name resultName;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    45
    private ArrayList<Name> dups;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    46
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    47
    private static final int F_TRANS = 0x10, F_OWNED = 0x03;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    48
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    49
    LambdaFormBuffer(LambdaForm lf) {
27803
d04ca9d519ce 8057020: LambdaForm caches should support eviction
vlivanov
parents: 26482
diff changeset
    50
        this.arity = lf.arity;
d04ca9d519ce 8057020: LambdaForm caches should support eviction
vlivanov
parents: 26482
diff changeset
    51
        setNames(lf.names);
d04ca9d519ce 8057020: LambdaForm caches should support eviction
vlivanov
parents: 26482
diff changeset
    52
        int result = lf.result;
d04ca9d519ce 8057020: LambdaForm caches should support eviction
vlivanov
parents: 26482
diff changeset
    53
        if (result == LAST_RESULT)  result = length - 1;
43893
0e72a2804a0c 8175233: Remove LambdaForm.debugName
redestad
parents: 39342
diff changeset
    54
        if (result >= 0 && lf.names[result].type != V_TYPE) {
27803
d04ca9d519ce 8057020: LambdaForm caches should support eviction
vlivanov
parents: 26482
diff changeset
    55
            resultName = lf.names[result];
43893
0e72a2804a0c 8175233: Remove LambdaForm.debugName
redestad
parents: 39342
diff changeset
    56
        }
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    57
        assert(lf.nameRefsAreLegal());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    58
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    59
26482
cea1ab1c3ac7 8057922: Improve LambdaForm sharing by using LambdaFormEditor more extensively
vlivanov
parents: 26481
diff changeset
    60
    private LambdaForm lambdaForm() {
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    61
        assert(!inTrans());  // need endEdit call to tidy things up
43893
0e72a2804a0c 8175233: Remove LambdaForm.debugName
redestad
parents: 39342
diff changeset
    62
        return new LambdaForm(arity, nameArray(), resultIndex());
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    63
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    64
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    65
    Name name(int i) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    66
        assert(i < length);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    67
        return names[i];
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    68
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    69
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    70
    Name[] nameArray() {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    71
        return Arrays.copyOf(names, length);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    72
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    73
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    74
    int resultIndex() {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    75
        if (resultName == null)  return VOID_RESULT;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    76
        int index = indexOf(resultName, names);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    77
        assert(index >= 0);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    78
        return index;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    79
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    80
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    81
    void setNames(Name[] names2) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    82
        names = originalNames = names2;  // keep a record of where everything was to start with
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    83
        length = names2.length;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    84
        flags = 0;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    85
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    86
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    87
    private boolean verifyArity() {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    88
        for (int i = 0; i < arity && i < firstChange; i++) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    89
            assert(names[i].isParam()) : "#" + i + "=" + names[i];
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    90
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    91
        for (int i = arity; i < length; i++) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    92
            assert(!names[i].isParam()) : "#" + i + "=" + names[i];
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    93
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    94
        for (int i = length; i < names.length; i++) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    95
            assert(names[i] == null) : "#" + i + "=" + names[i];
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    96
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    97
        // check resultName also
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    98
        if (resultName != null) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
    99
            int resultIndex = indexOf(resultName, names);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   100
            assert(resultIndex >= 0) : "not found: " + resultName.exprString() + Arrays.asList(names);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   101
            assert(names[resultIndex] == resultName);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   102
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   103
        return true;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   104
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   105
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   106
    private boolean verifyFirstChange() {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   107
        assert(inTrans());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   108
        for (int i = 0; i < length; i++) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   109
            if (names[i] != originalNames[i]) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   110
                assert(firstChange == i) : Arrays.asList(firstChange, i, originalNames[i].exprString(), Arrays.asList(names));
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   111
                return true;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   112
            }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   113
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   114
        assert(firstChange == length) : Arrays.asList(firstChange, Arrays.asList(names));
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   115
        return true;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   116
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   117
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   118
    private static int indexOf(NamedFunction fn, NamedFunction[] fns) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   119
        for (int i = 0; i < fns.length; i++) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   120
            if (fns[i] == fn)  return i;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   121
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   122
        return -1;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   123
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   124
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   125
    private static int indexOf(Name n, Name[] ns) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   126
        for (int i = 0; i < ns.length; i++) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   127
            if (ns[i] == n)  return i;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   128
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   129
        return -1;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   130
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   131
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   132
    boolean inTrans() {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   133
        return (flags & F_TRANS) != 0;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   134
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   135
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   136
    int ownedCount() {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   137
        return flags & F_OWNED;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   138
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   139
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   140
    void growNames(int insertPos, int growLength) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   141
        int oldLength = length;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   142
        int newLength = oldLength + growLength;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   143
        int oc = ownedCount();
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   144
        if (oc == 0 || newLength > names.length) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   145
            names = Arrays.copyOf(names, (names.length + growLength) * 5 / 4);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   146
            if (oc == 0) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   147
                flags++;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   148
                oc++;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   149
                assert(ownedCount() == oc);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   150
            }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   151
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   152
        if (originalNames != null && originalNames.length < names.length) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   153
            originalNames = Arrays.copyOf(originalNames, names.length);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   154
            if (oc == 1) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   155
                flags++;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   156
                oc++;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   157
                assert(ownedCount() == oc);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   158
            }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   159
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   160
        if (growLength == 0)  return;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   161
        int insertEnd = insertPos + growLength;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   162
        int tailLength = oldLength - insertPos;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   163
        System.arraycopy(names, insertPos, names, insertEnd, tailLength);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   164
        Arrays.fill(names, insertPos, insertEnd, null);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   165
        if (originalNames != null) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   166
            System.arraycopy(originalNames, insertPos, originalNames, insertEnd, tailLength);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   167
            Arrays.fill(originalNames, insertPos, insertEnd, null);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   168
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   169
        length = newLength;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   170
        if (firstChange >= insertPos) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   171
            firstChange += growLength;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   172
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   173
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   174
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   175
    int lastIndexOf(Name n) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   176
        int result = -1;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   177
        for (int i = 0; i < length; i++) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   178
            if (names[i] == n)  result = i;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   179
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   180
        return result;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   181
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   182
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   183
    /** We have just overwritten the name at pos1 with the name at pos2.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   184
     *  This means that there are two copies of the name, which we will have to fix later.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   185
     */
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   186
    private void noteDuplicate(int pos1, int pos2) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   187
        Name n = names[pos1];
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   188
        assert(n == names[pos2]);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   189
        assert(originalNames[pos1] != null);  // something was replaced at pos1
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   190
        assert(originalNames[pos2] == null || originalNames[pos2] == n);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   191
        if (dups == null) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   192
            dups = new ArrayList<>();
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   193
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   194
        dups.add(n);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   195
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   196
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   197
    /** Replace duplicate names by nulls, and remove all nulls. */
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   198
    private void clearDuplicatesAndNulls() {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   199
        if (dups != null) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   200
            // Remove duplicates.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   201
            assert(ownedCount() >= 1);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   202
            for (Name dup : dups) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   203
                for (int i = firstChange; i < length; i++) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   204
                    if (names[i] == dup && originalNames[i] != dup) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   205
                        names[i] = null;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   206
                        assert(Arrays.asList(names).contains(dup));
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   207
                        break;  // kill only one dup
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   208
                    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   209
                }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   210
            }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   211
            dups.clear();
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   212
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   213
        // Now that we are done with originalNames, remove "killed" names.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   214
        int oldLength = length;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   215
        for (int i = firstChange; i < length; i++) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   216
            if (names[i] == null) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   217
                System.arraycopy(names, i + 1, names, i, (--length - i));
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   218
                --i;  // restart loop at this position
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   219
            }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   220
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   221
        if (length < oldLength) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   222
            Arrays.fill(names, length, oldLength, null);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   223
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   224
        assert(!Arrays.asList(names).subList(0, length).contains(null));
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   225
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   226
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   227
    /** Create a private, writable copy of names.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   228
     *  Preserve the original copy, for reference.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   229
     */
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   230
    void startEdit() {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   231
        assert(verifyArity());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   232
        int oc = ownedCount();
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   233
        assert(!inTrans());  // no nested transactions
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   234
        flags |= F_TRANS;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   235
        Name[] oldNames = names;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   236
        Name[] ownBuffer = (oc == 2 ? originalNames : null);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   237
        assert(ownBuffer != oldNames);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   238
        if (ownBuffer != null && ownBuffer.length >= length) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   239
            names = copyNamesInto(ownBuffer);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   240
        } else {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   241
            // make a new buffer to hold the names
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   242
            final int SLOP = 2;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   243
            names = Arrays.copyOf(oldNames, Math.max(length + SLOP, oldNames.length));
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   244
            if (oc < 2)  ++flags;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   245
            assert(ownedCount() == oc + 1);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   246
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   247
        originalNames = oldNames;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   248
        assert(originalNames != names);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   249
        firstChange = length;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   250
        assert(inTrans());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   251
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   252
39342
f66a89ed6fca 8143211: provide bytecode intrinsics for loop and try/finally executors
mhaupt
parents: 27803
diff changeset
   253
    void changeName(int i, Name name) {
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   254
        assert(inTrans());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   255
        assert(i < length);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   256
        Name oldName = names[i];
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   257
        assert(oldName == originalNames[i]);  // no multiple changes
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   258
        assert(verifyFirstChange());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   259
        if (ownedCount() == 0)
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   260
            growNames(0, 0);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   261
        names[i] = name;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   262
        if (firstChange > i) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   263
            firstChange = i;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   264
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   265
        if (resultName != null && resultName == oldName) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   266
            resultName = name;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   267
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   268
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   269
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   270
    /** Change the result name.  Null means a void result. */
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   271
    void setResult(Name name) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   272
        assert(name == null || lastIndexOf(name) >= 0);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   273
        resultName = name;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   274
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   275
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   276
    /** Finish a transaction. */
26482
cea1ab1c3ac7 8057922: Improve LambdaForm sharing by using LambdaFormEditor more extensively
vlivanov
parents: 26481
diff changeset
   277
    LambdaForm endEdit() {
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   278
        assert(verifyFirstChange());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   279
        // Assuming names have been changed pairwise from originalNames[i] to names[i],
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   280
        // update arguments to ensure referential integrity.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   281
        for (int i = Math.max(firstChange, arity); i < length; i++) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   282
            Name name = names[i];
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   283
            if (name == null)  continue;  // space for removed duplicate
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   284
            Name newName = name.replaceNames(originalNames, names, firstChange, i);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   285
            if (newName != name) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   286
                names[i] = newName;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   287
                if (resultName == name) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   288
                    resultName = newName;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   289
                }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   290
            }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   291
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   292
        assert(inTrans());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   293
        flags &= ~F_TRANS;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   294
        clearDuplicatesAndNulls();
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   295
        originalNames = null;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   296
        // If any parameters have been changed, then reorder them as needed.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   297
        // This is a "sheep-and-goats" stable sort, pushing all non-parameters
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   298
        // to the right of all parameters.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   299
        if (firstChange < arity) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   300
            Name[] exprs = new Name[arity - firstChange];
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   301
            int argp = firstChange, exprp = 0;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   302
            for (int i = firstChange; i < arity; i++) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   303
                Name name = names[i];
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   304
                if (name.isParam()) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   305
                    names[argp++] = name;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   306
                } else {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   307
                    exprs[exprp++] = name;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   308
                }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   309
            }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   310
            assert(exprp == (arity - argp));
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   311
            // copy the exprs just after the last remaining param
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   312
            System.arraycopy(exprs, 0, names, argp, exprp);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   313
            // adjust arity
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   314
            arity -= exprp;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   315
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   316
        assert(verifyArity());
26482
cea1ab1c3ac7 8057922: Improve LambdaForm sharing by using LambdaFormEditor more extensively
vlivanov
parents: 26481
diff changeset
   317
        return lambdaForm();
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   318
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   319
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   320
    private Name[] copyNamesInto(Name[] buffer) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   321
        System.arraycopy(names, 0, buffer, 0, length);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   322
        Arrays.fill(buffer, length, buffer.length, null);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   323
        return buffer;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   324
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   325
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   326
    /** Replace any Name whose function is in oldFns with a copy
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   327
     *  whose function is in the corresponding position in newFns.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   328
     *  Only do this if the arguments are exactly equal to the given.
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   329
     */
47753
a2008587c13f 8184777: Factor out species generation logic from BoundMethodHandle
redestad
parents: 47216
diff changeset
   330
    LambdaFormBuffer replaceFunctions(List<NamedFunction> oldFns, List<NamedFunction> newFns,
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   331
                                      Object... forArguments) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   332
        assert(inTrans());
47753
a2008587c13f 8184777: Factor out species generation logic from BoundMethodHandle
redestad
parents: 47216
diff changeset
   333
        if (oldFns.isEmpty())  return this;
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   334
        for (int i = arity; i < length; i++) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   335
            Name n = names[i];
47753
a2008587c13f 8184777: Factor out species generation logic from BoundMethodHandle
redestad
parents: 47216
diff changeset
   336
            int nfi = oldFns.indexOf(n.function);
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   337
            if (nfi >= 0 && Arrays.equals(n.arguments, forArguments)) {
47753
a2008587c13f 8184777: Factor out species generation logic from BoundMethodHandle
redestad
parents: 47216
diff changeset
   338
                changeName(i, new Name(newFns.get(nfi), n.arguments));
26481
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   339
            }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   340
        }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   341
        return this;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   342
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   343
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   344
    private void replaceName(int pos, Name binding) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   345
        assert(inTrans());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   346
        assert(verifyArity());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   347
        assert(pos < arity);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   348
        Name param = names[pos];
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   349
        assert(param.isParam());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   350
        assert(param.type == binding.type);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   351
        changeName(pos, binding);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   352
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   353
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   354
    /** Replace a parameter by a fresh parameter. */
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   355
    LambdaFormBuffer renameParameter(int pos, Name newParam) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   356
        assert(newParam.isParam());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   357
        replaceName(pos, newParam);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   358
        return this;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   359
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   360
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   361
    /** Replace a parameter by a fresh expression. */
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   362
    LambdaFormBuffer replaceParameterByNewExpression(int pos, Name binding) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   363
        assert(!binding.isParam());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   364
        assert(lastIndexOf(binding) < 0);  // else use replaceParameterByCopy
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   365
        replaceName(pos, binding);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   366
        return this;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   367
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   368
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   369
    /** Replace a parameter by another parameter or expression already in the form. */
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   370
    LambdaFormBuffer replaceParameterByCopy(int pos, int valuePos) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   371
        assert(pos != valuePos);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   372
        replaceName(pos, names[valuePos]);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   373
        noteDuplicate(pos, valuePos);  // temporarily, will occur twice in the names array
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   374
        return this;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   375
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   376
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   377
    private void insertName(int pos, Name expr, boolean isParameter) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   378
        assert(inTrans());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   379
        assert(verifyArity());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   380
        assert(isParameter ? pos <= arity : pos >= arity);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   381
        growNames(pos, 1);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   382
        if (isParameter)  arity += 1;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   383
        changeName(pos, expr);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   384
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   385
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   386
    /** Insert a fresh expression. */
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   387
    LambdaFormBuffer insertExpression(int pos, Name expr) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   388
        assert(!expr.isParam());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   389
        insertName(pos, expr, false);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   390
        return this;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   391
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   392
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   393
    /** Insert a fresh parameter. */
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   394
    LambdaFormBuffer insertParameter(int pos, Name param) {
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   395
        assert(param.isParam());
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   396
        insertName(pos, param, true);
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   397
        return this;
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   398
    }
c5b74a88a3c0 8057042: LambdaFormEditor: derive new LFs from a base LF
vlivanov
parents:
diff changeset
   399
}