Mercurial > hg > graal-compiler
annotate src/share/vm/oops/generateOopMap.hpp @ 6972:bd7a7ce2e264
6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 12 Nov 2012 14:03:53 -0800 |
parents | da91efe96a93 |
children | 78bbf4d43a14 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2426
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:
605
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
605
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:
605
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_OOPS_GENERATEOOPMAP_HPP |
26 #define SHARE_VM_OOPS_GENERATEOOPMAP_HPP | |
27 | |
28 #include "interpreter/bytecodeStream.hpp" | |
29 #include "memory/allocation.inline.hpp" | |
30 #include "memory/universe.inline.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2426
diff
changeset
|
31 #include "oops/method.hpp" |
1972 | 32 #include "oops/oopsHierarchy.hpp" |
33 #include "runtime/signature.hpp" | |
34 | |
0 | 35 // Forward definition |
36 class GenerateOopMap; | |
37 class BasicBlock; | |
38 class CellTypeState; | |
39 class StackMap; | |
40 | |
41 // These two should be removed. But requires som code to be cleaned up | |
42 #define MAXARGSIZE 256 // This should be enough | |
43 #define MAX_LOCAL_VARS 65536 // 16-bit entry | |
44 | |
45 typedef void (*jmpFct_t)(GenerateOopMap *c, int bcpDelta, int* data); | |
46 | |
47 | |
48 // RetTable | |
49 // | |
50 // Contains maping between jsr targets and there return addresses. One-to-many mapping | |
51 // | |
52 class RetTableEntry : public ResourceObj { | |
53 private: | |
54 static int _init_nof_jsrs; // Default size of jsrs list | |
55 int _target_bci; // Target PC address of jump (bytecode index) | |
56 GrowableArray<intptr_t> * _jsrs; // List of return addresses (bytecode index) | |
57 RetTableEntry *_next; // Link to next entry | |
58 public: | |
59 RetTableEntry(int target, RetTableEntry *next) { _target_bci=target; _jsrs = new GrowableArray<intptr_t>(_init_nof_jsrs); _next = next; } | |
60 | |
61 // Query | |
62 int target_bci() const { return _target_bci; } | |
63 int nof_jsrs() const { return _jsrs->length(); } | |
64 int jsrs(int i) const { assert(i>=0 && i<nof_jsrs(), "Index out of bounds"); return _jsrs->at(i); } | |
65 | |
66 // Update entry | |
67 void add_jsr (int return_bci) { _jsrs->append(return_bci); } | |
68 void add_delta (int bci, int delta); | |
69 RetTableEntry * next() const { return _next; } | |
70 }; | |
71 | |
72 | |
73 class RetTable VALUE_OBJ_CLASS_SPEC { | |
74 private: | |
75 RetTableEntry *_first; | |
76 static int _init_nof_entries; | |
77 | |
78 void add_jsr(int return_bci, int target_bci); // Adds entry to list | |
79 public: | |
80 RetTable() { _first = NULL; } | |
81 void compute_ret_table(methodHandle method); | |
82 void update_ret_table(int bci, int delta); | |
83 RetTableEntry* find_jsrs_for_target(int targBci); | |
84 }; | |
85 | |
86 // | |
87 // CellTypeState | |
88 // | |
89 class CellTypeState VALUE_OBJ_CLASS_SPEC { | |
90 private: | |
91 unsigned int _state; | |
92 | |
93 // Masks for separating the BITS and INFO portions of a CellTypeState | |
94 enum { info_mask = right_n_bits(28), | |
95 bits_mask = (int)(~info_mask) }; | |
96 | |
97 // These constant are used for manipulating the BITS portion of a | |
98 // CellTypeState | |
99 enum { uninit_bit = (int)(nth_bit(31)), | |
100 ref_bit = nth_bit(30), | |
101 val_bit = nth_bit(29), | |
102 addr_bit = nth_bit(28), | |
103 live_bits_mask = (int)(bits_mask & ~uninit_bit) }; | |
104 | |
105 // These constants are used for manipulating the INFO portion of a | |
106 // CellTypeState | |
107 enum { top_info_bit = nth_bit(27), | |
108 not_bottom_info_bit = nth_bit(26), | |
109 info_data_mask = right_n_bits(26), | |
110 info_conflict = info_mask }; | |
111 | |
112 // Within the INFO data, these values are used to distinguish different | |
113 // kinds of references. | |
114 enum { ref_not_lock_bit = nth_bit(25), // 0 if this reference is locked as a monitor | |
115 ref_slot_bit = nth_bit(24), // 1 if this reference is a "slot" reference, | |
116 // 0 if it is a "line" reference. | |
117 ref_data_mask = right_n_bits(24) }; | |
118 | |
119 | |
120 // These values are used to initialize commonly used CellTypeState | |
121 // constants. | |
122 enum { bottom_value = 0, | |
123 uninit_value = (int)(uninit_bit | info_conflict), | |
124 ref_value = ref_bit, | |
125 ref_conflict = ref_bit | info_conflict, | |
126 val_value = val_bit | info_conflict, | |
127 addr_value = addr_bit, | |
128 addr_conflict = addr_bit | info_conflict }; | |
129 | |
130 public: | |
131 | |
132 // Since some C++ constructors generate poor code for declarations of the | |
133 // form... | |
134 // | |
135 // CellTypeState vector[length]; | |
136 // | |
137 // ...we avoid making a constructor for this class. CellTypeState values | |
138 // should be constructed using one of the make_* methods: | |
139 | |
140 static CellTypeState make_any(int state) { | |
141 CellTypeState s; | |
142 s._state = state; | |
143 // Causes SS10 warning. | |
144 // assert(s.is_valid_state(), "check to see if CellTypeState is valid"); | |
145 return s; | |
146 } | |
147 | |
148 static CellTypeState make_bottom() { | |
149 return make_any(0); | |
150 } | |
151 | |
152 static CellTypeState make_top() { | |
153 return make_any(AllBits); | |
154 } | |
155 | |
156 static CellTypeState make_addr(int bci) { | |
157 assert((bci >= 0) && (bci < info_data_mask), "check to see if ret addr is valid"); | |
158 return make_any(addr_bit | not_bottom_info_bit | (bci & info_data_mask)); | |
159 } | |
160 | |
161 static CellTypeState make_slot_ref(int slot_num) { | |
162 assert(slot_num >= 0 && slot_num < ref_data_mask, "slot out of range"); | |
163 return make_any(ref_bit | not_bottom_info_bit | ref_not_lock_bit | ref_slot_bit | | |
164 (slot_num & ref_data_mask)); | |
165 } | |
166 | |
167 static CellTypeState make_line_ref(int bci) { | |
168 assert(bci >= 0 && bci < ref_data_mask, "line out of range"); | |
169 return make_any(ref_bit | not_bottom_info_bit | ref_not_lock_bit | | |
170 (bci & ref_data_mask)); | |
171 } | |
172 | |
173 static CellTypeState make_lock_ref(int bci) { | |
174 assert(bci >= 0 && bci < ref_data_mask, "line out of range"); | |
175 return make_any(ref_bit | not_bottom_info_bit | (bci & ref_data_mask)); | |
176 } | |
177 | |
178 // Query methods: | |
179 bool is_bottom() const { return _state == 0; } | |
180 bool is_live() const { return ((_state & live_bits_mask) != 0); } | |
181 bool is_valid_state() const { | |
182 // Uninitialized and value cells must contain no data in their info field: | |
183 if ((can_be_uninit() || can_be_value()) && !is_info_top()) { | |
184 return false; | |
185 } | |
186 // The top bit is only set when all info bits are set: | |
187 if (is_info_top() && ((_state & info_mask) != info_mask)) { | |
188 return false; | |
189 } | |
190 // The not_bottom_bit must be set when any other info bit is set: | |
191 if (is_info_bottom() && ((_state & info_mask) != 0)) { | |
192 return false; | |
193 } | |
194 return true; | |
195 } | |
196 | |
197 bool is_address() const { return ((_state & bits_mask) == addr_bit); } | |
198 bool is_reference() const { return ((_state & bits_mask) == ref_bit); } | |
199 bool is_value() const { return ((_state & bits_mask) == val_bit); } | |
200 bool is_uninit() const { return ((_state & bits_mask) == (uint)uninit_bit); } | |
201 | |
202 bool can_be_address() const { return ((_state & addr_bit) != 0); } | |
203 bool can_be_reference() const { return ((_state & ref_bit) != 0); } | |
204 bool can_be_value() const { return ((_state & val_bit) != 0); } | |
205 bool can_be_uninit() const { return ((_state & uninit_bit) != 0); } | |
206 | |
207 bool is_info_bottom() const { return ((_state & not_bottom_info_bit) == 0); } | |
208 bool is_info_top() const { return ((_state & top_info_bit) != 0); } | |
209 int get_info() const { | |
210 assert((!is_info_top() && !is_info_bottom()), | |
211 "check to make sure top/bottom info is not used"); | |
212 return (_state & info_data_mask); | |
213 } | |
214 | |
215 bool is_good_address() const { return is_address() && !is_info_top(); } | |
216 bool is_lock_reference() const { | |
217 return ((_state & (bits_mask | top_info_bit | ref_not_lock_bit)) == ref_bit); | |
218 } | |
219 bool is_nonlock_reference() const { | |
220 return ((_state & (bits_mask | top_info_bit | ref_not_lock_bit)) == (ref_bit | ref_not_lock_bit)); | |
221 } | |
222 | |
223 bool equal(CellTypeState a) const { return _state == a._state; } | |
224 bool equal_kind(CellTypeState a) const { | |
225 return (_state & bits_mask) == (a._state & bits_mask); | |
226 } | |
227 | |
228 char to_char() const; | |
229 | |
230 // Merge | |
231 CellTypeState merge (CellTypeState cts, int slot) const; | |
232 | |
233 // Debugging output | |
234 void print(outputStream *os); | |
235 | |
236 // Default values of common values | |
237 static CellTypeState bottom; | |
238 static CellTypeState uninit; | |
239 static CellTypeState ref; | |
240 static CellTypeState value; | |
241 static CellTypeState refUninit; | |
242 static CellTypeState varUninit; | |
243 static CellTypeState top; | |
244 static CellTypeState addr; | |
245 }; | |
246 | |
247 | |
248 // | |
249 // BasicBlockStruct | |
250 // | |
251 class BasicBlock: ResourceObj { | |
252 private: | |
253 bool _changed; // Reached a fixpoint or not | |
254 public: | |
255 enum Constants { | |
256 _dead_basic_block = -2, | |
257 _unreached = -1 // Alive but not yet reached by analysis | |
258 // >=0 // Alive and has a merged state | |
259 }; | |
260 | |
261 int _bci; // Start of basic block | |
262 int _end_bci; // Bci of last instruction in basicblock | |
263 int _max_locals; // Determines split between vars and stack | |
264 int _max_stack; // Determines split between stack and monitors | |
265 CellTypeState* _state; // State (vars, stack) at entry. | |
266 int _stack_top; // -1 indicates bottom stack value. | |
267 int _monitor_top; // -1 indicates bottom monitor stack value. | |
268 | |
269 CellTypeState* vars() { return _state; } | |
270 CellTypeState* stack() { return _state + _max_locals; } | |
271 | |
272 bool changed() { return _changed; } | |
273 void set_changed(bool s) { _changed = s; } | |
274 | |
275 bool is_reachable() const { return _stack_top >= 0; } // Analysis has reached this basicblock | |
276 | |
277 // All basicblocks that are unreachable are going to have a _stack_top == _dead_basic_block. | |
278 // This info. is setup in a pre-parse before the real abstract interpretation starts. | |
279 bool is_dead() const { return _stack_top == _dead_basic_block; } | |
280 bool is_alive() const { return _stack_top != _dead_basic_block; } | |
281 void mark_as_alive() { assert(is_dead(), "must be dead"); _stack_top = _unreached; } | |
282 }; | |
283 | |
284 | |
285 // | |
286 // GenerateOopMap | |
287 // | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2426
diff
changeset
|
288 // Main class used to compute the pointer-maps in a Method |
0 | 289 // |
290 class GenerateOopMap VALUE_OBJ_CLASS_SPEC { | |
291 protected: | |
292 | |
293 // _monitor_top is set to this constant to indicate that a monitor matching | |
294 // problem was encountered prior to this point in control flow. | |
295 enum { bad_monitors = -1 }; | |
296 | |
297 // Main variables | |
298 methodHandle _method; // The method we are examine | |
299 RetTable _rt; // Contains the return address mappings | |
300 int _max_locals; // Cached value of no. of locals | |
301 int _max_stack; // Cached value of max. stack depth | |
302 int _max_monitors; // Cached value of max. monitor stack depth | |
303 int _has_exceptions; // True, if exceptions exist for method | |
605 | 304 bool _got_error; // True, if an error occurred during interpretation. |
0 | 305 Handle _exception; // Exception if got_error is true. |
306 bool _did_rewriting; // was bytecodes rewritten | |
307 bool _did_relocation; // was relocation neccessary | |
308 bool _monitor_safe; // The monitors in this method have been determined | |
309 // to be safe. | |
310 | |
311 // Working Cell type state | |
312 int _state_len; // Size of states | |
313 CellTypeState *_state; // list of states | |
314 char *_state_vec_buf; // Buffer used to print a readable version of a state | |
315 int _stack_top; | |
316 int _monitor_top; | |
317 | |
318 // Timing and statistics | |
319 static elapsedTimer _total_oopmap_time; // Holds cumulative oopmap generation time | |
320 static long _total_byte_count; // Holds cumulative number of bytes inspected | |
321 | |
322 // Cell type methods | |
323 void init_state(); | |
324 void make_context_uninitialized (); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
325 int methodsig_to_effect (Symbol* signature, bool isStatic, CellTypeState* effect); |
0 | 326 bool merge_local_state_vectors (CellTypeState* cts, CellTypeState* bbts); |
327 bool merge_monitor_state_vectors(CellTypeState* cts, CellTypeState* bbts); | |
328 void copy_state (CellTypeState *dst, CellTypeState *src); | |
329 void merge_state_into_bb (BasicBlock *bb); | |
330 static void merge_state (GenerateOopMap *gom, int bcidelta, int* data); | |
331 void set_var (int localNo, CellTypeState cts); | |
332 CellTypeState get_var (int localNo); | |
333 CellTypeState pop (); | |
334 void push (CellTypeState cts); | |
335 CellTypeState monitor_pop (); | |
336 void monitor_push (CellTypeState cts); | |
337 CellTypeState * vars () { return _state; } | |
338 CellTypeState * stack () { return _state+_max_locals; } | |
339 CellTypeState * monitors () { return _state+_max_locals+_max_stack; } | |
340 | |
341 void replace_all_CTS_matches (CellTypeState match, | |
342 CellTypeState replace); | |
343 void print_states (outputStream *os, CellTypeState *vector, int num); | |
344 void print_current_state (outputStream *os, | |
345 BytecodeStream *itr, | |
346 bool detailed); | |
347 void report_monitor_mismatch (const char *msg); | |
348 | |
349 // Basicblock info | |
350 BasicBlock * _basic_blocks; // Array of basicblock info | |
351 int _gc_points; | |
352 int _bb_count; | |
342 | 353 BitMap _bb_hdr_bits; |
0 | 354 |
355 // Basicblocks methods | |
356 void initialize_bb (); | |
357 void mark_bbheaders_and_count_gc_points(); | |
342 | 358 bool is_bb_header (int bci) const { |
359 return _bb_hdr_bits.at(bci); | |
360 } | |
0 | 361 int gc_points () const { return _gc_points; } |
362 int bb_count () const { return _bb_count; } | |
342 | 363 void set_bbmark_bit (int bci) { |
364 _bb_hdr_bits.at_put(bci, true); | |
365 } | |
366 void clear_bbmark_bit (int bci) { | |
367 _bb_hdr_bits.at_put(bci, false); | |
368 } | |
0 | 369 BasicBlock * get_basic_block_at (int bci) const; |
370 BasicBlock * get_basic_block_containing (int bci) const; | |
371 void interp_bb (BasicBlock *bb); | |
372 void restore_state (BasicBlock *bb); | |
373 int next_bb_start_pc (BasicBlock *bb); | |
374 void update_basic_blocks (int bci, int delta, int new_method_size); | |
375 static void bb_mark_fct (GenerateOopMap *c, int deltaBci, int *data); | |
376 | |
377 // Dead code detection | |
378 void mark_reachable_code(); | |
379 static void reachable_basicblock (GenerateOopMap *c, int deltaBci, int *data); | |
380 | |
381 // Interpretation methods (primary) | |
382 void do_interpretation (); | |
383 void init_basic_blocks (); | |
384 void setup_method_entry_state (); | |
385 void interp_all (); | |
386 | |
387 // Interpretation methods (secondary) | |
388 void interp1 (BytecodeStream *itr); | |
389 void do_exception_edge (BytecodeStream *itr); | |
390 void check_type (CellTypeState expected, CellTypeState actual); | |
391 void ppstore (CellTypeState *in, int loc_no); | |
392 void ppload (CellTypeState *out, int loc_no); | |
393 void ppush1 (CellTypeState in); | |
394 void ppush (CellTypeState *in); | |
395 void ppop1 (CellTypeState out); | |
396 void ppop (CellTypeState *out); | |
397 void ppop_any (int poplen); | |
398 void pp (CellTypeState *in, CellTypeState *out); | |
399 void pp_new_ref (CellTypeState *in, int bci); | |
400 void ppdupswap (int poplen, const char *out); | |
1910
d1896d1dda3e
6981788: GC map generator sometimes picks up the wrong kind of instruction operand
jrose
parents:
1552
diff
changeset
|
401 void do_ldc (int bci); |
0 | 402 void do_astore (int idx); |
403 void do_jsr (int delta); | |
404 void do_field (int is_get, int is_static, int idx, int bci); | |
405 void do_method (int is_static, int is_interface, int idx, int bci); | |
406 void do_multianewarray (int dims, int bci); | |
407 void do_monitorenter (int bci); | |
408 void do_monitorexit (int bci); | |
409 void do_return_monitor_check (); | |
410 void do_checkcast (); | |
411 CellTypeState *sigchar_to_effect (char sigch, int bci, CellTypeState *out); | |
412 int copy_cts (CellTypeState *dst, CellTypeState *src); | |
413 | |
414 // Error handling | |
415 void error_work (const char *format, va_list ap); | |
416 void report_error (const char *format, ...); | |
417 void verify_error (const char *format, ...); | |
418 bool got_error() { return _got_error; } | |
419 | |
420 // Create result set | |
421 bool _report_result; | |
422 bool _report_result_for_send; // Unfortunatly, stackmaps for sends are special, so we need some extra | |
423 BytecodeStream *_itr_send; // variables to handle them properly. | |
424 | |
425 void report_result (); | |
426 | |
427 // Initvars | |
428 GrowableArray<intptr_t> * _init_vars; | |
429 | |
430 void initialize_vars (); | |
431 void add_to_ref_init_set (int localNo); | |
432 | |
433 // Conflicts rewrite logic | |
605 | 434 bool _conflict; // True, if a conflict occurred during interpretation |
0 | 435 int _nof_refval_conflicts; // No. of conflicts that require rewrites |
436 int * _new_var_map; | |
437 | |
438 void record_refval_conflict (int varNo); | |
439 void rewrite_refval_conflicts (); | |
440 void rewrite_refval_conflict (int from, int to); | |
441 bool rewrite_refval_conflict_inst (BytecodeStream *i, int from, int to); | |
442 bool rewrite_load_or_store (BytecodeStream *i, Bytecodes::Code bc, Bytecodes::Code bc0, unsigned int varNo); | |
443 | |
444 void expand_current_instr (int bci, int ilen, int newIlen, u_char inst_buffer[]); | |
445 bool is_astore (BytecodeStream *itr, int *index); | |
446 bool is_aload (BytecodeStream *itr, int *index); | |
447 | |
448 // List of bci's where a return address is on top of the stack | |
449 GrowableArray<intptr_t> *_ret_adr_tos; | |
450 | |
451 bool stack_top_holds_ret_addr (int bci); | |
452 void compute_ret_adr_at_TOS (); | |
453 void update_ret_adr_at_TOS (int bci, int delta); | |
454 | |
455 int binsToHold (int no) { return ((no+(BitsPerWord-1))/BitsPerWord); } | |
456 char *state_vec_to_string (CellTypeState* vec, int len); | |
457 | |
458 // Helper method. Can be used in subclasses to fx. calculate gc_points. If the current instuction | |
459 // is a control transfer, then calls the jmpFct all possible destinations. | |
460 void ret_jump_targets_do (BytecodeStream *bcs, jmpFct_t jmpFct, int varNo,int *data); | |
461 bool jump_targets_do (BytecodeStream *bcs, jmpFct_t jmpFct, int *data); | |
462 | |
463 friend class RelocCallback; | |
464 public: | |
465 GenerateOopMap(methodHandle method); | |
466 | |
467 // Compute the map. | |
468 void compute_map(TRAPS); | |
469 void result_for_basicblock(int bci); // Do a callback on fill_stackmap_for_opcodes for basicblock containing bci | |
470 | |
471 // Query | |
472 int max_locals() const { return _max_locals; } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2426
diff
changeset
|
473 Method* method() const { return _method(); } |
0 | 474 methodHandle method_as_handle() const { return _method; } |
475 | |
476 bool did_rewriting() { return _did_rewriting; } | |
477 bool did_relocation() { return _did_relocation; } | |
478 | |
479 static void print_time(); | |
480 | |
481 // Monitor query | |
482 bool monitor_safe() { return _monitor_safe; } | |
483 | |
484 // Specialization methods. Intended use: | |
485 // - possible_gc_point must return true for every bci for which the stackmaps must be returned | |
486 // - fill_stackmap_prolog is called just before the result is reported. The arguments tells the estimated | |
487 // number of gc points | |
488 // - fill_stackmap_for_opcodes is called once for each bytecode index in order (0...code_length-1) | |
489 // - fill_stackmap_epilog is called after all results has been reported. Note: Since the algorithm does not report | |
490 // stackmaps for deadcode, fewer gc_points might have been encounted than assumed during the epilog. It is the | |
491 // responsibility of the subclass to count the correct number. | |
492 // - fill_init_vars are called once with the result of the init_vars computation | |
493 // | |
494 // All these methods are used during a call to: compute_map. Note: Non of the return results are valid | |
495 // after compute_map returns, since all values are allocated as resource objects. | |
496 // | |
497 // All virtual method must be implemented in subclasses | |
498 virtual bool allow_rewrites () const { return false; } | |
499 virtual bool report_results () const { return true; } | |
500 virtual bool report_init_vars () const { return true; } | |
501 virtual bool possible_gc_point (BytecodeStream *bcs) { ShouldNotReachHere(); return false; } | |
502 virtual void fill_stackmap_prolog (int nof_gc_points) { ShouldNotReachHere(); } | |
503 virtual void fill_stackmap_epilog () { ShouldNotReachHere(); } | |
504 virtual void fill_stackmap_for_opcodes (BytecodeStream *bcs, | |
505 CellTypeState* vars, | |
506 CellTypeState* stack, | |
507 int stackTop) { ShouldNotReachHere(); } | |
508 virtual void fill_init_vars (GrowableArray<intptr_t> *init_vars) { ShouldNotReachHere();; } | |
509 }; | |
510 | |
511 // | |
512 // Subclass of the GenerateOopMap Class that just do rewrites of the method, if needed. | |
513 // It does not store any oopmaps. | |
514 // | |
515 class ResolveOopMapConflicts: public GenerateOopMap { | |
516 private: | |
517 | |
518 bool _must_clear_locals; | |
519 | |
520 virtual bool report_results() const { return false; } | |
521 virtual bool report_init_vars() const { return true; } | |
522 virtual bool allow_rewrites() const { return true; } | |
523 virtual bool possible_gc_point (BytecodeStream *bcs) { return false; } | |
524 virtual void fill_stackmap_prolog (int nof_gc_points) {} | |
525 virtual void fill_stackmap_epilog () {} | |
526 virtual void fill_stackmap_for_opcodes (BytecodeStream *bcs, | |
527 CellTypeState* vars, | |
528 CellTypeState* stack, | |
529 int stack_top) {} | |
530 virtual void fill_init_vars (GrowableArray<intptr_t> *init_vars) { _must_clear_locals = init_vars->length() > 0; } | |
531 | |
532 #ifndef PRODUCT | |
533 // Statistics | |
534 static int _nof_invocations; | |
535 static int _nof_rewrites; | |
536 static int _nof_relocations; | |
537 #endif | |
538 | |
539 public: | |
540 ResolveOopMapConflicts(methodHandle method) : GenerateOopMap(method) { _must_clear_locals = false; }; | |
541 | |
542 methodHandle do_potential_rewrite(TRAPS); | |
543 bool must_clear_locals() const { return _must_clear_locals; } | |
544 }; | |
545 | |
546 | |
547 // | |
548 // Subclass used by the compiler to generate pairing infomation | |
549 // | |
550 class GeneratePairingInfo: public GenerateOopMap { | |
551 private: | |
552 | |
553 virtual bool report_results() const { return false; } | |
554 virtual bool report_init_vars() const { return false; } | |
555 virtual bool allow_rewrites() const { return false; } | |
556 virtual bool possible_gc_point (BytecodeStream *bcs) { return false; } | |
557 virtual void fill_stackmap_prolog (int nof_gc_points) {} | |
558 virtual void fill_stackmap_epilog () {} | |
559 virtual void fill_stackmap_for_opcodes (BytecodeStream *bcs, | |
560 CellTypeState* vars, | |
561 CellTypeState* stack, | |
562 int stack_top) {} | |
563 virtual void fill_init_vars (GrowableArray<intptr_t> *init_vars) {} | |
564 public: | |
565 GeneratePairingInfo(methodHandle method) : GenerateOopMap(method) {}; | |
566 | |
567 // Call compute_map(CHECK) to generate info. | |
568 }; | |
1972 | 569 |
570 #endif // SHARE_VM_OOPS_GENERATEOOPMAP_HPP |