src/share/vm/oops/instanceKlass.cpp

changeset 1412
74a5db69c1fe
parent 1409
26b774d693aa
child 1432
46b819ba120b
     1.1 --- a/src/share/vm/oops/instanceKlass.cpp	Wed Sep 16 15:42:46 2009 -0400
     1.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Mon Sep 21 09:30:24 2009 -0600
     1.3 @@ -967,33 +967,78 @@
     1.4  
     1.5  
     1.6  // Lookup or create a jmethodID.
     1.7 -// This code can be called by the VM thread.  For this reason it is critical that
     1.8 -// there are no blocking operations (safepoints) while the lock is held -- or a
     1.9 -// deadlock can occur.
    1.10 -jmethodID instanceKlass::jmethod_id_for_impl(instanceKlassHandle ik_h, methodHandle method_h) {
    1.11 +// This code is called by the VMThread and JavaThreads so the
    1.12 +// locking has to be done very carefully to avoid deadlocks
    1.13 +// and/or other cache consistency problems.
    1.14 +//
    1.15 +jmethodID instanceKlass::get_jmethod_id(instanceKlassHandle ik_h, methodHandle method_h) {
    1.16    size_t idnum = (size_t)method_h->method_idnum();
    1.17    jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire();
    1.18    size_t length = 0;
    1.19    jmethodID id = NULL;
    1.20 -  // array length stored in first element, other elements offset by one
    1.21 -  if (jmeths == NULL ||                         // If there is no jmethodID array,
    1.22 -      (length = (size_t)jmeths[0]) <= idnum ||  // or if it is too short,
    1.23 -      (id = jmeths[idnum+1]) == NULL) {         // or if this jmethodID isn't allocated
    1.24  
    1.25 -    // Do all the safepointing things (allocations) before grabbing the lock.
    1.26 -    // These allocations will have to be freed if they are unused.
    1.27 +  // We use a double-check locking idiom here because this cache is
    1.28 +  // performance sensitive. In the normal system, this cache only
    1.29 +  // transitions from NULL to non-NULL which is safe because we use
    1.30 +  // release_set_methods_jmethod_ids() to advertise the new cache.
    1.31 +  // A partially constructed cache should never be seen by a racing
    1.32 +  // thread. We also use release_store_ptr() to save a new jmethodID
    1.33 +  // in the cache so a partially constructed jmethodID should never be
    1.34 +  // seen either. Cache reads of existing jmethodIDs proceed without a
    1.35 +  // lock, but cache writes of a new jmethodID requires uniqueness and
    1.36 +  // creation of the cache itself requires no leaks so a lock is
    1.37 +  // generally acquired in those two cases.
    1.38 +  //
    1.39 +  // If the RedefineClasses() API has been used, then this cache can
    1.40 +  // grow and we'll have transitions from non-NULL to bigger non-NULL.
    1.41 +  // Cache creation requires no leaks and we require safety between all
    1.42 +  // cache accesses and freeing of the old cache so a lock is generally
    1.43 +  // acquired when the RedefineClasses() API has been used.
    1.44  
    1.45 -    // Allocate a new array of methods.
    1.46 +  if (jmeths != NULL) {
    1.47 +    // the cache already exists
    1.48 +    if (!ik_h->idnum_can_increment()) {
    1.49 +      // the cache can't grow so we can just get the current values
    1.50 +      get_jmethod_id_length_value(jmeths, idnum, &length, &id);
    1.51 +    } else {
    1.52 +      // cache can grow so we have to be more careful
    1.53 +      if (Threads::number_of_threads() == 0 ||
    1.54 +          SafepointSynchronize::is_at_safepoint()) {
    1.55 +        // we're single threaded or at a safepoint - no locking needed
    1.56 +        get_jmethod_id_length_value(jmeths, idnum, &length, &id);
    1.57 +      } else {
    1.58 +        MutexLocker ml(JmethodIdCreation_lock);
    1.59 +        get_jmethod_id_length_value(jmeths, idnum, &length, &id);
    1.60 +      }
    1.61 +    }
    1.62 +  }
    1.63 +  // implied else:
    1.64 +  // we need to allocate a cache so default length and id values are good
    1.65 +
    1.66 +  if (jmeths == NULL ||   // no cache yet
    1.67 +      length <= idnum ||  // cache is too short
    1.68 +      id == NULL) {       // cache doesn't contain entry
    1.69 +
    1.70 +    // This function can be called by the VMThread so we have to do all
    1.71 +    // things that might block on a safepoint before grabbing the lock.
    1.72 +    // Otherwise, we can deadlock with the VMThread or have a cache
    1.73 +    // consistency issue. These vars keep track of what we might have
    1.74 +    // to free after the lock is dropped.
    1.75 +    jmethodID  to_dealloc_id     = NULL;
    1.76 +    jmethodID* to_dealloc_jmeths = NULL;
    1.77 +
    1.78 +    // may not allocate new_jmeths or use it if we allocate it
    1.79      jmethodID* new_jmeths = NULL;
    1.80      if (length <= idnum) {
    1.81 -      // A new array will be needed (unless some other thread beats us to it)
    1.82 +      // allocate a new cache that might be used
    1.83        size_t size = MAX2(idnum+1, (size_t)ik_h->idnum_allocated_count());
    1.84        new_jmeths = NEW_C_HEAP_ARRAY(jmethodID, size+1);
    1.85        memset(new_jmeths, 0, (size+1)*sizeof(jmethodID));
    1.86 -      new_jmeths[0] =(jmethodID)size;  // array size held in the first element
    1.87 +      // cache size is stored in element[0], other elements offset by one
    1.88 +      new_jmeths[0] = (jmethodID)size;
    1.89      }
    1.90  
    1.91 -    // Allocate a new method ID.
    1.92 +    // allocate a new jmethodID that might be used
    1.93      jmethodID new_id = NULL;
    1.94      if (method_h->is_old() && !method_h->is_obsolete()) {
    1.95        // The method passed in is old (but not obsolete), we need to use the current version
    1.96 @@ -1007,63 +1052,111 @@
    1.97        new_id = JNIHandles::make_jmethod_id(method_h);
    1.98      }
    1.99  
   1.100 -    if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) {
   1.101 -      // No need and unsafe to lock the JmethodIdCreation_lock at safepoint.
   1.102 -      id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths);
   1.103 +    if (Threads::number_of_threads() == 0 ||
   1.104 +        SafepointSynchronize::is_at_safepoint()) {
   1.105 +      // we're single threaded or at a safepoint - no locking needed
   1.106 +      id = get_jmethod_id_fetch_or_update(ik_h, idnum, new_id, new_jmeths,
   1.107 +                                          &to_dealloc_id, &to_dealloc_jmeths);
   1.108      } else {
   1.109        MutexLocker ml(JmethodIdCreation_lock);
   1.110 -      id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths);
   1.111 +      id = get_jmethod_id_fetch_or_update(ik_h, idnum, new_id, new_jmeths,
   1.112 +                                          &to_dealloc_id, &to_dealloc_jmeths);
   1.113 +    }
   1.114 +
   1.115 +    // The lock has been dropped so we can free resources.
   1.116 +    // Free up either the old cache or the new cache if we allocated one.
   1.117 +    if (to_dealloc_jmeths != NULL) {
   1.118 +      FreeHeap(to_dealloc_jmeths);
   1.119 +    }
   1.120 +    // free up the new ID since it wasn't needed
   1.121 +    if (to_dealloc_id != NULL) {
   1.122 +      JNIHandles::destroy_jmethod_id(to_dealloc_id);
   1.123      }
   1.124    }
   1.125    return id;
   1.126  }
   1.127  
   1.128  
   1.129 -jmethodID instanceKlass::get_jmethod_id(instanceKlassHandle ik_h, size_t idnum,
   1.130 -                                        jmethodID new_id, jmethodID* new_jmeths) {
   1.131 -  // Retry lookup after we got the lock or ensured we are at safepoint
   1.132 +// Common code to fetch the jmethodID from the cache or update the
   1.133 +// cache with the new jmethodID. This function should never do anything
   1.134 +// that causes the caller to go to a safepoint or we can deadlock with
   1.135 +// the VMThread or have cache consistency issues.
   1.136 +//
   1.137 +jmethodID instanceKlass::get_jmethod_id_fetch_or_update(
   1.138 +            instanceKlassHandle ik_h, size_t idnum, jmethodID new_id,
   1.139 +            jmethodID* new_jmeths, jmethodID* to_dealloc_id_p,
   1.140 +            jmethodID** to_dealloc_jmeths_p) {
   1.141 +  assert(new_id != NULL, "sanity check");
   1.142 +  assert(to_dealloc_id_p != NULL, "sanity check");
   1.143 +  assert(to_dealloc_jmeths_p != NULL, "sanity check");
   1.144 +  assert(Threads::number_of_threads() == 0 ||
   1.145 +         SafepointSynchronize::is_at_safepoint() ||
   1.146 +         JmethodIdCreation_lock->owned_by_self(), "sanity check");
   1.147 +
   1.148 +  // reacquire the cache - we are locked, single threaded or at a safepoint
   1.149    jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire();
   1.150 -  jmethodID  id                = NULL;
   1.151 -  jmethodID  to_dealloc_id     = NULL;
   1.152 -  jmethodID* to_dealloc_jmeths = NULL;
   1.153 -  size_t     length;
   1.154 +  jmethodID  id     = NULL;
   1.155 +  size_t     length = 0;
   1.156  
   1.157 -  if (jmeths == NULL || (length = (size_t)jmeths[0]) <= idnum) {
   1.158 +  if (jmeths == NULL ||                         // no cache yet
   1.159 +      (length = (size_t)jmeths[0]) <= idnum) {  // cache is too short
   1.160      if (jmeths != NULL) {
   1.161 -      // We have grown the array: copy the existing entries, and delete the old array
   1.162 +      // copy any existing entries from the old cache
   1.163        for (size_t index = 0; index < length; index++) {
   1.164          new_jmeths[index+1] = jmeths[index+1];
   1.165        }
   1.166 -      to_dealloc_jmeths = jmeths; // using the new jmeths, deallocate the old one
   1.167 +      *to_dealloc_jmeths_p = jmeths;  // save old cache for later delete
   1.168      }
   1.169      ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths);
   1.170    } else {
   1.171 +    // fetch jmethodID (if any) from the existing cache
   1.172      id = jmeths[idnum+1];
   1.173 -    to_dealloc_jmeths = new_jmeths; // using the old jmeths, deallocate the new one
   1.174 +    *to_dealloc_jmeths_p = new_jmeths;  // save new cache for later delete
   1.175    }
   1.176    if (id == NULL) {
   1.177 +    // No matching jmethodID in the existing cache or we have a new
   1.178 +    // cache or we just grew the cache. This cache write is done here
   1.179 +    // by the first thread to win the foot race because a jmethodID
   1.180 +    // needs to be unique once it is generally available.
   1.181      id = new_id;
   1.182 -    jmeths[idnum+1] = id;  // install the new method ID
   1.183 +
   1.184 +    // The jmethodID cache can be read while unlocked so we have to
   1.185 +    // make sure the new jmethodID is complete before installing it
   1.186 +    // in the cache.
   1.187 +    OrderAccess::release_store_ptr(&jmeths[idnum+1], id);
   1.188    } else {
   1.189 -    to_dealloc_id = new_id; // the new id wasn't used, mark it for deallocation
   1.190 -  }
   1.191 -
   1.192 -  // Free up unneeded or no longer needed resources
   1.193 -  FreeHeap(to_dealloc_jmeths);
   1.194 -  if (to_dealloc_id != NULL) {
   1.195 -    JNIHandles::destroy_jmethod_id(to_dealloc_id);
   1.196 +    *to_dealloc_id_p = new_id; // save new id for later delete
   1.197    }
   1.198    return id;
   1.199  }
   1.200  
   1.201  
   1.202 +// Common code to get the jmethodID cache length and the jmethodID
   1.203 +// value at index idnum if there is one.
   1.204 +//
   1.205 +void instanceKlass::get_jmethod_id_length_value(jmethodID* cache,
   1.206 +       size_t idnum, size_t *length_p, jmethodID* id_p) {
   1.207 +  assert(cache != NULL, "sanity check");
   1.208 +  assert(length_p != NULL, "sanity check");
   1.209 +  assert(id_p != NULL, "sanity check");
   1.210 +
   1.211 +  // cache size is stored in element[0], other elements offset by one
   1.212 +  *length_p = (size_t)cache[0];
   1.213 +  if (*length_p <= idnum) {  // cache is too short
   1.214 +    *id_p = NULL;
   1.215 +  } else {
   1.216 +    *id_p = cache[idnum+1];  // fetch jmethodID (if any)
   1.217 +  }
   1.218 +}
   1.219 +
   1.220 +
   1.221  // Lookup a jmethodID, NULL if not found.  Do no blocking, no allocations, no handles
   1.222  jmethodID instanceKlass::jmethod_id_or_null(methodOop method) {
   1.223    size_t idnum = (size_t)method->method_idnum();
   1.224    jmethodID* jmeths = methods_jmethod_ids_acquire();
   1.225    size_t length;                                // length assigned as debugging crumb
   1.226    jmethodID id = NULL;
   1.227 -  if (jmeths != NULL &&                         // If there is a jmethodID array,
   1.228 +  if (jmeths != NULL &&                         // If there is a cache
   1.229        (length = (size_t)jmeths[0]) > idnum) {   // and if it is long enough,
   1.230      id = jmeths[idnum+1];                       // Look up the id (may be NULL)
   1.231    }
   1.232 @@ -1074,19 +1167,35 @@
   1.233  // Cache an itable index
   1.234  void instanceKlass::set_cached_itable_index(size_t idnum, int index) {
   1.235    int* indices = methods_cached_itable_indices_acquire();
   1.236 -  if (indices == NULL ||                         // If there is no index array,
   1.237 -      ((size_t)indices[0]) <= idnum) {           // or if it is too short
   1.238 -    // Lock before we allocate the array so we don't leak
   1.239 +  int* to_dealloc_indices = NULL;
   1.240 +
   1.241 +  // We use a double-check locking idiom here because this cache is
   1.242 +  // performance sensitive. In the normal system, this cache only
   1.243 +  // transitions from NULL to non-NULL which is safe because we use
   1.244 +  // release_set_methods_cached_itable_indices() to advertise the
   1.245 +  // new cache. A partially constructed cache should never be seen
   1.246 +  // by a racing thread. Cache reads and writes proceed without a
   1.247 +  // lock, but creation of the cache itself requires no leaks so a
   1.248 +  // lock is generally acquired in that case.
   1.249 +  //
   1.250 +  // If the RedefineClasses() API has been used, then this cache can
   1.251 +  // grow and we'll have transitions from non-NULL to bigger non-NULL.
   1.252 +  // Cache creation requires no leaks and we require safety between all
   1.253 +  // cache accesses and freeing of the old cache so a lock is generally
   1.254 +  // acquired when the RedefineClasses() API has been used.
   1.255 +
   1.256 +  if (indices == NULL || idnum_can_increment()) {
   1.257 +    // we need a cache or the cache can grow
   1.258      MutexLocker ml(JNICachedItableIndex_lock);
   1.259 -    // Retry lookup after we got the lock
   1.260 +    // reacquire the cache to see if another thread already did the work
   1.261      indices = methods_cached_itable_indices_acquire();
   1.262      size_t length = 0;
   1.263 -    // array length stored in first element, other elements offset by one
   1.264 +    // cache size is stored in element[0], other elements offset by one
   1.265      if (indices == NULL || (length = (size_t)indices[0]) <= idnum) {
   1.266        size_t size = MAX2(idnum+1, (size_t)idnum_allocated_count());
   1.267        int* new_indices = NEW_C_HEAP_ARRAY(int, size+1);
   1.268 -      new_indices[0] =(int)size;  // array size held in the first element
   1.269 -      // Copy the existing entries, if any
   1.270 +      new_indices[0] = (int)size;
   1.271 +      // copy any existing entries
   1.272        size_t i;
   1.273        for (i = 0; i < length; i++) {
   1.274          new_indices[i+1] = indices[i+1];
   1.275 @@ -1096,15 +1205,32 @@
   1.276          new_indices[i+1] = -1;
   1.277        }
   1.278        if (indices != NULL) {
   1.279 -        FreeHeap(indices);  // delete any old indices
   1.280 +        // We have an old cache to delete so save it for after we
   1.281 +        // drop the lock.
   1.282 +        to_dealloc_indices = indices;
   1.283        }
   1.284        release_set_methods_cached_itable_indices(indices = new_indices);
   1.285      }
   1.286 +
   1.287 +    if (idnum_can_increment()) {
   1.288 +      // this cache can grow so we have to write to it safely
   1.289 +      indices[idnum+1] = index;
   1.290 +    }
   1.291    } else {
   1.292      CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
   1.293    }
   1.294 -  // This is a cache, if there is a race to set it, it doesn't matter
   1.295 -  indices[idnum+1] = index;
   1.296 +
   1.297 +  if (!idnum_can_increment()) {
   1.298 +    // The cache cannot grow and this JNI itable index value does not
   1.299 +    // have to be unique like a jmethodID. If there is a race to set it,
   1.300 +    // it doesn't matter.
   1.301 +    indices[idnum+1] = index;
   1.302 +  }
   1.303 +
   1.304 +  if (to_dealloc_indices != NULL) {
   1.305 +    // we allocated a new cache so free the old one
   1.306 +    FreeHeap(to_dealloc_indices);
   1.307 +  }
   1.308  }
   1.309  
   1.310  
   1.311 @@ -2300,6 +2426,11 @@
   1.312  
   1.313  // Add an information node that contains weak references to the
   1.314  // interesting parts of the previous version of the_class.
   1.315 +// This is also where we clean out any unused weak references.
   1.316 +// Note that while we delete nodes from the _previous_versions
   1.317 +// array, we never delete the array itself until the klass is
   1.318 +// unloaded. The has_been_redefined() query depends on that fact.
   1.319 +//
   1.320  void instanceKlass::add_previous_version(instanceKlassHandle ikh,
   1.321         BitMap* emcp_methods, int emcp_method_count) {
   1.322    assert(Thread::current()->is_VM_thread(),

mercurial