author | attila |
Wed, 28 Jan 2015 17:58:08 +0100 | |
changeset 28690 | 78317797ab62 |
parent 27204 | 06ec78f29a56 |
child 29407 | 3fd4ede1581e |
permissions | -rw-r--r-- |
16147 | 1 |
/* |
16151 | 2 |
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
16147 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
||
26 |
package jdk.nashorn.internal.ir; |
|
27 |
||
28 |
import java.io.PrintWriter; |
|
29 |
import java.util.ArrayList; |
|
17233 | 30 |
import java.util.Arrays; |
16147 | 31 |
import java.util.Collections; |
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16168
diff
changeset
|
32 |
import java.util.Comparator; |
17233 | 33 |
import java.util.LinkedHashMap; |
16147 | 34 |
import java.util.List; |
17233 | 35 |
import java.util.Map; |
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16234
diff
changeset
|
36 |
import jdk.nashorn.internal.codegen.Label; |
17233 | 37 |
import jdk.nashorn.internal.ir.annotations.Immutable; |
16147 | 38 |
import jdk.nashorn.internal.ir.visitor.NodeVisitor; |
39 |
||
40 |
/** |
|
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
41 |
* IR representation for a list of statements. |
16147 | 42 |
*/ |
17233 | 43 |
@Immutable |
25244
627d7e86f3b5
8047357: More precise synthetic return + unreachable throw
attila
parents:
24759
diff
changeset
|
44 |
public class Block extends Node implements BreakableNode, Terminal, Flags<Block> { |
27204 | 45 |
private static final long serialVersionUID = 1L; |
46 |
||
16147 | 47 |
/** List of statements */ |
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:
17523
diff
changeset
|
48 |
protected final List<Statement> statements; |
16147 | 49 |
|
17233 | 50 |
/** Symbol table - keys must be returned in the order they were put in. */ |
51 |
protected final Map<String, Symbol> symbols; |
|
16147 | 52 |
|
53 |
/** Entry label. */ |
|
24719 | 54 |
private final Label entryLabel; |
16147 | 55 |
|
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
56 |
/** Break label. */ |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
57 |
private final Label breakLabel; |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
58 |
|
17233 | 59 |
/** Does the block/function need a new scope? */ |
60 |
protected final int flags; |
|
61 |
||
24751 | 62 |
/** |
63 |
* @see JoinPredecessor |
|
64 |
*/ |
|
65 |
private final LocalVariableConversion conversion; |
|
66 |
||
17233 | 67 |
/** Flag indicating that this block needs scope */ |
68 |
public static final int NEEDS_SCOPE = 1 << 0; |
|
16147 | 69 |
|
17233 | 70 |
/** |
71 |
* Is this block tagged as terminal based on its contents |
|
72 |
* (usually the last statement) |
|
73 |
*/ |
|
74 |
public static final int IS_TERMINAL = 1 << 2; |
|
16147 | 75 |
|
76 |
/** |
|
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
77 |
* Is this block the eager global scope - i.e. the original program. This isn't true for the |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
78 |
* outermost level of recompiles |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
79 |
*/ |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
80 |
public static final int IS_GLOBAL_SCOPE = 1 << 3; |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
81 |
|
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
82 |
/** |
16147 | 83 |
* Constructor |
84 |
* |
|
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
85 |
* @param token The first token of the block |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
86 |
* @param finish The index of the last character |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
87 |
* @param flags The flags of the block |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
88 |
* @param statements All statements in the block |
16147 | 89 |
*/ |
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
90 |
public Block(final long token, final int finish, final int flags, final Statement... statements) { |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
91 |
super(token, finish); |
16147 | 92 |
|
17233 | 93 |
this.statements = Arrays.asList(statements); |
94 |
this.symbols = new LinkedHashMap<>(); |
|
16147 | 95 |
this.entryLabel = new Label("block_entry"); |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
96 |
this.breakLabel = new Label("block_break"); |
19100
62d400be5b44
8021244: Inconsistent stackmap with splitter threshold set very low
hannesw
parents:
19095
diff
changeset
|
97 |
final int len = statements.length; |
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
98 |
final int terminalFlags = len > 0 && statements[len - 1].hasTerminalFlags() ? IS_TERMINAL : 0; |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
99 |
this.flags = terminalFlags | flags; |
24751 | 100 |
this.conversion = null; |
16147 | 101 |
} |
102 |
||
103 |
/** |
|
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
104 |
* Constructs a new block |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
105 |
* |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
106 |
* @param token The first token of the block |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
107 |
* @param finish The index of the last character |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
108 |
* @param statements All statements in the block |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
109 |
*/ |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
110 |
public Block(final long token, final int finish, final Statement...statements){ |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
111 |
this(token, finish, 0, statements); |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
112 |
} |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
113 |
|
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
114 |
/** |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
115 |
* Constructs a new block |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
116 |
* |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
117 |
* @param token The first token of the block |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
118 |
* @param finish The index of the last character |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
119 |
* @param statements All statements in the block |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
120 |
*/ |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
121 |
public Block(final long token, final int finish, final List<Statement> statements){ |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
122 |
this(token, finish, 0, statements); |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
123 |
} |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
124 |
|
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
125 |
/** |
17233 | 126 |
* Constructor |
16147 | 127 |
* |
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
128 |
* @param token The first token of the block |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
129 |
* @param finish The index of the last character |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
130 |
* @param flags The flags of the block |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
131 |
* @param statements All statements in the block |
16147 | 132 |
*/ |
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
133 |
public Block(final long token, final int finish, final int flags, final List<Statement> statements) { |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
134 |
this(token, finish, flags, statements.toArray(new Statement[statements.size()])); |
17233 | 135 |
} |
16147 | 136 |
|
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
137 |
private Block(final Block block, final int finish, final List<Statement> statements, final int flags, final Map<String, Symbol> symbols, final LocalVariableConversion conversion) { |
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26503
diff
changeset
|
138 |
super(block, finish); |
17233 | 139 |
this.statements = statements; |
140 |
this.flags = flags; |
|
17518
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
141 |
this.symbols = new LinkedHashMap<>(symbols); //todo - symbols have no dependencies on any IR node and can as far as we understand it be shallow copied now |
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16234
diff
changeset
|
142 |
this.entryLabel = new Label(block.entryLabel); |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
143 |
this.breakLabel = new Label(block.breakLabel); |
24751 | 144 |
this.conversion = conversion; |
17518
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
145 |
} |
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
146 |
|
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
147 |
/** |
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
148 |
* Is this block the outermost eager global scope - i.e. the primordial program? |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
149 |
* Used for global anchor point for scope depth computation for recompilation code |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
150 |
* @return true if outermost eager global scope |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
151 |
*/ |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
152 |
public boolean isGlobalScope() { |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
153 |
return getFlag(IS_GLOBAL_SCOPE); |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
154 |
} |
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
155 |
|
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
156 |
/** |
24751 | 157 |
* Clear the symbols in the block. |
158 |
* TODO: make this immutable. |
|
17518
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
159 |
*/ |
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
160 |
public void clearSymbols() { |
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
161 |
symbols.clear(); |
16147 | 162 |
} |
163 |
||
164 |
@Override |
|
17233 | 165 |
public Node ensureUniqueLabels(final LexicalContext lc) { |
24751 | 166 |
return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols, conversion)); |
16147 | 167 |
} |
168 |
||
169 |
/** |
|
170 |
* Assist in IR navigation. |
|
171 |
* |
|
172 |
* @param visitor IR navigating visitor. |
|
173 |
* @return new or same node |
|
174 |
*/ |
|
175 |
@Override |
|
17769
14ea7feaf658
8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents:
17524
diff
changeset
|
176 |
public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) { |
17233 | 177 |
if (visitor.enterBlock(this)) { |
25821
fbb51e67d2a7
8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents:
25244
diff
changeset
|
178 |
return visitor.leaveBlock(setStatements(lc, Node.accept(visitor, statements))); |
16147 | 179 |
} |
180 |
||
181 |
return this; |
|
182 |
} |
|
183 |
||
184 |
/** |
|
24751 | 185 |
* Get a copy of the list for all the symbols defined in this block |
16523
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16240
diff
changeset
|
186 |
* @return symbol iterator |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16240
diff
changeset
|
187 |
*/ |
17518
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
188 |
public List<Symbol> getSymbols() { |
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
189 |
return Collections.unmodifiableList(new ArrayList<>(symbols.values())); |
16523
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16240
diff
changeset
|
190 |
} |
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16240
diff
changeset
|
191 |
|
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16240
diff
changeset
|
192 |
/** |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16523
diff
changeset
|
193 |
* Retrieves an existing symbol defined in the current block. |
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16523
diff
changeset
|
194 |
* @param name the name of the symbol |
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16523
diff
changeset
|
195 |
* @return an existing symbol with the specified name defined in the current block, or null if this block doesn't |
17518
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
196 |
* define a symbol with this name.T |
16147 | 197 |
*/ |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16523
diff
changeset
|
198 |
public Symbol getExistingSymbol(final String name) { |
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16523
diff
changeset
|
199 |
return symbols.get(name); |
16147 | 200 |
} |
201 |
||
202 |
/** |
|
203 |
* Test if this block represents a <tt>catch</tt> block in a <tt>try</tt> statement. |
|
204 |
* This is used by the Splitter as catch blocks are not be subject to splitting. |
|
205 |
* |
|
206 |
* @return true if this block represents a catch block in a try statement. |
|
207 |
*/ |
|
208 |
public boolean isCatchBlock() { |
|
209 |
return statements.size() == 1 && statements.get(0) instanceof CatchNode; |
|
210 |
} |
|
211 |
||
212 |
@Override |
|
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
213 |
public void toString(final StringBuilder sb, final boolean printType) { |
16147 | 214 |
for (final Node statement : statements) { |
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
215 |
statement.toString(sb, printType); |
16147 | 216 |
sb.append(';'); |
217 |
} |
|
218 |
} |
|
219 |
||
220 |
/** |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16168
diff
changeset
|
221 |
* Print symbols in block in alphabetical order, sorted on name |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16168
diff
changeset
|
222 |
* Used for debugging, see the --print-symbols flag |
16147 | 223 |
* |
224 |
* @param stream print writer to output symbols to |
|
225 |
* |
|
226 |
* @return true if symbols were found |
|
227 |
*/ |
|
228 |
public boolean printSymbols(final PrintWriter stream) { |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16168
diff
changeset
|
229 |
final List<Symbol> values = new ArrayList<>(symbols.values()); |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16168
diff
changeset
|
230 |
|
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16168
diff
changeset
|
231 |
Collections.sort(values, new Comparator<Symbol>() { |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16168
diff
changeset
|
232 |
@Override |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16168
diff
changeset
|
233 |
public int compare(final Symbol s0, final Symbol s1) { |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16168
diff
changeset
|
234 |
return s0.getName().compareTo(s1.getName()); |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16168
diff
changeset
|
235 |
} |
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16168
diff
changeset
|
236 |
}); |
16147 | 237 |
|
238 |
for (final Symbol symbol : values) { |
|
239 |
symbol.print(stream); |
|
240 |
} |
|
241 |
||
242 |
return !values.isEmpty(); |
|
243 |
} |
|
244 |
||
245 |
/** |
|
17233 | 246 |
* Tag block as terminal or non terminal |
247 |
* @param lc lexical context |
|
248 |
* @param isTerminal is block terminal |
|
249 |
* @return same block, or new if flag changed |
|
16147 | 250 |
*/ |
17233 | 251 |
public Block setIsTerminal(final LexicalContext lc, final boolean isTerminal) { |
252 |
return isTerminal ? setFlag(lc, IS_TERMINAL) : clearFlag(lc, IS_TERMINAL); |
|
253 |
} |
|
254 |
||
255 |
@Override |
|
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24725
diff
changeset
|
256 |
public int getFlags() { |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24725
diff
changeset
|
257 |
return flags; |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24725
diff
changeset
|
258 |
} |
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24725
diff
changeset
|
259 |
|
25244
627d7e86f3b5
8047357: More precise synthetic return + unreachable throw
attila
parents:
24759
diff
changeset
|
260 |
/** |
627d7e86f3b5
8047357: More precise synthetic return + unreachable throw
attila
parents:
24759
diff
changeset
|
261 |
* Is this a terminal block, i.e. does it end control flow like ending with a throw or return? |
627d7e86f3b5
8047357: More precise synthetic return + unreachable throw
attila
parents:
24759
diff
changeset
|
262 |
* |
627d7e86f3b5
8047357: More precise synthetic return + unreachable throw
attila
parents:
24759
diff
changeset
|
263 |
* @return true if this node statement is terminal |
627d7e86f3b5
8047357: More precise synthetic return + unreachable throw
attila
parents:
24759
diff
changeset
|
264 |
*/ |
24738
be2026c9717c
8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents:
24725
diff
changeset
|
265 |
@Override |
17233 | 266 |
public boolean isTerminal() { |
267 |
return getFlag(IS_TERMINAL); |
|
16147 | 268 |
} |
269 |
||
270 |
/** |
|
271 |
* Get the entry label for this block |
|
272 |
* @return the entry label |
|
273 |
*/ |
|
274 |
public Label getEntryLabel() { |
|
275 |
return entryLabel; |
|
276 |
} |
|
277 |
||
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
278 |
@Override |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
279 |
public Label getBreakLabel() { |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
280 |
return breakLabel; |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
281 |
} |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
282 |
|
24751 | 283 |
@Override |
284 |
public Block setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) { |
|
285 |
if(this.conversion == conversion) { |
|
286 |
return this; |
|
287 |
} |
|
288 |
return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols, conversion)); |
|
289 |
} |
|
290 |
||
291 |
@Override |
|
292 |
public LocalVariableConversion getLocalVariableConversion() { |
|
293 |
return conversion; |
|
294 |
} |
|
295 |
||
16147 | 296 |
/** |
297 |
* Get the list of statements in this block |
|
298 |
* |
|
299 |
* @return a list of statements |
|
300 |
*/ |
|
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:
17523
diff
changeset
|
301 |
public List<Statement> getStatements() { |
16147 | 302 |
return Collections.unmodifiableList(statements); |
303 |
} |
|
304 |
||
305 |
/** |
|
26503 | 306 |
* Returns the number of statements in the block. |
307 |
* @return the number of statements in the block. |
|
308 |
*/ |
|
309 |
public int getStatementCount() { |
|
310 |
return statements.size(); |
|
311 |
} |
|
312 |
||
313 |
/** |
|
24751 | 314 |
* Returns the line number of the first statement in the block. |
315 |
* @return the line number of the first statement in the block, or -1 if the block has no statements. |
|
316 |
*/ |
|
317 |
public int getFirstStatementLineNumber() { |
|
318 |
if(statements == null || statements.isEmpty()) { |
|
319 |
return -1; |
|
320 |
} |
|
321 |
return statements.get(0).getLineNumber(); |
|
322 |
} |
|
323 |
||
324 |
/** |
|
28690 | 325 |
* Returns the last statement in the block. |
326 |
* @return the last statement in the block, or null if the block has no statements. |
|
327 |
*/ |
|
328 |
public Statement getLastStatement() { |
|
329 |
return statements.isEmpty() ? null : statements.get(statements.size() - 1); |
|
330 |
} |
|
331 |
||
332 |
/** |
|
16147 | 333 |
* Reset the statement list for this block |
334 |
* |
|
17233 | 335 |
* @param lc lexical context |
336 |
* @param statements new statement list |
|
337 |
* @return new block if statements changed, identity of statements == block.statements |
|
16147 | 338 |
*/ |
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:
17523
diff
changeset
|
339 |
public Block setStatements(final LexicalContext lc, final List<Statement> statements) { |
17233 | 340 |
if (this.statements == statements) { |
341 |
return this; |
|
342 |
} |
|
343 |
int lastFinish = 0; |
|
344 |
if (!statements.isEmpty()) { |
|
345 |
lastFinish = statements.get(statements.size() - 1).getFinish(); |
|
346 |
} |
|
24751 | 347 |
return Node.replaceInLexicalContext(lc, this, new Block(this, Math.max(finish, lastFinish), statements, flags, symbols, conversion)); |
16147 | 348 |
} |
349 |
||
350 |
/** |
|
351 |
* Add or overwrite an existing symbol in the block |
|
352 |
* |
|
17518
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
353 |
* @param lc get lexical context |
16147 | 354 |
* @param symbol symbol |
355 |
*/ |
|
17518
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
356 |
public void putSymbol(final LexicalContext lc, final Symbol symbol) { |
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
357 |
symbols.put(symbol.getName(), symbol); |
16147 | 358 |
} |
359 |
||
360 |
/** |
|
361 |
* Check whether scope is necessary for this Block |
|
362 |
* |
|
363 |
* @return true if this function needs a scope |
|
364 |
*/ |
|
365 |
public boolean needsScope() { |
|
17233 | 366 |
return (flags & NEEDS_SCOPE) == NEEDS_SCOPE; |
367 |
} |
|
368 |
||
369 |
@Override |
|
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
370 |
public Block setFlags(final LexicalContext lc, final int flags) { |
17233 | 371 |
if (this.flags == flags) { |
372 |
return this; |
|
373 |
} |
|
24751 | 374 |
return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols, conversion)); |
17233 | 375 |
} |
376 |
||
377 |
@Override |
|
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
378 |
public Block clearFlag(final LexicalContext lc, final int flag) { |
17233 | 379 |
return setFlags(lc, flags & ~flag); |
380 |
} |
|
381 |
||
382 |
@Override |
|
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
383 |
public Block setFlag(final LexicalContext lc, final int flag) { |
17233 | 384 |
return setFlags(lc, flags | flag); |
385 |
} |
|
386 |
||
387 |
@Override |
|
388 |
public boolean getFlag(final int flag) { |
|
389 |
return (flags & flag) == flag; |
|
16147 | 390 |
} |
391 |
||
392 |
/** |
|
16168
f0c208287983
8005976: Break out AccessSpecializer into one pass before CodeGenerator instead of iterative applications from CodeGenerator
lagergren
parents:
16160
diff
changeset
|
393 |
* Set the needs scope flag. |
17233 | 394 |
* @param lc lexicalContext |
395 |
* @return new block if state changed, otherwise this |
|
16147 | 396 |
*/ |
17233 | 397 |
public Block setNeedsScope(final LexicalContext lc) { |
398 |
if (needsScope()) { |
|
399 |
return this; |
|
400 |
} |
|
401 |
||
24751 | 402 |
return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags | NEEDS_SCOPE, symbols, conversion)); |
16147 | 403 |
} |
404 |
||
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16523
diff
changeset
|
405 |
/** |
17233 | 406 |
* Computationally determine the next slot for this block, |
407 |
* indexed from 0. Use this as a relative base when computing |
|
408 |
* frames |
|
409 |
* @return next slot |
|
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16523
diff
changeset
|
410 |
*/ |
17233 | 411 |
public int nextSlot() { |
412 |
int next = 0; |
|
17518
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
413 |
for (final Symbol symbol : getSymbols()) { |
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
414 |
if (symbol.hasSlot()) { |
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
415 |
next += symbol.slotCount(); |
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17233
diff
changeset
|
416 |
} |
17233 | 417 |
} |
418 |
return next; |
|
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16523
diff
changeset
|
419 |
} |
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16523
diff
changeset
|
420 |
|
17233 | 421 |
@Override |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
422 |
public boolean isBreakableWithoutLabel() { |
17233 | 423 |
return false; |
16530
201d682e75f4
8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
16523
diff
changeset
|
424 |
} |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
425 |
|
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
426 |
@Override |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
427 |
public List<Label> getLabels() { |
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24751
diff
changeset
|
428 |
return Collections.unmodifiableList(Arrays.asList(entryLabel, breakLabel)); |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
429 |
} |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
430 |
|
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
431 |
@Override |
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
432 |
public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { |
18867
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
433 |
return Acceptor.accept(this, visitor); |
bc91e3fcc5ba
8013925: Remove symbol fields from nodes that don't need them
attila
parents:
17769
diff
changeset
|
434 |
} |
16147 | 435 |
} |