Mercurial > hg > truffle
annotate src/share/vm/c1/c1_IR.hpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 0bf37f737702 |
children | 52b4284cb496 |
rev | line source |
---|---|
0 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
8860
diff
changeset
|
2 * Copyright (c) 1999, 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:
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. |
8860 | 257 bool _deoptimize_on_exception; |
0 | 258 |
259 FrameMap* frame_map() const { return scope()->compilation()->frame_map(); } | |
260 Compilation* compilation() const { return scope()->compilation(); } | |
261 | |
262 public: | |
263 | |
264 // use scope from ValueStack | |
8860 | 265 CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers, bool deoptimize_on_exception = false); |
0 | 266 |
267 // make a copy | |
1819 | 268 CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack = NULL); |
0 | 269 |
270 // accessors | |
271 OopMap* oop_map() { return _oop_map; } | |
272 ciMethod* method() const { return _scope->method(); } | |
273 IRScope* scope() const { return _scope; } | |
274 XHandlers* exception_handlers() const { return _exception_handlers; } | |
275 ValueStack* stack() const { return _stack; } | |
8860 | 276 bool deoptimize_on_exception() const { return _deoptimize_on_exception; } |
0 | 277 |
278 void add_register_oop(LIR_Opr opr); | |
1564 | 279 void record_debug_info(DebugInformationRecorder* recorder, int pc_offset); |
0 | 280 |
1564 | 281 bool is_method_handle_invoke() const { return _is_method_handle_invoke; } |
282 void set_is_method_handle_invoke(bool x) { _is_method_handle_invoke = x; } | |
17980
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17467
diff
changeset
|
283 |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17467
diff
changeset
|
284 int interpreter_frame_size() const; |
0 | 285 }; |
286 | |
287 | |
288 class IR: public CompilationResourceObj { | |
289 private: | |
290 Compilation* _compilation; // the current compilation | |
291 IRScope* _top_scope; // the root of the scope hierarchy | |
292 WordSize _locals_size; // the space required for all locals | |
293 int _num_loops; // Total number of loops | |
294 BlockList* _code; // the blocks in code generation order w/ use counts | |
295 | |
296 public: | |
297 // creation | |
298 IR(Compilation* compilation, ciMethod* method, int osr_bci); | |
299 | |
300 // accessors | |
301 bool is_valid() const { return top_scope()->is_valid(); } | |
302 Compilation* compilation() const { return _compilation; } | |
303 IRScope* top_scope() const { return _top_scope; } | |
304 int number_of_locks() const { return top_scope()->number_of_locks(); } | |
305 ciMethod* method() const { return top_scope()->method(); } | |
306 BlockBegin* start() const { return top_scope()->start(); } | |
307 BlockBegin* std_entry() const { return start()->end()->as_Base()->std_entry(); } | |
308 BlockBegin* osr_entry() const { return start()->end()->as_Base()->osr_entry(); } | |
309 WordSize locals_size() const { return _locals_size; } | |
310 int locals_size_in_words() const { return in_words(_locals_size); } | |
311 BlockList* code() const { return _code; } | |
312 int num_loops() const { return _num_loops; } | |
313 int max_stack() const { return top_scope()->max_stack(); } // expensive | |
314 | |
315 // ir manipulation | |
8860 | 316 void optimize_blocks(); |
317 void eliminate_null_checks(); | |
0 | 318 void compute_predecessors(); |
319 void split_critical_edges(); | |
320 void compute_code(); | |
321 void compute_use_counts(); | |
322 | |
323 // The linear-scan order and the code emission order are equal, but | |
324 // this may change in future | |
325 BlockList* linear_scan_order() { assert(_code != NULL, "not computed"); return _code; } | |
326 | |
327 // iteration | |
328 void iterate_preorder (BlockClosure* closure); | |
329 void iterate_postorder (BlockClosure* closure); | |
330 void iterate_linear_scan_order(BlockClosure* closure); | |
331 | |
332 // debugging | |
333 static void print(BlockBegin* start, bool cfg_only, bool live_only = false) PRODUCT_RETURN; | |
334 void print(bool cfg_only, bool live_only = false) PRODUCT_RETURN; | |
335 void verify() PRODUCT_RETURN; | |
336 }; | |
337 | |
338 | |
339 // Globally do instruction substitution and remove substituted | |
340 // instructions from the instruction list. | |
341 // | |
342 | |
1584 | 343 class SubstitutionResolver: public BlockClosure, ValueVisitor { |
344 virtual void visit(Value* v); | |
0 | 345 |
346 public: | |
347 SubstitutionResolver(IR* hir) { | |
348 hir->iterate_preorder(this); | |
349 } | |
350 | |
351 SubstitutionResolver(BlockBegin* block) { | |
352 block->iterate_preorder(this); | |
353 } | |
354 | |
355 virtual void block_do(BlockBegin* block); | |
356 }; | |
1972 | 357 |
358 #endif // SHARE_VM_C1_C1_IR_HPP |