Mercurial > hg > truffle
annotate src/share/vm/opto/parse.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 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
12966
diff
changeset
|
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:
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; | |
8119
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
61 const char* _msg; |
0 | 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); | |
8119
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
73 bool try_to_inline(ciMethod* callee_method, |
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
74 ciMethod* caller_method, |
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
75 int caller_bci, |
12862
0c4c40f5c399
8011138: C2: stack overflow in compiler thread because of recursive inlining of lambda form methods
twisti
parents:
12190
diff
changeset
|
76 JVMState* jvms, |
8119
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
77 ciCallProfile& profile, |
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
78 WarmCallInfo* wci_result, |
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
79 bool& should_delay); |
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
80 bool should_inline(ciMethod* callee_method, |
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
81 ciMethod* caller_method, |
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
82 int caller_bci, |
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
83 ciCallProfile& profile, |
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
84 WarmCallInfo* wci_result); |
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
85 bool should_not_inline(ciMethod* callee_method, |
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
86 ciMethod* caller_method, |
12862
0c4c40f5c399
8011138: C2: stack overflow in compiler thread because of recursive inlining of lambda form methods
twisti
parents:
12190
diff
changeset
|
87 JVMState* jvms, |
8119
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
88 WarmCallInfo* wci_result); |
7991
60bba1398c51
8005439: no message about inline method if it specifed by CompileCommand
vlivanov
parents:
7478
diff
changeset
|
89 void print_inlining(ciMethod* callee_method, int caller_bci, |
8119
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
90 bool success) const; |
0 | 91 |
8119
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
92 InlineTree* caller_tree() const { return _caller_tree; } |
0 | 93 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
|
94 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
|
95 int stack_depth() const { return _caller_jvms ? _caller_jvms->depth() : 0; } |
8119
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
96 const char* msg() const { return _msg; } |
133bf557ef77
8007439: C2: adding successful message of inlining
iignatyev
parents:
7991
diff
changeset
|
97 void set_msg(const char* msg) { _msg = msg; } |
0 | 98 public: |
3900
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3784
diff
changeset
|
99 static const char* check_can_parse(ciMethod* callee); |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3784
diff
changeset
|
100 |
0 | 101 static InlineTree* build_inline_tree_root(); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6131
diff
changeset
|
102 static InlineTree* find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee); |
0 | 103 |
104 // 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
|
105 InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, float site_invoke_ratio, int max_inline_level); |
0 | 106 |
107 // InlineTree enum | |
108 enum InlineStyle { | |
109 Inline_do_not_inline = 0, // | |
110 Inline_cha_is_monomorphic = 1, // | |
111 Inline_type_profile_monomorphic = 2 // | |
112 }; | |
113 | |
114 // See if it is OK to inline. | |
605 | 115 // The receiver is the inline tree for the caller. |
0 | 116 // |
117 // The result is a temperature indication. If it is hot or cold, | |
118 // inlining is immediate or undesirable. Otherwise, the info block | |
119 // returned is newly allocated and may be enqueued. | |
120 // | |
121 // If the method is inlinable, a new inline subtree is created on the fly, | |
122 // and may be accessed by find_subtree_from_root. | |
123 // The call_method is the dest_method for a special or static invocation. | |
124 // The call_method is an optimized virtual method candidate otherwise. | |
7473 | 125 WarmCallInfo* ok_to_inline(ciMethod *call_method, JVMState* caller_jvms, ciCallProfile& profile, WarmCallInfo* wci, bool& should_delay); |
0 | 126 |
127 // Information about inlined method | |
128 JVMState* caller_jvms() const { return _caller_jvms; } | |
129 ciMethod *method() const { return _method; } | |
130 int caller_bci() const { return _caller_jvms ? _caller_jvms->bci() : InvocationEntryBci; } | |
131 uint count_inline_bcs() const { return _count_inline_bcs; } | |
132 float site_invoke_ratio() const { return _site_invoke_ratio; }; | |
133 | |
134 #ifndef PRODUCT | |
135 private: | |
136 uint _count_inlines; // Count of inlined methods | |
137 public: | |
138 // Debug information collected during parse | |
139 uint count_inlines() const { return _count_inlines; }; | |
140 #endif | |
141 GrowableArray<InlineTree*> subtrees() { return _subtrees; } | |
3939 | 142 |
143 void print_value_on(outputStream* st) const PRODUCT_RETURN; | |
17622 | 144 |
145 bool _forced_inline; // Inlining was forced by CompilerOracle or ciReplay | |
146 bool forced_inline() const { return _forced_inline; } | |
147 // Count number of nodes in this subtree | |
148 int count() const; | |
149 // Dump inlining replay data to the stream. | |
150 void dump_replay_data(outputStream* out); | |
0 | 151 }; |
152 | |
153 | |
154 //----------------------------------------------------------------------------- | |
155 //------------------------------Parse------------------------------------------ | |
156 // Parse bytecodes, build a Graph | |
157 class Parse : public GraphKit { | |
158 public: | |
159 // Per-block information needed by the parser: | |
160 class Block { | |
161 private: | |
162 ciTypeFlow::Block* _flow; | |
163 int _pred_count; // how many predecessors in CFG? | |
164 int _preds_parsed; // how many of these have been parsed? | |
165 uint _count; // how many times executed? Currently only set by _goto's | |
166 bool _is_parsed; // has this block been parsed yet? | |
167 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
|
168 bool _has_merged_backedge; // does this block have merged backedge? |
0 | 169 SafePointNode* _start_map; // all values flowing into this block |
170 MethodLivenessResult _live_locals; // lazily initialized liveness bitmap | |
171 | |
172 int _num_successors; // Includes only normal control flow. | |
173 int _all_successors; // Include exception paths also. | |
174 Block** _successors; | |
175 | |
176 // Use init_node/init_graph to initialize Blocks. | |
177 // Block() : _live_locals((uintptr_t*)NULL,0) { ShouldNotReachHere(); } | |
178 Block() : _live_locals(NULL,0) { ShouldNotReachHere(); } | |
179 | |
180 public: | |
181 | |
182 // Set up the block data structure itself. | |
183 void init_node(Parse* outer, int po); | |
184 // Set up the block's relations to other blocks. | |
185 void init_graph(Parse* outer); | |
186 | |
187 ciTypeFlow::Block* flow() const { return _flow; } | |
188 int pred_count() const { return _pred_count; } | |
189 int preds_parsed() const { return _preds_parsed; } | |
190 bool is_parsed() const { return _is_parsed; } | |
191 bool is_handler() const { return _is_handler; } | |
192 void set_count( uint x ) { _count = x; } | |
193 uint count() const { return _count; } | |
194 | |
195 SafePointNode* start_map() const { assert(is_merged(),""); return _start_map; } | |
196 void set_start_map(SafePointNode* m) { assert(!is_merged(), ""); _start_map = m; } | |
197 | |
198 // True after any predecessor flows control into this block | |
199 bool is_merged() const { return _start_map != NULL; } | |
200 | |
2383
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
201 #ifdef ASSERT |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
202 // True after backedge predecessor flows control into this block |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
203 bool has_merged_backedge() const { return _has_merged_backedge; } |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
204 void mark_merged_backedge(Block* pred) { |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
205 assert(is_SEL_head(), "should be loop head"); |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
206 if (pred != NULL && is_SEL_backedge(pred)) { |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
207 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
|
208 _has_merged_backedge = true; |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
209 } |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
210 } |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
211 #endif |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
212 |
0 | 213 // True when all non-exception predecessors have been parsed. |
214 bool is_ready() const { return preds_parsed() == pred_count(); } | |
215 | |
216 int num_successors() const { return _num_successors; } | |
217 int all_successors() const { return _all_successors; } | |
218 Block* successor_at(int i) const { | |
219 assert((uint)i < (uint)all_successors(), ""); | |
220 return _successors[i]; | |
221 } | |
222 Block* successor_for_bci(int bci); | |
223 | |
224 int start() const { return flow()->start(); } | |
225 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
|
226 int rpo() const { return flow()->rpo(); } |
0 | 227 int start_sp() const { return flow()->stack_size(); } |
228 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
229 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
|
230 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
|
231 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
|
232 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
|
233 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
|
234 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
|
235 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
|
236 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
237 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
|
238 |
0 | 239 const Type* peek(int off=0) const { return stack_type_at(start_sp() - (off+1)); } |
240 | |
241 const Type* stack_type_at(int i) const; | |
242 const Type* local_type_at(int i) const; | |
243 static const Type* get_type(ciType* t) { return Type::get_typeflow_type(t); } | |
244 | |
245 bool has_trap_at(int bci) const { return flow()->has_trap() && flow()->trap_bci() == bci; } | |
246 | |
247 // Call this just before parsing a block. | |
248 void mark_parsed() { | |
249 assert(!_is_parsed, "must parse each block exactly once"); | |
250 _is_parsed = true; | |
251 } | |
252 | |
253 // Return the phi/region input index for the "current" pred, | |
254 // and bump the pred number. For historical reasons these index | |
255 // numbers are handed out in descending order. The last index is | |
256 // always PhiNode::Input (i.e., 1). The value returned is known | |
257 // as a "path number" because it distinguishes by which path we are | |
258 // entering the block. | |
259 int next_path_num() { | |
260 assert(preds_parsed() < pred_count(), "too many preds?"); | |
261 return pred_count() - _preds_parsed++; | |
262 } | |
263 | |
264 // Add a previously unaccounted predecessor to this block. | |
265 // This operates by increasing the size of the block's region | |
266 // and all its phi nodes (if any). The value returned is a | |
267 // path number ("pnum"). | |
268 int add_new_path(); | |
269 | |
270 // Initialize me by recording the parser's map. My own map must be NULL. | |
271 void record_state(Parse* outer); | |
272 }; | |
273 | |
274 #ifndef PRODUCT | |
275 // BytecodeParseHistogram collects number of bytecodes parsed, nodes constructed, and transformations. | |
276 class BytecodeParseHistogram : public ResourceObj { | |
277 private: | |
278 enum BPHType { | |
279 BPH_transforms, | |
280 BPH_values | |
281 }; | |
282 static bool _initialized; | |
283 static uint _bytecodes_parsed [Bytecodes::number_of_codes]; | |
284 static uint _nodes_constructed[Bytecodes::number_of_codes]; | |
285 static uint _nodes_transformed[Bytecodes::number_of_codes]; | |
286 static uint _new_values [Bytecodes::number_of_codes]; | |
287 | |
288 Bytecodes::Code _initial_bytecode; | |
289 int _initial_node_count; | |
290 int _initial_transforms; | |
291 int _initial_values; | |
292 | |
293 Parse *_parser; | |
294 Compile *_compiler; | |
295 | |
296 // Initialization | |
297 static void reset(); | |
298 | |
299 // Return info being collected, select with global flag 'BytecodeParseInfo' | |
300 int current_count(BPHType info_selector); | |
301 | |
302 public: | |
303 BytecodeParseHistogram(Parse *p, Compile *c); | |
304 static bool initialized(); | |
305 | |
306 // Record info when starting to parse one bytecode | |
307 void set_initial_state( Bytecodes::Code bc ); | |
308 // Record results of parsing one bytecode | |
309 void record_change(); | |
310 | |
311 // Profile printing | |
312 static void print(float cutoff = 0.01F); // cutoff in percent | |
313 }; | |
314 | |
315 public: | |
316 // Record work done during parsing | |
317 BytecodeParseHistogram* _parse_histogram; | |
318 void set_parse_histogram(BytecodeParseHistogram *bph) { _parse_histogram = bph; } | |
319 BytecodeParseHistogram* parse_histogram() { return _parse_histogram; } | |
320 #endif | |
321 | |
322 private: | |
323 friend class Block; | |
324 | |
325 // Variables which characterize this compilation as a whole: | |
326 | |
327 JVMState* _caller; // JVMS which carries incoming args & state. | |
328 float _expected_uses; // expected number of calls to this code | |
329 float _prof_factor; // discount applied to my profile counts | |
330 int _depth; // Inline tree depth, for debug printouts | |
331 const TypeFunc*_tf; // My kind of function type | |
332 int _entry_bci; // the osr bci or InvocationEntryBci | |
333 | |
334 ciTypeFlow* _flow; // Results of previous flow pass. | |
335 Block* _blocks; // Array of basic-block structs. | |
336 int _block_count; // Number of elements in _blocks. | |
337 | |
338 GraphKit _exits; // Record all normal returns and throws here. | |
339 bool _wrote_final; // Did we write a final field? | |
340 bool _count_invocations; // update and test invocation counter | |
341 bool _method_data_update; // update method data oop | |
10278 | 342 Node* _alloc_with_final; // An allocation node with final field |
0 | 343 |
344 // Variables which track Java semantics during bytecode parsing: | |
345 | |
346 Block* _block; // block currently getting parsed | |
347 ciBytecodeStream _iter; // stream of this method's bytecodes | |
348 | |
349 int _blocks_merged; // Progress meter: state merges from BB preds | |
350 int _blocks_parsed; // Progress meter: BBs actually parsed | |
351 | |
352 const FastLockNode* _synch_lock; // FastLockNode for synchronized method | |
353 | |
354 #ifndef PRODUCT | |
355 int _max_switch_depth; // Debugging SwitchRanges. | |
356 int _est_switch_depth; // Debugging SwitchRanges. | |
357 #endif | |
358 | |
12956
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12862
diff
changeset
|
359 // parser for the caller of the method of this object |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12862
diff
changeset
|
360 Parse* const _parent; |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12862
diff
changeset
|
361 |
0 | 362 public: |
363 // Constructor | |
12956
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12862
diff
changeset
|
364 Parse(JVMState* caller, ciMethod* parse_method, float expected_uses, Parse* parent); |
0 | 365 |
366 virtual Parse* is_Parse() const { return (Parse*)this; } | |
367 | |
368 // Accessors. | |
369 JVMState* caller() const { return _caller; } | |
370 float expected_uses() const { return _expected_uses; } | |
371 float prof_factor() const { return _prof_factor; } | |
372 int depth() const { return _depth; } | |
373 const TypeFunc* tf() const { return _tf; } | |
374 // entry_bci() -- see osr_bci, etc. | |
375 | |
376 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
|
377 // blocks() -- see rpo_at, start_block, etc. |
0 | 378 int block_count() const { return _block_count; } |
379 | |
380 GraphKit& exits() { return _exits; } | |
381 bool wrote_final() const { return _wrote_final; } | |
382 void set_wrote_final(bool z) { _wrote_final = z; } | |
383 bool count_invocations() const { return _count_invocations; } | |
384 bool method_data_update() const { return _method_data_update; } | |
10278 | 385 Node* alloc_with_final() const { return _alloc_with_final; } |
386 void set_alloc_with_final(Node* n) { | |
387 assert((_alloc_with_final == NULL) || (_alloc_with_final == n), "different init objects?"); | |
388 _alloc_with_final = n; | |
389 } | |
0 | 390 |
391 Block* block() const { return _block; } | |
392 ciBytecodeStream& iter() { return _iter; } | |
393 Bytecodes::Code bc() const { return _iter.cur_bc(); } | |
394 | |
395 void set_block(Block* b) { _block = b; } | |
396 | |
397 // Derived accessors: | |
398 bool is_normal_parse() const { return _entry_bci == InvocationEntryBci; } | |
399 bool is_osr_parse() const { return _entry_bci != InvocationEntryBci; } | |
400 int osr_bci() const { assert(is_osr_parse(),""); return _entry_bci; } | |
401 | |
402 void set_parse_bci(int bci); | |
403 | |
404 // Must this parse be aborted? | |
405 bool failing() { return C->failing(); } | |
406 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
248
diff
changeset
|
407 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
|
408 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
|
409 return &_blocks[rpo]; |
0 | 410 } |
411 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
|
412 return rpo_at(flow()->start_block()->rpo()); |
0 | 413 } |
414 // Can return NULL if the flow pass did not complete a block. | |
415 Block* successor_for_bci(int bci) { | |
416 return block()->successor_for_bci(bci); | |
417 } | |
418 | |
12956
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12862
diff
changeset
|
419 Parse* parent_parser() const { return _parent; } |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12862
diff
changeset
|
420 |
0 | 421 private: |
422 // Create a JVMS & map for the initial state of this method. | |
423 SafePointNode* create_entry_map(); | |
424 | |
425 // OSR helpers | |
426 Node *fetch_interpreter_state(int index, BasicType bt, Node *local_addrs, Node *local_addrs_base); | |
427 Node* check_interpreter_type(Node* l, const Type* type, SafePointNode* &bad_type_exit); | |
428 void load_interpreter_state(Node* osr_buf); | |
429 | |
430 // Functions for managing basic blocks: | |
431 void init_blocks(); | |
432 void load_state_from(Block* b); | |
433 void store_state_to(Block* b) { b->record_state(this); } | |
434 | |
435 // Parse all the basic blocks. | |
436 void do_all_blocks(); | |
437 | |
438 // Parse the current basic block | |
439 void do_one_block(); | |
440 | |
441 // Raise an error if we get a bad ciTypeFlow CFG. | |
442 void handle_missing_successor(int bci); | |
443 | |
444 // first actions (before BCI 0) | |
445 void do_method_entry(); | |
446 | |
447 // implementation of monitorenter/monitorexit | |
448 void do_monitor_enter(); | |
449 void do_monitor_exit(); | |
450 | |
451 // Eagerly create phie throughout the state, to cope with back edges. | |
452 void ensure_phis_everywhere(); | |
453 | |
454 // Merge the current mapping into the basic block starting at bci | |
455 void merge( int target_bci); | |
456 // Same as plain merge, except that it allocates a new path number. | |
457 void merge_new_path( int target_bci); | |
458 // Merge the current mapping into an exception handler. | |
459 void merge_exception(int target_bci); | |
460 // Helper: Merge the current mapping into the given basic block | |
461 void merge_common(Block* target, int pnum); | |
462 // Helper functions for merging individual cells. | |
463 PhiNode *ensure_phi( int idx, bool nocreate = false); | |
464 PhiNode *ensure_memory_phi(int idx, bool nocreate = false); | |
465 // Helper to merge the current memory state into the given basic block | |
466 void merge_memory_edges(MergeMemNode* n, int pnum, bool nophi); | |
467 | |
468 // Parse this bytecode, and alter the Parsers JVM->Node mapping | |
469 void do_one_bytecode(); | |
470 | |
471 // helper function to generate array store check | |
472 void array_store_check(); | |
473 // Helper function to generate array load | |
474 void array_load(BasicType etype); | |
475 // Helper function to generate array store | |
476 void array_store(BasicType etype); | |
477 // Helper function to compute array addressing | |
478 Node* array_addressing(BasicType type, int vals, const Type* *result2=NULL); | |
479 | |
480 // Pass current map to exits | |
481 void return_current(Node* value); | |
482 | |
483 // Register finalizers on return from Object.<init> | |
484 void call_register_finalizer(); | |
485 | |
486 // Insert a compiler safepoint into the graph | |
487 void add_safepoint(); | |
488 | |
489 // Insert a compiler safepoint into the graph, if there is a back-branch. | |
490 void maybe_add_safepoint(int target_bci) { | |
491 if (UseLoopSafepoints && target_bci <= bci()) { | |
492 add_safepoint(); | |
493 } | |
494 } | |
495 | |
496 // Note: Intrinsic generation routines may be found in library_call.cpp. | |
497 | |
498 // Helper function to setup Ideal Call nodes | |
499 void do_call(); | |
500 | |
501 // Helper function to uncommon-trap or bailout for non-compilable call-sites | |
502 bool can_not_compile_call_site(ciMethod *dest_method, ciInstanceKlass *klass); | |
503 | |
504 // Helper function to setup for type-profile based inlining | |
505 bool prepare_type_profile_inline(ciInstanceKlass* prof_klass, ciMethod* prof_method); | |
506 | |
507 // Helper functions for type checking bytecodes: | |
508 void do_checkcast(); | |
509 void do_instanceof(); | |
510 | |
511 // Helper functions for shifting & arithmetic | |
512 void modf(); | |
513 void modd(); | |
514 void l2f(); | |
515 | |
516 void do_irem(); | |
517 | |
518 // implementation of _get* and _put* bytecodes | |
519 void do_getstatic() { do_field_access(true, false); } | |
520 void do_getfield () { do_field_access(true, true); } | |
521 void do_putstatic() { do_field_access(false, false); } | |
522 void do_putfield () { do_field_access(false, true); } | |
523 | |
524 // common code for making initial checks and forming addresses | |
525 void do_field_access(bool is_get, bool is_field); | |
526 bool static_field_ok_in_clinit(ciField *field, ciMethod *method); | |
527 | |
528 // 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
|
529 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
|
530 void do_put_xxx(Node* obj, ciField* field, bool is_field); |
0 | 531 |
532 // loading from a constant field or the constant pool | |
533 // returns false if push failed (non-perm field constants only, not ldcs) | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
10278
diff
changeset
|
534 bool push_constant(ciConstant con, bool require_constant = false, bool is_autobox_cache = false, const Type* basic_type = NULL); |
0 | 535 |
536 // implementation of object creation bytecodes | |
1645
3941674cc7fa
6958668: repeated uncommon trapping for new of klass which is being initialized
never
parents:
1552
diff
changeset
|
537 void emit_guard_for_new(ciInstanceKlass* klass); |
0 | 538 void do_new(); |
539 void do_newarray(BasicType elemtype); | |
540 void do_anewarray(); | |
541 void do_multianewarray(); | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
605
diff
changeset
|
542 Node* expand_multianewarray(ciArrayKlass* array_klass, Node* *lengths, int ndimensions, int nargs); |
0 | 543 |
544 // implementation of jsr/ret | |
545 void do_jsr(); | |
546 void do_ret(); | |
547 | |
548 float dynamic_branch_prediction(float &cnt); | |
549 float branch_prediction(float &cnt, BoolTest::mask btest, int target_bci); | |
550 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
|
551 bool seems_stable_comparison(BoolTest::mask btest, Node* c); |
0 | 552 |
248
18aab3cdd513
6726504: handle do_ifxxx calls in parser more uniformly
rasbold
parents:
196
diff
changeset
|
553 void do_ifnull(BoolTest::mask btest, Node* c); |
0 | 554 void do_if(BoolTest::mask btest, Node* c); |
1172 | 555 int repush_if_args(); |
0 | 556 void adjust_map_after_if(BoolTest::mask btest, Node* c, float prob, |
557 Block* path, Block* other_path); | |
6131
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
3939
diff
changeset
|
558 void sharpen_type_after_if(BoolTest::mask btest, |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
3939
diff
changeset
|
559 Node* con, const Type* tcon, |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
3939
diff
changeset
|
560 Node* val, const Type* tval); |
0 | 561 IfNode* jump_if_fork_int(Node* a, Node* b, BoolTest::mask mask); |
562 Node* jump_if_join(Node* iffalse, Node* iftrue); | |
563 void jump_if_true_fork(IfNode *ifNode, int dest_bci_if_true, int prof_table_index); | |
564 void jump_if_false_fork(IfNode *ifNode, int dest_bci_if_false, int prof_table_index); | |
565 void jump_if_always_fork(int dest_bci_if_true, int prof_table_index); | |
566 | |
567 friend class SwitchRange; | |
568 void do_tableswitch(); | |
569 void do_lookupswitch(); | |
570 void jump_switch_ranges(Node* a, SwitchRange* lo, SwitchRange* hi, int depth = 0); | |
571 bool create_jump_tables(Node* a, SwitchRange* lo, SwitchRange* hi); | |
572 | |
573 // helper functions for methodData style profiling | |
574 void test_counter_against_threshold(Node* cnt, int limit); | |
575 void increment_and_test_invocation_counter(int limit); | |
576 void test_for_osr_md_counter_at(ciMethodData* md, ciProfileData* data, ByteSize offset, int limit); | |
577 Node* method_data_addressing(ciMethodData* md, ciProfileData* data, ByteSize offset, Node* idx = NULL, uint stride = 0); | |
578 void increment_md_counter_at(ciMethodData* md, ciProfileData* data, ByteSize offset, Node* idx = NULL, uint stride = 0); | |
579 void set_md_flag_at(ciMethodData* md, ciProfileData* data, int flag_constant); | |
580 | |
581 void profile_method_entry(); | |
582 void profile_taken_branch(int target_bci, bool force_update = false); | |
583 void profile_not_taken_branch(bool force_update = false); | |
584 void profile_call(Node* receiver); | |
585 void profile_generic_call(); | |
586 void profile_receiver_type(Node* receiver); | |
587 void profile_ret(int target_bci); | |
588 void profile_null_checkcast(); | |
589 void profile_switch_case(int table_index); | |
590 | |
591 // helper function for call statistics | |
592 void count_compiled_calls(bool at_method_entry, bool is_inline) PRODUCT_RETURN; | |
593 | |
594 Node_Notes* make_node_notes(Node_Notes* caller_nn); | |
595 | |
596 // Helper functions for handling normal and abnormal exits. | |
597 void build_exits(); | |
598 | |
599 // Fix up all exceptional control flow exiting a single bytecode. | |
600 void do_exceptions(); | |
601 | |
602 // Fix up all exiting control flow at the end of the parse. | |
603 void do_exits(); | |
604 | |
605 // Add Catch/CatchProjs | |
606 // The call is either a Java call or the VM's rethrow stub | |
607 void catch_call_exceptions(ciExceptionHandlerStream&); | |
608 | |
609 // Handle all exceptions thrown by the inlined method. | |
610 // Also handles exceptions for individual bytecodes. | |
611 void catch_inline_exceptions(SafePointNode* ex_map); | |
612 | |
613 // Merge the given map into correct exceptional exit state. | |
614 // Assumes that there is no applicable local handler. | |
615 void throw_to_exit(SafePointNode* ex_map); | |
616 | |
12966 | 617 // Use speculative type to optimize CmpP node |
618 Node* optimize_cmp_with_klass(Node* c); | |
619 | |
0 | 620 public: |
621 #ifndef PRODUCT | |
622 // Handle PrintOpto, etc. | |
623 void show_parse_info(); | |
624 void dump_map_adr_mem() const; | |
625 static void print_statistics(); // Print some performance counters | |
626 void dump(); | |
627 void dump_bci(int bci); | |
628 #endif | |
629 }; | |
1972 | 630 |
631 #endif // SHARE_VM_OPTO_PARSE_HPP |