Mercurial > hg > truffle
annotate src/share/vm/ci/ciMethodData.hpp @ 1145:e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking.
Reviewed-by: jmasa
author | ysr |
---|---|
date | Wed, 23 Dec 2009 09:23:54 -0800 |
parents | d1605aabd0a1 |
children | c18cbe5936b8 |
rev | line source |
---|---|
0 | 1 /* |
196 | 2 * Copyright 2001-2008 Sun Microsystems, Inc. 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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 class ciBitData; | |
26 class ciCounterData; | |
27 class ciJumpData; | |
28 class ciReceiverTypeData; | |
29 class ciRetData; | |
30 class ciBranchData; | |
31 class ciArrayData; | |
32 class ciMultiBranchData; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
33 class ciArgInfoData; |
0 | 34 |
35 typedef ProfileData ciProfileData; | |
36 | |
37 class ciBitData : public BitData { | |
38 public: | |
39 ciBitData(DataLayout* layout) : BitData(layout) {}; | |
40 }; | |
41 | |
42 class ciCounterData : public CounterData { | |
43 public: | |
44 ciCounterData(DataLayout* layout) : CounterData(layout) {}; | |
45 }; | |
46 | |
47 class ciJumpData : public JumpData { | |
48 public: | |
49 ciJumpData(DataLayout* layout) : JumpData(layout) {}; | |
50 }; | |
51 | |
52 class ciReceiverTypeData : public ReceiverTypeData { | |
53 public: | |
54 ciReceiverTypeData(DataLayout* layout) : ReceiverTypeData(layout) {}; | |
55 | |
56 void set_receiver(uint row, ciKlass* recv) { | |
57 assert((uint)row < row_limit(), "oob"); | |
58 set_intptr_at(receiver0_offset + row * receiver_type_row_cell_count, | |
59 (intptr_t) recv); | |
60 } | |
61 | |
62 ciKlass* receiver(uint row) { | |
63 assert((uint)row < row_limit(), "oob"); | |
64 ciObject* recv = (ciObject*)intptr_at(receiver0_offset + row * receiver_type_row_cell_count); | |
65 assert(recv == NULL || recv->is_klass(), "wrong type"); | |
66 return (ciKlass*)recv; | |
67 } | |
68 | |
69 // Copy & translate from oop based ReceiverTypeData | |
70 virtual void translate_from(ProfileData* data) { | |
71 translate_receiver_data_from(data); | |
72 } | |
73 void translate_receiver_data_from(ProfileData* data); | |
74 #ifndef PRODUCT | |
75 void print_data_on(outputStream* st); | |
76 void print_receiver_data_on(outputStream* st); | |
77 #endif | |
78 }; | |
79 | |
80 class ciVirtualCallData : public VirtualCallData { | |
81 // Fake multiple inheritance... It's a ciReceiverTypeData also. | |
82 ciReceiverTypeData* rtd_super() { return (ciReceiverTypeData*) this; } | |
83 | |
84 public: | |
85 ciVirtualCallData(DataLayout* layout) : VirtualCallData(layout) {}; | |
86 | |
87 void set_receiver(uint row, ciKlass* recv) { | |
88 rtd_super()->set_receiver(row, recv); | |
89 } | |
90 | |
91 ciKlass* receiver(uint row) { | |
92 return rtd_super()->receiver(row); | |
93 } | |
94 | |
95 // Copy & translate from oop based VirtualCallData | |
96 virtual void translate_from(ProfileData* data) { | |
97 rtd_super()->translate_receiver_data_from(data); | |
98 } | |
99 #ifndef PRODUCT | |
100 void print_data_on(outputStream* st); | |
101 #endif | |
102 }; | |
103 | |
104 | |
105 class ciRetData : public RetData { | |
106 public: | |
107 ciRetData(DataLayout* layout) : RetData(layout) {}; | |
108 }; | |
109 | |
110 class ciBranchData : public BranchData { | |
111 public: | |
112 ciBranchData(DataLayout* layout) : BranchData(layout) {}; | |
113 }; | |
114 | |
115 class ciArrayData : public ArrayData { | |
116 public: | |
117 ciArrayData(DataLayout* layout) : ArrayData(layout) {}; | |
118 }; | |
119 | |
120 class ciMultiBranchData : public MultiBranchData { | |
121 public: | |
122 ciMultiBranchData(DataLayout* layout) : MultiBranchData(layout) {}; | |
123 }; | |
124 | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
125 class ciArgInfoData : public ArgInfoData { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
126 public: |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
127 ciArgInfoData(DataLayout* layout) : ArgInfoData(layout) {}; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
128 }; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
129 |
0 | 130 // ciMethodData |
131 // | |
132 // This class represents a methodDataOop in the HotSpot virtual | |
133 // machine. | |
134 | |
135 class ciMethodData : public ciObject { | |
136 CI_PACKAGE_ACCESS | |
137 | |
138 private: | |
139 // Size in bytes | |
140 int _data_size; | |
141 int _extra_data_size; | |
142 | |
143 // Data entries | |
144 intptr_t* _data; | |
145 | |
146 // Cached hint for data_before() | |
147 int _hint_di; | |
148 | |
149 // Is data attached? And is it mature? | |
150 enum { empty_state, immature_state, mature_state }; | |
151 u_char _state; | |
152 | |
153 // Set this true if empty extra_data slots are ever witnessed. | |
154 u_char _saw_free_extra_data; | |
155 | |
156 // Support for interprocedural escape analysis | |
157 intx _eflags; // flags on escape information | |
158 intx _arg_local; // bit set of non-escaping arguments | |
159 intx _arg_stack; // bit set of stack-allocatable arguments | |
160 intx _arg_returned; // bit set of returned arguments | |
161 | |
162 // Maturity of the oop when the snapshot is taken. | |
163 int _current_mileage; | |
164 | |
165 // Coherent snapshot of original header. | |
166 methodDataOopDesc _orig; | |
167 | |
168 ciMethodData(methodDataHandle h_md); | |
169 ciMethodData(); | |
170 | |
171 // Accessors | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
172 int data_size() const { return _data_size; } |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
173 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
|
174 intptr_t * data() const { return _data; } |
0 | 175 |
176 methodDataOop get_methodDataOop() const { | |
177 if (handle() == NULL) return NULL; | |
178 methodDataOop mdo = (methodDataOop)get_oop(); | |
179 assert(mdo != NULL, "illegal use of unloaded method data"); | |
180 return mdo; | |
181 } | |
182 | |
183 const char* type_string() { return "ciMethodData"; } | |
184 | |
185 void print_impl(outputStream* st); | |
186 | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
187 DataLayout* data_layout_at(int data_index) const { |
0 | 188 assert(data_index % sizeof(intptr_t) == 0, "unaligned"); |
189 return (DataLayout*) (((address)_data) + data_index); | |
190 } | |
191 | |
192 bool out_of_bounds(int data_index) { | |
193 return data_index >= data_size(); | |
194 } | |
195 | |
196 // hint accessors | |
197 int hint_di() const { return _hint_di; } | |
198 void set_hint_di(int di) { | |
199 assert(!out_of_bounds(di), "hint_di out of bounds"); | |
200 _hint_di = di; | |
201 } | |
202 ciProfileData* data_before(int bci) { | |
203 // avoid SEGV on this edge case | |
204 if (data_size() == 0) | |
205 return NULL; | |
206 int hint = hint_di(); | |
207 if (data_layout_at(hint)->bci() <= bci) | |
208 return data_at(hint); | |
209 return first_data(); | |
210 } | |
211 | |
212 | |
213 // What is the index of the first data entry? | |
214 int first_di() { return 0; } | |
215 | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
216 ciArgInfoData *arg_info() const; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
217 |
0 | 218 public: |
219 bool is_method_data() { return true; } | |
220 bool is_empty() { return _state == empty_state; } | |
221 bool is_mature() { return _state == mature_state; } | |
222 | |
223 int creation_mileage() { return _orig.creation_mileage(); } | |
224 int current_mileage() { return _current_mileage; } | |
225 | |
226 void load_data(); | |
227 | |
228 // Convert a dp (data pointer) to a di (data index). | |
229 int dp_to_di(address dp) { | |
230 return dp - ((address)_data); | |
231 } | |
232 | |
233 // Get the data at an arbitrary (sort of) data index. | |
234 ciProfileData* data_at(int data_index); | |
235 | |
236 // Walk through the data in order. | |
237 ciProfileData* first_data() { return data_at(first_di()); } | |
238 ciProfileData* next_data(ciProfileData* current); | |
239 bool is_valid(ciProfileData* current) { return current != NULL; } | |
240 | |
241 // Get the data at an arbitrary bci, or NULL if there is none. | |
242 ciProfileData* bci_to_data(int bci); | |
243 ciProfileData* bci_to_extra_data(int bci, bool create_if_missing); | |
244 | |
245 uint overflow_trap_count() const { | |
246 return _orig.overflow_trap_count(); | |
247 } | |
248 uint overflow_recompile_count() const { | |
249 return _orig.overflow_recompile_count(); | |
250 } | |
251 uint decompile_count() const { | |
252 return _orig.decompile_count(); | |
253 } | |
254 uint trap_count(int reason) const { | |
255 return _orig.trap_count(reason); | |
256 } | |
257 uint trap_reason_limit() const { return _orig.trap_reason_limit(); } | |
258 uint trap_count_limit() const { return _orig.trap_count_limit(); } | |
259 | |
260 // Helpful query functions that decode trap_state. | |
261 int has_trap_at(ciProfileData* data, int reason); | |
262 int has_trap_at(int bci, int reason) { | |
263 return has_trap_at(bci_to_data(bci), reason); | |
264 } | |
265 int trap_recompiled_at(ciProfileData* data); | |
266 int trap_recompiled_at(int bci) { | |
267 return trap_recompiled_at(bci_to_data(bci)); | |
268 } | |
269 | |
270 void clear_escape_info(); | |
271 bool has_escape_info(); | |
272 void update_escape_info(); | |
273 | |
274 void set_eflag(methodDataOopDesc::EscapeFlag f); | |
275 void clear_eflag(methodDataOopDesc::EscapeFlag f); | |
276 bool eflag_set(methodDataOopDesc::EscapeFlag f) const; | |
277 | |
278 void set_arg_local(int i); | |
279 void set_arg_stack(int i); | |
280 void set_arg_returned(int i); | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
281 void set_arg_modified(int arg, uint val); |
0 | 282 |
283 bool is_arg_local(int i) const; | |
284 bool is_arg_stack(int i) const; | |
285 bool is_arg_returned(int i) const; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
286 uint arg_modified(int arg) const; |
0 | 287 |
288 // Code generation helper | |
289 ByteSize offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data); | |
290 int byte_offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) { return in_bytes(offset_of_slot(data, slot_offset_in_data)); } | |
291 | |
292 #ifndef PRODUCT | |
293 // printing support for method data | |
294 void print(); | |
295 void print_data_on(outputStream* st); | |
296 #endif | |
297 }; |