Mercurial > hg > truffle
annotate src/share/vm/ci/ciMethodData.hpp @ 3762:5c0a3c1858b1
7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
Summary: The LNC array is sized before the start of a scavenge, while the heap may expand during a scavenge. With CMS, the last block of an arbitrary suffice of the LNC array may expand due to coalition with the expansion delta. We now take care not to attempt access past the end of the LNC array. LNC array code will be cleaned up and suitably encapsulated as part of the forthcoming performance RFE 7043675.
Reviewed-by: brutisso
author | ysr |
---|---|
date | Thu, 02 Jun 2011 10:23:36 -0700 |
parents | fabcf26ee72f |
children | da91efe96a93 |
rev | line source |
---|---|
0 | 1 /* |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
1972
diff
changeset
|
2 * Copyright (c) 2001, 2011, 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:
196
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
196
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:
196
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_CI_CIMETHODDATA_HPP |
26 #define SHARE_VM_CI_CIMETHODDATA_HPP | |
27 | |
28 #include "ci/ciClassList.hpp" | |
29 #include "ci/ciKlass.hpp" | |
30 #include "ci/ciObject.hpp" | |
31 #include "ci/ciUtilities.hpp" | |
32 #include "oops/methodDataOop.hpp" | |
33 #include "oops/oop.inline.hpp" | |
34 | |
0 | 35 class ciBitData; |
36 class ciCounterData; | |
37 class ciJumpData; | |
38 class ciReceiverTypeData; | |
39 class ciRetData; | |
40 class ciBranchData; | |
41 class ciArrayData; | |
42 class ciMultiBranchData; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
43 class ciArgInfoData; |
0 | 44 |
45 typedef ProfileData ciProfileData; | |
46 | |
47 class ciBitData : public BitData { | |
48 public: | |
49 ciBitData(DataLayout* layout) : BitData(layout) {}; | |
50 }; | |
51 | |
52 class ciCounterData : public CounterData { | |
53 public: | |
54 ciCounterData(DataLayout* layout) : CounterData(layout) {}; | |
55 }; | |
56 | |
57 class ciJumpData : public JumpData { | |
58 public: | |
59 ciJumpData(DataLayout* layout) : JumpData(layout) {}; | |
60 }; | |
61 | |
62 class ciReceiverTypeData : public ReceiverTypeData { | |
63 public: | |
64 ciReceiverTypeData(DataLayout* layout) : ReceiverTypeData(layout) {}; | |
65 | |
66 void set_receiver(uint row, ciKlass* recv) { | |
67 assert((uint)row < row_limit(), "oob"); | |
68 set_intptr_at(receiver0_offset + row * receiver_type_row_cell_count, | |
69 (intptr_t) recv); | |
70 } | |
71 | |
72 ciKlass* receiver(uint row) { | |
73 assert((uint)row < row_limit(), "oob"); | |
74 ciObject* recv = (ciObject*)intptr_at(receiver0_offset + row * receiver_type_row_cell_count); | |
75 assert(recv == NULL || recv->is_klass(), "wrong type"); | |
76 return (ciKlass*)recv; | |
77 } | |
78 | |
79 // Copy & translate from oop based ReceiverTypeData | |
80 virtual void translate_from(ProfileData* data) { | |
81 translate_receiver_data_from(data); | |
82 } | |
83 void translate_receiver_data_from(ProfileData* data); | |
84 #ifndef PRODUCT | |
85 void print_data_on(outputStream* st); | |
86 void print_receiver_data_on(outputStream* st); | |
87 #endif | |
88 }; | |
89 | |
90 class ciVirtualCallData : public VirtualCallData { | |
91 // Fake multiple inheritance... It's a ciReceiverTypeData also. | |
92 ciReceiverTypeData* rtd_super() { return (ciReceiverTypeData*) this; } | |
93 | |
94 public: | |
95 ciVirtualCallData(DataLayout* layout) : VirtualCallData(layout) {}; | |
96 | |
97 void set_receiver(uint row, ciKlass* recv) { | |
98 rtd_super()->set_receiver(row, recv); | |
99 } | |
100 | |
101 ciKlass* receiver(uint row) { | |
102 return rtd_super()->receiver(row); | |
103 } | |
104 | |
105 // Copy & translate from oop based VirtualCallData | |
106 virtual void translate_from(ProfileData* data) { | |
107 rtd_super()->translate_receiver_data_from(data); | |
108 } | |
109 #ifndef PRODUCT | |
110 void print_data_on(outputStream* st); | |
111 #endif | |
112 }; | |
113 | |
114 | |
115 class ciRetData : public RetData { | |
116 public: | |
117 ciRetData(DataLayout* layout) : RetData(layout) {}; | |
118 }; | |
119 | |
120 class ciBranchData : public BranchData { | |
121 public: | |
122 ciBranchData(DataLayout* layout) : BranchData(layout) {}; | |
123 }; | |
124 | |
125 class ciArrayData : public ArrayData { | |
126 public: | |
127 ciArrayData(DataLayout* layout) : ArrayData(layout) {}; | |
128 }; | |
129 | |
130 class ciMultiBranchData : public MultiBranchData { | |
131 public: | |
132 ciMultiBranchData(DataLayout* layout) : MultiBranchData(layout) {}; | |
133 }; | |
134 | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
135 class ciArgInfoData : public ArgInfoData { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
136 public: |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
137 ciArgInfoData(DataLayout* layout) : ArgInfoData(layout) {}; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
138 }; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
139 |
0 | 140 // ciMethodData |
141 // | |
142 // This class represents a methodDataOop in the HotSpot virtual | |
143 // machine. | |
144 | |
145 class ciMethodData : public ciObject { | |
146 CI_PACKAGE_ACCESS | |
147 | |
148 private: | |
149 // Size in bytes | |
150 int _data_size; | |
151 int _extra_data_size; | |
152 | |
153 // Data entries | |
154 intptr_t* _data; | |
155 | |
156 // Cached hint for data_before() | |
157 int _hint_di; | |
158 | |
159 // Is data attached? And is it mature? | |
160 enum { empty_state, immature_state, mature_state }; | |
161 u_char _state; | |
162 | |
163 // Set this true if empty extra_data slots are ever witnessed. | |
164 u_char _saw_free_extra_data; | |
165 | |
166 // Support for interprocedural escape analysis | |
167 intx _eflags; // flags on escape information | |
168 intx _arg_local; // bit set of non-escaping arguments | |
169 intx _arg_stack; // bit set of stack-allocatable arguments | |
170 intx _arg_returned; // bit set of returned arguments | |
171 | |
172 // Maturity of the oop when the snapshot is taken. | |
173 int _current_mileage; | |
174 | |
1783 | 175 // These counters hold the age of MDO in tiered. In tiered we can have the same method |
176 // running at different compilation levels concurrently. So, in order to precisely measure | |
177 // its maturity we need separate counters. | |
178 int _invocation_counter; | |
179 int _backedge_counter; | |
180 | |
0 | 181 // Coherent snapshot of original header. |
182 methodDataOopDesc _orig; | |
183 | |
184 ciMethodData(methodDataHandle h_md); | |
185 ciMethodData(); | |
186 | |
187 // Accessors | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
188 int data_size() const { return _data_size; } |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
189 int extra_data_size() const { return _extra_data_size; } |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
190 intptr_t * data() const { return _data; } |
0 | 191 |
192 methodDataOop get_methodDataOop() const { | |
193 if (handle() == NULL) return NULL; | |
194 methodDataOop mdo = (methodDataOop)get_oop(); | |
195 assert(mdo != NULL, "illegal use of unloaded method data"); | |
196 return mdo; | |
197 } | |
198 | |
199 const char* type_string() { return "ciMethodData"; } | |
200 | |
201 void print_impl(outputStream* st); | |
202 | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
203 DataLayout* data_layout_at(int data_index) const { |
0 | 204 assert(data_index % sizeof(intptr_t) == 0, "unaligned"); |
205 return (DataLayout*) (((address)_data) + data_index); | |
206 } | |
207 | |
208 bool out_of_bounds(int data_index) { | |
209 return data_index >= data_size(); | |
210 } | |
211 | |
212 // hint accessors | |
213 int hint_di() const { return _hint_di; } | |
214 void set_hint_di(int di) { | |
215 assert(!out_of_bounds(di), "hint_di out of bounds"); | |
216 _hint_di = di; | |
217 } | |
218 ciProfileData* data_before(int bci) { | |
219 // avoid SEGV on this edge case | |
220 if (data_size() == 0) | |
221 return NULL; | |
222 int hint = hint_di(); | |
223 if (data_layout_at(hint)->bci() <= bci) | |
224 return data_at(hint); | |
225 return first_data(); | |
226 } | |
227 | |
228 | |
229 // What is the index of the first data entry? | |
230 int first_di() { return 0; } | |
231 | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
232 ciArgInfoData *arg_info() const; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
233 |
0 | 234 public: |
235 bool is_method_data() { return true; } | |
3371
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
1972
diff
changeset
|
236 |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
1972
diff
changeset
|
237 void set_mature() { _state = mature_state; } |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
1972
diff
changeset
|
238 |
fabcf26ee72f
6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents:
1972
diff
changeset
|
239 bool is_empty() { return _state == empty_state; } |
0 | 240 bool is_mature() { return _state == mature_state; } |
241 | |
242 int creation_mileage() { return _orig.creation_mileage(); } | |
243 int current_mileage() { return _current_mileage; } | |
244 | |
1783 | 245 int invocation_count() { return _invocation_counter; } |
246 int backedge_count() { return _backedge_counter; } | |
247 // Transfer information about the method to methodDataOop. | |
248 // would_profile means we would like to profile this method, | |
249 // meaning it's not trivial. | |
250 void set_would_profile(bool p); | |
251 // Also set the numer of loops and blocks in the method. | |
252 // Again, this is used to determine if a method is trivial. | |
253 void set_compilation_stats(short loops, short blocks); | |
254 | |
0 | 255 void load_data(); |
256 | |
257 // Convert a dp (data pointer) to a di (data index). | |
258 int dp_to_di(address dp) { | |
259 return dp - ((address)_data); | |
260 } | |
261 | |
262 // Get the data at an arbitrary (sort of) data index. | |
263 ciProfileData* data_at(int data_index); | |
264 | |
265 // Walk through the data in order. | |
266 ciProfileData* first_data() { return data_at(first_di()); } | |
267 ciProfileData* next_data(ciProfileData* current); | |
268 bool is_valid(ciProfileData* current) { return current != NULL; } | |
269 | |
270 // Get the data at an arbitrary bci, or NULL if there is none. | |
271 ciProfileData* bci_to_data(int bci); | |
272 ciProfileData* bci_to_extra_data(int bci, bool create_if_missing); | |
273 | |
274 uint overflow_trap_count() const { | |
275 return _orig.overflow_trap_count(); | |
276 } | |
277 uint overflow_recompile_count() const { | |
278 return _orig.overflow_recompile_count(); | |
279 } | |
280 uint decompile_count() const { | |
281 return _orig.decompile_count(); | |
282 } | |
283 uint trap_count(int reason) const { | |
284 return _orig.trap_count(reason); | |
285 } | |
286 uint trap_reason_limit() const { return _orig.trap_reason_limit(); } | |
287 uint trap_count_limit() const { return _orig.trap_count_limit(); } | |
288 | |
289 // Helpful query functions that decode trap_state. | |
290 int has_trap_at(ciProfileData* data, int reason); | |
291 int has_trap_at(int bci, int reason) { | |
292 return has_trap_at(bci_to_data(bci), reason); | |
293 } | |
294 int trap_recompiled_at(ciProfileData* data); | |
295 int trap_recompiled_at(int bci) { | |
296 return trap_recompiled_at(bci_to_data(bci)); | |
297 } | |
298 | |
299 void clear_escape_info(); | |
300 bool has_escape_info(); | |
301 void update_escape_info(); | |
302 | |
303 void set_eflag(methodDataOopDesc::EscapeFlag f); | |
304 void clear_eflag(methodDataOopDesc::EscapeFlag f); | |
305 bool eflag_set(methodDataOopDesc::EscapeFlag f) const; | |
306 | |
307 void set_arg_local(int i); | |
308 void set_arg_stack(int i); | |
309 void set_arg_returned(int i); | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
310 void set_arg_modified(int arg, uint val); |
0 | 311 |
312 bool is_arg_local(int i) const; | |
313 bool is_arg_stack(int i) const; | |
314 bool is_arg_returned(int i) const; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
315 uint arg_modified(int arg) const; |
0 | 316 |
317 // Code generation helper | |
318 ByteSize offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data); | |
319 int byte_offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) { return in_bytes(offset_of_slot(data, slot_offset_in_data)); } | |
320 | |
321 #ifndef PRODUCT | |
322 // printing support for method data | |
323 void print(); | |
324 void print_data_on(outputStream* st); | |
325 #endif | |
326 }; | |
1972 | 327 |
328 #endif // SHARE_VM_CI_CIMETHODDATA_HPP |