Mercurial > hg > truffle
annotate src/share/vm/opto/compile.hpp @ 17716:cdb71841f4bc
6498581: ThreadInterruptTest3 produces wrong output on Windows
Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set.
Reviewed-by: acorn, kvn
Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author | minqi |
---|---|
date | Wed, 26 Feb 2014 15:20:41 -0800 |
parents | 849eb7bfceac |
children | abec000618bf 606acabe7b5c |
rev | line source |
---|---|
0 | 1 /* |
10405 | 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
0 | 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. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_OPTO_COMPILE_HPP |
26 #define SHARE_VM_OPTO_COMPILE_HPP | |
27 | |
28 #include "asm/codeBuffer.hpp" | |
29 #include "ci/compilerInterface.hpp" | |
30 #include "code/debugInfoRec.hpp" | |
31 #include "code/exceptionHandlerTable.hpp" | |
32 #include "compiler/compilerOracle.hpp" | |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
33 #include "compiler/compileBroker.hpp" |
1972 | 34 #include "libadt/dict.hpp" |
35 #include "libadt/port.hpp" | |
36 #include "libadt/vectset.hpp" | |
37 #include "memory/resourceArea.hpp" | |
38 #include "opto/idealGraphPrinter.hpp" | |
10405 | 39 #include "opto/phasetype.hpp" |
1972 | 40 #include "opto/phase.hpp" |
41 #include "opto/regmask.hpp" | |
42 #include "runtime/deoptimization.hpp" | |
43 #include "runtime/vmThread.hpp" | |
10405 | 44 #include "trace/tracing.hpp" |
13400
86e6d691f2e1
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
13045
diff
changeset
|
45 #include "utilities/ticks.hpp" |
1972 | 46 |
0 | 47 class Block; |
48 class Bundle; | |
49 class C2Compiler; | |
50 class CallGenerator; | |
51 class ConnectionGraph; | |
52 class InlineTree; | |
53 class Int_Array; | |
54 class Matcher; | |
2008 | 55 class MachConstantNode; |
56 class MachConstantBaseNode; | |
0 | 57 class MachNode; |
2008 | 58 class MachOper; |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
59 class MachSafePointNode; |
0 | 60 class Node; |
61 class Node_Array; | |
62 class Node_Notes; | |
63 class OptoReg; | |
64 class PhaseCFG; | |
65 class PhaseGVN; | |
1172 | 66 class PhaseIterGVN; |
0 | 67 class PhaseRegAlloc; |
68 class PhaseCCP; | |
69 class PhaseCCP_DCE; | |
70 class RootNode; | |
71 class relocInfo; | |
72 class Scope; | |
73 class StartNode; | |
74 class SafePointNode; | |
75 class JVMState; | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
10405
diff
changeset
|
76 class Type; |
0 | 77 class TypeData; |
78 class TypePtr; | |
7478 | 79 class TypeOopPtr; |
0 | 80 class TypeFunc; |
81 class Unique_Node_List; | |
82 class nmethod; | |
83 class WarmCallInfo; | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
84 class Node_Stack; |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
85 struct Final_Reshape_Counts; |
0 | 86 |
87 //------------------------------Compile---------------------------------------- | |
88 // This class defines a top-level Compiler invocation. | |
89 | |
90 class Compile : public Phase { | |
3939 | 91 friend class VMStructs; |
92 | |
0 | 93 public: |
94 // Fixed alias indexes. (See also MergeMemNode.) | |
95 enum { | |
96 AliasIdxTop = 1, // pseudo-index, aliases to nothing (used as sentinel value) | |
97 AliasIdxBot = 2, // pseudo-index, aliases to everything | |
98 AliasIdxRaw = 3 // hard-wired index for TypeRawPtr::BOTTOM | |
99 }; | |
100 | |
101 // Variant of TraceTime(NULL, &_t_accumulator, TimeCompiler); | |
102 // Integrated with logging. If logging is turned on, and dolog is true, | |
103 // then brackets are put into the log, with time stamps and node counts. | |
104 // (The time collection itself is always conditionalized on TimeCompiler.) | |
105 class TracePhase : public TraceTime { | |
106 private: | |
107 Compile* C; | |
108 CompileLog* _log; | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
109 const char* _phase_name; |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
110 bool _dolog; |
0 | 111 public: |
112 TracePhase(const char* name, elapsedTimer* accumulator, bool dolog); | |
113 ~TracePhase(); | |
114 }; | |
115 | |
116 // Information per category of alias (memory slice) | |
117 class AliasType { | |
118 private: | |
119 friend class Compile; | |
120 | |
121 int _index; // unique index, used with MergeMemNode | |
122 const TypePtr* _adr_type; // normalized address type | |
123 ciField* _field; // relevant instance field, or null if none | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
10405
diff
changeset
|
124 const Type* _element; // relevant array element type, or null if none |
0 | 125 bool _is_rewritable; // false if the memory is write-once only |
126 int _general_index; // if this is type is an instance, the general | |
127 // type that this is an instance of | |
128 | |
129 void Init(int i, const TypePtr* at); | |
130 | |
131 public: | |
132 int index() const { return _index; } | |
133 const TypePtr* adr_type() const { return _adr_type; } | |
134 ciField* field() const { return _field; } | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
10405
diff
changeset
|
135 const Type* element() const { return _element; } |
0 | 136 bool is_rewritable() const { return _is_rewritable; } |
137 bool is_volatile() const { return (_field ? _field->is_volatile() : false); } | |
138 int general_index() const { return (_general_index != 0) ? _general_index : _index; } | |
139 | |
140 void set_rewritable(bool z) { _is_rewritable = z; } | |
141 void set_field(ciField* f) { | |
142 assert(!_field,""); | |
143 _field = f; | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
10405
diff
changeset
|
144 if (f->is_final() || f->is_stable()) { |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
10405
diff
changeset
|
145 // In the case of @Stable, multiple writes are possible but may be assumed to be no-ops. |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
10405
diff
changeset
|
146 _is_rewritable = false; |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
10405
diff
changeset
|
147 } |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
10405
diff
changeset
|
148 } |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
10405
diff
changeset
|
149 void set_element(const Type* e) { |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
10405
diff
changeset
|
150 assert(_element == NULL, ""); |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
10405
diff
changeset
|
151 _element = e; |
0 | 152 } |
153 | |
154 void print_on(outputStream* st) PRODUCT_RETURN; | |
155 }; | |
156 | |
157 enum { | |
158 logAliasCacheSize = 6, | |
159 AliasCacheSize = (1<<logAliasCacheSize) | |
160 }; | |
161 struct AliasCacheEntry { const TypePtr* _adr_type; int _index; }; // simple duple type | |
162 enum { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
163 trapHistLength = MethodData::_trap_hist_limit |
0 | 164 }; |
165 | |
2008 | 166 // Constant entry of the constant table. |
167 class Constant { | |
168 private: | |
169 BasicType _type; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
170 union { |
6888
cfe522e6461c
8000623: tools/javac/Diagnostics/6769027/T6769027.java crashes in PSPromotionManager::copy_to_survivor_space
kvn
parents:
6792
diff
changeset
|
171 jvalue _value; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
172 Metadata* _metadata; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
173 } _v; |
2008 | 174 int _offset; // offset of this constant (in bytes) relative to the constant table base. |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
175 float _freq; |
2008 | 176 bool _can_be_reused; // true (default) if the value can be shared with other users. |
177 | |
178 public: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
179 Constant() : _type(T_ILLEGAL), _offset(-1), _freq(0.0f), _can_be_reused(true) { _v._value.l = 0; } |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
180 Constant(BasicType type, jvalue value, float freq = 0.0f, bool can_be_reused = true) : |
2008 | 181 _type(type), |
182 _offset(-1), | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
183 _freq(freq), |
2008 | 184 _can_be_reused(can_be_reused) |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
185 { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
186 assert(type != T_METADATA, "wrong constructor"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
187 _v._value = value; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
188 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
189 Constant(Metadata* metadata, bool can_be_reused = true) : |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
190 _type(T_METADATA), |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
191 _offset(-1), |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
192 _freq(0.0f), |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
193 _can_be_reused(can_be_reused) |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
194 { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
195 _v._metadata = metadata; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
196 } |
2008 | 197 |
198 bool operator==(const Constant& other); | |
199 | |
200 BasicType type() const { return _type; } | |
201 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
202 jlong get_jlong() const { return _v._value.j; } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
203 jfloat get_jfloat() const { return _v._value.f; } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
204 jdouble get_jdouble() const { return _v._value.d; } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
205 jobject get_jobject() const { return _v._value.l; } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
206 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
207 Metadata* get_metadata() const { return _v._metadata; } |
2008 | 208 |
209 int offset() const { return _offset; } | |
210 void set_offset(int offset) { _offset = offset; } | |
211 | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
212 float freq() const { return _freq; } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
213 void inc_freq(float freq) { _freq += freq; } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
214 |
2008 | 215 bool can_be_reused() const { return _can_be_reused; } |
216 }; | |
217 | |
218 // Constant table. | |
219 class ConstantTable { | |
220 private: | |
221 GrowableArray<Constant> _constants; // Constants of this table. | |
222 int _size; // Size in bytes the emitted constant table takes (including padding). | |
223 int _table_base_offset; // Offset of the table base that gets added to the constant offsets. | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
224 int _nof_jump_tables; // Number of jump-tables in this constant table. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
225 |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
226 static int qsort_comparator(Constant* a, Constant* b); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
227 |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
228 // We use negative frequencies to keep the order of the |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
229 // jump-tables in which they were added. Otherwise we get into |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
230 // trouble with relocation. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
231 float next_jump_table_freq() { return -1.0f * (++_nof_jump_tables); } |
2008 | 232 |
233 public: | |
234 ConstantTable() : | |
235 _size(-1), | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
236 _table_base_offset(-1), // We can use -1 here since the constant table is always bigger than 2 bytes (-(size / 2), see MachConstantBaseNode::emit). |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
237 _nof_jump_tables(0) |
2008 | 238 {} |
239 | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
240 int size() const { assert(_size != -1, "not calculated yet"); return _size; } |
2008 | 241 |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
242 int calculate_table_base_offset() const; // AD specific |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
243 void set_table_base_offset(int x) { assert(_table_base_offset == -1 || x == _table_base_offset, "can't change"); _table_base_offset = x; } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
244 int table_base_offset() const { assert(_table_base_offset != -1, "not set yet"); return _table_base_offset; } |
2008 | 245 |
246 void emit(CodeBuffer& cb); | |
247 | |
248 // Returns the offset of the last entry (the top) of the constant table. | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
249 int top_offset() const { assert(_constants.top().offset() != -1, "not bound yet"); return _constants.top().offset(); } |
2008 | 250 |
251 void calculate_offsets_and_size(); | |
252 int find_offset(Constant& con) const; | |
253 | |
254 void add(Constant& con); | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
255 Constant add(MachConstantNode* n, BasicType type, jvalue value); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
256 Constant add(Metadata* metadata); |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
257 Constant add(MachConstantNode* n, MachOper* oper); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
258 Constant add(MachConstantNode* n, jfloat f) { |
2008 | 259 jvalue value; value.f = f; |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
260 return add(n, T_FLOAT, value); |
2008 | 261 } |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
262 Constant add(MachConstantNode* n, jdouble d) { |
2008 | 263 jvalue value; value.d = d; |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
264 return add(n, T_DOUBLE, value); |
2008 | 265 } |
266 | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
267 // Jump-table |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
268 Constant add_jump_table(MachConstantNode* n); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
3939
diff
changeset
|
269 void fill_jump_table(CodeBuffer& cb, MachConstantNode* n, GrowableArray<Label*> labels) const; |
2008 | 270 }; |
271 | |
0 | 272 private: |
273 // Fixed parameters to this compilation. | |
274 const int _compile_id; | |
275 const bool _save_argument_registers; // save/restore arg regs for trampolines | |
276 const bool _subsume_loads; // Load can be matched as part of a larger op. | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
277 const bool _do_escape_analysis; // Do escape analysis. |
10278 | 278 const bool _eliminate_boxing; // Do boxing elimination. |
0 | 279 ciMethod* _method; // The method being compiled. |
280 int _entry_bci; // entry bci for osr methods. | |
281 const TypeFunc* _tf; // My kind of signature | |
282 InlineTree* _ilt; // Ditto (temporary). | |
283 address _stub_function; // VM entry for stub being compiled, or NULL | |
284 const char* _stub_name; // Name of stub or adapter being compiled, or NULL | |
285 address _stub_entry_point; // Compile code entry for generated stub, or NULL | |
286 | |
287 // Control of this compilation. | |
288 int _num_loop_opts; // Number of iterations for doing loop optimiztions | |
289 int _max_inline_size; // Max inline size for this compilation | |
290 int _freq_inline_size; // Max hot method inline size for this compilation | |
291 int _fixed_slots; // count of frame slots not allocated by the register | |
292 // allocator i.e. locks, original deopt pc, etc. | |
293 // For deopt | |
294 int _orig_pc_slot; | |
295 int _orig_pc_slot_offset_in_bytes; | |
296 | |
297 int _major_progress; // Count of something big happening | |
7473 | 298 bool _inlining_progress; // progress doing incremental inlining? |
299 bool _inlining_incrementally;// Are we doing incremental inlining (post parse) | |
0 | 300 bool _has_loops; // True if the method _may_ have some loops |
301 bool _has_split_ifs; // True if the method _may_ have some split-if | |
302 bool _has_unsafe_access; // True if the method _may_ produce faults in unsafe loads or stores. | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
303 bool _has_stringbuilder; // True StringBuffers or StringBuilders are allocated |
10278 | 304 bool _has_boxed_value; // True if a boxed object is allocated |
6792
137868b7aa6f
7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents:
6725
diff
changeset
|
305 int _max_vector_size; // Maximum size of generated vectors |
0 | 306 uint _trap_hist[trapHistLength]; // Cumulative traps |
307 bool _trap_can_recompile; // Have we emitted a recompiling trap? | |
308 uint _decompile_count; // Cumulative decompilation counts. | |
309 bool _do_inlining; // True if we intend to do inlining | |
310 bool _do_scheduling; // True if we intend to do scheduling | |
418 | 311 bool _do_freq_based_layout; // True if we intend to do frequency based block layout |
0 | 312 bool _do_count_invocations; // True if we generate code to count invocations |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5927
diff
changeset
|
313 bool _do_method_data_update; // True if we generate code to update MethodData*s |
0 | 314 int _AliasLevel; // Locally-adjusted version of AliasLevel flag. |
315 bool _print_assembly; // True if we should dump assembly code for this compilation | |
12295 | 316 bool _print_inlining; // True if we should print inlining for this compilation |
317 bool _print_intrinsics; // True if we should print intrinsics for this compilation | |
0 | 318 #ifndef PRODUCT |
319 bool _trace_opto_output; | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
196
diff
changeset
|
320 bool _parsed_irreducible_loop; // True if ciTypeFlow detected irreducible loops during parsing |
0 | 321 #endif |
322 | |
1265 | 323 // JSR 292 |
324 bool _has_method_handle_invokes; // True if this method has MethodHandle invokes. | |
325 | |
0 | 326 // Compilation environment. |
327 Arena _comp_arena; // Arena with lifetime equivalent to Compile | |
328 ciEnv* _env; // CI interface | |
329 CompileLog* _log; // from CompilerThread | |
330 const char* _failure_reason; // for record_failure/failing pattern | |
331 GrowableArray<CallGenerator*>* _intrinsics; // List of intrinsics. | |
332 GrowableArray<Node*>* _macro_nodes; // List of nodes which need to be expanded before matching. | |
1172 | 333 GrowableArray<Node*>* _predicate_opaqs; // List of Opaque1 nodes for the loop predicates. |
8048
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
334 GrowableArray<Node*>* _expensive_nodes; // List of nodes that are expensive to compute and that we'd better not let the GVN freely common |
0 | 335 ConnectionGraph* _congraph; |
336 #ifndef PRODUCT | |
337 IdealGraphPrinter* _printer; | |
338 #endif | |
339 | |
10405 | 340 |
0 | 341 // Node management |
342 uint _unique; // Counter for unique Node indices | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
343 VectorSet _dead_node_list; // Set of dead nodes |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
344 uint _dead_node_count; // Number of dead nodes; VectorSet::Size() is O(N). |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
345 // So use this to keep count and make the call O(1). |
0 | 346 debug_only(static int _debug_idx;) // Monotonic counter (not reset), use -XX:BreakAtNode=<idx> |
347 Arena _node_arena; // Arena for new-space Nodes | |
348 Arena _old_arena; // Arena for old-space Nodes, lifetime during xform | |
349 RootNode* _root; // Unique root of compilation, or NULL after bail-out. | |
350 Node* _top; // Unique top node. (Reset by various phases.) | |
351 | |
352 Node* _immutable_memory; // Initial memory state | |
353 | |
354 Node* _recent_alloc_obj; | |
355 Node* _recent_alloc_ctl; | |
356 | |
2008 | 357 // Constant table |
358 ConstantTable _constant_table; // The constant table for this compile. | |
359 MachConstantBaseNode* _mach_constant_base_node; // Constant table base node singleton. | |
360 | |
361 | |
0 | 362 // Blocked array of debugging and profiling information, |
363 // tracked per node. | |
364 enum { _log2_node_notes_block_size = 8, | |
365 _node_notes_block_size = (1<<_log2_node_notes_block_size) | |
366 }; | |
367 GrowableArray<Node_Notes*>* _node_note_array; | |
368 Node_Notes* _default_node_notes; // default notes for new nodes | |
369 | |
370 // After parsing and every bulk phase we hang onto the Root instruction. | |
371 // The RootNode instruction is where the whole program begins. It produces | |
372 // the initial Control and BOTTOM for everybody else. | |
373 | |
374 // Type management | |
375 Arena _Compile_types; // Arena for all types | |
376 Arena* _type_arena; // Alias for _Compile_types except in Initialize_shared() | |
377 Dict* _type_dict; // Intern table | |
378 void* _type_hwm; // Last allocation (see Type::operator new/delete) | |
379 size_t _type_last_size; // Last allocation size (see Type::operator new/delete) | |
380 ciMethod* _last_tf_m; // Cache for | |
381 const TypeFunc* _last_tf; // TypeFunc::make | |
382 AliasType** _alias_types; // List of alias types seen so far. | |
383 int _num_alias_types; // Logical length of _alias_types | |
384 int _max_alias_types; // Physical length of _alias_types | |
385 AliasCacheEntry _alias_cache[AliasCacheSize]; // Gets aliases w/o data structure walking | |
386 | |
387 // Parsing, optimization | |
388 PhaseGVN* _initial_gvn; // Results of parse-time PhaseGVN | |
389 Unique_Node_List* _for_igvn; // Initial work-list for next round of Iterative GVN | |
390 WarmCallInfo* _warm_calls; // Sorted work-list for heat-based inlining. | |
391 | |
7473 | 392 GrowableArray<CallGenerator*> _late_inlines; // List of CallGenerators to be revisited after |
393 // main parsing has finished. | |
394 GrowableArray<CallGenerator*> _string_late_inlines; // same but for string operations | |
395 | |
10278 | 396 GrowableArray<CallGenerator*> _boxing_late_inlines; // same but for boxing operations |
397 | |
7473 | 398 int _late_inlines_pos; // Where in the queue should the next late inlining candidate go (emulate depth first inlining) |
399 uint _number_of_mh_late_inlines; // number of method handle late inlining still pending | |
400 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
401 |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
402 // Inlining may not happen in parse order which would make |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
403 // PrintInlining output confusing. Keep track of PrintInlining |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
404 // pieces in order. |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
405 class PrintInliningBuffer : public ResourceObj { |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
406 private: |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
407 CallGenerator* _cg; |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
408 stringStream* _ss; |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
409 |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
410 public: |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
411 PrintInliningBuffer() |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
412 : _cg(NULL) { _ss = new stringStream(); } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
413 |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
414 stringStream* ss() const { return _ss; } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
415 CallGenerator* cg() const { return _cg; } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
416 void set_cg(CallGenerator* cg) { _cg = cg; } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
417 }; |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
418 |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
419 GrowableArray<PrintInliningBuffer>* _print_inlining_list; |
12295 | 420 int _print_inlining_idx; |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
421 |
8048
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
422 // Only keep nodes in the expensive node list that need to be optimized |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
423 void cleanup_expensive_nodes(PhaseIterGVN &igvn); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
424 // Use for sorting expensive nodes to bring similar nodes together |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
425 static int cmp_expensive_nodes(Node** n1, Node** n2); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
426 // Expensive nodes list already sorted? |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
427 bool expensive_nodes_sorted() const; |
12966 | 428 // Remove the speculative part of types and clean up the graph |
429 void remove_speculative_types(PhaseIterGVN &igvn); | |
8048
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
430 |
12956
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
431 // Are we within a PreserveJVMState block? |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
432 int _preserve_jvm_state; |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
433 |
17622 | 434 void* _replay_inline_data; // Pointer to data loaded from file |
435 | |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
436 public: |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
437 |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
438 outputStream* print_inlining_stream() const { |
12295 | 439 return _print_inlining_list->adr_at(_print_inlining_idx)->ss(); |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
440 } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
441 |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
442 void print_inlining_skip(CallGenerator* cg) { |
12295 | 443 if (_print_inlining) { |
444 _print_inlining_list->adr_at(_print_inlining_idx)->set_cg(cg); | |
445 _print_inlining_idx++; | |
446 _print_inlining_list->insert_before(_print_inlining_idx, PrintInliningBuffer()); | |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
447 } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
448 } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
449 |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
450 void print_inlining_insert(CallGenerator* cg) { |
12295 | 451 if (_print_inlining) { |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
452 for (int i = 0; i < _print_inlining_list->length(); i++) { |
12295 | 453 if (_print_inlining_list->adr_at(i)->cg() == cg) { |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
454 _print_inlining_list->insert_before(i+1, PrintInliningBuffer()); |
12295 | 455 _print_inlining_idx = i+1; |
456 _print_inlining_list->adr_at(i)->set_cg(NULL); | |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
457 return; |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
458 } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
459 } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
460 ShouldNotReachHere(); |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
461 } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
462 } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
463 |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
464 void print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) { |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
465 stringStream ss; |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
466 CompileTask::print_inlining(&ss, method, inline_level, bci, msg); |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
467 print_inlining_stream()->print(ss.as_string()); |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
468 } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
469 |
17622 | 470 void* replay_inline_data() const { return _replay_inline_data; } |
471 | |
472 // Dump inlining replay data to the stream. | |
473 void dump_inline_data(outputStream* out); | |
474 | |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
475 private: |
0 | 476 // Matching, CFG layout, allocation, code generation |
477 PhaseCFG* _cfg; // Results of CFG finding | |
478 bool _select_24_bit_instr; // We selected an instruction with a 24-bit result | |
479 bool _in_24_bit_fp_mode; // We are emitting instructions with 24-bit results | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
418
diff
changeset
|
480 int _java_calls; // Number of java calls in the method |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
418
diff
changeset
|
481 int _inner_loops; // Number of inner loops in the method |
0 | 482 Matcher* _matcher; // Engine to map ideal to machine instructions |
483 PhaseRegAlloc* _regalloc; // Results of register allocation. | |
484 int _frame_slots; // Size of total frame in stack slots | |
485 CodeOffsets _code_offsets; // Offsets into the code for various interesting entries | |
486 RegMask _FIRST_STACK_mask; // All stack slots usable for spills (depends on frame layout) | |
487 Arena* _indexSet_arena; // control IndexSet allocation within PhaseChaitin | |
488 void* _indexSet_free_block_list; // free list of IndexSet bit blocks | |
489 | |
490 uint _node_bundling_limit; | |
491 Bundle* _node_bundling_base; // Information for instruction bundling | |
492 | |
493 // Instruction bits passed off to the VM | |
494 int _method_size; // Size of nmethod code segment in bytes | |
495 CodeBuffer _code_buffer; // Where the code is assembled | |
496 int _first_block_size; // Size of unvalidated entry point code / OSR poison code | |
497 ExceptionHandlerTable _handler_table; // Table of native-code exception handlers | |
498 ImplicitExceptionTable _inc_table; // Table of implicit null checks in native code | |
499 OopMapSet* _oop_map_set; // Table of oop maps (one for each safepoint location) | |
500 static int _CompiledZap_count; // counter compared against CompileZap[First/Last] | |
501 BufferBlob* _scratch_buffer_blob; // For temporary code buffers. | |
502 relocInfo* _scratch_locs_memory; // For temporary code buffers. | |
2008 | 503 int _scratch_const_size; // For temporary code buffers. |
504 bool _in_scratch_emit_size; // true when in scratch_emit_size. | |
0 | 505 |
506 public: | |
507 // Accessors | |
508 | |
509 // The Compile instance currently active in this (compiler) thread. | |
510 static Compile* current() { | |
511 return (Compile*) ciEnv::current()->compiler_data(); | |
512 } | |
513 | |
514 // ID for this compilation. Useful for setting breakpoints in the debugger. | |
515 int compile_id() const { return _compile_id; } | |
516 | |
517 // Does this compilation allow instructions to subsume loads? User | |
518 // instructions that subsume a load may result in an unschedulable | |
519 // instruction sequence. | |
520 bool subsume_loads() const { return _subsume_loads; } | |
10278 | 521 /** Do escape analysis. */ |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
522 bool do_escape_analysis() const { return _do_escape_analysis; } |
10278 | 523 /** Do boxing elimination. */ |
524 bool eliminate_boxing() const { return _eliminate_boxing; } | |
525 /** Do aggressive boxing elimination. */ | |
526 bool aggressive_unboxing() const { return _eliminate_boxing && AggressiveUnboxing; } | |
0 | 527 bool save_argument_registers() const { return _save_argument_registers; } |
528 | |
529 | |
530 // Other fixed compilation parameters. | |
531 ciMethod* method() const { return _method; } | |
532 int entry_bci() const { return _entry_bci; } | |
533 bool is_osr_compilation() const { return _entry_bci != InvocationEntryBci; } | |
534 bool is_method_compilation() const { return (_method != NULL && !_method->flags().is_native()); } | |
535 const TypeFunc* tf() const { assert(_tf!=NULL, ""); return _tf; } | |
536 void init_tf(const TypeFunc* tf) { assert(_tf==NULL, ""); _tf = tf; } | |
537 InlineTree* ilt() const { return _ilt; } | |
538 address stub_function() const { return _stub_function; } | |
539 const char* stub_name() const { return _stub_name; } | |
540 address stub_entry_point() const { return _stub_entry_point; } | |
541 | |
542 // Control of this compilation. | |
543 int fixed_slots() const { assert(_fixed_slots >= 0, ""); return _fixed_slots; } | |
544 void set_fixed_slots(int n) { _fixed_slots = n; } | |
545 int major_progress() const { return _major_progress; } | |
7473 | 546 void set_inlining_progress(bool z) { _inlining_progress = z; } |
547 int inlining_progress() const { return _inlining_progress; } | |
548 void set_inlining_incrementally(bool z) { _inlining_incrementally = z; } | |
549 int inlining_incrementally() const { return _inlining_incrementally; } | |
0 | 550 void set_major_progress() { _major_progress++; } |
551 void clear_major_progress() { _major_progress = 0; } | |
552 int num_loop_opts() const { return _num_loop_opts; } | |
553 void set_num_loop_opts(int n) { _num_loop_opts = n; } | |
554 int max_inline_size() const { return _max_inline_size; } | |
555 void set_freq_inline_size(int n) { _freq_inline_size = n; } | |
556 int freq_inline_size() const { return _freq_inline_size; } | |
557 void set_max_inline_size(int n) { _max_inline_size = n; } | |
558 bool has_loops() const { return _has_loops; } | |
559 void set_has_loops(bool z) { _has_loops = z; } | |
560 bool has_split_ifs() const { return _has_split_ifs; } | |
561 void set_has_split_ifs(bool z) { _has_split_ifs = z; } | |
562 bool has_unsafe_access() const { return _has_unsafe_access; } | |
563 void set_has_unsafe_access(bool z) { _has_unsafe_access = z; } | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
564 bool has_stringbuilder() const { return _has_stringbuilder; } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
565 void set_has_stringbuilder(bool z) { _has_stringbuilder = z; } |
10278 | 566 bool has_boxed_value() const { return _has_boxed_value; } |
567 void set_has_boxed_value(bool z) { _has_boxed_value = z; } | |
6792
137868b7aa6f
7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents:
6725
diff
changeset
|
568 int max_vector_size() const { return _max_vector_size; } |
137868b7aa6f
7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents:
6725
diff
changeset
|
569 void set_max_vector_size(int s) { _max_vector_size = s; } |
0 | 570 void set_trap_count(uint r, uint c) { assert(r < trapHistLength, "oob"); _trap_hist[r] = c; } |
571 uint trap_count(uint r) const { assert(r < trapHistLength, "oob"); return _trap_hist[r]; } | |
572 bool trap_can_recompile() const { return _trap_can_recompile; } | |
573 void set_trap_can_recompile(bool z) { _trap_can_recompile = z; } | |
574 uint decompile_count() const { return _decompile_count; } | |
575 void set_decompile_count(uint c) { _decompile_count = c; } | |
576 bool allow_range_check_smearing() const; | |
577 bool do_inlining() const { return _do_inlining; } | |
578 void set_do_inlining(bool z) { _do_inlining = z; } | |
579 bool do_scheduling() const { return _do_scheduling; } | |
580 void set_do_scheduling(bool z) { _do_scheduling = z; } | |
418 | 581 bool do_freq_based_layout() const{ return _do_freq_based_layout; } |
582 void set_do_freq_based_layout(bool z){ _do_freq_based_layout = z; } | |
0 | 583 bool do_count_invocations() const{ return _do_count_invocations; } |
584 void set_do_count_invocations(bool z){ _do_count_invocations = z; } | |
585 bool do_method_data_update() const { return _do_method_data_update; } | |
586 void set_do_method_data_update(bool z) { _do_method_data_update = z; } | |
587 int AliasLevel() const { return _AliasLevel; } | |
588 bool print_assembly() const { return _print_assembly; } | |
589 void set_print_assembly(bool z) { _print_assembly = z; } | |
12295 | 590 bool print_inlining() const { return _print_inlining; } |
591 void set_print_inlining(bool z) { _print_inlining = z; } | |
592 bool print_intrinsics() const { return _print_intrinsics; } | |
593 void set_print_intrinsics(bool z) { _print_intrinsics = z; } | |
0 | 594 // check the CompilerOracle for special behaviours for this compile |
595 bool method_has_option(const char * option) { | |
596 return method() != NULL && method()->has_option(option); | |
597 } | |
598 #ifndef PRODUCT | |
599 bool trace_opto_output() const { return _trace_opto_output; } | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
196
diff
changeset
|
600 bool parsed_irreducible_loop() const { return _parsed_irreducible_loop; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
196
diff
changeset
|
601 void set_parsed_irreducible_loop(bool z) { _parsed_irreducible_loop = z; } |
0 | 602 #endif |
603 | |
1265 | 604 // JSR 292 |
605 bool has_method_handle_invokes() const { return _has_method_handle_invokes; } | |
606 void set_has_method_handle_invokes(bool z) { _has_method_handle_invokes = z; } | |
607 | |
13400
86e6d691f2e1
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
13045
diff
changeset
|
608 Ticks _latest_stage_start_counter; |
10405 | 609 |
0 | 610 void begin_method() { |
611 #ifndef PRODUCT | |
612 if (_printer) _printer->begin_method(this); | |
613 #endif | |
13400
86e6d691f2e1
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
13045
diff
changeset
|
614 C->_latest_stage_start_counter.stamp(); |
0 | 615 } |
10405 | 616 |
617 void print_method(CompilerPhaseType cpt, int level = 1) { | |
13400
86e6d691f2e1
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
13045
diff
changeset
|
618 EventCompilerPhase event; |
10405 | 619 if (event.should_commit()) { |
620 event.set_starttime(C->_latest_stage_start_counter); | |
621 event.set_phase((u1) cpt); | |
622 event.set_compileID(C->_compile_id); | |
623 event.set_phaseLevel(level); | |
624 event.commit(); | |
625 } | |
626 | |
627 | |
0 | 628 #ifndef PRODUCT |
10405 | 629 if (_printer) _printer->print_method(this, CompilerPhaseTypeHelper::to_string(cpt), level); |
0 | 630 #endif |
13400
86e6d691f2e1
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
13045
diff
changeset
|
631 C->_latest_stage_start_counter.stamp(); |
0 | 632 } |
10405 | 633 |
634 void end_method(int level = 1) { | |
13400
86e6d691f2e1
8028128: Add a type safe alternative for working with counter based data
mgronlun
parents:
13045
diff
changeset
|
635 EventCompilerPhase event; |
10405 | 636 if (event.should_commit()) { |
637 event.set_starttime(C->_latest_stage_start_counter); | |
638 event.set_phase((u1) PHASE_END); | |
639 event.set_compileID(C->_compile_id); | |
640 event.set_phaseLevel(level); | |
641 event.commit(); | |
642 } | |
0 | 643 #ifndef PRODUCT |
644 if (_printer) _printer->end_method(); | |
645 #endif | |
646 } | |
647 | |
10278 | 648 int macro_count() const { return _macro_nodes->length(); } |
649 int predicate_count() const { return _predicate_opaqs->length();} | |
650 int expensive_count() const { return _expensive_nodes->length(); } | |
651 Node* macro_node(int idx) const { return _macro_nodes->at(idx); } | |
652 Node* predicate_opaque1_node(int idx) const { return _predicate_opaqs->at(idx);} | |
653 Node* expensive_node(int idx) const { return _expensive_nodes->at(idx); } | |
0 | 654 ConnectionGraph* congraph() { return _congraph;} |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1552
diff
changeset
|
655 void set_congraph(ConnectionGraph* congraph) { _congraph = congraph;} |
0 | 656 void add_macro_node(Node * n) { |
657 //assert(n->is_macro(), "must be a macro node"); | |
658 assert(!_macro_nodes->contains(n), " duplicate entry in expand list"); | |
659 _macro_nodes->append(n); | |
660 } | |
661 void remove_macro_node(Node * n) { | |
662 // this function may be called twice for a node so check | |
663 // that the node is in the array before attempting to remove it | |
664 if (_macro_nodes->contains(n)) | |
665 _macro_nodes->remove(n); | |
1172 | 666 // remove from _predicate_opaqs list also if it is there |
667 if (predicate_count() > 0 && _predicate_opaqs->contains(n)){ | |
668 _predicate_opaqs->remove(n); | |
669 } | |
0 | 670 } |
8048
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
671 void add_expensive_node(Node * n); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
672 void remove_expensive_node(Node * n) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
673 if (_expensive_nodes->contains(n)) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
674 _expensive_nodes->remove(n); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
675 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
676 } |
1172 | 677 void add_predicate_opaq(Node * n) { |
678 assert(!_predicate_opaqs->contains(n), " duplicate entry in predicate opaque1"); | |
679 assert(_macro_nodes->contains(n), "should have already been in macro list"); | |
680 _predicate_opaqs->append(n); | |
681 } | |
682 // remove the opaque nodes that protect the predicates so that the unused checks and | |
683 // uncommon traps will be eliminated from the graph. | |
684 void cleanup_loop_predicates(PhaseIterGVN &igvn); | |
2445 | 685 bool is_predicate_opaq(Node * n) { |
686 return _predicate_opaqs->contains(n); | |
687 } | |
0 | 688 |
8048
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
689 // Are there candidate expensive nodes for optimization? |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
690 bool should_optimize_expensive_nodes(PhaseIterGVN &igvn); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
691 // Check whether n1 and n2 are similar |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
692 static int cmp_expensive_nodes(Node* n1, Node* n2); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
693 // Sort expensive nodes to locate similar expensive nodes |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
694 void sort_expensive_nodes(); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7478
diff
changeset
|
695 |
0 | 696 // Compilation environment. |
697 Arena* comp_arena() { return &_comp_arena; } | |
698 ciEnv* env() const { return _env; } | |
699 CompileLog* log() const { return _log; } | |
700 bool failing() const { return _env->failing() || _failure_reason != NULL; } | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
701 const char* failure_reason() { return _failure_reason; } |
0 | 702 bool failure_reason_is(const char* r) { return (r==_failure_reason) || (r!=NULL && _failure_reason!=NULL && strcmp(r, _failure_reason)==0); } |
703 | |
704 void record_failure(const char* reason); | |
705 void record_method_not_compilable(const char* reason, bool all_tiers = false) { | |
706 // All bailouts cover "all_tiers" when TieredCompilation is off. | |
707 if (!TieredCompilation) all_tiers = true; | |
708 env()->record_method_not_compilable(reason, all_tiers); | |
709 // Record failure reason. | |
710 record_failure(reason); | |
711 } | |
712 void record_method_not_compilable_all_tiers(const char* reason) { | |
713 record_method_not_compilable(reason, true); | |
714 } | |
715 bool check_node_count(uint margin, const char* reason) { | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
716 if (live_nodes() + margin > (uint)MaxNodeLimit) { |
0 | 717 record_method_not_compilable(reason); |
718 return true; | |
719 } else { | |
720 return false; | |
721 } | |
722 } | |
723 | |
724 // Node management | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
725 uint unique() const { return _unique; } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
726 uint next_unique() { return _unique++; } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
727 void set_unique(uint i) { _unique = i; } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
728 static int debug_idx() { return debug_only(_debug_idx)+0; } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
729 static void set_debug_idx(int i) { debug_only(_debug_idx = i); } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
730 Arena* node_arena() { return &_node_arena; } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
731 Arena* old_arena() { return &_old_arena; } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
732 RootNode* root() const { return _root; } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
733 void set_root(RootNode* r) { _root = r; } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
734 StartNode* start() const; // (Derived from root.) |
0 | 735 void init_start(StartNode* s); |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
736 Node* immutable_memory(); |
0 | 737 |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
738 Node* recent_alloc_ctl() const { return _recent_alloc_ctl; } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
739 Node* recent_alloc_obj() const { return _recent_alloc_obj; } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
740 void set_recent_alloc(Node* ctl, Node* obj) { |
0 | 741 _recent_alloc_ctl = ctl; |
742 _recent_alloc_obj = obj; | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
743 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
744 void record_dead_node(uint idx) { if (_dead_node_list.test_set(idx)) return; |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
745 _dead_node_count++; |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
746 } |
8695
ff55877839bc
8009472: Print additional information for 8004640 failure
kvn
parents:
8691
diff
changeset
|
747 bool is_dead_node(uint idx) { return _dead_node_list.test(idx) != 0; } |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
748 uint dead_node_count() { return _dead_node_count; } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
749 void reset_dead_node_list() { _dead_node_list.Reset(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
750 _dead_node_count = 0; |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
751 } |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
752 uint live_nodes() const { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
753 int val = _unique - _dead_node_count; |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
754 assert (val >= 0, err_msg_res("number of tracked dead nodes %d more than created nodes %d", _unique, _dead_node_count)); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
755 return (uint) val; |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
756 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
757 #ifdef ASSERT |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
758 uint count_live_nodes_by_graph_walk(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
759 void print_missing_nodes(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
760 #endif |
0 | 761 |
2008 | 762 // Constant table |
763 ConstantTable& constant_table() { return _constant_table; } | |
764 | |
765 MachConstantBaseNode* mach_constant_base_node(); | |
766 bool has_mach_constant_base_node() const { return _mach_constant_base_node != NULL; } | |
767 | |
0 | 768 // Handy undefined Node |
769 Node* top() const { return _top; } | |
770 | |
771 // these are used by guys who need to know about creation and transformation of top: | |
772 Node* cached_top_node() { return _top; } | |
773 void set_cached_top_node(Node* tn); | |
774 | |
775 GrowableArray<Node_Notes*>* node_note_array() const { return _node_note_array; } | |
776 void set_node_note_array(GrowableArray<Node_Notes*>* arr) { _node_note_array = arr; } | |
777 Node_Notes* default_node_notes() const { return _default_node_notes; } | |
778 void set_default_node_notes(Node_Notes* n) { _default_node_notes = n; } | |
779 | |
780 Node_Notes* node_notes_at(int idx) { | |
781 return locate_node_notes(_node_note_array, idx, false); | |
782 } | |
783 inline bool set_node_notes_at(int idx, Node_Notes* value); | |
784 | |
785 // Copy notes from source to dest, if they exist. | |
786 // Overwrite dest only if source provides something. | |
787 // Return true if information was moved. | |
788 bool copy_node_notes_to(Node* dest, Node* source); | |
789 | |
790 // Workhorse function to sort out the blocked Node_Notes array: | |
791 inline Node_Notes* locate_node_notes(GrowableArray<Node_Notes*>* arr, | |
792 int idx, bool can_grow = false); | |
793 | |
794 void grow_node_notes(GrowableArray<Node_Notes*>* arr, int grow_by); | |
795 | |
796 // Type management | |
797 Arena* type_arena() { return _type_arena; } | |
798 Dict* type_dict() { return _type_dict; } | |
799 void* type_hwm() { return _type_hwm; } | |
800 size_t type_last_size() { return _type_last_size; } | |
801 int num_alias_types() { return _num_alias_types; } | |
802 | |
803 void init_type_arena() { _type_arena = &_Compile_types; } | |
804 void set_type_arena(Arena* a) { _type_arena = a; } | |
805 void set_type_dict(Dict* d) { _type_dict = d; } | |
806 void set_type_hwm(void* p) { _type_hwm = p; } | |
807 void set_type_last_size(size_t sz) { _type_last_size = sz; } | |
808 | |
809 const TypeFunc* last_tf(ciMethod* m) { | |
810 return (m == _last_tf_m) ? _last_tf : NULL; | |
811 } | |
812 void set_last_tf(ciMethod* m, const TypeFunc* tf) { | |
813 assert(m != NULL || tf == NULL, ""); | |
814 _last_tf_m = m; | |
815 _last_tf = tf; | |
816 } | |
817 | |
818 AliasType* alias_type(int idx) { assert(idx < num_alias_types(), "oob"); return _alias_types[idx]; } | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2008
diff
changeset
|
819 AliasType* alias_type(const TypePtr* adr_type, ciField* field = NULL) { return find_alias_type(adr_type, false, field); } |
0 | 820 bool have_alias_type(const TypePtr* adr_type); |
821 AliasType* alias_type(ciField* field); | |
822 | |
823 int get_alias_index(const TypePtr* at) { return alias_type(at)->index(); } | |
824 const TypePtr* get_adr_type(uint aidx) { return alias_type(aidx)->adr_type(); } | |
825 int get_general_index(uint aidx) { return alias_type(aidx)->general_index(); } | |
826 | |
827 // Building nodes | |
828 void rethrow_exceptions(JVMState* jvms); | |
829 void return_values(JVMState* jvms); | |
830 JVMState* build_start_state(StartNode* start, const TypeFunc* tf); | |
831 | |
832 // Decide how to build a call. | |
833 // The profile factor is a discount to apply to this site's interp. profile. | |
12956
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
834 CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_does_dispatch, |
12966 | 835 JVMState* jvms, bool allow_inline, float profile_factor, ciKlass* speculative_receiver_type = NULL, |
836 bool allow_intrinsics = true, bool delayed_forbidden = false); | |
10278 | 837 bool should_delay_inlining(ciMethod* call_method, JVMState* jvms) { |
838 return should_delay_string_inlining(call_method, jvms) || | |
839 should_delay_boxing_inlining(call_method, jvms); | |
840 } | |
841 bool should_delay_string_inlining(ciMethod* call_method, JVMState* jvms); | |
842 bool should_delay_boxing_inlining(ciMethod* call_method, JVMState* jvms); | |
0 | 843 |
7478 | 844 // Helper functions to identify inlining potential at call-site |
845 ciMethod* optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass, | |
846 ciMethod* callee, const TypeOopPtr* receiver_type, | |
847 bool is_virtual, | |
848 bool &call_does_dispatch, int &vtable_index); | |
849 ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, | |
850 ciMethod* callee, const TypeOopPtr* receiver_type); | |
851 | |
0 | 852 // Report if there were too many traps at a current method and bci. |
853 // Report if a trap was recorded, and/or PerMethodTrapLimit was exceeded. | |
854 // If there is no MDO at all, report no trap unless told to assume it. | |
855 bool too_many_traps(ciMethod* method, int bci, Deoptimization::DeoptReason reason); | |
856 // This version, unspecific to a particular bci, asks if | |
857 // PerMethodTrapLimit was exceeded for all inlined methods seen so far. | |
858 bool too_many_traps(Deoptimization::DeoptReason reason, | |
859 // Privately used parameter for logging: | |
860 ciMethodData* logmd = NULL); | |
861 // Report if there were too many recompiles at a method and bci. | |
862 bool too_many_recompiles(ciMethod* method, int bci, Deoptimization::DeoptReason reason); | |
863 | |
864 // Parsing, optimization | |
865 PhaseGVN* initial_gvn() { return _initial_gvn; } | |
866 Unique_Node_List* for_igvn() { return _for_igvn; } | |
867 inline void record_for_igvn(Node* n); // Body is after class Unique_Node_List. | |
868 void set_initial_gvn(PhaseGVN *gvn) { _initial_gvn = gvn; } | |
869 void set_for_igvn(Unique_Node_List *for_igvn) { _for_igvn = for_igvn; } | |
870 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
871 // Replace n by nn using initial_gvn, calling hash_delete and |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
872 // record_for_igvn as needed. |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
873 void gvn_replace_by(Node* n, Node* nn); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
874 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
875 |
0 | 876 void identify_useful_nodes(Unique_Node_List &useful); |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
877 void update_dead_node_list(Unique_Node_List &useful); |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
878 void remove_useless_nodes (Unique_Node_List &useful); |
0 | 879 |
880 WarmCallInfo* warm_calls() const { return _warm_calls; } | |
881 void set_warm_calls(WarmCallInfo* l) { _warm_calls = l; } | |
882 WarmCallInfo* pop_warm_call(); | |
883 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
884 // Record this CallGenerator for inlining at the end of parsing. |
7473 | 885 void add_late_inline(CallGenerator* cg) { |
886 _late_inlines.insert_before(_late_inlines_pos, cg); | |
887 _late_inlines_pos++; | |
888 } | |
889 | |
890 void prepend_late_inline(CallGenerator* cg) { | |
891 _late_inlines.insert_before(0, cg); | |
892 } | |
893 | |
894 void add_string_late_inline(CallGenerator* cg) { | |
895 _string_late_inlines.push(cg); | |
896 } | |
897 | |
10278 | 898 void add_boxing_late_inline(CallGenerator* cg) { |
899 _boxing_late_inlines.push(cg); | |
900 } | |
901 | |
7473 | 902 void remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines, Unique_Node_List &useful); |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
903 |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
904 void dump_inlining(); |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7196
diff
changeset
|
905 |
7473 | 906 bool over_inlining_cutoff() const { |
907 if (!inlining_incrementally()) { | |
908 return unique() > (uint)NodeCountInliningCutoff; | |
909 } else { | |
910 return live_nodes() > (uint)LiveNodeCountInliningCutoff; | |
911 } | |
912 } | |
913 | |
914 void inc_number_of_mh_late_inlines() { _number_of_mh_late_inlines++; } | |
915 void dec_number_of_mh_late_inlines() { assert(_number_of_mh_late_inlines > 0, "_number_of_mh_late_inlines < 0 !"); _number_of_mh_late_inlines--; } | |
916 bool has_mh_late_inlines() const { return _number_of_mh_late_inlines > 0; } | |
917 | |
918 void inline_incrementally_one(PhaseIterGVN& igvn); | |
919 void inline_incrementally(PhaseIterGVN& igvn); | |
920 void inline_string_calls(bool parse_time); | |
10278 | 921 void inline_boxing_calls(PhaseIterGVN& igvn); |
7473 | 922 |
0 | 923 // Matching, CFG layout, allocation, code generation |
924 PhaseCFG* cfg() { return _cfg; } | |
925 bool select_24_bit_instr() const { return _select_24_bit_instr; } | |
926 bool in_24_bit_fp_mode() const { return _in_24_bit_fp_mode; } | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
418
diff
changeset
|
927 bool has_java_calls() const { return _java_calls > 0; } |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
418
diff
changeset
|
928 int java_calls() const { return _java_calls; } |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
418
diff
changeset
|
929 int inner_loops() const { return _inner_loops; } |
0 | 930 Matcher* matcher() { return _matcher; } |
931 PhaseRegAlloc* regalloc() { return _regalloc; } | |
932 int frame_slots() const { return _frame_slots; } | |
933 int frame_size_in_words() const; // frame_slots in units of the polymorphic 'words' | |
934 RegMask& FIRST_STACK_mask() { return _FIRST_STACK_mask; } | |
935 Arena* indexSet_arena() { return _indexSet_arena; } | |
936 void* indexSet_free_block_list() { return _indexSet_free_block_list; } | |
937 uint node_bundling_limit() { return _node_bundling_limit; } | |
938 Bundle* node_bundling_base() { return _node_bundling_base; } | |
939 void set_node_bundling_limit(uint n) { _node_bundling_limit = n; } | |
940 void set_node_bundling_base(Bundle* b) { _node_bundling_base = b; } | |
941 bool starts_bundle(const Node *n) const; | |
942 bool need_stack_bang(int frame_size_in_bytes) const; | |
943 bool need_register_stack_bang() const; | |
944 | |
945 void set_matcher(Matcher* m) { _matcher = m; } | |
946 //void set_regalloc(PhaseRegAlloc* ra) { _regalloc = ra; } | |
947 void set_indexSet_arena(Arena* a) { _indexSet_arena = a; } | |
948 void set_indexSet_free_block_list(void* p) { _indexSet_free_block_list = p; } | |
949 | |
950 // Remember if this compilation changes hardware mode to 24-bit precision | |
951 void set_24_bit_selection_and_mode(bool selection, bool mode) { | |
952 _select_24_bit_instr = selection; | |
953 _in_24_bit_fp_mode = mode; | |
954 } | |
955 | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
418
diff
changeset
|
956 void set_java_calls(int z) { _java_calls = z; } |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
418
diff
changeset
|
957 void set_inner_loops(int z) { _inner_loops = z; } |
0 | 958 |
959 // Instruction bits passed off to the VM | |
960 int code_size() { return _method_size; } | |
961 CodeBuffer* code_buffer() { return &_code_buffer; } | |
962 int first_block_size() { return _first_block_size; } | |
963 void set_frame_complete(int off) { _code_offsets.set_value(CodeOffsets::Frame_Complete, off); } | |
964 ExceptionHandlerTable* handler_table() { return &_handler_table; } | |
965 ImplicitExceptionTable* inc_table() { return &_inc_table; } | |
966 OopMapSet* oop_map_set() { return _oop_map_set; } | |
967 DebugInformationRecorder* debug_info() { return env()->debug_info(); } | |
968 Dependencies* dependencies() { return env()->dependencies(); } | |
969 static int CompiledZap_count() { return _CompiledZap_count; } | |
970 BufferBlob* scratch_buffer_blob() { return _scratch_buffer_blob; } | |
2008 | 971 void init_scratch_buffer_blob(int const_size); |
972 void clear_scratch_buffer_blob(); | |
0 | 973 void set_scratch_buffer_blob(BufferBlob* b) { _scratch_buffer_blob = b; } |
974 relocInfo* scratch_locs_memory() { return _scratch_locs_memory; } | |
975 void set_scratch_locs_memory(relocInfo* b) { _scratch_locs_memory = b; } | |
976 | |
977 // emit to scratch blob, report resulting size | |
978 uint scratch_emit_size(const Node* n); | |
2008 | 979 void set_in_scratch_emit_size(bool x) { _in_scratch_emit_size = x; } |
980 bool in_scratch_emit_size() const { return _in_scratch_emit_size; } | |
0 | 981 |
982 enum ScratchBufferBlob { | |
983 MAX_inst_size = 1024, | |
984 MAX_locs_size = 128, // number of relocInfo elements | |
985 MAX_const_size = 128, | |
986 MAX_stubs_size = 128 | |
987 }; | |
988 | |
989 // Major entry point. Given a Scope, compile the associated method. | |
990 // For normal compilations, entry_bci is InvocationEntryBci. For on stack | |
991 // replacement, entry_bci indicates the bytecode for which to compile a | |
992 // continuation. | |
993 Compile(ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, | |
10278 | 994 int entry_bci, bool subsume_loads, bool do_escape_analysis, |
995 bool eliminate_boxing); | |
0 | 996 |
997 // Second major entry point. From the TypeFunc signature, generate code | |
998 // to pass arguments from the Java calling convention to the C calling | |
999 // convention. | |
1000 Compile(ciEnv* ci_env, const TypeFunc *(*gen)(), | |
1001 address stub_function, const char *stub_name, | |
1002 int is_fancy_jump, bool pass_tls, | |
1003 bool save_arg_registers, bool return_pc); | |
1004 | |
1005 // From the TypeFunc signature, generate code to pass arguments | |
1006 // from Compiled calling convention to Interpreter's calling convention | |
1007 void Generate_Compiled_To_Interpreter_Graph(const TypeFunc *tf, address interpreter_entry); | |
1008 | |
1009 // From the TypeFunc signature, generate code to pass arguments | |
1010 // from Interpreter's calling convention to Compiler's calling convention | |
1011 void Generate_Interpreter_To_Compiled_Graph(const TypeFunc *tf); | |
1012 | |
1013 // Are we compiling a method? | |
1014 bool has_method() { return method() != NULL; } | |
1015 | |
1016 // Maybe print some information about this compile. | |
1017 void print_compile_messages(); | |
1018 | |
1019 // Final graph reshaping, a post-pass after the regular optimizer is done. | |
1020 bool final_graph_reshaping(); | |
1021 | |
1022 // returns true if adr is completely contained in the given alias category | |
1023 bool must_alias(const TypePtr* adr, int alias_idx); | |
1024 | |
1025 // returns true if adr overlaps with the given alias category | |
1026 bool can_alias(const TypePtr* adr, int alias_idx); | |
1027 | |
1028 // Driver for converting compiler's IR into machine code bits | |
1029 void Output(); | |
1030 | |
1031 // Accessors for node bundling info. | |
1032 Bundle* node_bundling(const Node *n); | |
1033 bool valid_bundle_info(const Node *n); | |
1034 | |
1035 // Schedule and Bundle the instructions | |
1036 void ScheduleAndBundle(); | |
1037 | |
1038 // Build OopMaps for each GC point | |
1039 void BuildOopMaps(); | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1040 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1041 // Append debug info for the node "local" at safepoint node "sfpt" to the |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1042 // "array", May also consult and add to "objs", which describes the |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1043 // scalar-replaced objects. |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1044 void FillLocArray( int idx, MachSafePointNode* sfpt, |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1045 Node *local, GrowableArray<ScopeValue*> *array, |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1046 GrowableArray<ScopeValue*> *objs ); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1047 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1048 // If "objs" contains an ObjectValue whose id is "id", returns it, else NULL. |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1049 static ObjectValue* sv_for_node_id(GrowableArray<ScopeValue*> *objs, int id); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1050 // Requres that "objs" does not contains an ObjectValue whose id matches |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1051 // that of "sv. Appends "sv". |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1052 static void set_sv_for_object_node(GrowableArray<ScopeValue*> *objs, |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
38
diff
changeset
|
1053 ObjectValue* sv ); |
0 | 1054 |
1055 // Process an OopMap Element while emitting nodes | |
1056 void Process_OopMap_Node(MachNode *mach, int code_offset); | |
1057 | |
3851 | 1058 // Initialize code buffer |
1059 CodeBuffer* init_buffer(uint* blk_starts); | |
1060 | |
0 | 1061 // Write out basic block data to code buffer |
3851 | 1062 void fill_buffer(CodeBuffer* cb, uint* blk_starts); |
0 | 1063 |
1064 // Determine which variable sized branches can be shortened | |
3851 | 1065 void shorten_branches(uint* blk_starts, int& code_size, int& reloc_size, int& stub_size); |
1066 | |
0 | 1067 // Compute the size of first NumberOfLoopInstrToAlign instructions |
1068 // at the head of a loop. | |
1069 void compute_loop_first_inst_sizes(); | |
1070 | |
1071 // Compute the information for the exception tables | |
1072 void FillExceptionTables(uint cnt, uint *call_returns, uint *inct_starts, Label *blk_labels); | |
1073 | |
1074 // Stack slots that may be unused by the calling convention but must | |
1075 // otherwise be preserved. On Intel this includes the return address. | |
1076 // On PowerPC it includes the 4 words holding the old TOC & LR glue. | |
1077 uint in_preserve_stack_slots(); | |
1078 | |
1079 // "Top of Stack" slots that may be unused by the calling convention but must | |
1080 // otherwise be preserved. | |
1081 // On Intel these are not necessary and the value can be zero. | |
1082 // On Sparc this describes the words reserved for storing a register window | |
1083 // when an interrupt occurs. | |
1084 static uint out_preserve_stack_slots(); | |
1085 | |
1086 // Number of outgoing stack slots killed above the out_preserve_stack_slots | |
1087 // for calls to C. Supports the var-args backing area for register parms. | |
1088 uint varargs_C_out_slots_killed() const; | |
1089 | |
1090 // Number of Stack Slots consumed by a synchronization entry | |
1091 int sync_stack_slots() const; | |
1092 | |
1093 // Compute the name of old_SP. See <arch>.ad for frame layout. | |
1094 OptoReg::Name compute_old_SP(); | |
1095 | |
1096 #ifdef ENABLE_ZAP_DEAD_LOCALS | |
1097 static bool is_node_getting_a_safepoint(Node*); | |
1098 void Insert_zap_nodes(); | |
1099 Node* call_zap_node(MachSafePointNode* n, int block_no); | |
1100 #endif | |
1101 | |
1102 private: | |
1103 // Phase control: | |
1104 void Init(int aliaslevel); // Prepare for a single compilation | |
1105 int Inline_Warm(); // Find more inlining work. | |
1106 void Finish_Warm(); // Give up on further inlines. | |
1107 void Optimize(); // Given a graph, optimize it | |
1108 void Code_Gen(); // Generate code from a graph | |
1109 | |
1110 // Management of the AliasType table. | |
1111 void grow_alias_types(); | |
1112 AliasCacheEntry* probe_alias_cache(const TypePtr* adr_type); | |
1113 const TypePtr *flatten_alias_type(const TypePtr* adr_type) const; | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2008
diff
changeset
|
1114 AliasType* find_alias_type(const TypePtr* adr_type, bool no_create, ciField* field); |
0 | 1115 |
1116 void verify_top(Node*) const PRODUCT_RETURN; | |
1117 | |
1118 // Intrinsic setup. | |
1119 void register_library_intrinsics(); // initializer | |
1120 CallGenerator* make_vm_intrinsic(ciMethod* m, bool is_virtual); // constructor | |
1121 int intrinsic_insertion_index(ciMethod* m, bool is_virtual); // helper | |
1122 CallGenerator* find_intrinsic(ciMethod* m, bool is_virtual); // query fn | |
1123 void register_intrinsic(CallGenerator* cg); // update fn | |
1124 | |
1125 #ifndef PRODUCT | |
1126 static juint _intrinsic_hist_count[vmIntrinsics::ID_LIMIT]; | |
1127 static jubyte _intrinsic_hist_flags[vmIntrinsics::ID_LIMIT]; | |
1128 #endif | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1129 // Function calls made by the public function final_graph_reshaping. |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1130 // No need to be made public as they are not called elsewhere. |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1131 void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1132 void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &frc ); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1133 void eliminate_redundant_card_marks(Node* n); |
0 | 1134 |
1135 public: | |
1136 | |
1137 // Note: Histogram array size is about 1 Kb. | |
1138 enum { // flag bits: | |
1139 _intrinsic_worked = 1, // succeeded at least once | |
1140 _intrinsic_failed = 2, // tried it but it failed | |
1141 _intrinsic_disabled = 4, // was requested but disabled (e.g., -XX:-InlineUnsafeOps) | |
1142 _intrinsic_virtual = 8, // was seen in the virtual form (rare) | |
1143 _intrinsic_both = 16 // was seen in the non-virtual form (usual) | |
1144 }; | |
1145 // Update histogram. Return boolean if this is a first-time occurrence. | |
1146 static bool gather_intrinsic_statistics(vmIntrinsics::ID id, | |
1147 bool is_virtual, int flags) PRODUCT_RETURN0; | |
1148 static void print_intrinsic_statistics() PRODUCT_RETURN; | |
1149 | |
1150 // Graph verification code | |
1151 // Walk the node list, verifying that there is a one-to-one | |
1152 // correspondence between Use-Def edges and Def-Use edges | |
1153 // The option no_dead_code enables stronger checks that the | |
1154 // graph is strongly connected from root in both directions. | |
1155 void verify_graph_edges(bool no_dead_code = false) PRODUCT_RETURN; | |
1156 | |
13045
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
1157 // Verify GC barrier patterns |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
1158 void verify_barriers() PRODUCT_RETURN; |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
1159 |
0 | 1160 // End-of-run dumps. |
1161 static void print_statistics() PRODUCT_RETURN; | |
1162 | |
1163 // Dump formatted assembly | |
1164 void dump_asm(int *pcs = NULL, uint pc_limit = 0) PRODUCT_RETURN; | |
1165 void dump_pc(int *pcs, int pc_limit, Node *n); | |
1166 | |
1167 // Verify ADLC assumptions during startup | |
1168 static void adlc_verification() PRODUCT_RETURN; | |
1169 | |
1170 // Definitions of pd methods | |
1171 static void pd_compiler2_init(); | |
8691
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
1172 |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
1173 // Auxiliary method for randomized fuzzing/stressing |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
1174 static bool randomized_select(int count); |
12956
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1175 |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1176 // enter a PreserveJVMState block |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1177 void inc_preserve_jvm_state() { |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1178 _preserve_jvm_state++; |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1179 } |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1180 |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1181 // exit a PreserveJVMState block |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1182 void dec_preserve_jvm_state() { |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1183 _preserve_jvm_state--; |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1184 assert(_preserve_jvm_state >= 0, "_preserve_jvm_state shouldn't be negative"); |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1185 } |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1186 |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1187 bool has_preserve_jvm_state() const { |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1188 return _preserve_jvm_state > 0; |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12295
diff
changeset
|
1189 } |
0 | 1190 }; |
1972 | 1191 |
1192 #endif // SHARE_VM_OPTO_COMPILE_HPP |