Mercurial > hg > truffle
annotate src/share/vm/compiler/oopMap.hpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | 06f017f7daa7 |
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:
948
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
948
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:
948
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_COMPILER_OOPMAP_HPP |
26 #define SHARE_VM_COMPILER_OOPMAP_HPP | |
27 | |
28 #include "code/compressedStream.hpp" | |
29 #include "code/vmreg.hpp" | |
30 #include "memory/allocation.hpp" | |
31 #include "utilities/growableArray.hpp" | |
32 | |
0 | 33 // Interface for generating the frame map for compiled code. A frame map |
34 // describes for a specific pc whether each register and frame stack slot is: | |
35 // Oop - A GC root for current frame | |
36 // Value - Live non-oop, non-float value: int, either half of double | |
37 // Dead - Dead; can be Zapped for debugging | |
38 // CalleeXX - Callee saved; also describes which caller register is saved | |
39 // DerivedXX - A derived oop; original oop is described. | |
40 // | |
41 // OopMapValue describes a single OopMap entry | |
42 | |
43 class frame; | |
44 class RegisterMap; | |
45 class DerivedPointerEntry; | |
46 | |
47 class OopMapValue: public StackObj { | |
48 friend class VMStructs; | |
49 private: | |
50 short _value; | |
51 int value() const { return _value; } | |
52 void set_value(int value) { _value = value; } | |
53 short _content_reg; | |
54 | |
55 public: | |
56 // Constants | |
244
524eca34ea76
6684714: Optimize EA Connection Graph build performance
kvn
parents:
113
diff
changeset
|
57 enum { type_bits = 5, |
0 | 58 register_bits = BitsPerShort - type_bits }; |
59 | |
60 enum { type_shift = 0, | |
61 register_shift = type_bits }; | |
62 | |
63 enum { type_mask = right_n_bits(type_bits), | |
64 type_mask_in_place = type_mask << type_shift, | |
65 register_mask = right_n_bits(register_bits), | |
66 register_mask_in_place = register_mask << register_shift }; | |
67 | |
68 enum oop_types { // must fit in type_bits | |
69 unused_value =0, // powers of 2, for masking OopMapStream | |
70 oop_value = 1, | |
71 value_value = 2, | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
72 narrowoop_value = 4, |
0 | 73 callee_saved_value = 8, |
244
524eca34ea76
6684714: Optimize EA Connection Graph build performance
kvn
parents:
113
diff
changeset
|
74 derived_oop_value= 16 }; |
0 | 75 |
76 // Constructors | |
77 OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); } | |
78 OopMapValue (VMReg reg, oop_types t) { set_reg_type(reg,t); } | |
79 OopMapValue (VMReg reg, oop_types t, VMReg reg2) { set_reg_type(reg,t); set_content_reg(reg2); } | |
80 OopMapValue (CompressedReadStream* stream) { read_from(stream); } | |
81 | |
82 // Archiving | |
83 void write_on(CompressedWriteStream* stream) { | |
84 stream->write_int(value()); | |
85 if(is_callee_saved() || is_derived_oop()) { | |
86 stream->write_int(content_reg()->value()); | |
87 } | |
88 } | |
89 | |
90 void read_from(CompressedReadStream* stream) { | |
91 set_value(stream->read_int()); | |
92 if(is_callee_saved() || is_derived_oop()) { | |
93 set_content_reg(VMRegImpl::as_VMReg(stream->read_int(), true)); | |
94 } | |
95 } | |
96 | |
97 // Querying | |
98 bool is_oop() { return mask_bits(value(), type_mask_in_place) == oop_value; } | |
99 bool is_value() { return mask_bits(value(), type_mask_in_place) == value_value; } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
100 bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; } |
0 | 101 bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; } |
102 bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; } | |
103 | |
104 void set_oop() { set_value((value() & register_mask_in_place) | oop_value); } | |
105 void set_value() { set_value((value() & register_mask_in_place) | value_value); } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
106 void set_narrowoop() { set_value((value() & register_mask_in_place) | narrowoop_value); } |
0 | 107 void set_callee_saved() { set_value((value() & register_mask_in_place) | callee_saved_value); } |
108 void set_derived_oop() { set_value((value() & register_mask_in_place) | derived_oop_value); } | |
109 | |
110 VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); } | |
111 oop_types type() const { return (oop_types)mask_bits(value(), type_mask_in_place); } | |
112 | |
113 static bool legal_vm_reg_name(VMReg p) { | |
114 return (p->value() == (p->value() & register_mask)); | |
115 } | |
116 | |
117 void set_reg_type(VMReg p, oop_types t) { | |
118 set_value((p->value() << register_shift) | t); | |
119 assert(reg() == p, "sanity check" ); | |
120 assert(type() == t, "sanity check" ); | |
121 } | |
122 | |
123 | |
124 VMReg content_reg() const { return VMRegImpl::as_VMReg(_content_reg, true); } | |
125 void set_content_reg(VMReg r) { _content_reg = r->value(); } | |
126 | |
127 // Physical location queries | |
128 bool is_register_loc() { return reg()->is_reg(); } | |
129 bool is_stack_loc() { return reg()->is_stack(); } | |
130 | |
131 // Returns offset from sp. | |
132 int stack_offset() { | |
133 assert(is_stack_loc(), "must be stack location"); | |
134 return reg()->reg2stack(); | |
135 } | |
136 | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
25
diff
changeset
|
137 void print_on(outputStream* st) const; |
25
c5cbd367e4d1
6621094: PrintOptoAssembly is broken for oops information in DebugInfo
kvn
parents:
0
diff
changeset
|
138 void print() const { print_on(tty); } |
0 | 139 }; |
140 | |
141 | |
142 class OopMap: public ResourceObj { | |
143 friend class OopMapStream; | |
144 friend class VMStructs; | |
145 private: | |
146 int _pc_offset; | |
147 int _omv_count; | |
148 int _omv_data_size; | |
149 unsigned char* _omv_data; | |
150 CompressedWriteStream* _write_stream; | |
151 | |
152 debug_only( OopMapValue::oop_types* _locs_used; int _locs_length;) | |
153 | |
154 // Accessors | |
155 unsigned char* omv_data() const { return _omv_data; } | |
156 void set_omv_data(unsigned char* value) { _omv_data = value; } | |
157 int omv_data_size() const { return _omv_data_size; } | |
158 void set_omv_data_size(int value) { _omv_data_size = value; } | |
159 int omv_count() const { return _omv_count; } | |
160 void set_omv_count(int value) { _omv_count = value; } | |
161 void increment_count() { _omv_count++; } | |
162 CompressedWriteStream* write_stream() const { return _write_stream; } | |
163 void set_write_stream(CompressedWriteStream* value) { _write_stream = value; } | |
164 | |
165 private: | |
166 enum DeepCopyToken { _deep_copy_token }; | |
167 OopMap(DeepCopyToken, OopMap* source); // used only by deep_copy | |
168 | |
169 public: | |
170 OopMap(int frame_size, int arg_count); | |
171 | |
172 // pc-offset handling | |
173 int offset() const { return _pc_offset; } | |
174 void set_offset(int o) { _pc_offset = o; } | |
175 | |
176 // Check to avoid double insertion | |
177 debug_only(OopMapValue::oop_types locs_used( int indx ) { return _locs_used[indx]; }) | |
178 | |
179 // Construction | |
180 // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd | |
181 // slots to hold 4-byte values like ints and floats in the LP64 build. | |
182 void set_oop ( VMReg local); | |
183 void set_value( VMReg local); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
184 void set_narrowoop(VMReg local); |
0 | 185 void set_dead ( VMReg local); |
186 void set_callee_saved( VMReg local, VMReg caller_machine_register ); | |
187 void set_derived_oop ( VMReg local, VMReg derived_from_local_register ); | |
188 void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional); | |
189 | |
190 int heap_size() const; | |
191 void copy_to(address addr); | |
192 OopMap* deep_copy(); | |
193 | |
194 bool has_derived_pointer() const PRODUCT_RETURN0; | |
195 | |
196 bool legal_vm_reg_name(VMReg local) { | |
197 return OopMapValue::legal_vm_reg_name(local); | |
198 } | |
199 | |
200 // Printing | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
25
diff
changeset
|
201 void print_on(outputStream* st) const; |
0 | 202 void print() const { print_on(tty); } |
203 }; | |
204 | |
205 | |
206 class OopMapSet : public ResourceObj { | |
207 friend class VMStructs; | |
208 private: | |
209 int _om_count; | |
210 int _om_size; | |
211 OopMap** _om_data; | |
212 | |
213 int om_count() const { return _om_count; } | |
214 void set_om_count(int value) { _om_count = value; } | |
215 void increment_count() { _om_count++; } | |
216 int om_size() const { return _om_size; } | |
217 void set_om_size(int value) { _om_size = value; } | |
218 OopMap** om_data() const { return _om_data; } | |
219 void set_om_data(OopMap** value) { _om_data = value; } | |
220 void grow_om_data(); | |
221 void set(int index,OopMap* value) { assert((index == 0) || ((index > 0) && (index < om_size())),"bad index"); _om_data[index] = value; } | |
222 | |
223 public: | |
224 OopMapSet(); | |
225 | |
226 // returns the number of OopMaps in this OopMapSet | |
227 int size() const { return _om_count; } | |
228 // returns the OopMap at a given index | |
229 OopMap* at(int index) const { assert((index >= 0) && (index <= om_count()),"bad index"); return _om_data[index]; } | |
230 | |
231 // Collect OopMaps. | |
232 void add_gc_map(int pc, OopMap* map); | |
233 | |
234 // Returns the only oop map. Used for reconstructing | |
235 // Adapter frames during deoptimization | |
236 OopMap* singular_oop_map(); | |
237 | |
238 // returns OopMap in that is anchored to the pc | |
239 OopMap* find_map_at_offset(int pc_offset) const; | |
240 | |
241 int heap_size() const; | |
242 void copy_to(address addr); | |
243 | |
858 | 244 // Methods oops_do() and all_do() filter out NULL oops and |
245 // oop == Universe::narrow_oop_base() before passing oops | |
246 // to closures. | |
247 | |
0 | 248 // Iterates through frame for a compiled method |
249 static void oops_do (const frame* fr, | |
250 const RegisterMap* reg_map, OopClosure* f); | |
251 static void update_register_map(const frame* fr, RegisterMap *reg_map); | |
252 | |
253 // Iterates through frame for a compiled method for dead ones and values, too | |
254 static void all_do(const frame* fr, const RegisterMap* reg_map, | |
255 OopClosure* oop_fn, | |
256 void derived_oop_fn(oop* base, oop* derived), | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
257 OopClosure* value_fn); |
0 | 258 |
259 // Printing | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
25
diff
changeset
|
260 void print_on(outputStream* st) const; |
0 | 261 void print() const { print_on(tty); } |
262 }; | |
263 | |
264 | |
265 class OopMapStream : public StackObj { | |
266 private: | |
267 CompressedReadStream* _stream; | |
268 int _mask; | |
269 int _size; | |
270 int _position; | |
271 bool _valid_omv; | |
272 OopMapValue _omv; | |
273 void find_next(); | |
274 | |
275 public: | |
276 OopMapStream(OopMap* oop_map); | |
277 OopMapStream(OopMap* oop_map, int oop_types_mask); | |
278 bool is_done() { if(!_valid_omv) { find_next(); } return !_valid_omv; } | |
279 void next() { find_next(); } | |
280 OopMapValue current() { return _omv; } | |
281 }; | |
282 | |
283 | |
284 // Derived pointer support. This table keeps track of all derived points on a | |
285 // stack. It is cleared before each scavenge/GC. During the traversal of all | |
286 // oops, it is filled in with references to all locations that contains a | |
287 // derived oop (assumed to be very few). When the GC is complete, the derived | |
288 // pointers are updated based on their base pointers new value and an offset. | |
289 #ifdef COMPILER2 | |
290 class DerivedPointerTable : public AllStatic { | |
291 friend class VMStructs; | |
292 private: | |
293 static GrowableArray<DerivedPointerEntry*>* _list; | |
294 static bool _active; // do not record pointers for verify pass etc. | |
295 public: | |
296 static void clear(); // Called before scavenge/GC | |
297 static void add(oop *derived, oop *base); // Called during scavenge/GC | |
298 static void update_pointers(); // Called after scavenge/GC | |
299 static bool is_empty() { return _list == NULL || _list->is_empty(); } | |
300 static bool is_active() { return _active; } | |
301 static void set_active(bool value) { _active = value; } | |
302 }; | |
303 | |
304 // A utility class to temporarily "deactivate" the DerivedPointerTable. | |
305 // (Note: clients are responsible for any MT-safety issues) | |
306 class DerivedPointerTableDeactivate: public StackObj { | |
307 private: | |
308 bool _active; | |
309 public: | |
310 DerivedPointerTableDeactivate() { | |
311 _active = DerivedPointerTable::is_active(); | |
312 if (_active) { | |
313 DerivedPointerTable::set_active(false); | |
314 } | |
315 } | |
316 | |
317 ~DerivedPointerTableDeactivate() { | |
318 assert(!DerivedPointerTable::is_active(), | |
319 "Inconsistency: not MT-safe"); | |
320 if (_active) { | |
321 DerivedPointerTable::set_active(true); | |
322 } | |
323 } | |
324 }; | |
325 #endif // COMPILER2 | |
1972 | 326 |
327 #endif // SHARE_VM_COMPILER_OOPMAP_HPP |