src/share/vm/oops/methodData.hpp

changeset 6377
b8413a9cbb84
parent 6105
6e1826d5c23e
child 6382
1a43981d86ea
     1.1 --- a/src/share/vm/oops/methodData.hpp	Mon Jan 27 13:14:53 2014 +0100
     1.2 +++ b/src/share/vm/oops/methodData.hpp	Tue Feb 25 18:16:24 2014 +0100
     1.3 @@ -120,7 +120,8 @@
     1.4      arg_info_data_tag,
     1.5      call_type_data_tag,
     1.6      virtual_call_type_data_tag,
     1.7 -    parameters_type_data_tag
     1.8 +    parameters_type_data_tag,
     1.9 +    speculative_trap_data_tag
    1.10    };
    1.11  
    1.12    enum {
    1.13 @@ -189,8 +190,11 @@
    1.14    void set_header(intptr_t value) {
    1.15      _header._bits = value;
    1.16    }
    1.17 -  void release_set_header(intptr_t value) {
    1.18 -    OrderAccess::release_store_ptr(&_header._bits, value);
    1.19 +  bool atomic_set_header(intptr_t value) {
    1.20 +    if (Atomic::cmpxchg_ptr(value, (volatile intptr_t*)&_header._bits, 0) == 0) {
    1.21 +      return true;
    1.22 +    }
    1.23 +    return false;
    1.24    }
    1.25    intptr_t header() {
    1.26      return _header._bits;
    1.27 @@ -266,6 +270,7 @@
    1.28  class     MultiBranchData;
    1.29  class     ArgInfoData;
    1.30  class     ParametersTypeData;
    1.31 +class   SpeculativeTrapData;
    1.32  
    1.33  // ProfileData
    1.34  //
    1.35 @@ -286,6 +291,8 @@
    1.36    // This is a pointer to a section of profiling data.
    1.37    DataLayout* _data;
    1.38  
    1.39 +  char* print_data_on_helper(const MethodData* md) const;
    1.40 +
    1.41  protected:
    1.42    DataLayout* data() { return _data; }
    1.43    const DataLayout* data() const { return _data; }
    1.44 @@ -400,6 +407,7 @@
    1.45    virtual bool is_CallTypeData()    const { return false; }
    1.46    virtual bool is_VirtualCallTypeData()const { return false; }
    1.47    virtual bool is_ParametersTypeData() const { return false; }
    1.48 +  virtual bool is_SpeculativeTrapData()const { return false; }
    1.49  
    1.50  
    1.51    BitData* as_BitData() const {
    1.52 @@ -454,6 +462,10 @@
    1.53      assert(is_ParametersTypeData(), "wrong type");
    1.54      return is_ParametersTypeData() ? (ParametersTypeData*)this : NULL;
    1.55    }
    1.56 +  SpeculativeTrapData* as_SpeculativeTrapData() const {
    1.57 +    assert(is_SpeculativeTrapData(), "wrong type");
    1.58 +    return is_SpeculativeTrapData() ? (SpeculativeTrapData*)this : NULL;
    1.59 +  }
    1.60  
    1.61  
    1.62    // Subclass specific initialization
    1.63 @@ -469,12 +481,14 @@
    1.64    // translation here, and the required translators are in the ci subclasses.
    1.65    virtual void translate_from(const ProfileData* data) {}
    1.66  
    1.67 -  virtual void print_data_on(outputStream* st) const {
    1.68 +  virtual void print_data_on(outputStream* st, const char* extra = NULL) const {
    1.69      ShouldNotReachHere();
    1.70    }
    1.71  
    1.72 +  void print_data_on(outputStream* st, const MethodData* md) const;
    1.73 +
    1.74  #ifndef PRODUCT
    1.75 -  void print_shared(outputStream* st, const char* name) const;
    1.76 +  void print_shared(outputStream* st, const char* name, const char* extra) const;
    1.77    void tab(outputStream* st, bool first = false) const;
    1.78  #endif
    1.79  };
    1.80 @@ -522,7 +536,7 @@
    1.81    }
    1.82  
    1.83  #ifndef PRODUCT
    1.84 -  void print_data_on(outputStream* st) const;
    1.85 +  void print_data_on(outputStream* st, const char* extra = NULL) const;
    1.86  #endif
    1.87  };
    1.88  
    1.89 @@ -566,7 +580,7 @@
    1.90    }
    1.91  
    1.92  #ifndef PRODUCT
    1.93 -  void print_data_on(outputStream* st) const;
    1.94 +  void print_data_on(outputStream* st, const char* extra = NULL) const;
    1.95  #endif
    1.96  };
    1.97  
    1.98 @@ -639,7 +653,7 @@
    1.99    void post_initialize(BytecodeStream* stream, MethodData* mdo);
   1.100  
   1.101  #ifndef PRODUCT
   1.102 -  void print_data_on(outputStream* st) const;
   1.103 +  void print_data_on(outputStream* st, const char* extra = NULL) const;
   1.104  #endif
   1.105  };
   1.106  
   1.107 @@ -1050,7 +1064,7 @@
   1.108    }
   1.109  
   1.110  #ifndef PRODUCT
   1.111 -  virtual void print_data_on(outputStream* st) const;
   1.112 +  virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
   1.113  #endif
   1.114  };
   1.115  
   1.116 @@ -1158,7 +1172,7 @@
   1.117  
   1.118  #ifndef PRODUCT
   1.119    void print_receiver_data_on(outputStream* st) const;
   1.120 -  void print_data_on(outputStream* st) const;
   1.121 +  void print_data_on(outputStream* st, const char* extra = NULL) const;
   1.122  #endif
   1.123  };
   1.124  
   1.125 @@ -1191,7 +1205,7 @@
   1.126    }
   1.127  
   1.128  #ifndef PRODUCT
   1.129 -  void print_data_on(outputStream* st) const;
   1.130 +  void print_data_on(outputStream* st, const char* extra = NULL) const;
   1.131  #endif
   1.132  };
   1.133  
   1.134 @@ -1317,7 +1331,7 @@
   1.135    }
   1.136  
   1.137  #ifndef PRODUCT
   1.138 -  virtual void print_data_on(outputStream* st) const;
   1.139 +  virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
   1.140  #endif
   1.141  };
   1.142  
   1.143 @@ -1416,7 +1430,7 @@
   1.144    void post_initialize(BytecodeStream* stream, MethodData* mdo);
   1.145  
   1.146  #ifndef PRODUCT
   1.147 -  void print_data_on(outputStream* st) const;
   1.148 +  void print_data_on(outputStream* st, const char* extra = NULL) const;
   1.149  #endif
   1.150  };
   1.151  
   1.152 @@ -1480,7 +1494,7 @@
   1.153    void post_initialize(BytecodeStream* stream, MethodData* mdo);
   1.154  
   1.155  #ifndef PRODUCT
   1.156 -  void print_data_on(outputStream* st) const;
   1.157 +  void print_data_on(outputStream* st, const char* extra = NULL) const;
   1.158  #endif
   1.159  };
   1.160  
   1.161 @@ -1637,7 +1651,7 @@
   1.162    void post_initialize(BytecodeStream* stream, MethodData* mdo);
   1.163  
   1.164  #ifndef PRODUCT
   1.165 -  void print_data_on(outputStream* st) const;
   1.166 +  void print_data_on(outputStream* st, const char* extra = NULL) const;
   1.167  #endif
   1.168  };
   1.169  
   1.170 @@ -1664,7 +1678,7 @@
   1.171    }
   1.172  
   1.173  #ifndef PRODUCT
   1.174 -  void print_data_on(outputStream* st) const;
   1.175 +  void print_data_on(outputStream* st, const char* extra = NULL) const;
   1.176  #endif
   1.177  };
   1.178  
   1.179 @@ -1725,7 +1739,7 @@
   1.180    }
   1.181  
   1.182  #ifndef PRODUCT
   1.183 -  virtual void print_data_on(outputStream* st) const;
   1.184 +  virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
   1.185  #endif
   1.186  
   1.187    static ByteSize stack_slot_offset(int i) {
   1.188 @@ -1737,6 +1751,54 @@
   1.189    }
   1.190  };
   1.191  
   1.192 +// SpeculativeTrapData
   1.193 +//
   1.194 +// A SpeculativeTrapData is used to record traps due to type
   1.195 +// speculation. It records the root of the compilation: that type
   1.196 +// speculation is wrong in the context of one compilation (for
   1.197 +// method1) doesn't mean it's wrong in the context of another one (for
   1.198 +// method2). Type speculation could have more/different data in the
   1.199 +// context of the compilation of method2 and it's worthwhile to try an
   1.200 +// optimization that failed for compilation of method1 in the context
   1.201 +// of compilation of method2.
   1.202 +// Space for SpeculativeTrapData entries is allocated from the extra
   1.203 +// data space in the MDO. If we run out of space, the trap data for
   1.204 +// the ProfileData at that bci is updated.
   1.205 +class SpeculativeTrapData : public ProfileData {
   1.206 +protected:
   1.207 +  enum {
   1.208 +    method_offset,
   1.209 +    speculative_trap_cell_count
   1.210 +  };
   1.211 +public:
   1.212 +  SpeculativeTrapData(DataLayout* layout) : ProfileData(layout) {
   1.213 +    assert(layout->tag() == DataLayout::speculative_trap_data_tag, "wrong type");
   1.214 +  }
   1.215 +
   1.216 +  virtual bool is_SpeculativeTrapData() const { return true; }
   1.217 +
   1.218 +  static int static_cell_count() {
   1.219 +    return speculative_trap_cell_count;
   1.220 +  }
   1.221 +
   1.222 +  virtual int cell_count() const {
   1.223 +    return static_cell_count();
   1.224 +  }
   1.225 +
   1.226 +  // Direct accessor
   1.227 +  Method* method() const {
   1.228 +    return (Method*)intptr_at(method_offset);
   1.229 +  }
   1.230 +
   1.231 +  void set_method(Method* m) {
   1.232 +    set_intptr_at(method_offset, (intptr_t)m);
   1.233 +  }
   1.234 +
   1.235 +#ifndef PRODUCT
   1.236 +  virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
   1.237 +#endif
   1.238 +};
   1.239 +
   1.240  // MethodData*
   1.241  //
   1.242  // A MethodData* holds information which has been collected about
   1.243 @@ -1803,7 +1865,7 @@
   1.244  
   1.245    // Whole-method sticky bits and flags
   1.246    enum {
   1.247 -    _trap_hist_limit    = 17,   // decoupled from Deoptimization::Reason_LIMIT
   1.248 +    _trap_hist_limit    = 18,   // decoupled from Deoptimization::Reason_LIMIT
   1.249      _trap_hist_mask     = max_jubyte,
   1.250      _extra_data_count   = 4     // extra DataLayout headers, for trap history
   1.251    }; // Public flag values
   1.252 @@ -1858,6 +1920,7 @@
   1.253    // Helper for size computation
   1.254    static int compute_data_size(BytecodeStream* stream);
   1.255    static int bytecode_cell_count(Bytecodes::Code code);
   1.256 +  static bool is_speculative_trap_bytecode(Bytecodes::Code code);
   1.257    enum { no_profile_data = -1, variable_cell_count = -2 };
   1.258  
   1.259    // Helper for initialization
   1.260 @@ -1901,8 +1964,9 @@
   1.261    // What is the index of the first data entry?
   1.262    int first_di() const { return 0; }
   1.263  
   1.264 +  ProfileData* bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp);
   1.265    // Find or create an extra ProfileData:
   1.266 -  ProfileData* bci_to_extra_data(int bci, bool create_if_missing);
   1.267 +  ProfileData* bci_to_extra_data(int bci, Method* m, bool create_if_missing);
   1.268  
   1.269    // return the argument info cell
   1.270    ArgInfoData *arg_info();
   1.271 @@ -1925,6 +1989,10 @@
   1.272    static bool profile_parameters_jsr292_only();
   1.273    static bool profile_all_parameters();
   1.274  
   1.275 +  void clean_extra_data(BoolObjectClosure* is_alive);
   1.276 +  void clean_extra_data_helper(DataLayout* dp, int shift, bool reset = false);
   1.277 +  void verify_extra_data_clean(BoolObjectClosure* is_alive);
   1.278 +
   1.279  public:
   1.280    static int header_size() {
   1.281      return sizeof(MethodData)/wordSize;
   1.282 @@ -1933,7 +2001,7 @@
   1.283    // Compute the size of a MethodData* before it is created.
   1.284    static int compute_allocation_size_in_bytes(methodHandle method);
   1.285    static int compute_allocation_size_in_words(methodHandle method);
   1.286 -  static int compute_extra_data_count(int data_size, int empty_bc_count);
   1.287 +  static int compute_extra_data_count(int data_size, int empty_bc_count, bool needs_speculative_traps);
   1.288  
   1.289    // Determine if a given bytecode can have profile information.
   1.290    static bool bytecode_has_profile(Bytecodes::Code code) {
   1.291 @@ -2074,9 +2142,26 @@
   1.292    ProfileData* bci_to_data(int bci);
   1.293  
   1.294    // Same, but try to create an extra_data record if one is needed:
   1.295 -  ProfileData* allocate_bci_to_data(int bci) {
   1.296 -    ProfileData* data = bci_to_data(bci);
   1.297 -    return (data != NULL) ? data : bci_to_extra_data(bci, true);
   1.298 +  ProfileData* allocate_bci_to_data(int bci, Method* m) {
   1.299 +    ProfileData* data = NULL;
   1.300 +    // If m not NULL, try to allocate a SpeculativeTrapData entry
   1.301 +    if (m == NULL) {
   1.302 +      data = bci_to_data(bci);
   1.303 +    }
   1.304 +    if (data != NULL) {
   1.305 +      return data;
   1.306 +    }
   1.307 +    data = bci_to_extra_data(bci, m, true);
   1.308 +    if (data != NULL) {
   1.309 +      return data;
   1.310 +    }
   1.311 +    // If SpeculativeTrapData allocation fails try to allocate a
   1.312 +    // regular entry
   1.313 +    data = bci_to_data(bci);
   1.314 +    if (data != NULL) {
   1.315 +      return data;
   1.316 +    }
   1.317 +    return bci_to_extra_data(bci, NULL, true);
   1.318    }
   1.319  
   1.320    // Add a handful of extra data records, for trap tracking.
   1.321 @@ -2084,7 +2169,7 @@
   1.322    DataLayout* extra_data_limit() const { return (DataLayout*)((address)this + size_in_bytes()); }
   1.323    int extra_data_size() const { return (address)extra_data_limit()
   1.324                                 - (address)extra_data_base(); }
   1.325 -  static DataLayout* next_extra(DataLayout* dp) { return (DataLayout*)((address)dp + in_bytes(DataLayout::cell_offset(0))); }
   1.326 +  static DataLayout* next_extra(DataLayout* dp);
   1.327  
   1.328    // Return (uint)-1 for overflow.
   1.329    uint trap_count(int reason) const {
   1.330 @@ -2184,6 +2269,8 @@
   1.331    static bool profile_return();
   1.332    static bool profile_parameters();
   1.333    static bool profile_return_jsr292_only();
   1.334 +
   1.335 +  void clean_method_data(BoolObjectClosure* is_alive);
   1.336  };
   1.337  
   1.338  #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP

mercurial