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