src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Label.java
author hannesw
Wed, 07 Mar 2018 18:36:21 +0100
changeset 49145 2854589fd853
parent 47216 71c04702a3d5
permissions -rw-r--r--
8199236: Nashorn uses deprecated HTML tags in Javadoc Reviewed-by: jlaskey, sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
     1
/*
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
     4
 *
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    10
 *
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    15
 * accompanied this code).
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    16
 *
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    20
 *
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    23
 * questions.
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    24
 */
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    25
package jdk.nashorn.internal.codegen;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    26
27204
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26887
diff changeset
    27
import java.io.Serializable;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    28
import java.util.ArrayList;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    29
import java.util.Arrays;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    30
import java.util.BitSet;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    31
import java.util.Iterator;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    32
import java.util.List;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    33
import java.util.ListIterator;
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    34
import jdk.nashorn.internal.codegen.types.Type;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    35
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    36
/**
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    37
 * Abstraction for labels, separating a label from the underlying
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    38
 * byte code emitter. Also augmenting label with e.g. a name
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    39
 * for easier debugging and reading code
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    40
 *
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    41
 * see -Dnashorn.codegen.debug, --log=codegen
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
    42
 */
27204
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26887
diff changeset
    43
public final class Label implements Serializable {
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26887
diff changeset
    44
    private static final long serialVersionUID = 1L;
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26887
diff changeset
    45
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    46
    //byte code generation evaluation type stack for consistency check
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    47
    //and correct opcode selection. one per label as a label may be a
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    48
    //join point
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    49
    static final class Stack implements Cloneable {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
    50
        static final int NON_LOAD = -1;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
    51
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    52
        Type[] data;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    53
        int[]  localLoads;
24720
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
    54
        int    sp;
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    55
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    56
        List<Type> localVariableTypes;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    57
        int firstTemp; // index of the first temporary local variable
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    58
        // Bitmap marking last slot belonging to a single symbol.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    59
        BitSet symbolBoundary;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    60
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    61
        Stack() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    62
            data = new Type[8];
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    63
            localLoads = new int[8];
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    64
            localVariableTypes = new ArrayList<>(8);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
    65
            symbolBoundary = new BitSet();
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    66
        }
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    67
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    68
        boolean isEmpty() {
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    69
            return sp == 0;
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    70
        }
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    71
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    72
        int size() {
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    73
            return sp;
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    74
        }
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    75
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    76
        void clear() {
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    77
            sp = 0;
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    78
        }
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    79
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    80
        void push(final Type type) {
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    81
            if (data.length == sp) {
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    82
                final Type[] newData = new Type[sp * 2];
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
    83
                final int[]  newLocalLoad = new int[sp * 2];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
    84
                System.arraycopy(data, 0, newData, 0, sp);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
    85
                System.arraycopy(localLoads, 0, newLocalLoad, 0, sp);
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    86
                data = newData;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
    87
                localLoads = newLocalLoad;
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    88
            }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
    89
            data[sp] = type;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
    90
            localLoads[sp] = NON_LOAD;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
    91
            sp++;
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    92
        }
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    93
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    94
        Type peek() {
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    95
            return peek(0);
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    96
        }
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    97
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
    98
        Type peek(final int n) {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
    99
            final int pos = sp - 1 - n;
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
   100
            return pos < 0 ? null : data[pos];
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
   101
        }
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
   102
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   103
        /**
49145
2854589fd853 8199236: Nashorn uses deprecated HTML tags in Javadoc
hannesw
parents: 47216
diff changeset
   104
         * Retrieve the top <code>count</code> types on the stack without modifying it.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   105
         *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   106
         * @param count number of types to return
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   107
         * @return array of Types
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   108
         */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   109
        Type[] getTopTypes(final int count) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   110
            final Type[] topTypes = new Type[count];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   111
            System.arraycopy(data, sp - count, topTypes, 0, count);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   112
            return topTypes;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   113
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   114
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   115
        int[] getLocalLoads(final int from, final int to) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   116
            final int count = to - from;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   117
            final int[] topLocalLoads = new int[count];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   118
            System.arraycopy(localLoads, from, topLocalLoads, 0, count);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   119
            return topLocalLoads;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   120
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   121
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   122
        /**
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   123
         * Returns the number of used local variable slots, including all live stack-store temporaries.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   124
         * @return the number of used local variable slots, including all live stack-store temporaries.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   125
         */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   126
        int getUsedSlotsWithLiveTemporaries() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   127
            // There are at least as many as are declared by the current blocks.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   128
            int usedSlots = firstTemp;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   129
            // Look at every load on the stack, and bump the number of used slots up by the temporaries seen there.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   130
            for(int i = sp; i-->0;) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   131
                final int slot = localLoads[i];
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   132
                if(slot != Label.Stack.NON_LOAD) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   133
                    final int afterSlot = slot + localVariableTypes.get(slot).getSlots();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   134
                    if(afterSlot > usedSlots) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   135
                        usedSlots = afterSlot;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   136
                    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   137
                }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   138
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   139
            return usedSlots;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   140
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   141
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   142
        /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   143
         *
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   144
         * @param joinOrigin the stack from the other branch.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   145
         */
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   146
        void joinFrom(final Stack joinOrigin, final boolean breakTarget) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   147
            assert isStackCompatible(joinOrigin);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   148
            if(breakTarget) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   149
                // As we're joining labels that can jump across block boundaries, the number of local variables can
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   150
                // differ, and we should always respect the one having less variables.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   151
                firstTemp = Math.min(firstTemp, joinOrigin.firstTemp);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   152
            } else {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   153
                assert firstTemp == joinOrigin.firstTemp;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   154
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   155
            final int[] otherLoads = joinOrigin.localLoads;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   156
            int firstDeadTemp = firstTemp;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   157
            for(int i = 0; i < sp; ++i) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   158
                final int localLoad = localLoads[i];
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   159
                if(localLoad != otherLoads[i]) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   160
                    localLoads[i] = NON_LOAD;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   161
                } else if(localLoad >= firstDeadTemp) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   162
                    firstDeadTemp = localLoad + localVariableTypes.get(localLoad).getSlots();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   163
                }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   164
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   165
            // Eliminate dead temporaries
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   166
            undefineLocalVariables(firstDeadTemp, false);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   167
            assert isVariablePartitioningEqual(joinOrigin, firstDeadTemp);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   168
            mergeVariableTypes(joinOrigin, firstDeadTemp);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   169
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   170
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   171
        private void mergeVariableTypes(final Stack joinOrigin, final int toSlot) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   172
            final ListIterator<Type> it1 = localVariableTypes.listIterator();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   173
            final Iterator<Type> it2 = joinOrigin.localVariableTypes.iterator();
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   174
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   175
            for(int i = 0; i < toSlot; ++i) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   176
                final Type thisType = it1.next();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   177
                final Type otherType = it2.next();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   178
                if(otherType == Type.UNKNOWN) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   179
                    // Variables that are <unknown> on the other branch will become <unknown> here too.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   180
                    it1.set(Type.UNKNOWN);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   181
                } else if (thisType != otherType) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   182
                    if(thisType.isObject() && otherType.isObject()) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   183
                        // different object types are merged into Object.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   184
                        // TODO: maybe find most common superclass?
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   185
                        it1.set(Type.OBJECT);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   186
                    } else {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   187
                        assert thisType == Type.UNKNOWN;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   188
                    }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   189
                }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   190
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   191
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   192
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   193
        void joinFromTry(final Stack joinOrigin) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   194
            // As we're joining labels that can jump across block boundaries, the number of local variables can
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   195
            // differ, and we should always respect the one having less variables.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   196
            firstTemp = Math.min(firstTemp, joinOrigin.firstTemp);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   197
            assert isVariablePartitioningEqual(joinOrigin, firstTemp);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   198
            mergeVariableTypes(joinOrigin, firstTemp);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   199
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   200
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   201
        private int getFirstDeadLocal(final List<Type> types) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   202
            int i = types.size();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   203
            for(final ListIterator<Type> it = types.listIterator(i);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   204
                it.hasPrevious() && it.previous() == Type.UNKNOWN;
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   205
                --i) {
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   206
                // no body
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   207
            }
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   208
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   209
            // Respect symbol boundaries; we never chop off half a symbol's storage
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   210
            while(!symbolBoundary.get(i - 1)) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   211
                ++i;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   212
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   213
            return i;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   214
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   215
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   216
        private boolean isStackCompatible(final Stack other) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   217
            if (sp != other.sp) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   218
                return false;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   219
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   220
            for (int i = 0; i < sp; i++) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   221
                if (!data[i].isEquivalentTo(other.data[i])) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   222
                    return false;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   223
                }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   224
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   225
            return true;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   226
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   227
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   228
        private boolean isVariablePartitioningEqual(final Stack other, final int toSlot) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   229
            // No difference in the symbol boundaries before the toSlot
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   230
            final BitSet diff = other.getSymbolBoundaryCopy();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   231
            diff.xor(symbolBoundary);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   232
            return diff.previousSetBit(toSlot - 1) == -1;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   233
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   234
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   235
        void markDeadLocalVariables(final int fromSlot, final int slotCount) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   236
            final int localCount = localVariableTypes.size();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   237
            if(fromSlot >= localCount) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   238
                return;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   239
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   240
            final int toSlot = Math.min(fromSlot + slotCount, localCount);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   241
            invalidateLocalLoadsOnStack(fromSlot, toSlot);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   242
            for(int i = fromSlot; i < toSlot; ++i) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   243
                localVariableTypes.set(i, Type.UNKNOWN);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   244
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   245
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   246
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   247
        @SuppressWarnings("unchecked")
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   248
        List<Type> getLocalVariableTypesCopy() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   249
            return (List<Type>)((ArrayList<Type>)localVariableTypes).clone();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   250
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   251
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   252
        BitSet getSymbolBoundaryCopy() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   253
            return (BitSet)symbolBoundary.clone();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   254
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   255
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   256
        /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   257
         * Returns a list of local variable slot types, but for those symbols that have multiple values, only the slot
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   258
         * holding the widest type is marked as live.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   259
         * @return a list of widest local variable slot types.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   260
         */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   261
        List<Type> getWidestLiveLocals(final List<Type> lvarTypes) {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   262
            final List<Type> widestLiveLocals = new ArrayList<>(lvarTypes);
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   263
            boolean keepNextValue = true;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   264
            final int size = widestLiveLocals.size();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   265
            for(int i = size - 1; i-- > 0;) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   266
                if(symbolBoundary.get(i)) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   267
                    keepNextValue = true;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   268
                }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   269
                final Type t = widestLiveLocals.get(i);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   270
                if(t != Type.UNKNOWN) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   271
                    if(keepNextValue) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   272
                        if(t != Type.SLOT_2) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   273
                            keepNextValue = false;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   274
                        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   275
                    } else {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   276
                        widestLiveLocals.set(i, Type.UNKNOWN);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   277
                    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   278
                }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   279
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   280
            widestLiveLocals.subList(Math.max(getFirstDeadLocal(widestLiveLocals), firstTemp), widestLiveLocals.size()).clear();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   281
            return widestLiveLocals;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   282
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   283
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   284
        String markSymbolBoundariesInLvarTypesDescriptor(final String lvarDescriptor) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   285
            final char[] chars = lvarDescriptor.toCharArray();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   286
            int j = 0;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   287
            for(int i = 0; i < chars.length; ++i) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   288
                final char c = chars[i];
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   289
                final int nextj = j + CodeGeneratorLexicalContext.getTypeForSlotDescriptor(c).getSlots();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   290
                if(!symbolBoundary.get(nextj - 1)) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   291
                    chars[i] = Character.toLowerCase(c);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   292
                }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   293
                j = nextj;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   294
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   295
            return new String(chars);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   296
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   297
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
   298
        Type pop() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   299
            assert sp > 0;
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
   300
            return data[--sp];
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
   301
        }
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
   302
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   303
        @Override
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   304
        public Stack clone() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   305
            try {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   306
                final Stack clone = (Stack)super.clone();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   307
                clone.data = data.clone();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   308
                clone.localLoads = localLoads.clone();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   309
                clone.symbolBoundary = getSymbolBoundaryCopy();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   310
                clone.localVariableTypes = getLocalVariableTypesCopy();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   311
                return clone;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   312
            } catch(final CloneNotSupportedException e) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   313
                throw new AssertionError("", e);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   314
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   315
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   316
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   317
        private Stack cloneWithEmptyStack() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   318
            final Stack stack = clone();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   319
            stack.sp = 0;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   320
            return stack;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   321
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   322
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   323
        int getTopLocalLoad() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   324
            return localLoads[sp - 1];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   325
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   326
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   327
        void markLocalLoad(final int slot) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   328
            localLoads[sp - 1] = slot;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   329
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   330
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   331
        /**
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   332
         * Performs various bookeeping when a value is stored in a local variable slot.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   333
         * @param slot the slot written to
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   334
         * @param onlySymbolLiveValue if true, this is the symbol's only live value, and other values of the symbol
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   335
         * should be marked dead
30388
3a270ce8e030 8078049: Nashorn crashes when attempting to start TypeScript compiler
hannesw
parents: 27204
diff changeset
   336
         * @param type the type written to the slot
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   337
         */
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   338
        void onLocalStore(final Type type, final int slot, final boolean onlySymbolLiveValue) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   339
            if(onlySymbolLiveValue) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   340
                final int fromSlot = slot == 0 ? 0 : (symbolBoundary.previousSetBit(slot - 1) + 1);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   341
                final int toSlot = symbolBoundary.nextSetBit(slot) + 1;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   342
                for(int i = fromSlot; i < toSlot; ++i) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   343
                    localVariableTypes.set(i, Type.UNKNOWN);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   344
                }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   345
                invalidateLocalLoadsOnStack(fromSlot, toSlot);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   346
            } else {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   347
                invalidateLocalLoadsOnStack(slot, slot + type.getSlots());
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   348
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   349
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   350
            localVariableTypes.set(slot, type);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   351
            if(type.isCategory2()) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   352
                localVariableTypes.set(slot + 1, Type.SLOT_2);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   353
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   354
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   355
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   356
        /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   357
         * Given a slot range, invalidate knowledge about local loads on stack from these slots (because they're being
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   358
         * killed).
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   359
         * @param fromSlot first slot, inclusive.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   360
         * @param toSlot last slot, exclusive.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   361
         */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   362
        private void invalidateLocalLoadsOnStack(final int fromSlot, final int toSlot) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   363
            for(int i = 0; i < sp; ++i) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   364
                final int localLoad = localLoads[i];
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   365
                if(localLoad >= fromSlot && localLoad < toSlot) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   366
                    localLoads[i] = NON_LOAD;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   367
                }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   368
            }
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
   369
        }
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 17527
diff changeset
   370
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   371
        /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   372
         * Marks a range of slots as belonging to a defined local variable. The slots will start out with no live value
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   373
         * in them.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   374
         * @param fromSlot first slot, inclusive.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   375
         * @param toSlot last slot, exclusive.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   376
         */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   377
        void defineBlockLocalVariable(final int fromSlot, final int toSlot) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   378
            defineLocalVariable(fromSlot, toSlot);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   379
            assert firstTemp < toSlot;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   380
            firstTemp = toSlot;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   381
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   382
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   383
        /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   384
         * Defines a new temporary local variable and returns its allocated index.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   385
         * @param width the required width (in slots) for the new variable.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   386
         * @return the bytecode slot index where the newly allocated local begins.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   387
         */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   388
        int defineTemporaryLocalVariable(final int width) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   389
            final int fromSlot = getUsedSlotsWithLiveTemporaries();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   390
            defineLocalVariable(fromSlot, fromSlot + width);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   391
            return fromSlot;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   392
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   393
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   394
        /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   395
         * Marks a range of slots as belonging to a defined temporary local variable. The slots will start out with no
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   396
         * live value in them.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   397
         * @param fromSlot first slot, inclusive.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   398
         * @param toSlot last slot, exclusive.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   399
         */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   400
        void defineTemporaryLocalVariable(final int fromSlot, final int toSlot) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   401
            defineLocalVariable(fromSlot, toSlot);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   402
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   403
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   404
        private void defineLocalVariable(final int fromSlot, final int toSlot) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   405
            assert !hasLoadsOnStack(fromSlot, toSlot);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   406
            assert fromSlot < toSlot;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   407
            symbolBoundary.clear(fromSlot, toSlot - 1);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   408
            symbolBoundary.set(toSlot - 1);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   409
            final int lastExisting = Math.min(toSlot, localVariableTypes.size());
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   410
            for(int i = fromSlot; i < lastExisting; ++i) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   411
                localVariableTypes.set(i, Type.UNKNOWN);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   412
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   413
            for(int i = lastExisting; i < toSlot; ++i) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   414
                localVariableTypes.add(i, Type.UNKNOWN);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   415
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   416
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   417
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   418
        /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   419
         * Undefines all local variables past the specified slot.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   420
         * @param fromSlot the first slot to be undefined
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   421
         * @param canTruncateSymbol if false, the fromSlot must be either the first slot of a symbol, or the first slot
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   422
         * after the last symbol. If true, the fromSlot can be in the middle of the storage area for a symbol. This
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   423
         * should be used with care - it is only meant for use in optimism exception handlers.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   424
         */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   425
        void undefineLocalVariables(final int fromSlot, final boolean canTruncateSymbol) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   426
            final int lvarCount = localVariableTypes.size();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   427
            assert lvarCount == symbolBoundary.length();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   428
            assert !hasLoadsOnStack(fromSlot, lvarCount);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   429
            if(canTruncateSymbol) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   430
                if(fromSlot > 0) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   431
                    symbolBoundary.set(fromSlot - 1);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   432
                }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   433
            } else {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   434
                assert fromSlot == 0 || symbolBoundary.get(fromSlot - 1);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   435
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   436
            if(fromSlot < lvarCount) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   437
                symbolBoundary.clear(fromSlot, lvarCount);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   438
                localVariableTypes.subList(fromSlot, lvarCount).clear();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   439
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   440
            firstTemp = Math.min(fromSlot, firstTemp);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   441
            assert symbolBoundary.length() == localVariableTypes.size();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   442
            assert symbolBoundary.length() == fromSlot;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   443
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   444
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   445
        private void markAsOptimisticCatchHandler(final int liveLocalCount) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   446
            // Live temporaries that are no longer on stack are undefined
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   447
            undefineLocalVariables(liveLocalCount, true);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   448
            // Temporaries are promoted
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   449
            firstTemp = liveLocalCount;
32534
b3ec7f3b3c2a 8136349: Typos patch for nashorn sources submitted on Sep 10, 2015
sundar
parents: 32435
diff changeset
   450
            // No trailing undefined values
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   451
            localVariableTypes.subList(firstTemp, localVariableTypes.size()).clear();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   452
            assert symbolBoundary.length() == firstTemp;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   453
            // Generalize all reference types to Object, and promote boolean to int
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   454
            for(final ListIterator<Type> it = localVariableTypes.listIterator(); it.hasNext();) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   455
                final Type type = it.next();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   456
                if(type == Type.BOOLEAN) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   457
                    it.set(Type.INT);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   458
                } else if(type.isObject() && type != Type.OBJECT) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   459
                    it.set(Type.OBJECT);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   460
                }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   461
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   462
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   463
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   464
        /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   465
         * Returns true if any loads on the stack come from the specified slot range.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   466
         * @param fromSlot start of the range (inclusive)
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   467
         * @param toSlot end of the range (exclusive)
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   468
         * @return true if any loads on the stack come from the specified slot range.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   469
         */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   470
        boolean hasLoadsOnStack(final int fromSlot, final int toSlot) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   471
            for(int i = 0; i < sp; ++i) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   472
                final int load = localLoads[i];
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   473
                if(load >= fromSlot && load < toSlot) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   474
                    return true;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   475
                }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   476
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   477
            return false;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   478
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   479
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 17527
diff changeset
   480
        @Override
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 17527
diff changeset
   481
        public String toString() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   482
            return "stack=" + Arrays.toString(Arrays.copyOf(data, sp))
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   483
                 + ", symbolBoundaries=" + String.valueOf(symbolBoundary)
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   484
                 + ", firstTemp=" + firstTemp
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   485
                 + ", localTypes=" + String.valueOf(localVariableTypes)
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   486
                 ;
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 17527
diff changeset
   487
        }
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
   488
    }
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
   489
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   490
    /** Next id for debugging purposes, remove if footprint becomes unmanageable */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   491
    private static int nextId = 0;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   492
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   493
    /** Name of this label */
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   494
    private final String name;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   495
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   496
    /** Type stack at this label */
27204
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26887
diff changeset
   497
    private transient Label.Stack stack;
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   498
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 16240
diff changeset
   499
    /** ASM representation of this label */
32435
cfd619ef23a6 8133300: Ensure symbol table immutability in Nashorn AST
attila
parents: 30388
diff changeset
   500
    private transient jdk.internal.org.objectweb.asm.Label label;
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 16240
diff changeset
   501
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   502
    /** Id for debugging purposes, remove if footprint becomes unmanageable */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   503
    private final int id;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   504
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   505
    /** Is this label reachable (anything ever jumped to it)? */
27204
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26887
diff changeset
   506
    private transient boolean reachable;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   507
27204
06ec78f29a56 8059843: Make AST serializable
attila
parents: 26887
diff changeset
   508
    private transient boolean breakTarget;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   509
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   510
    /**
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   511
     * Constructor
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   512
     *
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   513
     * @param name name of this label
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   514
     */
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   515
    public Label(final String name) {
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   516
        super();
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   517
        this.name = name;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   518
        this.id   = nextId++;
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   519
    }
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   520
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   521
    /**
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   522
     * Copy constructor
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   523
     *
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   524
     * @param label a label to clone
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   525
     */
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   526
    public Label(final Label label) {
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   527
        super();
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   528
        this.name = label.name;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19084
diff changeset
   529
        this.id   = label.id;
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   530
    }
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   531
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 16240
diff changeset
   532
    jdk.internal.org.objectweb.asm.Label getLabel() {
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 16240
diff changeset
   533
        if (this.label == null) {
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 16240
diff changeset
   534
            this.label = new jdk.internal.org.objectweb.asm.Label();
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 16240
diff changeset
   535
        }
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 16240
diff changeset
   536
        return label;
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 16240
diff changeset
   537
    }
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 16240
diff changeset
   538
17527
6e45d9c2328c 8014329: Slim down the label stack structure in CodeGenerator
lagergren
parents: 17524
diff changeset
   539
    Label.Stack getStack() {
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   540
        return stack;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   541
    }
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   542
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   543
    void joinFrom(final Label.Stack joinOrigin) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   544
        this.reachable = true;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   545
        if(stack == null) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   546
            stack = joinOrigin.clone();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   547
        } else {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   548
            stack.joinFrom(joinOrigin, breakTarget);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   549
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   550
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   551
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   552
    void joinFromTry(final Label.Stack joinOrigin, final boolean isOptimismHandler) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   553
        this.reachable = true;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   554
        if (stack == null) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   555
            if(!isOptimismHandler) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   556
                stack = joinOrigin.cloneWithEmptyStack();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   557
                // Optimism handler needs temporaries to remain live, others don't.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   558
                stack.undefineLocalVariables(stack.firstTemp, false);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   559
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   560
        } else {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   561
            assert !isOptimismHandler;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   562
            stack.joinFromTry(joinOrigin);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   563
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   564
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   565
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   566
    void markAsBreakTarget() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   567
        breakTarget = true;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   568
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   569
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   570
    boolean isBreakTarget() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   571
        return breakTarget;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   572
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   573
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   574
    void onCatch() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   575
        if(stack != null) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   576
            stack = stack.cloneWithEmptyStack();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   577
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   578
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   579
    void markAsOptimisticCatchHandler(final Label.Stack currentStack, final int liveLocalCount) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   580
        stack = currentStack.cloneWithEmptyStack();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   581
        stack.markAsOptimisticCatchHandler(liveLocalCount);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   582
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   583
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   584
    void markAsOptimisticContinuationHandlerFor(final Label afterConsumeStackLabel) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   585
        stack = afterConsumeStackLabel.stack.cloneWithEmptyStack();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   586
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   587
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   588
    boolean isReachable() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   589
        return reachable;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   590
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   591
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   592
    boolean isAfter(final Label other) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24720
diff changeset
   593
        return label.getOffset() > other.label.getOffset();
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   594
    }
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   595
26887
f7e8b7f8f554 8059321: Decrease warmup time by caching common structures that were reused during parse
lagergren
parents: 25865
diff changeset
   596
    private String str;
f7e8b7f8f554 8059321: Decrease warmup time by caching common structures that were reused during parse
lagergren
parents: 25865
diff changeset
   597
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   598
    @Override
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   599
    public String toString() {
26887
f7e8b7f8f554 8059321: Decrease warmup time by caching common structures that were reused during parse
lagergren
parents: 25865
diff changeset
   600
        if (str == null) {
f7e8b7f8f554 8059321: Decrease warmup time by caching common structures that were reused during parse
lagergren
parents: 25865
diff changeset
   601
            str = name + '_' + id;
f7e8b7f8f554 8059321: Decrease warmup time by caching common structures that were reused during parse
lagergren
parents: 25865
diff changeset
   602
        }
f7e8b7f8f554 8059321: Decrease warmup time by caching common structures that were reused during parse
lagergren
parents: 25865
diff changeset
   603
        return str;
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   604
    }
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
diff changeset
   605
}