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