ciMethodData.hpp revision 5776:de6a9e811145
1/*
2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
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/methodData.hpp"
33#include "oops/oop.inline.hpp"
34
35class ciBitData;
36class ciCounterData;
37class ciJumpData;
38class ciReceiverTypeData;
39class ciRetData;
40class ciBranchData;
41class ciArrayData;
42class ciMultiBranchData;
43class ciArgInfoData;
44class ciCallTypeData;
45class ciVirtualCallTypeData;
46class ciParametersTypeData;
47
48typedef ProfileData ciProfileData;
49
50class ciBitData : public BitData {
51public:
52  ciBitData(DataLayout* layout) : BitData(layout) {};
53};
54
55class ciCounterData : public CounterData {
56public:
57  ciCounterData(DataLayout* layout) : CounterData(layout) {};
58};
59
60class ciJumpData : public JumpData {
61public:
62  ciJumpData(DataLayout* layout) : JumpData(layout) {};
63};
64
65class ciTypeEntries {
66protected:
67  static intptr_t translate_klass(intptr_t k) {
68    Klass* v = TypeEntries::valid_klass(k);
69    if (v != NULL) {
70      ciKlass* klass = CURRENT_ENV->get_klass(v);
71      return with_status(klass, k);
72    }
73    return with_status(NULL, k);
74  }
75
76public:
77  static ciKlass* valid_ciklass(intptr_t k) {
78    if (!TypeEntries::is_type_none(k) &&
79        !TypeEntries::is_type_unknown(k)) {
80      ciKlass* res = (ciKlass*)TypeEntries::klass_part(k);
81      assert(res != NULL, "invalid");
82      return res;
83    } else {
84      return NULL;
85    }
86  }
87
88  static intptr_t with_status(ciKlass* k, intptr_t in) {
89    return TypeEntries::with_status((intptr_t)k, in);
90  }
91
92#ifndef PRODUCT
93  static void print_ciklass(outputStream* st, intptr_t k);
94#endif
95};
96
97class ciTypeStackSlotEntries : public TypeStackSlotEntries, ciTypeEntries {
98public:
99  void translate_type_data_from(const TypeStackSlotEntries* args);
100
101  ciKlass* valid_type(int i) const {
102    return valid_ciklass(type(i));
103  }
104
105  bool maybe_null(int i) const {
106    return was_null_seen(type(i));
107  }
108
109#ifndef PRODUCT
110  void print_data_on(outputStream* st) const;
111#endif
112};
113
114class ciReturnTypeEntry : public ReturnTypeEntry, ciTypeEntries {
115public:
116  void translate_type_data_from(const ReturnTypeEntry* ret);
117
118  ciKlass* valid_type() const {
119    return valid_ciklass(type());
120  }
121
122  bool maybe_null() const {
123    return was_null_seen(type());
124  }
125
126#ifndef PRODUCT
127  void print_data_on(outputStream* st) const;
128#endif
129};
130
131class ciCallTypeData : public CallTypeData {
132public:
133  ciCallTypeData(DataLayout* layout) : CallTypeData(layout) {}
134
135  ciTypeStackSlotEntries* args() const { return (ciTypeStackSlotEntries*)CallTypeData::args(); }
136  ciReturnTypeEntry* ret() const { return (ciReturnTypeEntry*)CallTypeData::ret(); }
137
138  void translate_from(const ProfileData* data) {
139    if (has_arguments()) {
140      args()->translate_type_data_from(data->as_CallTypeData()->args());
141    }
142    if (has_return()) {
143      ret()->translate_type_data_from(data->as_CallTypeData()->ret());
144    }
145  }
146
147  intptr_t argument_type(int i) const {
148    assert(has_arguments(), "no arg type profiling data");
149    return args()->type(i);
150  }
151
152  ciKlass* valid_argument_type(int i) const {
153    assert(has_arguments(), "no arg type profiling data");
154    return args()->valid_type(i);
155  }
156
157  intptr_t return_type() const {
158    assert(has_return(), "no ret type profiling data");
159    return ret()->type();
160  }
161
162  ciKlass* valid_return_type() const {
163    assert(has_return(), "no ret type profiling data");
164    return ret()->valid_type();
165  }
166
167  bool argument_maybe_null(int i) const {
168    return args()->maybe_null(i);
169  }
170
171  bool return_maybe_null() const {
172    return ret()->maybe_null();
173  }
174
175#ifndef PRODUCT
176  void print_data_on(outputStream* st) const;
177#endif
178};
179
180class ciReceiverTypeData : public ReceiverTypeData {
181public:
182  ciReceiverTypeData(DataLayout* layout) : ReceiverTypeData(layout) {};
183
184  void set_receiver(uint row, ciKlass* recv) {
185    assert((uint)row < row_limit(), "oob");
186    set_intptr_at(receiver0_offset + row * receiver_type_row_cell_count,
187                  (intptr_t) recv);
188  }
189
190  ciKlass* receiver(uint row) const {
191    assert((uint)row < row_limit(), "oob");
192    ciKlass* recv = (ciKlass*)intptr_at(receiver0_offset + row * receiver_type_row_cell_count);
193    assert(recv == NULL || recv->is_klass(), "wrong type");
194    return recv;
195  }
196
197  // Copy & translate from oop based ReceiverTypeData
198  virtual void translate_from(const ProfileData* data) {
199    translate_receiver_data_from(data);
200  }
201  void translate_receiver_data_from(const ProfileData* data);
202#ifndef PRODUCT
203  void print_data_on(outputStream* st) const;
204  void print_receiver_data_on(outputStream* st) const;
205#endif
206};
207
208class ciVirtualCallData : public VirtualCallData {
209  // Fake multiple inheritance...  It's a ciReceiverTypeData also.
210  ciReceiverTypeData* rtd_super() const { return (ciReceiverTypeData*) this; }
211
212public:
213  ciVirtualCallData(DataLayout* layout) : VirtualCallData(layout) {};
214
215  void set_receiver(uint row, ciKlass* recv) {
216    rtd_super()->set_receiver(row, recv);
217  }
218
219  ciKlass* receiver(uint row) {
220    return rtd_super()->receiver(row);
221  }
222
223  // Copy & translate from oop based VirtualCallData
224  virtual void translate_from(const ProfileData* data) {
225    rtd_super()->translate_receiver_data_from(data);
226  }
227#ifndef PRODUCT
228  void print_data_on(outputStream* st) const;
229#endif
230};
231
232class ciVirtualCallTypeData : public VirtualCallTypeData {
233private:
234  // Fake multiple inheritance...  It's a ciReceiverTypeData also.
235  ciReceiverTypeData* rtd_super() const { return (ciReceiverTypeData*) this; }
236public:
237  ciVirtualCallTypeData(DataLayout* layout) : VirtualCallTypeData(layout) {}
238
239  void set_receiver(uint row, ciKlass* recv) {
240    rtd_super()->set_receiver(row, recv);
241  }
242
243  ciKlass* receiver(uint row) const {
244    return rtd_super()->receiver(row);
245  }
246
247  ciTypeStackSlotEntries* args() const { return (ciTypeStackSlotEntries*)VirtualCallTypeData::args(); }
248  ciReturnTypeEntry* ret() const { return (ciReturnTypeEntry*)VirtualCallTypeData::ret(); }
249
250  // Copy & translate from oop based VirtualCallData
251  virtual void translate_from(const ProfileData* data) {
252    rtd_super()->translate_receiver_data_from(data);
253    if (has_arguments()) {
254      args()->translate_type_data_from(data->as_VirtualCallTypeData()->args());
255    }
256    if (has_return()) {
257      ret()->translate_type_data_from(data->as_VirtualCallTypeData()->ret());
258    }
259  }
260
261  intptr_t argument_type(int i) const {
262    assert(has_arguments(), "no arg type profiling data");
263    return args()->type(i);
264  }
265
266  ciKlass* valid_argument_type(int i) const {
267    assert(has_arguments(), "no arg type profiling data");
268    return args()->valid_type(i);
269  }
270
271  intptr_t return_type() const {
272    assert(has_return(), "no ret type profiling data");
273    return ret()->type();
274  }
275
276  ciKlass* valid_return_type() const {
277    assert(has_return(), "no ret type profiling data");
278    return ret()->valid_type();
279  }
280
281  bool argument_maybe_null(int i) const {
282    return args()->maybe_null(i);
283  }
284
285  bool return_maybe_null() const {
286    return ret()->maybe_null();
287  }
288
289#ifndef PRODUCT
290  void print_data_on(outputStream* st) const;
291#endif
292};
293
294
295class ciRetData : public RetData {
296public:
297  ciRetData(DataLayout* layout) : RetData(layout) {};
298};
299
300class ciBranchData : public BranchData {
301public:
302  ciBranchData(DataLayout* layout) : BranchData(layout) {};
303};
304
305class ciArrayData : public ArrayData {
306public:
307  ciArrayData(DataLayout* layout) : ArrayData(layout) {};
308};
309
310class ciMultiBranchData : public MultiBranchData {
311public:
312  ciMultiBranchData(DataLayout* layout) : MultiBranchData(layout) {};
313};
314
315class ciArgInfoData : public ArgInfoData {
316public:
317  ciArgInfoData(DataLayout* layout) : ArgInfoData(layout) {};
318};
319
320class ciParametersTypeData : public ParametersTypeData {
321public:
322  ciParametersTypeData(DataLayout* layout) : ParametersTypeData(layout) {}
323
324  virtual void translate_from(const ProfileData* data) {
325    parameters()->translate_type_data_from(data->as_ParametersTypeData()->parameters());
326  }
327
328  ciTypeStackSlotEntries* parameters() const { return (ciTypeStackSlotEntries*)ParametersTypeData::parameters(); }
329
330  ciKlass* valid_parameter_type(int i) const {
331    return parameters()->valid_type(i);
332  }
333
334  bool parameter_maybe_null(int i) const {
335    return parameters()->maybe_null(i);
336  }
337
338#ifndef PRODUCT
339  void print_data_on(outputStream* st) const;
340#endif
341};
342
343// ciMethodData
344//
345// This class represents a MethodData* in the HotSpot virtual
346// machine.
347
348class ciMethodData : public ciMetadata {
349  CI_PACKAGE_ACCESS
350  friend class ciReplay;
351
352private:
353  // Size in bytes
354  int _data_size;
355  int _extra_data_size;
356
357  // Data entries
358  intptr_t* _data;
359
360  // Cached hint for data_before()
361  int _hint_di;
362
363  // Is data attached?  And is it mature?
364  enum { empty_state, immature_state, mature_state };
365  u_char _state;
366
367  // Set this true if empty extra_data slots are ever witnessed.
368  u_char _saw_free_extra_data;
369
370  // Support for interprocedural escape analysis
371  intx              _eflags;          // flags on escape information
372  intx              _arg_local;       // bit set of non-escaping arguments
373  intx              _arg_stack;       // bit set of stack-allocatable arguments
374  intx              _arg_returned;    // bit set of returned arguments
375
376  // Maturity of the oop when the snapshot is taken.
377  int _current_mileage;
378
379  // These counters hold the age of MDO in tiered. In tiered we can have the same method
380  // running at different compilation levels concurrently. So, in order to precisely measure
381  // its maturity we need separate counters.
382  int _invocation_counter;
383  int _backedge_counter;
384
385  // Coherent snapshot of original header.
386  MethodData _orig;
387
388  // Dedicated area dedicated to parameters. Null if no parameter
389  // profiling for this method.
390  DataLayout* _parameters;
391
392  ciMethodData(MethodData* md);
393  ciMethodData();
394
395  // Accessors
396  int data_size() const { return _data_size; }
397  int extra_data_size() const { return _extra_data_size; }
398  intptr_t * data() const { return _data; }
399
400  MethodData* get_MethodData() const {
401    return (MethodData*)_metadata;
402  }
403
404  const char* type_string()                      { return "ciMethodData"; }
405
406  void print_impl(outputStream* st);
407
408  DataLayout* data_layout_at(int data_index) const {
409    assert(data_index % sizeof(intptr_t) == 0, "unaligned");
410    return (DataLayout*) (((address)_data) + data_index);
411  }
412
413  bool out_of_bounds(int data_index) {
414    return data_index >= data_size();
415  }
416
417  // hint accessors
418  int      hint_di() const  { return _hint_di; }
419  void set_hint_di(int di)  {
420    assert(!out_of_bounds(di), "hint_di out of bounds");
421    _hint_di = di;
422  }
423  ciProfileData* data_before(int bci) {
424    // avoid SEGV on this edge case
425    if (data_size() == 0)
426      return NULL;
427    int hint = hint_di();
428    if (data_layout_at(hint)->bci() <= bci)
429      return data_at(hint);
430    return first_data();
431  }
432
433
434  // What is the index of the first data entry?
435  int first_di() { return 0; }
436
437  ciArgInfoData *arg_info() const;
438
439public:
440  bool is_method_data() const { return true; }
441
442  bool is_empty()  { return _state == empty_state; }
443  bool is_mature() { return _state == mature_state; }
444
445  int creation_mileage() { return _orig.creation_mileage(); }
446  int current_mileage()  { return _current_mileage; }
447
448  int invocation_count() { return _invocation_counter; }
449  int backedge_count()   { return _backedge_counter;   }
450  // Transfer information about the method to MethodData*.
451  // would_profile means we would like to profile this method,
452  // meaning it's not trivial.
453  void set_would_profile(bool p);
454  // Also set the numer of loops and blocks in the method.
455  // Again, this is used to determine if a method is trivial.
456  void set_compilation_stats(short loops, short blocks);
457  // If the compiler finds a profiled type that is known statically
458  // for sure, set it in the MethodData
459  void set_argument_type(int bci, int i, ciKlass* k);
460  void set_parameter_type(int i, ciKlass* k);
461  void set_return_type(int bci, ciKlass* k);
462
463  void load_data();
464
465  // Convert a dp (data pointer) to a di (data index).
466  int dp_to_di(address dp) {
467    return dp - ((address)_data);
468  }
469
470  // Get the data at an arbitrary (sort of) data index.
471  ciProfileData* data_at(int data_index);
472
473  // Walk through the data in order.
474  ciProfileData* first_data() { return data_at(first_di()); }
475  ciProfileData* next_data(ciProfileData* current);
476  bool is_valid(ciProfileData* current) { return current != NULL; }
477
478  // Get the data at an arbitrary bci, or NULL if there is none.
479  ciProfileData* bci_to_data(int bci);
480  ciProfileData* bci_to_extra_data(int bci, bool create_if_missing);
481
482  uint overflow_trap_count() const {
483    return _orig.overflow_trap_count();
484  }
485  uint overflow_recompile_count() const {
486    return _orig.overflow_recompile_count();
487  }
488  uint decompile_count() const {
489    return _orig.decompile_count();
490  }
491  uint trap_count(int reason) const {
492    return _orig.trap_count(reason);
493  }
494  uint trap_reason_limit() const { return _orig.trap_reason_limit(); }
495  uint trap_count_limit()  const { return _orig.trap_count_limit(); }
496
497  // Helpful query functions that decode trap_state.
498  int has_trap_at(ciProfileData* data, int reason);
499  int has_trap_at(int bci, int reason) {
500    return has_trap_at(bci_to_data(bci), reason);
501  }
502  int trap_recompiled_at(ciProfileData* data);
503  int trap_recompiled_at(int bci) {
504    return trap_recompiled_at(bci_to_data(bci));
505  }
506
507  void clear_escape_info();
508  bool has_escape_info();
509  void update_escape_info();
510
511  void set_eflag(MethodData::EscapeFlag f);
512  void clear_eflag(MethodData::EscapeFlag f);
513  bool eflag_set(MethodData::EscapeFlag f) const;
514
515  void set_arg_local(int i);
516  void set_arg_stack(int i);
517  void set_arg_returned(int i);
518  void set_arg_modified(int arg, uint val);
519
520  bool is_arg_local(int i) const;
521  bool is_arg_stack(int i) const;
522  bool is_arg_returned(int i) const;
523  uint arg_modified(int arg) const;
524
525  ciParametersTypeData* parameters_type_data() const {
526    return _parameters != NULL ? new ciParametersTypeData(_parameters) : NULL;
527  }
528
529  // Code generation helper
530  ByteSize offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data);
531  int      byte_offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) { return in_bytes(offset_of_slot(data, slot_offset_in_data)); }
532
533#ifndef PRODUCT
534  // printing support for method data
535  void print();
536  void print_data_on(outputStream* st);
537#endif
538  void dump_replay_data(outputStream* out);
539};
540
541#endif // SHARE_VM_CI_CIMETHODDATA_HPP
542