Mercurial > hg > graal-compiler
annotate src/share/vm/opto/parse.hpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | f6f3bb0ee072 |
children | 8f6ce6f1049b |
rev | line source |
---|---|
0 | 1 /* |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
1972
diff
changeset
|
2 * Copyright (c) 1997, 2011, 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:
1344
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1344
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:
1344
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_OPTO_PARSE_HPP |
26 #define SHARE_VM_OPTO_PARSE_HPP | |
27 | |
28 #include "ci/ciMethodData.hpp" | |
29 #include "ci/ciTypeFlow.hpp" | |
30 #include "compiler/methodLiveness.hpp" | |
31 #include "libadt/vectset.hpp" | |
32 #include "oops/generateOopMap.hpp" | |
33 #include "opto/graphKit.hpp" | |
34 #include "opto/subnode.hpp" | |
35 | |
0 | 36 class BytecodeParseHistogram; |
37 class InlineTree; | |
38 class Parse; | |
39 class SwitchRange; | |
40 | |
41 | |
42 //------------------------------InlineTree------------------------------------- | |
43 class InlineTree : public ResourceObj { | |
3939 | 44 friend class VMStructs; |
45 | |
0 | 46 Compile* C; // cache |
47 JVMState* _caller_jvms; // state of caller | |
48 ciMethod* _method; // method being called by the caller_jvms | |
49 InlineTree* _caller_tree; | |
50 uint _count_inline_bcs; // Accumulated count of inlined bytecodes | |
51 // Call-site count / interpreter invocation count, scaled recursively. | |
52 // Always between 0.0 and 1.0. Represents the percentage of the method's | |
53 // total execution time used at this call site. | |
54 const float _site_invoke_ratio; | |
3784
aabf25fa3f05
7057587: JSR 292 - crash with jruby in test/test_respond_to.rb
never
parents:
3366
diff
changeset
|
55 const int _max_inline_level; // the maximum inline level for this sub-tree (may be adjusted) |
0 | 56 float compute_callee_frequency( int caller_bci ) const; |
57 | |
58 GrowableArray<InlineTree*> _subtrees; | |
3939 | 59 |
60 void print_impl(outputStream* stj, int indent) const PRODUCT_RETURN; | |
0 | 61 |
62 protected: | |
63 InlineTree(Compile* C, | |
64 const InlineTree* caller_tree, | |
65 ciMethod* callee_method, | |
66 JVMState* caller_jvms, | |
67 int caller_bci, | |
1157
c3b315a0d58a
6912063: inlining parameters need to be adjusted for some uses of the JVM
jrose
parents:
989
diff
changeset
|
68 float site_invoke_ratio, |
3784
aabf25fa3f05
7057587: JSR 292 - crash with jruby in test/test_respond_to.rb
never
parents:
3366
diff
changeset
|
69 int max_inline_level); |
0 | 70 InlineTree *build_inline_tree_for_callee(ciMethod* callee_method, |
71 JVMState* caller_jvms, | |
72 int caller_bci); | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
73 const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result); |
3366
e2a92dd0d3d2
7042122: JSR 292: adjust various inline thresholds for JSR 292 API methods and method handle adapters
twisti
parents:
3345
diff
changeset
|
74 const char* should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const; |
e2a92dd0d3d2
7042122: JSR 292: adjust various inline thresholds for JSR 292 API methods and method handle adapters
twisti
parents:
3345
diff
changeset
|
75 const char* should_not_inline(ciMethod* callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const; |
3345 | 76 void print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const; |
0 | 77 |
78 InlineTree *caller_tree() const { return _caller_tree; } | |
79 InlineTree* callee_at(int bci, ciMethod* m) const; | |
3784
aabf25fa3f05
7057587: JSR 292 - crash with jruby in test/test_respond_to.rb
never
parents:
3366
diff
changeset
|
80 int inline_level() const { return stack_depth(); } |
1157
c3b315a0d58a
6912063: inlining parameters need to be adjusted for some uses of the JVM
jrose
parents:
989
diff
changeset
|
81 int stack_depth() const { return _caller_jvms ? _caller_jvms->depth() : 0; } |
0 | 82 |
83 public: | |
3900
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3784
diff
changeset
|
84 static const char* check_can_parse(ciMethod* callee); |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3784
diff
changeset
|
85 |
0 | 86 static InlineTree* build_inline_tree_root(); |
87 static InlineTree* find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee, bool create_if_not_found = false); | |
88 | |
89 // For temporary (stack-allocated, stateless) ilts: | |
3784
aabf25fa3f05
7057587: JSR 292 - crash with jruby in test/test_respond_to.rb
never
parents:
3366
diff
changeset
|
90 InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, float site_invoke_ratio, int max_inline_level); |
0 | 91 |
92 // InlineTree enum | |
93 enum InlineStyle { | |
94 Inline_do_not_inline = 0, // | |
95 Inline_cha_is_monomorphic = 1, // | |
96 Inline_type_profile_monomorphic = 2 // | |
97 }; | |
98 | |
99 // See if it is OK to inline. | |
605 | 100 // The receiver is the inline tree for the caller. |
0 | 101 // |
102 // The result is a temperature indication. If it is hot or cold, | |
103 // inlining is immediate or undesirable. Otherwise, the info block | |
104 // returned is newly allocated and may be enqueued. | |
105 // | |
106 // If the method is inlinable, a new inline subtree is created on the fly, | |
107 // and may be accessed by find_subtree_from_root. | |
108 // The call_method is the dest_method for a special or static invocation. | |
109 // The call_method is an optimized virtual method candidate otherwise. | |
110 WarmCallInfo* ok_to_inline(ciMethod *call_method, JVMState* caller_jvms, ciCallProfile& profile, WarmCallInfo* wci); | |
111 | |
112 // Information about inlined method | |
113 JVMState* caller_jvms() const { return _caller_jvms; } | |
114 ciMethod *method() const { return _method; } | |
115 int caller_bci() const { return _caller_jvms ? _caller_jvms->bci() : InvocationEntryBci; } | |
116 uint count_inline_bcs() const { return _count_inline_bcs; } | |
117 float site_invoke_ratio() const { return _site_invoke_ratio; }; | |
118 | |
119 #ifndef PRODUCT | |
120 private: | |
121 uint _count_inlines; // Count of inlined methods | |
122 public: | |
123 // Debug information collected during parse | |
124 uint count_inlines() const { return _count_inlines; }; | |
125 #endif | |
126 GrowableArray<InlineTree*> subtrees() { return _subtrees; } | |
3939 | 127 |
128 void print_value_on(outputStream* st) const PRODUCT_RETURN; | |
0 | 129 }; |
130 | |
131 | |
132 //----------------------------------------------------------------------------- | |
133 //------------------------------Parse------------------------------------------ | |
134 // Parse bytecodes, build a Graph | |
135 class Parse : public GraphKit { | |
136 public: | |
137 // Per-block information needed by the parser: | |
138 class Block { | |
139 private: | |
140 ciTypeFlow::Block* _flow; | |
141 int _pred_count; // how many predecessors in CFG? | |
142 int _preds_parsed; // how many of these have been parsed? | |
143 uint _count; // how many times executed? Currently only set by _goto's | |
144 bool _is_parsed; // has this block been parsed yet? | |
145 bool _is_handler; // is this block an exception handler? | |
2383
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
146 bool _has_merged_backedge; // does this block have merged backedge? |
0 | 147 SafePointNode* _start_map; // all values flowing into this block |
148 MethodLivenessResult _live_locals; // lazily initialized liveness bitmap | |
149 | |
150 int _num_successors; // Includes only normal control flow. | |
151 int _all_successors; // Include exception paths also. | |
152 Block** _successors; | |
153 | |
154 // Use init_node/init_graph to initialize Blocks. | |
155 // Block() : _live_locals((uintptr_t*)NULL,0) { ShouldNotReachHere(); } | |
156 Block() : _live_locals(NULL,0) { ShouldNotReachHere(); } | |
157 | |
158 public: | |
159 | |
160 // Set up the block data structure itself. | |
161 void init_node(Parse* outer, int po); | |
162 // Set up the block's relations to other blocks. | |
163 void init_graph(Parse* outer); | |
164 | |
165 ciTypeFlow::Block* flow() const { return _flow; } | |
166 int pred_count() const { return _pred_count; } | |
167 int preds_parsed() const { return _preds_parsed; } | |
168 bool is_parsed() const { return _is_parsed; } | |
169 bool is_handler() const { return _is_handler; } | |
170 void set_count( uint x ) { _count = x; } | |
171 uint count() const { return _count; } | |
172 | |
173 SafePointNode* start_map() const { assert(is_merged(),""); return _start_map; } | |
174 void set_start_map(SafePointNode* m) { assert(!is_merged(), ""); _start_map = m; } | |
175 | |
176 // True after any predecessor flows control into this block | |
177 bool is_merged() const { return _start_map != NULL; } | |
178 | |
2383
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
179 #ifdef ASSERT |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
180 // True after backedge predecessor flows control into this block |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
181 bool has_merged_backedge() const { return _has_merged_backedge; } |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
182 void mark_merged_backedge(Block* pred) { |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
183 assert(is_SEL_head(), "should be loop head"); |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
184 if (pred != NULL && is_SEL_backedge(pred)) { |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
185 assert(is_parsed(), "block should be parsed before merging backedges"); |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
186 _has_merged_backedge = true; |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
187 } |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
188 } |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
189 #endif |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
190 |
0 | 191 // True when all non-exception predecessors have been parsed. |
192 bool is_ready() const { return preds_parsed() == pred_count(); } | |
193 | |
194 int num_successors() const { return _num_successors; } | |
195 int all_successors() const { return _all_successors; } | |
196 Block* successor_at(int i) const { | |
197 assert((uint)i < (uint)all_successors(), ""); | |
198 return _successors[i]; | |
199 } | |
200 Block* successor_for_bci(int bci); | |
201 | |
202 int start() const { return flow()->start(); } | |
203 int limit() const { return flow()->limit(); } | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
204 int rpo() const { return flow()->rpo(); } |
0 | 205 int start_sp() const { return flow()->stack_size(); } |
206 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
207 bool is_loop_head() const { return flow()->is_loop_head(); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
208 bool is_SEL_head() const { return flow()->is_single_entry_loop_head(); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
209 bool is_SEL_backedge(Block* pred) const{ return is_SEL_head() && pred->rpo() >= rpo(); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
210 bool is_invariant_local(uint i) const { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
211 const JVMState* jvms = start_map()->jvms(); |
435
b1d6a3e95810
6766316: assert(!nocreate,"Cannot build a phi for a block already parsed.")
kvn
parents:
367
diff
changeset
|
212 if (!jvms->is_loc(i) || flow()->outer()->has_irreducible_entry()) return false; |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
213 return flow()->is_invariant_local(i - jvms->locoff()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
214 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
215 bool can_elide_SEL_phi(uint i) const { assert(is_SEL_head(),""); return is_invariant_local(i); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
216 |
0 | 217 const Type* peek(int off=0) const { return stack_type_at(start_sp() - (off+1)); } |
218 | |
219 const Type* stack_type_at(int i) const; | |
220 const Type* local_type_at(int i) const; | |
221 static const Type* get_type(ciType* t) { return Type::get_typeflow_type(t); } | |
222 | |
223 bool has_trap_at(int bci) const { return flow()->has_trap() && flow()->trap_bci() == bci; } | |
224 | |
225 // Call this just before parsing a block. | |
226 void mark_parsed() { | |
227 assert(!_is_parsed, "must parse each block exactly once"); | |
228 _is_parsed = true; | |
229 } | |
230 | |
231 // Return the phi/region input index for the "current" pred, | |
232 // and bump the pred number. For historical reasons these index | |
233 // numbers are handed out in descending order. The last index is | |
234 // always PhiNode::Input (i.e., 1). The value returned is known | |
235 // as a "path number" because it distinguishes by which path we are | |
236 // entering the block. | |
237 int next_path_num() { | |
238 assert(preds_parsed() < pred_count(), "too many preds?"); | |
239 return pred_count() - _preds_parsed++; | |
240 } | |
241 | |
242 // Add a previously unaccounted predecessor to this block. | |
243 // This operates by increasing the size of the block's region | |
244 // and all its phi nodes (if any). The value returned is a | |
245 // path number ("pnum"). | |
246 int add_new_path(); | |
247 | |
248 // Initialize me by recording the parser's map. My own map must be NULL. | |
249 void record_state(Parse* outer); | |
250 }; | |
251 | |
252 #ifndef PRODUCT | |
253 // BytecodeParseHistogram collects number of bytecodes parsed, nodes constructed, and transformations. | |
254 class BytecodeParseHistogram : public ResourceObj { | |
255 private: | |
256 enum BPHType { | |
257 BPH_transforms, | |
258 BPH_values | |
259 }; | |
260 static bool _initialized; | |
261 static uint _bytecodes_parsed [Bytecodes::number_of_codes]; | |
262 static uint _nodes_constructed[Bytecodes::number_of_codes]; | |
263 static uint _nodes_transformed[Bytecodes::number_of_codes]; | |
264 static uint _new_values [Bytecodes::number_of_codes]; | |
265 | |
266 Bytecodes::Code _initial_bytecode; | |
267 int _initial_node_count; | |
268 int _initial_transforms; | |
269 int _initial_values; | |
270 | |
271 Parse *_parser; | |
272 Compile *_compiler; | |
273 | |
274 // Initialization | |
275 static void reset(); | |
276 | |
277 // Return info being collected, select with global flag 'BytecodeParseInfo' | |
278 int current_count(BPHType info_selector); | |
279 | |
280 public: | |
281 BytecodeParseHistogram(Parse *p, Compile *c); | |
282 static bool initialized(); | |
283 | |
284 // Record info when starting to parse one bytecode | |
285 void set_initial_state( Bytecodes::Code bc ); | |
286 // Record results of parsing one bytecode | |
287 void record_change(); | |
288 | |
289 // Profile printing | |
290 static void print(float cutoff = 0.01F); // cutoff in percent | |
291 }; | |
292 | |
293 public: | |
294 // Record work done during parsing | |
295 BytecodeParseHistogram* _parse_histogram; | |
296 void set_parse_histogram(BytecodeParseHistogram *bph) { _parse_histogram = bph; } | |
297 BytecodeParseHistogram* parse_histogram() { return _parse_histogram; } | |
298 #endif | |
299 | |
300 private: | |
301 friend class Block; | |
302 | |
303 // Variables which characterize this compilation as a whole: | |
304 | |
305 JVMState* _caller; // JVMS which carries incoming args & state. | |
306 float _expected_uses; // expected number of calls to this code | |
307 float _prof_factor; // discount applied to my profile counts | |
308 int _depth; // Inline tree depth, for debug printouts | |
309 const TypeFunc*_tf; // My kind of function type | |
310 int _entry_bci; // the osr bci or InvocationEntryBci | |
311 | |
312 ciTypeFlow* _flow; // Results of previous flow pass. | |
313 Block* _blocks; // Array of basic-block structs. | |
314 int _block_count; // Number of elements in _blocks. | |
315 | |
316 GraphKit _exits; // Record all normal returns and throws here. | |
317 bool _wrote_final; // Did we write a final field? | |
318 bool _count_invocations; // update and test invocation counter | |
319 bool _method_data_update; // update method data oop | |
320 | |
321 // Variables which track Java semantics during bytecode parsing: | |
322 | |
323 Block* _block; // block currently getting parsed | |
324 ciBytecodeStream _iter; // stream of this method's bytecodes | |
325 | |
326 int _blocks_merged; // Progress meter: state merges from BB preds | |
327 int _blocks_parsed; // Progress meter: BBs actually parsed | |
328 | |
329 const FastLockNode* _synch_lock; // FastLockNode for synchronized method | |
330 | |
331 #ifndef PRODUCT | |
332 int _max_switch_depth; // Debugging SwitchRanges. | |
333 int _est_switch_depth; // Debugging SwitchRanges. | |
334 #endif | |
335 | |
336 public: | |
337 // Constructor | |
338 Parse(JVMState* caller, ciMethod* parse_method, float expected_uses); | |
339 | |
340 virtual Parse* is_Parse() const { return (Parse*)this; } | |
341 | |
342 public: | |
343 // Accessors. | |
344 JVMState* caller() const { return _caller; } | |
345 float expected_uses() const { return _expected_uses; } | |
346 float prof_factor() const { return _prof_factor; } | |
347 int depth() const { return _depth; } | |
348 const TypeFunc* tf() const { return _tf; } | |
349 // entry_bci() -- see osr_bci, etc. | |
350 | |
351 ciTypeFlow* flow() const { return _flow; } | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
352 // blocks() -- see rpo_at, start_block, etc. |
0 | 353 int block_count() const { return _block_count; } |
354 | |
355 GraphKit& exits() { return _exits; } | |
356 bool wrote_final() const { return _wrote_final; } | |
357 void set_wrote_final(bool z) { _wrote_final = z; } | |
358 bool count_invocations() const { return _count_invocations; } | |
359 bool method_data_update() const { return _method_data_update; } | |
360 | |
361 Block* block() const { return _block; } | |
362 ciBytecodeStream& iter() { return _iter; } | |
363 Bytecodes::Code bc() const { return _iter.cur_bc(); } | |
364 | |
365 void set_block(Block* b) { _block = b; } | |
366 | |
367 // Derived accessors: | |
368 bool is_normal_parse() const { return _entry_bci == InvocationEntryBci; } | |
369 bool is_osr_parse() const { return _entry_bci != InvocationEntryBci; } | |
370 int osr_bci() const { assert(is_osr_parse(),""); return _entry_bci; } | |
371 | |
372 void set_parse_bci(int bci); | |
373 | |
374 // Must this parse be aborted? | |
375 bool failing() { return C->failing(); } | |
376 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
377 Block* rpo_at(int rpo) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
378 assert(0 <= rpo && rpo < _block_count, "oob"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
379 return &_blocks[rpo]; |
0 | 380 } |
381 Block* start_block() { | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
382 return rpo_at(flow()->start_block()->rpo()); |
0 | 383 } |
384 // Can return NULL if the flow pass did not complete a block. | |
385 Block* successor_for_bci(int bci) { | |
386 return block()->successor_for_bci(bci); | |
387 } | |
388 | |
389 private: | |
390 // Create a JVMS & map for the initial state of this method. | |
391 SafePointNode* create_entry_map(); | |
392 | |
393 // OSR helpers | |
394 Node *fetch_interpreter_state(int index, BasicType bt, Node *local_addrs, Node *local_addrs_base); | |
395 Node* check_interpreter_type(Node* l, const Type* type, SafePointNode* &bad_type_exit); | |
396 void load_interpreter_state(Node* osr_buf); | |
397 | |
398 // Functions for managing basic blocks: | |
399 void init_blocks(); | |
400 void load_state_from(Block* b); | |
401 void store_state_to(Block* b) { b->record_state(this); } | |
402 | |
403 // Parse all the basic blocks. | |
404 void do_all_blocks(); | |
405 | |
406 // Parse the current basic block | |
407 void do_one_block(); | |
408 | |
409 // Raise an error if we get a bad ciTypeFlow CFG. | |
410 void handle_missing_successor(int bci); | |
411 | |
412 // first actions (before BCI 0) | |
413 void do_method_entry(); | |
414 | |
415 // implementation of monitorenter/monitorexit | |
416 void do_monitor_enter(); | |
417 void do_monitor_exit(); | |
418 | |
419 // Eagerly create phie throughout the state, to cope with back edges. | |
420 void ensure_phis_everywhere(); | |
421 | |
422 // Merge the current mapping into the basic block starting at bci | |
423 void merge( int target_bci); | |
424 // Same as plain merge, except that it allocates a new path number. | |
425 void merge_new_path( int target_bci); | |
426 // Merge the current mapping into an exception handler. | |
427 void merge_exception(int target_bci); | |
428 // Helper: Merge the current mapping into the given basic block | |
429 void merge_common(Block* target, int pnum); | |
430 // Helper functions for merging individual cells. | |
431 PhiNode *ensure_phi( int idx, bool nocreate = false); | |
432 PhiNode *ensure_memory_phi(int idx, bool nocreate = false); | |
433 // Helper to merge the current memory state into the given basic block | |
434 void merge_memory_edges(MergeMemNode* n, int pnum, bool nophi); | |
435 | |
436 // Parse this bytecode, and alter the Parsers JVM->Node mapping | |
437 void do_one_bytecode(); | |
438 | |
439 // helper function to generate array store check | |
440 void array_store_check(); | |
441 // Helper function to generate array load | |
442 void array_load(BasicType etype); | |
443 // Helper function to generate array store | |
444 void array_store(BasicType etype); | |
445 // Helper function to compute array addressing | |
446 Node* array_addressing(BasicType type, int vals, const Type* *result2=NULL); | |
447 | |
448 // Pass current map to exits | |
449 void return_current(Node* value); | |
450 | |
451 // Register finalizers on return from Object.<init> | |
452 void call_register_finalizer(); | |
453 | |
454 // Insert a compiler safepoint into the graph | |
455 void add_safepoint(); | |
456 | |
457 // Insert a compiler safepoint into the graph, if there is a back-branch. | |
458 void maybe_add_safepoint(int target_bci) { | |
459 if (UseLoopSafepoints && target_bci <= bci()) { | |
460 add_safepoint(); | |
461 } | |
462 } | |
463 | |
464 // Note: Intrinsic generation routines may be found in library_call.cpp. | |
465 | |
466 // Helper function to setup Ideal Call nodes | |
467 void do_call(); | |
468 | |
469 // Helper function to uncommon-trap or bailout for non-compilable call-sites | |
470 bool can_not_compile_call_site(ciMethod *dest_method, ciInstanceKlass *klass); | |
471 | |
472 // Helper function to identify inlining potential at call-site | |
473 ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, | |
474 ciMethod *dest_method, const TypeOopPtr* receiver_type); | |
475 | |
476 // Helper function to setup for type-profile based inlining | |
477 bool prepare_type_profile_inline(ciInstanceKlass* prof_klass, ciMethod* prof_method); | |
478 | |
479 // Helper functions for type checking bytecodes: | |
480 void do_checkcast(); | |
481 void do_instanceof(); | |
482 | |
483 // Helper functions for shifting & arithmetic | |
484 void modf(); | |
485 void modd(); | |
486 void l2f(); | |
487 | |
488 void do_irem(); | |
489 | |
490 // implementation of _get* and _put* bytecodes | |
491 void do_getstatic() { do_field_access(true, false); } | |
492 void do_getfield () { do_field_access(true, true); } | |
493 void do_putstatic() { do_field_access(false, false); } | |
494 void do_putfield () { do_field_access(false, true); } | |
495 | |
496 // common code for making initial checks and forming addresses | |
497 void do_field_access(bool is_get, bool is_field); | |
498 bool static_field_ok_in_clinit(ciField *field, ciMethod *method); | |
499 | |
500 // common code for actually performing the load or store | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
1972
diff
changeset
|
501 void do_get_xxx(Node* obj, ciField* field, bool is_field); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
1972
diff
changeset
|
502 void do_put_xxx(Node* obj, ciField* field, bool is_field); |
0 | 503 |
504 // loading from a constant field or the constant pool | |
505 // returns false if push failed (non-perm field constants only, not ldcs) | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
506 bool push_constant(ciConstant con, bool require_constant = false); |
0 | 507 |
508 // implementation of object creation bytecodes | |
1645
3941674cc7fa
6958668: repeated uncommon trapping for new of klass which is being initialized
never
parents:
1552
diff
changeset
|
509 void emit_guard_for_new(ciInstanceKlass* klass); |
0 | 510 void do_new(); |
511 void do_newarray(BasicType elemtype); | |
512 void do_anewarray(); | |
513 void do_multianewarray(); | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
605
diff
changeset
|
514 Node* expand_multianewarray(ciArrayKlass* array_klass, Node* *lengths, int ndimensions, int nargs); |
0 | 515 |
516 // implementation of jsr/ret | |
517 void do_jsr(); | |
518 void do_ret(); | |
519 | |
520 float dynamic_branch_prediction(float &cnt); | |
521 float branch_prediction(float &cnt, BoolTest::mask btest, int target_bci); | |
522 bool seems_never_taken(float prob); | |
1746
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1645
diff
changeset
|
523 bool seems_stable_comparison(BoolTest::mask btest, Node* c); |
0 | 524 |
248
18aab3cdd513
6726504: handle do_ifxxx calls in parser more uniformly
rasbold
parents:
196
diff
changeset
|
525 void do_ifnull(BoolTest::mask btest, Node* c); |
0 | 526 void do_if(BoolTest::mask btest, Node* c); |
1172 | 527 int repush_if_args(); |
0 | 528 void adjust_map_after_if(BoolTest::mask btest, Node* c, float prob, |
529 Block* path, Block* other_path); | |
530 IfNode* jump_if_fork_int(Node* a, Node* b, BoolTest::mask mask); | |
531 Node* jump_if_join(Node* iffalse, Node* iftrue); | |
532 void jump_if_true_fork(IfNode *ifNode, int dest_bci_if_true, int prof_table_index); | |
533 void jump_if_false_fork(IfNode *ifNode, int dest_bci_if_false, int prof_table_index); | |
534 void jump_if_always_fork(int dest_bci_if_true, int prof_table_index); | |
535 | |
536 friend class SwitchRange; | |
537 void do_tableswitch(); | |
538 void do_lookupswitch(); | |
539 void jump_switch_ranges(Node* a, SwitchRange* lo, SwitchRange* hi, int depth = 0); | |
540 bool create_jump_tables(Node* a, SwitchRange* lo, SwitchRange* hi); | |
541 | |
542 // helper functions for methodData style profiling | |
543 void test_counter_against_threshold(Node* cnt, int limit); | |
544 void increment_and_test_invocation_counter(int limit); | |
545 void test_for_osr_md_counter_at(ciMethodData* md, ciProfileData* data, ByteSize offset, int limit); | |
546 Node* method_data_addressing(ciMethodData* md, ciProfileData* data, ByteSize offset, Node* idx = NULL, uint stride = 0); | |
547 void increment_md_counter_at(ciMethodData* md, ciProfileData* data, ByteSize offset, Node* idx = NULL, uint stride = 0); | |
548 void set_md_flag_at(ciMethodData* md, ciProfileData* data, int flag_constant); | |
549 | |
550 void profile_method_entry(); | |
551 void profile_taken_branch(int target_bci, bool force_update = false); | |
552 void profile_not_taken_branch(bool force_update = false); | |
553 void profile_call(Node* receiver); | |
554 void profile_generic_call(); | |
555 void profile_receiver_type(Node* receiver); | |
556 void profile_ret(int target_bci); | |
557 void profile_null_checkcast(); | |
558 void profile_switch_case(int table_index); | |
559 | |
560 // helper function for call statistics | |
561 void count_compiled_calls(bool at_method_entry, bool is_inline) PRODUCT_RETURN; | |
562 | |
563 Node_Notes* make_node_notes(Node_Notes* caller_nn); | |
564 | |
565 // Helper functions for handling normal and abnormal exits. | |
566 void build_exits(); | |
567 | |
568 // Fix up all exceptional control flow exiting a single bytecode. | |
569 void do_exceptions(); | |
570 | |
571 // Fix up all exiting control flow at the end of the parse. | |
572 void do_exits(); | |
573 | |
574 // Add Catch/CatchProjs | |
575 // The call is either a Java call or the VM's rethrow stub | |
576 void catch_call_exceptions(ciExceptionHandlerStream&); | |
577 | |
578 // Handle all exceptions thrown by the inlined method. | |
579 // Also handles exceptions for individual bytecodes. | |
580 void catch_inline_exceptions(SafePointNode* ex_map); | |
581 | |
582 // Merge the given map into correct exceptional exit state. | |
583 // Assumes that there is no applicable local handler. | |
584 void throw_to_exit(SafePointNode* ex_map); | |
585 | |
586 public: | |
587 #ifndef PRODUCT | |
588 // Handle PrintOpto, etc. | |
589 void show_parse_info(); | |
590 void dump_map_adr_mem() const; | |
591 static void print_statistics(); // Print some performance counters | |
592 void dump(); | |
593 void dump_bci(int bci); | |
594 #endif | |
595 }; | |
1972 | 596 |
597 #endif // SHARE_VM_OPTO_PARSE_HPP |