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