1.1 --- a/src/share/vm/oops/methodData.hpp Tue Mar 25 12:54:21 2014 -0700 1.2 +++ b/src/share/vm/oops/methodData.hpp Tue Mar 25 17:07:36 2014 -0700 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,9 +190,6 @@ 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 - } 1.20 intptr_t header() { 1.21 return _header._bits; 1.22 } 1.23 @@ -271,6 +269,7 @@ 1.24 class MultiBranchData; 1.25 class ArgInfoData; 1.26 class ParametersTypeData; 1.27 +class SpeculativeTrapData; 1.28 1.29 // ProfileData 1.30 // 1.31 @@ -291,6 +290,8 @@ 1.32 // This is a pointer to a section of profiling data. 1.33 DataLayout* _data; 1.34 1.35 + char* print_data_on_helper(const MethodData* md) const; 1.36 + 1.37 protected: 1.38 DataLayout* data() { return _data; } 1.39 const DataLayout* data() const { return _data; } 1.40 @@ -440,6 +441,7 @@ 1.41 virtual bool is_CallTypeData() const { return false; } 1.42 virtual bool is_VirtualCallTypeData()const { return false; } 1.43 virtual bool is_ParametersTypeData() const { return false; } 1.44 + virtual bool is_SpeculativeTrapData()const { return false; } 1.45 1.46 1.47 BitData* as_BitData() const { 1.48 @@ -494,6 +496,10 @@ 1.49 assert(is_ParametersTypeData(), "wrong type"); 1.50 return is_ParametersTypeData() ? (ParametersTypeData*)this : NULL; 1.51 } 1.52 + SpeculativeTrapData* as_SpeculativeTrapData() const { 1.53 + assert(is_SpeculativeTrapData(), "wrong type"); 1.54 + return is_SpeculativeTrapData() ? (SpeculativeTrapData*)this : NULL; 1.55 + } 1.56 1.57 1.58 // Subclass specific initialization 1.59 @@ -509,12 +515,14 @@ 1.60 // translation here, and the required translators are in the ci subclasses. 1.61 virtual void translate_from(const ProfileData* data) {} 1.62 1.63 - virtual void print_data_on(outputStream* st) const { 1.64 + virtual void print_data_on(outputStream* st, const char* extra = NULL) const { 1.65 ShouldNotReachHere(); 1.66 } 1.67 1.68 + void print_data_on(outputStream* st, const MethodData* md) const; 1.69 + 1.70 #ifndef PRODUCT 1.71 - void print_shared(outputStream* st, const char* name) const; 1.72 + void print_shared(outputStream* st, const char* name, const char* extra) const; 1.73 void tab(outputStream* st, bool first = false) const; 1.74 #endif 1.75 }; 1.76 @@ -576,7 +584,7 @@ 1.77 #endif // CC_INTERP 1.78 1.79 #ifndef PRODUCT 1.80 - void print_data_on(outputStream* st) const; 1.81 + void print_data_on(outputStream* st, const char* extra = NULL) const; 1.82 #endif 1.83 }; 1.84 1.85 @@ -639,7 +647,7 @@ 1.86 #endif // CC_INTERP 1.87 1.88 #ifndef PRODUCT 1.89 - void print_data_on(outputStream* st) const; 1.90 + void print_data_on(outputStream* st, const char* extra = NULL) const; 1.91 #endif 1.92 }; 1.93 1.94 @@ -726,7 +734,7 @@ 1.95 void post_initialize(BytecodeStream* stream, MethodData* mdo); 1.96 1.97 #ifndef PRODUCT 1.98 - void print_data_on(outputStream* st) const; 1.99 + void print_data_on(outputStream* st, const char* extra = NULL) const; 1.100 #endif 1.101 }; 1.102 1.103 @@ -1137,7 +1145,7 @@ 1.104 } 1.105 1.106 #ifndef PRODUCT 1.107 - virtual void print_data_on(outputStream* st) const; 1.108 + virtual void print_data_on(outputStream* st, const char* extra = NULL) const; 1.109 #endif 1.110 }; 1.111 1.112 @@ -1282,7 +1290,7 @@ 1.113 1.114 #ifndef PRODUCT 1.115 void print_receiver_data_on(outputStream* st) const; 1.116 - void print_data_on(outputStream* st) const; 1.117 + void print_data_on(outputStream* st, const char* extra = NULL) const; 1.118 #endif 1.119 }; 1.120 1.121 @@ -1325,7 +1333,7 @@ 1.122 #endif // CC_INTERP 1.123 1.124 #ifndef PRODUCT 1.125 - void print_data_on(outputStream* st) const; 1.126 + void print_data_on(outputStream* st, const char* extra = NULL) const; 1.127 #endif 1.128 }; 1.129 1.130 @@ -1451,7 +1459,7 @@ 1.131 } 1.132 1.133 #ifndef PRODUCT 1.134 - virtual void print_data_on(outputStream* st) const; 1.135 + virtual void print_data_on(outputStream* st, const char* extra = NULL) const; 1.136 #endif 1.137 }; 1.138 1.139 @@ -1554,7 +1562,7 @@ 1.140 void post_initialize(BytecodeStream* stream, MethodData* mdo); 1.141 1.142 #ifndef PRODUCT 1.143 - void print_data_on(outputStream* st) const; 1.144 + void print_data_on(outputStream* st, const char* extra = NULL) const; 1.145 #endif 1.146 }; 1.147 1.148 @@ -1632,7 +1640,7 @@ 1.149 void post_initialize(BytecodeStream* stream, MethodData* mdo); 1.150 1.151 #ifndef PRODUCT 1.152 - void print_data_on(outputStream* st) const; 1.153 + void print_data_on(outputStream* st, const char* extra = NULL) const; 1.154 #endif 1.155 }; 1.156 1.157 @@ -1825,7 +1833,7 @@ 1.158 void post_initialize(BytecodeStream* stream, MethodData* mdo); 1.159 1.160 #ifndef PRODUCT 1.161 - void print_data_on(outputStream* st) const; 1.162 + void print_data_on(outputStream* st, const char* extra = NULL) const; 1.163 #endif 1.164 }; 1.165 1.166 @@ -1852,7 +1860,7 @@ 1.167 } 1.168 1.169 #ifndef PRODUCT 1.170 - void print_data_on(outputStream* st) const; 1.171 + void print_data_on(outputStream* st, const char* extra = NULL) const; 1.172 #endif 1.173 }; 1.174 1.175 @@ -1913,7 +1921,7 @@ 1.176 } 1.177 1.178 #ifndef PRODUCT 1.179 - virtual void print_data_on(outputStream* st) const; 1.180 + virtual void print_data_on(outputStream* st, const char* extra = NULL) const; 1.181 #endif 1.182 1.183 static ByteSize stack_slot_offset(int i) { 1.184 @@ -1925,6 +1933,54 @@ 1.185 } 1.186 }; 1.187 1.188 +// SpeculativeTrapData 1.189 +// 1.190 +// A SpeculativeTrapData is used to record traps due to type 1.191 +// speculation. It records the root of the compilation: that type 1.192 +// speculation is wrong in the context of one compilation (for 1.193 +// method1) doesn't mean it's wrong in the context of another one (for 1.194 +// method2). Type speculation could have more/different data in the 1.195 +// context of the compilation of method2 and it's worthwhile to try an 1.196 +// optimization that failed for compilation of method1 in the context 1.197 +// of compilation of method2. 1.198 +// Space for SpeculativeTrapData entries is allocated from the extra 1.199 +// data space in the MDO. If we run out of space, the trap data for 1.200 +// the ProfileData at that bci is updated. 1.201 +class SpeculativeTrapData : public ProfileData { 1.202 +protected: 1.203 + enum { 1.204 + method_offset, 1.205 + speculative_trap_cell_count 1.206 + }; 1.207 +public: 1.208 + SpeculativeTrapData(DataLayout* layout) : ProfileData(layout) { 1.209 + assert(layout->tag() == DataLayout::speculative_trap_data_tag, "wrong type"); 1.210 + } 1.211 + 1.212 + virtual bool is_SpeculativeTrapData() const { return true; } 1.213 + 1.214 + static int static_cell_count() { 1.215 + return speculative_trap_cell_count; 1.216 + } 1.217 + 1.218 + virtual int cell_count() const { 1.219 + return static_cell_count(); 1.220 + } 1.221 + 1.222 + // Direct accessor 1.223 + Method* method() const { 1.224 + return (Method*)intptr_at(method_offset); 1.225 + } 1.226 + 1.227 + void set_method(Method* m) { 1.228 + set_intptr_at(method_offset, (intptr_t)m); 1.229 + } 1.230 + 1.231 +#ifndef PRODUCT 1.232 + virtual void print_data_on(outputStream* st, const char* extra = NULL) const; 1.233 +#endif 1.234 +}; 1.235 + 1.236 // MethodData* 1.237 // 1.238 // A MethodData* holds information which has been collected about 1.239 @@ -1985,16 +2041,18 @@ 1.240 // Cached hint for bci_to_dp and bci_to_data 1.241 int _hint_di; 1.242 1.243 + Mutex _extra_data_lock; 1.244 + 1.245 MethodData(methodHandle method, int size, TRAPS); 1.246 public: 1.247 static MethodData* allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS); 1.248 - MethodData() {}; // For ciMethodData 1.249 + MethodData() : _extra_data_lock(Monitor::leaf, "MDO extra data lock") {}; // For ciMethodData 1.250 1.251 bool is_methodData() const volatile { return true; } 1.252 1.253 // Whole-method sticky bits and flags 1.254 enum { 1.255 - _trap_hist_limit = 17, // decoupled from Deoptimization::Reason_LIMIT 1.256 + _trap_hist_limit = 19, // decoupled from Deoptimization::Reason_LIMIT 1.257 _trap_hist_mask = max_jubyte, 1.258 _extra_data_count = 4 // extra DataLayout headers, for trap history 1.259 }; // Public flag values 1.260 @@ -2025,6 +2083,12 @@ 1.261 // Counter values at the time profiling started. 1.262 int _invocation_counter_start; 1.263 int _backedge_counter_start; 1.264 + 1.265 +#if INCLUDE_RTM_OPT 1.266 + // State of RTM code generation during compilation of the method 1.267 + int _rtm_state; 1.268 +#endif 1.269 + 1.270 // Number of loops and blocks is computed when compiling the first 1.271 // time with C1. It is used to determine if method is trivial. 1.272 short _num_loops; 1.273 @@ -2049,6 +2113,7 @@ 1.274 // Helper for size computation 1.275 static int compute_data_size(BytecodeStream* stream); 1.276 static int bytecode_cell_count(Bytecodes::Code code); 1.277 + static bool is_speculative_trap_bytecode(Bytecodes::Code code); 1.278 enum { no_profile_data = -1, variable_cell_count = -2 }; 1.279 1.280 // Helper for initialization 1.281 @@ -2092,8 +2157,9 @@ 1.282 // What is the index of the first data entry? 1.283 int first_di() const { return 0; } 1.284 1.285 + ProfileData* bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp, bool concurrent); 1.286 // Find or create an extra ProfileData: 1.287 - ProfileData* bci_to_extra_data(int bci, bool create_if_missing); 1.288 + ProfileData* bci_to_extra_data(int bci, Method* m, bool create_if_missing); 1.289 1.290 // return the argument info cell 1.291 ArgInfoData *arg_info(); 1.292 @@ -2116,6 +2182,10 @@ 1.293 static bool profile_parameters_jsr292_only(); 1.294 static bool profile_all_parameters(); 1.295 1.296 + void clean_extra_data(BoolObjectClosure* is_alive); 1.297 + void clean_extra_data_helper(DataLayout* dp, int shift, bool reset = false); 1.298 + void verify_extra_data_clean(BoolObjectClosure* is_alive); 1.299 + 1.300 public: 1.301 static int header_size() { 1.302 return sizeof(MethodData)/wordSize; 1.303 @@ -2124,7 +2194,7 @@ 1.304 // Compute the size of a MethodData* before it is created. 1.305 static int compute_allocation_size_in_bytes(methodHandle method); 1.306 static int compute_allocation_size_in_words(methodHandle method); 1.307 - static int compute_extra_data_count(int data_size, int empty_bc_count); 1.308 + static int compute_extra_data_count(int data_size, int empty_bc_count, bool needs_speculative_traps); 1.309 1.310 // Determine if a given bytecode can have profile information. 1.311 static bool bytecode_has_profile(Bytecodes::Code code) { 1.312 @@ -2182,6 +2252,22 @@ 1.313 InvocationCounter* invocation_counter() { return &_invocation_counter; } 1.314 InvocationCounter* backedge_counter() { return &_backedge_counter; } 1.315 1.316 +#if INCLUDE_RTM_OPT 1.317 + int rtm_state() const { 1.318 + return _rtm_state; 1.319 + } 1.320 + void set_rtm_state(RTMState rstate) { 1.321 + _rtm_state = (int)rstate; 1.322 + } 1.323 + void atomic_set_rtm_state(RTMState rstate) { 1.324 + Atomic::store((int)rstate, &_rtm_state); 1.325 + } 1.326 + 1.327 + static int rtm_state_offset_in_bytes() { 1.328 + return offset_of(MethodData, _rtm_state); 1.329 + } 1.330 +#endif 1.331 + 1.332 void set_would_profile(bool p) { _would_profile = p; } 1.333 bool would_profile() const { return _would_profile; } 1.334 1.335 @@ -2265,9 +2351,26 @@ 1.336 ProfileData* bci_to_data(int bci); 1.337 1.338 // Same, but try to create an extra_data record if one is needed: 1.339 - ProfileData* allocate_bci_to_data(int bci) { 1.340 - ProfileData* data = bci_to_data(bci); 1.341 - return (data != NULL) ? data : bci_to_extra_data(bci, true); 1.342 + ProfileData* allocate_bci_to_data(int bci, Method* m) { 1.343 + ProfileData* data = NULL; 1.344 + // If m not NULL, try to allocate a SpeculativeTrapData entry 1.345 + if (m == NULL) { 1.346 + data = bci_to_data(bci); 1.347 + } 1.348 + if (data != NULL) { 1.349 + return data; 1.350 + } 1.351 + data = bci_to_extra_data(bci, m, true); 1.352 + if (data != NULL) { 1.353 + return data; 1.354 + } 1.355 + // If SpeculativeTrapData allocation fails try to allocate a 1.356 + // regular entry 1.357 + data = bci_to_data(bci); 1.358 + if (data != NULL) { 1.359 + return data; 1.360 + } 1.361 + return bci_to_extra_data(bci, NULL, true); 1.362 } 1.363 1.364 // Add a handful of extra data records, for trap tracking. 1.365 @@ -2275,7 +2378,7 @@ 1.366 DataLayout* extra_data_limit() const { return (DataLayout*)((address)this + size_in_bytes()); } 1.367 int extra_data_size() const { return (address)extra_data_limit() 1.368 - (address)extra_data_base(); } 1.369 - static DataLayout* next_extra(DataLayout* dp) { return (DataLayout*)((address)dp + in_bytes(DataLayout::cell_offset(0))); } 1.370 + static DataLayout* next_extra(DataLayout* dp); 1.371 1.372 // Return (uint)-1 for overflow. 1.373 uint trap_count(int reason) const { 1.374 @@ -2375,6 +2478,8 @@ 1.375 static bool profile_return(); 1.376 static bool profile_parameters(); 1.377 static bool profile_return_jsr292_only(); 1.378 + 1.379 + void clean_method_data(BoolObjectClosure* is_alive); 1.380 }; 1.381 1.382 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP