hotspot/src/share/vm/oops/methodData.cpp
changeset 23201 6920163f479e
parent 22916 582da2ed4dfa
child 23491 f690330b10b9
equal deleted inserted replaced
23198:5c8e61b02988 23201:6920163f479e
  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() {