Mercurial > hg > truffle
annotate src/share/vm/c1/c1_IR.hpp @ 4710:41406797186b
7113012: G1: rename not-fully-young GCs as "mixed"
Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets).
Reviewed-by: johnc, brutisso
author | tonyp |
---|---|
date | Fri, 16 Dec 2011 02:14:27 -0500 |
parents | f95d63e2154a |
children | 5857923e563c 701a83c86f28 |
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 | |
152 BlockBegin* _start; // the start block, successsors are method entries | |
153 | |
154 BitMap _requires_phi_function; // bit is set if phi functions at loop headers are necessary for a local variable | |
155 | |
156 // helper functions | |
157 BlockBegin* build_graph(Compilation* compilation, int osr_bci); | |
158 | |
159 public: | |
160 // creation | |
161 IRScope(Compilation* compilation, IRScope* caller, int caller_bci, ciMethod* method, int osr_bci, bool create_graph = false); | |
162 | |
163 // accessors | |
164 Compilation* compilation() const { return _compilation; } | |
165 IRScope* caller() const { return _caller; } | |
166 int level() const { return _level; } | |
167 ciMethod* method() const { return _method; } | |
168 int max_stack() const; // NOTE: expensive | |
169 BitMap& requires_phi_function() { return _requires_phi_function; } | |
170 | |
171 // hierarchy | |
172 bool is_top_scope() const { return _caller == NULL; } | |
173 void add_callee(IRScope* callee) { _callees.append(callee); } | |
174 int number_of_callees() const { return _callees.length(); } | |
175 IRScope* callee_no(int i) const { return _callees.at(i); } | |
176 | |
177 // accessors, graph | |
178 bool is_valid() const { return start() != NULL; } | |
179 XHandlers* xhandlers() const { return _xhandlers; } | |
180 int number_of_locks() const { return _number_of_locks; } | |
181 void set_min_number_of_locks(int n) { if (n > _number_of_locks) _number_of_locks = n; } | |
182 bool monitor_pairing_ok() const { return _monitor_pairing_ok; } | |
183 BlockBegin* start() const { return _start; } | |
184 }; | |
185 | |
186 | |
187 // | |
188 // IRScopeDebugInfo records the debug information for a particular IRScope | |
189 // in a particular CodeEmitInfo. This allows the information to be computed | |
190 // once early enough for the OopMap to be available to the LIR and also to be | |
191 // reemited for different pcs using the same CodeEmitInfo without recomputing | |
192 // everything. | |
193 // | |
194 | |
195 class IRScopeDebugInfo: public CompilationResourceObj { | |
196 private: | |
197 IRScope* _scope; | |
198 int _bci; | |
199 GrowableArray<ScopeValue*>* _locals; | |
200 GrowableArray<ScopeValue*>* _expressions; | |
201 GrowableArray<MonitorValue*>* _monitors; | |
202 IRScopeDebugInfo* _caller; | |
203 | |
204 public: | |
205 IRScopeDebugInfo(IRScope* scope, | |
206 int bci, | |
207 GrowableArray<ScopeValue*>* locals, | |
208 GrowableArray<ScopeValue*>* expressions, | |
209 GrowableArray<MonitorValue*>* monitors, | |
210 IRScopeDebugInfo* caller): | |
211 _scope(scope) | |
212 , _locals(locals) | |
213 , _bci(bci) | |
214 , _expressions(expressions) | |
215 , _monitors(monitors) | |
216 , _caller(caller) {} | |
217 | |
218 | |
219 IRScope* scope() { return _scope; } | |
220 int bci() { return _bci; } | |
221 GrowableArray<ScopeValue*>* locals() { return _locals; } | |
222 GrowableArray<ScopeValue*>* expressions() { return _expressions; } | |
223 GrowableArray<MonitorValue*>* monitors() { return _monitors; } | |
224 IRScopeDebugInfo* caller() { return _caller; } | |
225 | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
0
diff
changeset
|
226 //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
|
227 bool should_reexecute(); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
0
diff
changeset
|
228 |
1295 | 229 void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool topmost, bool is_method_handle_invoke = false) { |
0 | 230 if (caller() != NULL) { |
231 // 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
|
232 caller()->record_debug_info(recorder, pc_offset, false/*topmost*/); |
0 | 233 } |
234 DebugToken* locvals = recorder->create_scope_values(locals()); | |
235 DebugToken* expvals = recorder->create_scope_values(expressions()); | |
236 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
|
237 // 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
|
238 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
|
239 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
|
240 recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals); |
0 | 241 } |
242 }; | |
243 | |
244 | |
245 class CodeEmitInfo: public CompilationResourceObj { | |
246 friend class LinearScan; | |
247 private: | |
248 IRScopeDebugInfo* _scope_debug_info; | |
249 IRScope* _scope; | |
250 XHandlers* _exception_handlers; | |
251 OopMap* _oop_map; | |
252 ValueStack* _stack; // used by deoptimization (contains also monitors | |
1564 | 253 bool _is_method_handle_invoke; // true if the associated call site is a MethodHandle call site. |
0 | 254 |
255 FrameMap* frame_map() const { return scope()->compilation()->frame_map(); } | |
256 Compilation* compilation() const { return scope()->compilation(); } | |
257 | |
258 public: | |
259 | |
260 // use scope from ValueStack | |
1819 | 261 CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers); |
0 | 262 |
263 // make a copy | |
1819 | 264 CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack = NULL); |
0 | 265 |
266 // accessors | |
267 OopMap* oop_map() { return _oop_map; } | |
268 ciMethod* method() const { return _scope->method(); } | |
269 IRScope* scope() const { return _scope; } | |
270 XHandlers* exception_handlers() const { return _exception_handlers; } | |
271 ValueStack* stack() const { return _stack; } | |
272 | |
273 void add_register_oop(LIR_Opr opr); | |
1564 | 274 void record_debug_info(DebugInformationRecorder* recorder, int pc_offset); |
0 | 275 |
1564 | 276 bool is_method_handle_invoke() const { return _is_method_handle_invoke; } |
277 void set_is_method_handle_invoke(bool x) { _is_method_handle_invoke = x; } | |
0 | 278 }; |
279 | |
280 | |
281 class IR: public CompilationResourceObj { | |
282 private: | |
283 Compilation* _compilation; // the current compilation | |
284 IRScope* _top_scope; // the root of the scope hierarchy | |
285 WordSize _locals_size; // the space required for all locals | |
286 int _num_loops; // Total number of loops | |
287 BlockList* _code; // the blocks in code generation order w/ use counts | |
288 | |
289 public: | |
290 // creation | |
291 IR(Compilation* compilation, ciMethod* method, int osr_bci); | |
292 | |
293 // accessors | |
294 bool is_valid() const { return top_scope()->is_valid(); } | |
295 Compilation* compilation() const { return _compilation; } | |
296 IRScope* top_scope() const { return _top_scope; } | |
297 int number_of_locks() const { return top_scope()->number_of_locks(); } | |
298 ciMethod* method() const { return top_scope()->method(); } | |
299 BlockBegin* start() const { return top_scope()->start(); } | |
300 BlockBegin* std_entry() const { return start()->end()->as_Base()->std_entry(); } | |
301 BlockBegin* osr_entry() const { return start()->end()->as_Base()->osr_entry(); } | |
302 WordSize locals_size() const { return _locals_size; } | |
303 int locals_size_in_words() const { return in_words(_locals_size); } | |
304 BlockList* code() const { return _code; } | |
305 int num_loops() const { return _num_loops; } | |
306 int max_stack() const { return top_scope()->max_stack(); } // expensive | |
307 | |
308 // ir manipulation | |
309 void optimize(); | |
310 void compute_predecessors(); | |
311 void split_critical_edges(); | |
312 void compute_code(); | |
313 void compute_use_counts(); | |
314 | |
315 // The linear-scan order and the code emission order are equal, but | |
316 // this may change in future | |
317 BlockList* linear_scan_order() { assert(_code != NULL, "not computed"); return _code; } | |
318 | |
319 // iteration | |
320 void iterate_preorder (BlockClosure* closure); | |
321 void iterate_postorder (BlockClosure* closure); | |
322 void iterate_linear_scan_order(BlockClosure* closure); | |
323 | |
324 // debugging | |
325 static void print(BlockBegin* start, bool cfg_only, bool live_only = false) PRODUCT_RETURN; | |
326 void print(bool cfg_only, bool live_only = false) PRODUCT_RETURN; | |
327 void verify() PRODUCT_RETURN; | |
328 }; | |
329 | |
330 | |
331 // Globally do instruction substitution and remove substituted | |
332 // instructions from the instruction list. | |
333 // | |
334 | |
1584 | 335 class SubstitutionResolver: public BlockClosure, ValueVisitor { |
336 virtual void visit(Value* v); | |
0 | 337 |
338 public: | |
339 SubstitutionResolver(IR* hir) { | |
340 hir->iterate_preorder(this); | |
341 } | |
342 | |
343 SubstitutionResolver(BlockBegin* block) { | |
344 block->iterate_preorder(this); | |
345 } | |
346 | |
347 virtual void block_do(BlockBegin* block); | |
348 }; | |
1972 | 349 |
350 #endif // SHARE_VM_C1_C1_IR_HPP |