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