Mercurial > hg > truffle
annotate src/share/vm/compiler/methodLiveness.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 | f95d63e2154a |
children |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
342
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
342
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:
342
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_COMPILER_METHODLIVENESS_HPP |
26 #define SHARE_VM_COMPILER_METHODLIVENESS_HPP | |
27 | |
28 #include "utilities/bitMap.hpp" | |
29 #include "utilities/growableArray.hpp" | |
30 | |
0 | 31 class ciMethod; |
32 | |
33 class MethodLivenessResult : public BitMap { | |
34 private: | |
35 bool _is_valid; | |
36 | |
37 public: | |
342 | 38 MethodLivenessResult(BitMap::bm_word_t* map, idx_t size_in_bits) |
0 | 39 : BitMap(map, size_in_bits) |
40 , _is_valid(false) | |
41 {} | |
42 | |
43 MethodLivenessResult(idx_t size_in_bits) | |
44 : BitMap(size_in_bits) | |
45 , _is_valid(false) | |
46 {} | |
47 | |
48 void set_is_valid() { _is_valid = true; } | |
49 bool is_valid() { return _is_valid; } | |
50 }; | |
51 | |
52 class MethodLiveness : public ResourceObj { | |
53 public: | |
54 // The BasicBlock class is used to represent a basic block in the | |
55 // liveness analysis. | |
56 class BasicBlock : public ResourceObj { | |
57 private: | |
58 // This class is only used by the MethodLiveness class. | |
59 friend class MethodLiveness; | |
60 | |
61 // The analyzer which created this basic block. | |
62 MethodLiveness* _analyzer; | |
63 | |
64 // The range of this basic block is [start_bci,limit_bci) | |
65 int _start_bci; | |
66 int _limit_bci; | |
67 | |
68 // The liveness at the start of the block; | |
69 BitMap _entry; | |
70 | |
71 // The summarized liveness effects of our direct successors reached | |
72 // by normal control flow | |
73 BitMap _normal_exit; | |
74 | |
75 // The summarized liveness effects of our direct successors reached | |
76 // by exceptional control flow | |
77 BitMap _exception_exit; | |
78 | |
79 // These members hold the results of the last call to | |
80 // compute_gen_kill_range(). _gen is the set of locals | |
81 // used before they are defined in the range. _kill is the | |
82 // set of locals defined before they are used. | |
83 BitMap _gen; | |
84 BitMap _kill; | |
85 int _last_bci; | |
86 | |
87 // A list of all blocks which could come directly before this one | |
88 // in normal (non-exceptional) control flow. We propagate liveness | |
89 // information to these blocks. | |
90 GrowableArray<BasicBlock*>* _normal_predecessors; | |
91 | |
92 // A list of all blocks which could come directly before this one | |
93 // in exceptional control flow. | |
94 GrowableArray<BasicBlock*>* _exception_predecessors; | |
95 | |
96 // The following fields are used to manage a work list used in the | |
97 // dataflow. | |
98 BasicBlock *_next; | |
99 bool _on_work_list; | |
100 | |
101 // Our successors call this method to merge liveness information into | |
102 // our _normal_exit member. | |
103 bool merge_normal(BitMap other); | |
104 | |
105 // Our successors call this method to merge liveness information into | |
106 // our _exception_exit member. | |
107 bool merge_exception(BitMap other); | |
108 | |
109 // This helper routine is used to help compute the gen/kill pair for | |
110 // the block. It is also used to answer queries. | |
111 void compute_gen_kill_range(ciBytecodeStream *bytes); | |
112 | |
113 // Compute the gen/kill effect of a single instruction. | |
114 void compute_gen_kill_single(ciBytecodeStream *instruction); | |
115 | |
116 // Helpers for compute_gen_kill_single. | |
117 void load_one(int local); | |
118 void load_two(int local); | |
119 void store_one(int local); | |
120 void store_two(int local); | |
121 | |
122 BasicBlock(MethodLiveness *analyzer, int start, int limit); | |
123 | |
124 // -- Accessors | |
125 | |
126 int start_bci() const { return _start_bci; } | |
127 | |
128 int limit_bci() const { return _limit_bci; } | |
129 void set_limit_bci(int limit) { _limit_bci = limit; } | |
130 | |
131 BasicBlock *next() const { return _next; } | |
132 void set_next(BasicBlock *next) { _next = next; } | |
133 | |
134 bool on_work_list() const { return _on_work_list; } | |
135 void set_on_work_list(bool val) { _on_work_list = val; } | |
136 | |
137 // -- Flow graph construction. | |
138 | |
139 // Add a basic block to our list of normal predecessors. | |
140 void add_normal_predecessor(BasicBlock *pred) { | |
141 _normal_predecessors->append_if_missing(pred); | |
142 } | |
143 | |
144 // Add a basic block to our list of exceptional predecessors | |
145 void add_exception_predecessor(BasicBlock *pred) { | |
146 _exception_predecessors->append_if_missing(pred); | |
147 } | |
148 | |
149 // Split the basic block at splitBci. This basic block | |
150 // becomes the second half. The first half is newly created. | |
151 BasicBlock *split(int splitBci); | |
152 | |
153 // -- Dataflow. | |
154 | |
155 void compute_gen_kill(ciMethod* method); | |
156 | |
157 // Propagate changes from this basic block | |
158 void propagate(MethodLiveness *ml); | |
159 | |
160 // -- Query. | |
161 | |
162 MethodLivenessResult get_liveness_at(ciMethod* method, int bci); | |
163 | |
164 // -- Debugging. | |
165 | |
166 void print_on(outputStream *os) const PRODUCT_RETURN; | |
167 | |
168 }; // End of MethodLiveness::BasicBlock | |
169 | |
170 private: | |
171 // The method we are analyzing. | |
172 ciMethod* _method; | |
173 ciMethod* method() const { return _method; } | |
174 | |
175 // The arena for storing structures... | |
176 Arena* _arena; | |
177 Arena* arena() const { return _arena; } | |
178 | |
179 // We cache the length of the method. | |
180 int _code_size; | |
181 | |
182 // The size of a BitMap. | |
183 int _bit_map_size_bits; | |
184 int _bit_map_size_words; | |
185 | |
186 // A list of all BasicBlocks. | |
187 BasicBlock **_block_list; | |
188 | |
189 // number of blocks | |
190 int _block_count; | |
191 | |
192 // Keeps track of bci->block mapping. One entry for each bci. Only block starts are | |
193 // recorded. | |
194 GrowableArray<BasicBlock*>* _block_map; | |
195 | |
196 // Our work list. | |
197 BasicBlock *_work_list; | |
198 | |
199 #ifdef COMPILER1 | |
200 // bcis where blocks start are marked | |
201 BitMap _bci_block_start; | |
202 #endif // COMPILER1 | |
203 | |
204 // -- Graph construction & Analysis | |
205 | |
206 // Compute ranges and predecessors for basic blocks. | |
207 void init_basic_blocks(); | |
208 | |
209 // Compute gen/kill information for all basic blocks. | |
210 void init_gen_kill(); | |
211 | |
212 // Perform the dataflow. | |
213 void propagate_liveness(); | |
214 | |
215 // The class MethodLiveness::BasicBlock needs special access to some | |
216 // of our members. | |
217 friend class MethodLiveness::BasicBlock; | |
218 | |
219 // And accessors. | |
220 int bit_map_size_bits() const { return _bit_map_size_bits; } | |
221 int bit_map_size_words() const { return _bit_map_size_words; } | |
222 | |
223 // Work list manipulation routines. Called internally by BasicBlock. | |
224 BasicBlock *work_list_get(); | |
225 void work_list_add(BasicBlock *block); | |
226 | |
227 // -- Timing and Statistics. | |
228 | |
229 | |
230 // Timers | |
231 static elapsedTimer _time_build_graph; | |
232 static elapsedTimer _time_gen_kill; | |
233 static elapsedTimer _time_flow; | |
234 static elapsedTimer _time_query; | |
235 static elapsedTimer _time_total; | |
236 | |
237 #ifndef PRODUCT | |
238 | |
239 // Counts | |
240 static long _total_bytes; | |
241 static int _total_methods; | |
242 | |
243 static long _total_blocks; | |
244 static int _max_method_blocks; | |
245 | |
246 static long _total_edges; | |
247 static int _max_block_edges; | |
248 | |
249 static long _total_exc_edges; | |
250 static int _max_block_exc_edges; | |
251 | |
252 static long _total_method_locals; | |
253 static int _max_method_locals; | |
254 | |
255 static long _total_locals_queried; | |
256 static long _total_live_locals_queried; | |
257 | |
258 static long _total_visits; | |
259 | |
260 #endif | |
261 | |
262 public: | |
263 // Create a liveness analyzer for a method | |
264 MethodLiveness(Arena* arena, ciMethod* method); | |
265 | |
266 // Compute liveness information for the method | |
267 void compute_liveness(); | |
268 | |
269 // Find out which locals are live at a specific bci. | |
270 MethodLivenessResult get_liveness_at(int bci); | |
271 | |
272 #ifdef COMPILER1 | |
273 const BitMap get_bci_block_start() const { return _bci_block_start; } | |
274 #endif // COMPILER1 | |
275 | |
276 static void print_times() PRODUCT_RETURN; | |
277 }; | |
1972 | 278 |
279 #endif // SHARE_VM_COMPILER_METHODLIVENESS_HPP |