1069 parameters_type_data()->post_initialize(NULL, this); |
1069 parameters_type_data()->post_initialize(NULL, this); |
1070 } |
1070 } |
1071 } |
1071 } |
1072 |
1072 |
1073 // Initialize the MethodData* corresponding to a given method. |
1073 // Initialize the MethodData* corresponding to a given method. |
1074 MethodData::MethodData(methodHandle method, int size, TRAPS) { |
1074 MethodData::MethodData(methodHandle method, int size, TRAPS) |
|
1075 : _extra_data_lock(Monitor::leaf, "MDO extra data lock") { |
1075 No_Safepoint_Verifier no_safepoint; // init function atomic wrt GC |
1076 No_Safepoint_Verifier no_safepoint; // init function atomic wrt GC |
1076 ResourceMark rm; |
1077 ResourceMark rm; |
1077 // Set the method back-pointer. |
1078 // Set the method back-pointer. |
1078 _method = method(); |
1079 _method = method(); |
1079 |
1080 |
1233 fatal(err_msg("unexpected tag %d", dp->tag())); |
1234 fatal(err_msg("unexpected tag %d", dp->tag())); |
1234 } |
1235 } |
1235 return (DataLayout*)((address)dp + DataLayout::compute_size_in_bytes(nb_cells)); |
1236 return (DataLayout*)((address)dp + DataLayout::compute_size_in_bytes(nb_cells)); |
1236 } |
1237 } |
1237 |
1238 |
1238 ProfileData* MethodData::bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp) { |
1239 ProfileData* MethodData::bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp, bool concurrent) { |
1239 DataLayout* end = extra_data_limit(); |
1240 DataLayout* end = extra_data_limit(); |
1240 |
1241 |
1241 for (;; dp = next_extra(dp)) { |
1242 for (;; dp = next_extra(dp)) { |
1242 assert(dp < end, "moved past end of extra data"); |
1243 assert(dp < end, "moved past end of extra data"); |
1243 // No need for "OrderAccess::load_acquire" ops, |
1244 // No need for "OrderAccess::load_acquire" ops, |
1255 break; |
1256 break; |
1256 case DataLayout::speculative_trap_data_tag: |
1257 case DataLayout::speculative_trap_data_tag: |
1257 if (m != NULL) { |
1258 if (m != NULL) { |
1258 SpeculativeTrapData* data = new SpeculativeTrapData(dp); |
1259 SpeculativeTrapData* data = new SpeculativeTrapData(dp); |
1259 // data->method() may be null in case of a concurrent |
1260 // data->method() may be null in case of a concurrent |
1260 // allocation. Assume it's for the same method and use that |
1261 // allocation. Maybe it's for the same method. Try to use that |
1261 // entry in that case. |
1262 // entry in that case. |
1262 if (dp->bci() == bci) { |
1263 if (dp->bci() == bci) { |
1263 if (data->method() == NULL) { |
1264 if (data->method() == NULL) { |
|
1265 assert(concurrent, "impossible because no concurrent allocation"); |
1264 return NULL; |
1266 return NULL; |
1265 } else if (data->method() == m) { |
1267 } else if (data->method() == m) { |
1266 return data; |
1268 return data; |
1267 } |
1269 } |
1268 } |
1270 } |
1287 DataLayout* end = extra_data_limit(); |
1289 DataLayout* end = extra_data_limit(); |
1288 |
1290 |
1289 // Allocation in the extra data space has to be atomic because not |
1291 // Allocation in the extra data space has to be atomic because not |
1290 // all entries have the same size and non atomic concurrent |
1292 // all entries have the same size and non atomic concurrent |
1291 // allocation would result in a corrupted extra data space. |
1293 // allocation would result in a corrupted extra data space. |
1292 while (true) { |
1294 ProfileData* result = bci_to_extra_data_helper(bci, m, dp, true); |
1293 ProfileData* result = bci_to_extra_data_helper(bci, m, dp); |
1295 if (result != NULL) { |
1294 if (result != NULL) { |
1296 return result; |
|
1297 } |
|
1298 |
|
1299 if (create_if_missing && dp < end) { |
|
1300 MutexLocker ml(&_extra_data_lock); |
|
1301 // Check again now that we have the lock. Another thread may |
|
1302 // have added extra data entries. |
|
1303 ProfileData* result = bci_to_extra_data_helper(bci, m, dp, false); |
|
1304 if (result != NULL || dp >= end) { |
1295 return result; |
1305 return result; |
1296 } |
1306 } |
1297 |
1307 |
1298 if (create_if_missing && dp < end) { |
1308 assert(dp->tag() == DataLayout::no_tag || (dp->tag() == DataLayout::speculative_trap_data_tag && m != NULL), "should be free"); |
1299 assert(dp->tag() == DataLayout::no_tag || (dp->tag() == DataLayout::speculative_trap_data_tag && m != NULL), "should be free"); |
1309 assert(next_extra(dp)->tag() == DataLayout::no_tag || next_extra(dp)->tag() == DataLayout::arg_info_data_tag, "should be free or arg info"); |
1300 assert(next_extra(dp)->tag() == DataLayout::no_tag || next_extra(dp)->tag() == DataLayout::arg_info_data_tag, "should be free or arg info"); |
1310 u1 tag = m == NULL ? DataLayout::bit_data_tag : DataLayout::speculative_trap_data_tag; |
1301 u1 tag = m == NULL ? DataLayout::bit_data_tag : DataLayout::speculative_trap_data_tag; |
1311 // SpeculativeTrapData is 2 slots. Make sure we have room. |
1302 // SpeculativeTrapData is 2 slots. Make sure we have room. |
1312 if (m != NULL && next_extra(dp)->tag() != DataLayout::no_tag) { |
1303 if (m != NULL && next_extra(dp)->tag() != DataLayout::no_tag) { |
1313 return NULL; |
1304 return NULL; |
1314 } |
1305 } |
1315 DataLayout temp; |
1306 DataLayout temp; |
1316 temp.initialize(tag, bci, 0); |
1307 temp.initialize(tag, bci, 0); |
1317 |
1308 // May have been set concurrently |
1318 dp->set_header(temp.header()); |
1309 if (dp->header() != temp.header() && !dp->atomic_set_header(temp.header())) { |
1319 assert(dp->tag() == tag, "sane"); |
1310 // Allocation failure because of concurrent allocation. Try |
1320 assert(dp->bci() == bci, "no concurrent allocation"); |
1311 // again. |
1321 if (tag == DataLayout::bit_data_tag) { |
1312 continue; |
1322 return new BitData(dp); |
1313 } |
1323 } else { |
1314 assert(dp->tag() == tag, "sane"); |
1324 SpeculativeTrapData* data = new SpeculativeTrapData(dp); |
1315 assert(dp->bci() == bci, "no concurrent allocation"); |
1325 data->set_method(m); |
1316 if (tag == DataLayout::bit_data_tag) { |
1326 return data; |
1317 return new BitData(dp); |
1327 } |
1318 } else { |
|
1319 // If being allocated concurrently, one trap may be lost |
|
1320 SpeculativeTrapData* data = new SpeculativeTrapData(dp); |
|
1321 data->set_method(m); |
|
1322 return data; |
|
1323 } |
|
1324 } |
|
1325 return NULL; |
|
1326 } |
1328 } |
1327 return NULL; |
1329 return NULL; |
1328 } |
1330 } |
1329 |
1331 |
1330 ArgInfoData *MethodData::arg_info() { |
1332 ArgInfoData *MethodData::arg_info() { |