comparison src/share/vm/oops/methodData.cpp @ 14674:53ed0f89f44e

8035841: assert(dp_src->tag() == dp_dst->tag()) failed: should be same tags 1 != 0 at ciMethodData.cpp:90 Summary: concurrent update of traps with construction of ciMethodData Reviewed-by: kvn, twisti
author roland
date Wed, 05 Mar 2014 09:29:12 +0100
parents fdad2932c73f
children b51e29501f30
comparison
equal deleted inserted replaced
14671:77ca9a58fbe8 14674:53ed0f89f44e
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() {