Wed, 06 Jan 2010 14:22:39 -0800
6914300: ciEnv should export all well known classes
Reviewed-by: kvn, twisti
1 /*
2 * Copyright 2001-2008 Sun Microsystems, Inc. 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 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 */
25 class ciBitData;
26 class ciCounterData;
27 class ciJumpData;
28 class ciReceiverTypeData;
29 class ciRetData;
30 class ciBranchData;
31 class ciArrayData;
32 class ciMultiBranchData;
33 class ciArgInfoData;
35 typedef ProfileData ciProfileData;
37 class ciBitData : public BitData {
38 public:
39 ciBitData(DataLayout* layout) : BitData(layout) {};
40 };
42 class ciCounterData : public CounterData {
43 public:
44 ciCounterData(DataLayout* layout) : CounterData(layout) {};
45 };
47 class ciJumpData : public JumpData {
48 public:
49 ciJumpData(DataLayout* layout) : JumpData(layout) {};
50 };
52 class ciReceiverTypeData : public ReceiverTypeData {
53 public:
54 ciReceiverTypeData(DataLayout* layout) : ReceiverTypeData(layout) {};
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 }
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 }
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 };
80 class ciVirtualCallData : public VirtualCallData {
81 // Fake multiple inheritance... It's a ciReceiverTypeData also.
82 ciReceiverTypeData* rtd_super() { return (ciReceiverTypeData*) this; }
84 public:
85 ciVirtualCallData(DataLayout* layout) : VirtualCallData(layout) {};
87 void set_receiver(uint row, ciKlass* recv) {
88 rtd_super()->set_receiver(row, recv);
89 }
91 ciKlass* receiver(uint row) {
92 return rtd_super()->receiver(row);
93 }
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 };
105 class ciRetData : public RetData {
106 public:
107 ciRetData(DataLayout* layout) : RetData(layout) {};
108 };
110 class ciBranchData : public BranchData {
111 public:
112 ciBranchData(DataLayout* layout) : BranchData(layout) {};
113 };
115 class ciArrayData : public ArrayData {
116 public:
117 ciArrayData(DataLayout* layout) : ArrayData(layout) {};
118 };
120 class ciMultiBranchData : public MultiBranchData {
121 public:
122 ciMultiBranchData(DataLayout* layout) : MultiBranchData(layout) {};
123 };
125 class ciArgInfoData : public ArgInfoData {
126 public:
127 ciArgInfoData(DataLayout* layout) : ArgInfoData(layout) {};
128 };
130 // ciMethodData
131 //
132 // This class represents a methodDataOop in the HotSpot virtual
133 // machine.
135 class ciMethodData : public ciObject {
136 CI_PACKAGE_ACCESS
138 private:
139 // Size in bytes
140 int _data_size;
141 int _extra_data_size;
143 // Data entries
144 intptr_t* _data;
146 // Cached hint for data_before()
147 int _hint_di;
149 // Is data attached? And is it mature?
150 enum { empty_state, immature_state, mature_state };
151 u_char _state;
153 // Set this true if empty extra_data slots are ever witnessed.
154 u_char _saw_free_extra_data;
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
162 // Maturity of the oop when the snapshot is taken.
163 int _current_mileage;
165 // Coherent snapshot of original header.
166 methodDataOopDesc _orig;
168 ciMethodData(methodDataHandle h_md);
169 ciMethodData();
171 // Accessors
172 int data_size() const { return _data_size; }
173 int extra_data_size() const { return _extra_data_size; }
174 intptr_t * data() const { return _data; }
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 }
183 const char* type_string() { return "ciMethodData"; }
185 void print_impl(outputStream* st);
187 DataLayout* data_layout_at(int data_index) const {
188 assert(data_index % sizeof(intptr_t) == 0, "unaligned");
189 return (DataLayout*) (((address)_data) + data_index);
190 }
192 bool out_of_bounds(int data_index) {
193 return data_index >= data_size();
194 }
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 }
213 // What is the index of the first data entry?
214 int first_di() { return 0; }
216 ciArgInfoData *arg_info() const;
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; }
223 int creation_mileage() { return _orig.creation_mileage(); }
224 int current_mileage() { return _current_mileage; }
226 void load_data();
228 // Convert a dp (data pointer) to a di (data index).
229 int dp_to_di(address dp) {
230 return dp - ((address)_data);
231 }
233 // Get the data at an arbitrary (sort of) data index.
234 ciProfileData* data_at(int data_index);
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; }
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);
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(); }
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 }
270 void clear_escape_info();
271 bool has_escape_info();
272 void update_escape_info();
274 void set_eflag(methodDataOopDesc::EscapeFlag f);
275 void clear_eflag(methodDataOopDesc::EscapeFlag f);
276 bool eflag_set(methodDataOopDesc::EscapeFlag f) const;
278 void set_arg_local(int i);
279 void set_arg_stack(int i);
280 void set_arg_returned(int i);
281 void set_arg_modified(int arg, uint val);
283 bool is_arg_local(int i) const;
284 bool is_arg_stack(int i) const;
285 bool is_arg_returned(int i) const;
286 uint arg_modified(int arg) const;
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)); }
292 #ifndef PRODUCT
293 // printing support for method data
294 void print();
295 void print_data_on(outputStream* st);
296 #endif
297 };