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