Mercurial > hg > truffle
annotate src/share/vm/ci/ciMethodData.hpp @ 2007:5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
Summary: C1 with profiling doesn't check whether the MDO has been really allocated, which can silently fail if the perm gen is full. The solution is to check if the allocation failed and bailout out of inlining or compilation.
Reviewed-by: kvn, never
author | iveresov |
---|---|
date | Thu, 02 Dec 2010 17:21:12 -0800 |
parents | f95d63e2154a |
children | fabcf26ee72f |
rev | line source |
---|---|
0 | 1 /* |
1783 | 2 * Copyright (c) 2001, 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:
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; } | |
236 bool is_empty() { return _state == empty_state; } | |
237 bool is_mature() { return _state == mature_state; } | |
238 | |
239 int creation_mileage() { return _orig.creation_mileage(); } | |
240 int current_mileage() { return _current_mileage; } | |
241 | |
1783 | 242 int invocation_count() { return _invocation_counter; } |
243 int backedge_count() { return _backedge_counter; } | |
244 // Transfer information about the method to methodDataOop. | |
245 // would_profile means we would like to profile this method, | |
246 // meaning it's not trivial. | |
247 void set_would_profile(bool p); | |
248 // Also set the numer of loops and blocks in the method. | |
249 // Again, this is used to determine if a method is trivial. | |
250 void set_compilation_stats(short loops, short blocks); | |
251 | |
0 | 252 void load_data(); |
253 | |
254 // Convert a dp (data pointer) to a di (data index). | |
255 int dp_to_di(address dp) { | |
256 return dp - ((address)_data); | |
257 } | |
258 | |
259 // Get the data at an arbitrary (sort of) data index. | |
260 ciProfileData* data_at(int data_index); | |
261 | |
262 // Walk through the data in order. | |
263 ciProfileData* first_data() { return data_at(first_di()); } | |
264 ciProfileData* next_data(ciProfileData* current); | |
265 bool is_valid(ciProfileData* current) { return current != NULL; } | |
266 | |
267 // Get the data at an arbitrary bci, or NULL if there is none. | |
268 ciProfileData* bci_to_data(int bci); | |
269 ciProfileData* bci_to_extra_data(int bci, bool create_if_missing); | |
270 | |
271 uint overflow_trap_count() const { | |
272 return _orig.overflow_trap_count(); | |
273 } | |
274 uint overflow_recompile_count() const { | |
275 return _orig.overflow_recompile_count(); | |
276 } | |
277 uint decompile_count() const { | |
278 return _orig.decompile_count(); | |
279 } | |
280 uint trap_count(int reason) const { | |
281 return _orig.trap_count(reason); | |
282 } | |
283 uint trap_reason_limit() const { return _orig.trap_reason_limit(); } | |
284 uint trap_count_limit() const { return _orig.trap_count_limit(); } | |
285 | |
286 // Helpful query functions that decode trap_state. | |
287 int has_trap_at(ciProfileData* data, int reason); | |
288 int has_trap_at(int bci, int reason) { | |
289 return has_trap_at(bci_to_data(bci), reason); | |
290 } | |
291 int trap_recompiled_at(ciProfileData* data); | |
292 int trap_recompiled_at(int bci) { | |
293 return trap_recompiled_at(bci_to_data(bci)); | |
294 } | |
295 | |
296 void clear_escape_info(); | |
297 bool has_escape_info(); | |
298 void update_escape_info(); | |
299 | |
300 void set_eflag(methodDataOopDesc::EscapeFlag f); | |
301 void clear_eflag(methodDataOopDesc::EscapeFlag f); | |
302 bool eflag_set(methodDataOopDesc::EscapeFlag f) const; | |
303 | |
304 void set_arg_local(int i); | |
305 void set_arg_stack(int i); | |
306 void set_arg_returned(int i); | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
307 void set_arg_modified(int arg, uint val); |
0 | 308 |
309 bool is_arg_local(int i) const; | |
310 bool is_arg_stack(int i) const; | |
311 bool is_arg_returned(int i) const; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
312 uint arg_modified(int arg) const; |
0 | 313 |
314 // Code generation helper | |
315 ByteSize offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data); | |
316 int byte_offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) { return in_bytes(offset_of_slot(data, slot_offset_in_data)); } | |
317 | |
318 #ifndef PRODUCT | |
319 // printing support for method data | |
320 void print(); | |
321 void print_data_on(outputStream* st); | |
322 #endif | |
323 }; | |
1972 | 324 |
325 #endif // SHARE_VM_CI_CIMETHODDATA_HPP |