Mercurial > hg > truffle
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() { |