comparison src/share/vm/oops/methodData.cpp @ 17733:1a43981d86ea

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