Mercurial > hg > truffle
annotate src/share/vm/c1/c1_IR.hpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | 701a83c86f28 |
children | 33df1aeaebbf b9a9ed0f8eeb |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
diff
changeset
|
2 * Copyright (c) 1999, 2010, 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:
1295
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
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:
1295
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_C1_C1_IR_HPP |
26 #define SHARE_VM_C1_C1_IR_HPP | |
27 | |
28 #include "c1/c1_Instruction.hpp" | |
29 #include "ci/ciExceptionHandler.hpp" | |
30 #include "ci/ciMethod.hpp" | |
31 #include "ci/ciStreams.hpp" | |
32 #include "memory/allocation.hpp" | |
33 | |
0 | 34 // An XHandler is a C1 internal description for an exception handler |
35 | |
36 class XHandler: public CompilationResourceObj { | |
37 private: | |
38 ciExceptionHandler* _desc; | |
39 | |
40 BlockBegin* _entry_block; // Entry block of xhandler | |
41 LIR_List* _entry_code; // LIR-operations that must be executed before jumping to entry_block | |
42 int _entry_pco; // pco where entry_code (or entry_block if no entry_code) starts | |
43 int _phi_operand; // For resolving of phi functions at begin of entry_block | |
44 int _scope_count; // for filling ExceptionRangeEntry::scope_count | |
45 | |
46 #ifdef ASSERT | |
47 int _lir_op_id; // op_id of the LIR-operation throwing to this handler | |
48 #endif | |
49 | |
50 public: | |
51 // creation | |
52 XHandler(ciExceptionHandler* desc) | |
53 : _desc(desc) | |
54 , _entry_block(NULL) | |
55 , _entry_code(NULL) | |
56 , _entry_pco(-1) | |
57 , _phi_operand(-1) | |
58 , _scope_count(-1) | |
59 #ifdef ASSERT | |
60 , _lir_op_id(-1) | |
61 #endif | |
62 { } | |
63 | |
64 XHandler(XHandler* other) | |
65 : _desc(other->_desc) | |
66 , _entry_block(other->_entry_block) | |
67 , _entry_code(other->_entry_code) | |
68 , _entry_pco(other->_entry_pco) | |
69 , _phi_operand(other->_phi_operand) | |
70 , _scope_count(other->_scope_count) | |
71 #ifdef ASSERT | |
72 , _lir_op_id(other->_lir_op_id) | |
73 #endif | |
74 { } | |
75 | |
76 // accessors for data of ciExceptionHandler | |
77 int beg_bci() const { return _desc->start(); } | |
78 int end_bci() const { return _desc->limit(); } | |
79 int handler_bci() const { return _desc->handler_bci(); } | |
80 bool is_catch_all() const { return _desc->is_catch_all(); } | |
81 int catch_type() const { return _desc->catch_klass_index(); } | |
82 ciInstanceKlass* catch_klass() const { return _desc->catch_klass(); } | |
83 bool covers(int bci) const { return beg_bci() <= bci && bci < end_bci(); } | |
84 | |
85 // accessors for additional fields | |
86 BlockBegin* entry_block() const { return _entry_block; } | |
87 LIR_List* entry_code() const { return _entry_code; } | |
88 int entry_pco() const { return _entry_pco; } | |
89 int phi_operand() const { assert(_phi_operand != -1, "not set"); return _phi_operand; } | |
90 int scope_count() const { assert(_scope_count != -1, "not set"); return _scope_count; } | |
91 DEBUG_ONLY(int lir_op_id() const { return _lir_op_id; }); | |
92 | |
93 void set_entry_block(BlockBegin* entry_block) { | |
94 assert(entry_block->is_set(BlockBegin::exception_entry_flag), "must be an exception handler entry"); | |
95 assert(entry_block->bci() == handler_bci(), "bci's must correspond"); | |
96 _entry_block = entry_block; | |
97 } | |
98 void set_entry_code(LIR_List* entry_code) { _entry_code = entry_code; } | |
99 void set_entry_pco(int entry_pco) { _entry_pco = entry_pco; } | |
100 void set_phi_operand(int phi_operand) { _phi_operand = phi_operand; } | |
101 void set_scope_count(int scope_count) { _scope_count = scope_count; } | |
102 DEBUG_ONLY(void set_lir_op_id(int lir_op_id) { _lir_op_id = lir_op_id; }); | |
103 | |
104 bool equals(XHandler* other) const; | |
105 }; | |
106 | |
107 define_array(_XHandlerArray, XHandler*) | |
108 define_stack(_XHandlerList, _XHandlerArray) | |
109 | |
110 | |
111 // XHandlers is the C1 internal list of exception handlers for a method | |
112 class XHandlers: public CompilationResourceObj { | |
113 private: | |
114 _XHandlerList _list; | |
115 | |
116 public: | |
117 // creation | |
118 XHandlers() : _list() { } | |
119 XHandlers(ciMethod* method); | |
120 XHandlers(XHandlers* other); | |
121 | |
122 // accessors | |
123 int length() const { return _list.length(); } | |
124 XHandler* handler_at(int i) const { return _list.at(i); } | |
125 bool has_handlers() const { return _list.length() > 0; } | |
126 void append(XHandler* h) { _list.append(h); } | |
127 XHandler* remove_last() { return _list.pop(); } | |
128 | |
129 bool could_catch(ciInstanceKlass* klass, bool type_is_exact) const; | |
130 bool equals(XHandlers* others) const; | |
131 }; | |
132 | |
133 | |
134 class IRScope; | |
135 define_array(IRScopeArray, IRScope*) | |
136 define_stack(IRScopeList, IRScopeArray) | |
137 | |
138 class Compilation; | |
139 class IRScope: public CompilationResourceObj { | |
140 private: | |
141 // hierarchy | |
142 Compilation* _compilation; // the current compilation | |
143 IRScope* _caller; // the caller scope, or NULL | |
144 int _level; // the inlining level | |
145 ciMethod* _method; // the corresponding method | |
146 IRScopeList _callees; // the inlined method scopes | |
147 | |
148 // graph | |
149 XHandlers* _xhandlers; // the exception handlers | |
150 int _number_of_locks; // the number of monitor lock slots needed | |
151 bool _monitor_pairing_ok; // the monitor pairing info | |
4966
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
1972
diff
changeset
|
152 bool _wrote_final; // has written final field |
0 | 153 BlockBegin* _start; // the start block, successsors are method entries |
154 | |
155 BitMap _requires_phi_function; // bit is set if phi functions at loop headers are necessary for a local variable | |
156 | |
157 // helper functions | |
158 BlockBegin* build_graph(Compilation* compilation, int osr_bci); | |
159 | |
160 public: | |
161 // creation | |
162 IRScope(Compilation* compilation, IRScope* caller, int caller_bci, ciMethod* method, int osr_bci, bool create_graph = false); | |
163 | |
164 // accessors | |
165 Compilation* compilation() const { return _compilation; } | |
166 IRScope* caller() const { return _caller; } | |
167 int level() const { return _level; } | |
168 ciMethod* method() const { return _method; } | |
169 int max_stack() const; // NOTE: expensive | |
170 BitMap& requires_phi_function() { return _requires_phi_function; } | |
171 | |
172 // hierarchy | |
173 bool is_top_scope() const { return _caller == NULL; } | |
174 void add_callee(IRScope* callee) { _callees.append(callee); } | |
175 int number_of_callees() const { return _callees.length(); } | |
176 IRScope* callee_no(int i) const { return _callees.at(i); } | |
177 | |
178 // accessors, graph | |
179 bool is_valid() const { return start() != NULL; } | |
180 XHandlers* xhandlers() const { return _xhandlers; } | |
181 int number_of_locks() const { return _number_of_locks; } | |
182 void set_min_number_of_locks(int n) { if (n > _number_of_locks) _number_of_locks = n; } | |
183 bool monitor_pairing_ok() const { return _monitor_pairing_ok; } | |
184 BlockBegin* start() const { return _start; } | |
4966
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
1972
diff
changeset
|
185 void set_wrote_final() { _wrote_final = true; } |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
1972
diff
changeset
|
186 bool wrote_final () const { return _wrote_final; } |
0 | 187 }; |
188 | |
189 | |
190 // | |
191 // IRScopeDebugInfo records the debug information for a particular IRScope | |
192 // in a particular CodeEmitInfo. This allows the information to be computed | |
193 // once early enough for the OopMap to be available to the LIR and also to be | |
194 // reemited for different pcs using the same CodeEmitInfo without recomputing | |
195 // everything. | |
196 // | |
197 | |
198 class IRScopeDebugInfo: public CompilationResourceObj { | |
199 private: | |
200 IRScope* _scope; | |
201 int _bci; | |
202 GrowableArray<ScopeValue*>* _locals; | |
203 GrowableArray<ScopeValue*>* _expressions; | |
204 GrowableArray<MonitorValue*>* _monitors; | |
205 IRScopeDebugInfo* _caller; | |
206 | |
207 public: | |
208 IRScopeDebugInfo(IRScope* scope, | |
209 int bci, | |
210 GrowableArray<ScopeValue*>* locals, | |
211 GrowableArray<ScopeValue*>* expressions, | |
212 GrowableArray<MonitorValue*>* monitors, | |
213 IRScopeDebugInfo* caller): | |
214 _scope(scope) | |
215 , _locals(locals) | |
216 , _bci(bci) | |
217 , _expressions(expressions) | |
218 , _monitors(monitors) | |
219 , _caller(caller) {} | |
220 | |
221 | |
222 IRScope* scope() { return _scope; } | |
223 int bci() { return _bci; } | |
224 GrowableArray<ScopeValue*>* locals() { return _locals; } | |
225 GrowableArray<ScopeValue*>* expressions() { return _expressions; } | |
226 GrowableArray<MonitorValue*>* monitors() { return _monitors; } | |
227 IRScopeDebugInfo* caller() { return _caller; } | |
228 | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
0
diff
changeset
|
229 //Whether we should reexecute this bytecode for deopt |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
0
diff
changeset
|
230 bool should_reexecute(); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
0
diff
changeset
|
231 |
1295 | 232 void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool topmost, bool is_method_handle_invoke = false) { |
0 | 233 if (caller() != NULL) { |
234 // Order is significant: Must record caller first. | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
0
diff
changeset
|
235 caller()->record_debug_info(recorder, pc_offset, false/*topmost*/); |
0 | 236 } |
237 DebugToken* locvals = recorder->create_scope_values(locals()); | |
238 DebugToken* expvals = recorder->create_scope_values(expressions()); | |
239 DebugToken* monvals = recorder->create_monitor_values(monitors()); | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
0
diff
changeset
|
240 // reexecute allowed only for the topmost frame |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
948
diff
changeset
|
241 bool reexecute = topmost ? should_reexecute() : false; |
1253
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1135
diff
changeset
|
242 bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis. |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1135
diff
changeset
|
243 recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals); |
0 | 244 } |
245 }; | |
246 | |
247 | |
248 class CodeEmitInfo: public CompilationResourceObj { | |
249 friend class LinearScan; | |
250 private: | |
251 IRScopeDebugInfo* _scope_debug_info; | |
252 IRScope* _scope; | |
253 XHandlers* _exception_handlers; | |
254 OopMap* _oop_map; | |
255 ValueStack* _stack; // used by deoptimization (contains also monitors | |
1564 | 256 bool _is_method_handle_invoke; // true if the associated call site is a MethodHandle call site. |
0 | 257 |
258 FrameMap* frame_map() const { return scope()->compilation()->frame_map(); } | |
259 Compilation* compilation() const { return scope()->compilation(); } | |
260 | |
261 public: | |
262 | |
263 // use scope from ValueStack | |
1819 | 264 CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers); |
0 | 265 |
266 // make a copy | |
1819 | 267 CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack = NULL); |
0 | 268 |
269 // accessors | |
270 OopMap* oop_map() { return _oop_map; } | |
271 ciMethod* method() const { return _scope->method(); } | |
272 IRScope* scope() const { return _scope; } | |
273 XHandlers* exception_handlers() const { return _exception_handlers; } | |
274 ValueStack* stack() const { return _stack; } | |
275 | |
276 void add_register_oop(LIR_Opr opr); | |
1564 | 277 void record_debug_info(DebugInformationRecorder* recorder, int pc_offset); |
0 | 278 |
1564 | 279 bool is_method_handle_invoke() const { return _is_method_handle_invoke; } |
280 void set_is_method_handle_invoke(bool x) { _is_method_handle_invoke = x; } | |
0 | 281 }; |
282 | |
283 | |
284 class IR: public CompilationResourceObj { | |
285 private: | |
286 Compilation* _compilation; // the current compilation | |
287 IRScope* _top_scope; // the root of the scope hierarchy | |
288 WordSize _locals_size; // the space required for all locals | |
289 int _num_loops; // Total number of loops | |
290 BlockList* _code; // the blocks in code generation order w/ use counts | |
291 | |
292 public: | |
293 // creation | |
294 IR(Compilation* compilation, ciMethod* method, int osr_bci); | |
295 | |
296 // accessors | |
297 bool is_valid() const { return top_scope()->is_valid(); } | |
298 Compilation* compilation() const { return _compilation; } | |
299 IRScope* top_scope() const { return _top_scope; } | |
300 int number_of_locks() const { return top_scope()->number_of_locks(); } | |
301 ciMethod* method() const { return top_scope()->method(); } | |
302 BlockBegin* start() const { return top_scope()->start(); } | |
303 BlockBegin* std_entry() const { return start()->end()->as_Base()->std_entry(); } | |
304 BlockBegin* osr_entry() const { return start()->end()->as_Base()->osr_entry(); } | |
305 WordSize locals_size() const { return _locals_size; } | |
306 int locals_size_in_words() const { return in_words(_locals_size); } | |
307 BlockList* code() const { return _code; } | |
308 int num_loops() const { return _num_loops; } | |
309 int max_stack() const { return top_scope()->max_stack(); } // expensive | |
310 | |
311 // ir manipulation | |
312 void optimize(); | |
313 void compute_predecessors(); | |
314 void split_critical_edges(); | |
315 void compute_code(); | |
316 void compute_use_counts(); | |
317 | |
318 // The linear-scan order and the code emission order are equal, but | |
319 // this may change in future | |
320 BlockList* linear_scan_order() { assert(_code != NULL, "not computed"); return _code; } | |
321 | |
322 // iteration | |
323 void iterate_preorder (BlockClosure* closure); | |
324 void iterate_postorder (BlockClosure* closure); | |
325 void iterate_linear_scan_order(BlockClosure* closure); | |
326 | |
327 // debugging | |
328 static void print(BlockBegin* start, bool cfg_only, bool live_only = false) PRODUCT_RETURN; | |
329 void print(bool cfg_only, bool live_only = false) PRODUCT_RETURN; | |
330 void verify() PRODUCT_RETURN; | |
331 }; | |
332 | |
333 | |
334 // Globally do instruction substitution and remove substituted | |
335 // instructions from the instruction list. | |
336 // | |
337 | |
1584 | 338 class SubstitutionResolver: public BlockClosure, ValueVisitor { |
339 virtual void visit(Value* v); | |
0 | 340 |
341 public: | |
342 SubstitutionResolver(IR* hir) { | |
343 hir->iterate_preorder(this); | |
344 } | |
345 | |
346 SubstitutionResolver(BlockBegin* block) { | |
347 block->iterate_preorder(this); | |
348 } | |
349 | |
350 virtual void block_do(BlockBegin* block); | |
351 }; | |
1972 | 352 |
353 #endif // SHARE_VM_C1_C1_IR_HPP |