src/hotspot/share/code/dependencyContext.cpp
author coleenp
Wed, 26 Sep 2018 14:01:48 -0400
changeset 51887 32161fbea3fe
parent 48955 e22914003cf0
child 52781 436097b038a1
permissions -rw-r--r--
8210856: Move InstanceKlass DependencyContext cleaning to SystemDictionary::do_unloading() Summary: Already walk classes in ClassLoaderData::unload so generalize to also clean nmethod dependencies. Reviewed-by: eosterlund, dlong, vlivanov
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
34195
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
     1
/*
48955
e22914003cf0 8194691: Cleanup unnecessary casts in Atomic/OrderAccess uses
kbarrett
parents: 47216
diff changeset
     2
 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
34195
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
     4
 *
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
     7
 * published by the Free Software Foundation.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
     8
 *
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    13
 * accompanied this code).
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    14
 *
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    18
 *
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    21
 * questions.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    22
 *
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    23
 */
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    24
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    25
#include "precompiled.hpp"
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    26
#include "code/nmethod.hpp"
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    27
#include "code/dependencies.hpp"
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    28
#include "code/dependencyContext.hpp"
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    29
#include "memory/resourceArea.hpp"
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    30
#include "runtime/atomic.hpp"
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    31
#include "runtime/perfData.hpp"
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    32
#include "utilities/exceptions.hpp"
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    33
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    34
PerfCounter* DependencyContext::_perf_total_buckets_allocated_count   = NULL;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    35
PerfCounter* DependencyContext::_perf_total_buckets_deallocated_count = NULL;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    36
PerfCounter* DependencyContext::_perf_total_buckets_stale_count       = NULL;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    37
PerfCounter* DependencyContext::_perf_total_buckets_stale_acc_count   = NULL;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    38
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    39
void dependencyContext_init() {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    40
  DependencyContext::init();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    41
}
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    42
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    43
void DependencyContext::init() {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    44
  if (UsePerfData) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    45
    EXCEPTION_MARK;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    46
    _perf_total_buckets_allocated_count =
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    47
        PerfDataManager::create_counter(SUN_CI, "nmethodBucketsAllocated", PerfData::U_Events, CHECK);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    48
    _perf_total_buckets_deallocated_count =
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    49
        PerfDataManager::create_counter(SUN_CI, "nmethodBucketsDeallocated", PerfData::U_Events, CHECK);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    50
    _perf_total_buckets_stale_count =
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    51
        PerfDataManager::create_counter(SUN_CI, "nmethodBucketsStale", PerfData::U_Events, CHECK);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    52
    _perf_total_buckets_stale_acc_count =
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    53
        PerfDataManager::create_counter(SUN_CI, "nmethodBucketsStaleAccumulated", PerfData::U_Events, CHECK);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    54
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    55
}
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    56
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    57
//
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    58
// Walk the list of dependent nmethods searching for nmethods which
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    59
// are dependent on the changes that were passed in and mark them for
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    60
// deoptimization.  Returns the number of nmethods found.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    61
//
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    62
int DependencyContext::mark_dependent_nmethods(DepChange& changes) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    63
  int found = 0;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    64
  for (nmethodBucket* b = dependencies(); b != NULL; b = b->next()) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    65
    nmethod* nm = b->get_nmethod();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    66
    // since dependencies aren't removed until an nmethod becomes a zombie,
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    67
    // the dependency list may contain nmethods which aren't alive.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    68
    if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    69
      if (TraceDependencies) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    70
        ResourceMark rm;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    71
        tty->print_cr("Marked for deoptimization");
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    72
        changes.print();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    73
        nm->print();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    74
        nm->print_dependencies();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    75
      }
36300
5b47f168b948 7177745: JSR292: Many Callsite relinkages cause target method to always run in interpreter mode
vlivanov
parents: 34221
diff changeset
    76
      changes.mark_for_deoptimization(nm);
34195
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    77
      found++;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    78
    }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    79
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    80
  return found;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    81
}
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    82
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    83
//
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    84
// Add an nmethod to the dependency context.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    85
// It's possible that an nmethod has multiple dependencies on a klass
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    86
// so a count is kept for each bucket to guarantee that creation and
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    87
// deletion of dependencies is consistent.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    88
//
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    89
void DependencyContext::add_dependent_nmethod(nmethod* nm, bool expunge) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    90
  assert_lock_strong(CodeCache_lock);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    91
  for (nmethodBucket* b = dependencies(); b != NULL; b = b->next()) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    92
    if (nm == b->get_nmethod()) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    93
      b->increment();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    94
      return;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    95
    }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    96
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    97
  set_dependencies(new nmethodBucket(nm, dependencies()));
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    98
  if (UsePerfData) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
    99
    _perf_total_buckets_allocated_count->inc();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   100
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   101
  if (expunge) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   102
    // Remove stale entries from the list.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   103
    expunge_stale_entries();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   104
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   105
}
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   106
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   107
//
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   108
// Remove an nmethod dependency from the context.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   109
// Decrement count of the nmethod in the dependency list and, optionally, remove
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   110
// the bucket completely when the count goes to 0.  This method must find
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   111
// a corresponding bucket otherwise there's a bug in the recording of dependencies.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   112
// Can be called concurrently by parallel GC threads.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   113
//
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   114
void DependencyContext::remove_dependent_nmethod(nmethod* nm, bool expunge) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   115
  assert_locked_or_safepoint(CodeCache_lock);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   116
  nmethodBucket* first = dependencies();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   117
  nmethodBucket* last = NULL;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   118
  for (nmethodBucket* b = first; b != NULL; b = b->next()) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   119
    if (nm == b->get_nmethod()) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   120
      int val = b->decrement();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   121
      guarantee(val >= 0, "Underflow: %d", val);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   122
      if (val == 0) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   123
        if (expunge) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   124
          if (last == NULL) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   125
            set_dependencies(b->next());
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   126
          } else {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   127
            last->set_next(b->next());
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   128
          }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   129
          delete b;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   130
          if (UsePerfData) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   131
            _perf_total_buckets_deallocated_count->inc();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   132
          }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   133
        } else {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   134
          // Mark the context as having stale entries, since it is not safe to
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   135
          // expunge the list right now.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   136
          set_has_stale_entries(true);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   137
          if (UsePerfData) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   138
            _perf_total_buckets_stale_count->inc();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   139
            _perf_total_buckets_stale_acc_count->inc();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   140
          }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   141
        }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   142
      }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   143
      if (expunge) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   144
        // Remove stale entries from the list.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   145
        expunge_stale_entries();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   146
      }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   147
      return;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   148
    }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   149
    last = b;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   150
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   151
#ifdef ASSERT
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   152
  tty->print_raw_cr("### can't find dependent nmethod");
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   153
  nm->print();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   154
#endif // ASSERT
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   155
  ShouldNotReachHere();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   156
}
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   157
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   158
//
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   159
// Reclaim all unused buckets.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   160
//
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   161
void DependencyContext::expunge_stale_entries() {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   162
  assert_locked_or_safepoint(CodeCache_lock);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   163
  if (!has_stale_entries()) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   164
    assert(!find_stale_entries(), "inconsistent info");
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   165
    return;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   166
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   167
  nmethodBucket* first = dependencies();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   168
  nmethodBucket* last = NULL;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   169
  int removed = 0;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   170
  for (nmethodBucket* b = first; b != NULL;) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   171
    assert(b->count() >= 0, "bucket count: %d", b->count());
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   172
    nmethodBucket* next = b->next();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   173
    if (b->count() == 0) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   174
      if (last == NULL) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   175
        first = next;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   176
      } else {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   177
        last->set_next(next);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   178
      }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   179
      removed++;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   180
      delete b;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   181
      // last stays the same.
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   182
    } else {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   183
      last = b;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   184
    }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   185
    b = next;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   186
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   187
  set_dependencies(first);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   188
  set_has_stale_entries(false);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   189
  if (UsePerfData && removed > 0) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   190
    _perf_total_buckets_deallocated_count->inc(removed);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   191
    _perf_total_buckets_stale_count->dec(removed);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   192
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   193
}
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   194
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   195
//
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   196
// Invalidate all dependencies in the context
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   197
int DependencyContext::remove_all_dependents() {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   198
  assert_locked_or_safepoint(CodeCache_lock);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   199
  nmethodBucket* b = dependencies();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   200
  set_dependencies(NULL);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   201
  int marked = 0;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   202
  int removed = 0;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   203
  while (b != NULL) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   204
    nmethod* nm = b->get_nmethod();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   205
    if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization()) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   206
      nm->mark_for_deoptimization();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   207
      marked++;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   208
    }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   209
    nmethodBucket* next = b->next();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   210
    removed++;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   211
    delete b;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   212
    b = next;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   213
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   214
  set_has_stale_entries(false);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   215
  if (UsePerfData && removed > 0) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   216
    _perf_total_buckets_deallocated_count->inc(removed);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   217
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   218
  return marked;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   219
}
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   220
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   221
#ifndef PRODUCT
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   222
void DependencyContext::print_dependent_nmethods(bool verbose) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   223
  int idx = 0;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   224
  for (nmethodBucket* b = dependencies(); b != NULL; b = b->next()) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   225
    nmethod* nm = b->get_nmethod();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   226
    tty->print("[%d] count=%d { ", idx++, b->count());
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   227
    if (!verbose) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   228
      nm->print_on(tty, "nmethod");
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   229
      tty->print_cr(" } ");
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   230
    } else {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   231
      nm->print();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   232
      nm->print_dependencies();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   233
      tty->print_cr("--- } ");
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   234
    }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   235
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   236
}
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   237
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   238
bool DependencyContext::is_dependent_nmethod(nmethod* nm) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   239
  for (nmethodBucket* b = dependencies(); b != NULL; b = b->next()) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   240
    if (nm == b->get_nmethod()) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   241
#ifdef ASSERT
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   242
      int count = b->count();
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   243
      assert(count >= 0, "count shouldn't be negative: %d", count);
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   244
#endif
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   245
      return true;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   246
    }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   247
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   248
  return false;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   249
}
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   250
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   251
bool DependencyContext::find_stale_entries() {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   252
  for (nmethodBucket* b = dependencies(); b != NULL; b = b->next()) {
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   253
    if (b->count() == 0)  return true;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   254
  }
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   255
  return false;
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   256
}
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   257
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   258
#endif //PRODUCT
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   259
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   260
int nmethodBucket::decrement() {
48955
e22914003cf0 8194691: Cleanup unnecessary casts in Atomic/OrderAccess uses
kbarrett
parents: 47216
diff changeset
   261
  return Atomic::sub(1, &_count);
34195
89011d12ebd3 8139595: MethodHandles::remove_dependent_nmethod is not MT safe
vlivanov
parents:
diff changeset
   262
}