Mercurial > hg > graal-jvmci-8
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() { |