src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp
author zgu
Wed, 27 Nov 2019 11:52:57 -0500
changeset 59296 9186be5c78ba
permissions -rw-r--r--
8228720: Shenandoah: Implementation of concurrent class unloading Reviewed-by: rkennke
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
59296
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
     1
/*
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
     2
 * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
     3
 *
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
     4
 * This code is free software; you can redistribute it and/or modify it
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
     5
 * under the terms of the GNU General Public License version 2 only, as
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
     6
 * published by the Free Software Foundation.
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
     7
 *
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
     8
 * This code is distributed in the hope that it will be useful, but WITHOUT
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
     9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    10
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    11
 * version 2 for more details (a copy is included in the LICENSE file that
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    12
 * accompanied this code).
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    13
 *
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    14
 * You should have received a copy of the GNU General Public License version
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    15
 * 2 along with this work; if not, write to the Free Software Foundation,
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    16
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    17
 *
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    18
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    19
 * or visit www.oracle.com if you need additional information or have any
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    20
 * questions.
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    21
 *
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    22
 */
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    23
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    24
#include "precompiled.hpp"
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    25
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    26
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    27
#include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    28
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    29
#include "gc/shenandoah/shenandoahNMethod.inline.hpp"
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    30
#include "memory/resourceArea.hpp"
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    31
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    32
ShenandoahNMethod::ShenandoahNMethod(nmethod* nm, GrowableArray<oop*>& oops, bool non_immediate_oops) :
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    33
  _nm(nm), _oops(NULL), _oops_count(0), _unregistered(false) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    34
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    35
  if (!oops.is_empty()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    36
    _oops_count = oops.length();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    37
    _oops = NEW_C_HEAP_ARRAY(oop*, _oops_count, mtGC);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    38
    for (int c = 0; c < _oops_count; c++) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    39
      _oops[c] = oops.at(c);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    40
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    41
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    42
  _has_non_immed_oops = non_immediate_oops;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    43
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    44
  assert_same_oops();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    45
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    46
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    47
ShenandoahNMethod::~ShenandoahNMethod() {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    48
  if (_oops != NULL) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    49
    FREE_C_HEAP_ARRAY(oop*, _oops);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    50
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    51
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    52
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    53
class ShenandoahHasCSetOopClosure : public OopClosure {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    54
private:
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    55
  ShenandoahHeap* const _heap;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    56
  bool                  _has_cset_oops;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    57
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    58
public:
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    59
  ShenandoahHasCSetOopClosure() :
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    60
    _heap(ShenandoahHeap::heap()),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    61
    _has_cset_oops(false) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    62
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    63
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    64
  bool has_cset_oops() const {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    65
    return _has_cset_oops;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    66
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    67
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    68
  void do_oop(oop* p) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    69
    oop value = RawAccess<>::oop_load(p);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    70
    if (!_has_cset_oops && _heap->in_collection_set(value)) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    71
      _has_cset_oops = true;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    72
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    73
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    74
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    75
  void do_oop(narrowOop* p) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    76
    ShouldNotReachHere();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    77
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    78
};
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    79
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    80
bool ShenandoahNMethod::has_cset_oops(ShenandoahHeap *heap) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    81
  ShenandoahHasCSetOopClosure cl;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    82
  oops_do(&cl);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    83
  return cl.has_cset_oops();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    84
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    85
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    86
void ShenandoahNMethod::update() {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    87
  ResourceMark rm;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    88
  bool non_immediate_oops = false;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    89
  GrowableArray<oop*> oops;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    90
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    91
  detect_reloc_oops(nm(), oops, non_immediate_oops);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    92
  if (oops.length() != _oops_count) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    93
    if (_oops != NULL) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    94
      FREE_C_HEAP_ARRAY(oop*, _oops);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    95
      _oops = NULL;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    96
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    97
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    98
    _oops_count = oops.length();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
    99
    if (_oops_count > 0) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   100
      _oops = NEW_C_HEAP_ARRAY(oop*, _oops_count, mtGC);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   101
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   102
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   103
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   104
  for (int index = 0; index < _oops_count; index ++) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   105
    _oops[index] = oops.at(index);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   106
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   107
  _has_non_immed_oops = non_immediate_oops;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   108
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   109
  assert_same_oops();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   110
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   111
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   112
void ShenandoahNMethod::oops_do(OopClosure* oops, bool fix_relocations) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   113
  for (int c = 0; c < _oops_count; c ++) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   114
    oops->do_oop(_oops[c]);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   115
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   116
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   117
  oop* const begin = _nm->oops_begin();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   118
  oop* const end = _nm->oops_end();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   119
  for (oop* p = begin; p < end; p++) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   120
    if (*p != Universe::non_oop_word()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   121
      oops->do_oop(p);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   122
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   123
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   124
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   125
  if (fix_relocations && _has_non_immed_oops) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   126
    _nm->fix_oop_relocations();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   127
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   128
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   129
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   130
void ShenandoahNMethod::detect_reloc_oops(nmethod* nm, GrowableArray<oop*>& oops, bool& has_non_immed_oops) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   131
  has_non_immed_oops = false;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   132
  // Find all oops relocations
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   133
  RelocIterator iter(nm);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   134
  while (iter.next()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   135
    if (iter.type() != relocInfo::oop_type) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   136
      // Not an oop
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   137
      continue;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   138
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   139
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   140
    oop_Relocation* r = iter.oop_reloc();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   141
    if (!r->oop_is_immediate()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   142
      // Non-immediate oop found
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   143
      has_non_immed_oops = true;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   144
      continue;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   145
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   146
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   147
    if (r->oop_value() != NULL) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   148
      // Non-NULL immediate oop found. NULL oops can safely be
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   149
      // ignored since the method will be re-registered if they
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   150
      // are later patched to be non-NULL.
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   151
      oops.push(r->oop_addr());
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   152
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   153
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   154
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   155
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   156
ShenandoahNMethod* ShenandoahNMethod::for_nmethod(nmethod* nm) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   157
  ResourceMark rm;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   158
  bool non_immediate_oops = false;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   159
  GrowableArray<oop*> oops;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   160
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   161
  detect_reloc_oops(nm, oops, non_immediate_oops);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   162
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   163
  // No embedded oops
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   164
  if(!ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() &&
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   165
    oops.is_empty() && nm->oops_begin() >= nm->oops_end()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   166
    return NULL;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   167
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   168
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   169
  return new ShenandoahNMethod(nm, oops, non_immediate_oops);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   170
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   171
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   172
void ShenandoahNMethod::heal_nmethod(nmethod* nm) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   173
  ShenandoahNMethod* data = gc_data(nm);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   174
  assert(data != NULL, "Sanity");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   175
  assert(data->lock()->owned_by_self(), "Must hold the lock");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   176
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   177
  ShenandoahEvacuateUpdateRootsClosure cl;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   178
  data->oops_do(&cl, true /*fix relocation*/);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   179
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   180
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   181
#ifdef ASSERT
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   182
void ShenandoahNMethod::assert_alive_and_correct() {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   183
  assert(_nm->is_alive(), "only alive nmethods here");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   184
  ShenandoahHeap* heap = ShenandoahHeap::heap();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   185
  for (int c = 0; c < _oops_count; c++) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   186
    oop *loc = _oops[c];
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   187
    assert(_nm->code_contains((address) loc) || _nm->oops_contains(loc), "nmethod should contain the oop*");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   188
    oop o = RawAccess<>::oop_load(loc);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   189
    shenandoah_assert_correct_except(loc, o, o == NULL || heap->is_full_gc_move_in_progress());
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   190
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   191
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   192
  oop* const begin = _nm->oops_begin();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   193
  oop* const end = _nm->oops_end();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   194
  for (oop* p = begin; p < end; p++) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   195
    if (*p != Universe::non_oop_word()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   196
      oop o = RawAccess<>::oop_load(p);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   197
      shenandoah_assert_correct_except(p, o, o == NULL || heap->is_full_gc_move_in_progress());
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   198
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   199
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   200
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   201
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   202
class ShenandoahNMethodOopDetector : public OopClosure {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   203
private:
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   204
  ResourceMark rm; // For growable array allocation below.
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   205
  GrowableArray<oop*> _oops;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   206
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   207
public:
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   208
  ShenandoahNMethodOopDetector() : _oops(10) {};
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   209
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   210
  void do_oop(oop* o) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   211
    _oops.append(o);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   212
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   213
  void do_oop(narrowOop* o) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   214
    fatal("NMethods should not have compressed oops embedded.");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   215
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   216
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   217
  GrowableArray<oop*>* oops() {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   218
    return &_oops;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   219
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   220
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   221
  bool has_oops() {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   222
    return !_oops.is_empty();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   223
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   224
};
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   225
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   226
void ShenandoahNMethod::assert_same_oops(bool allow_dead) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   227
  ShenandoahNMethodOopDetector detector;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   228
  nm()->oops_do(&detector, allow_dead);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   229
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   230
  GrowableArray<oop*>* oops = detector.oops();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   231
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   232
  assert(oops->length() == oop_count(), "Must match");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   233
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   234
  for (int index = 0; index < _oops_count; index ++) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   235
    assert(oops->contains(_oops[index]), "Must contain this oop");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   236
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   237
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   238
  for (oop* p = nm()->oops_begin(); p < nm()->oops_end(); p ++) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   239
    assert(oops->contains(p), "Must contain this oop");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   240
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   241
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   242
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   243
void ShenandoahNMethod::assert_no_oops(nmethod* nm, bool allow_dead) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   244
  ShenandoahNMethodOopDetector detector;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   245
  nm->oops_do(&detector, allow_dead);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   246
  assert(detector.oops()->length() == 0, "Should not have oops");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   247
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   248
#endif
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   249
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   250
ShenandoahNMethodTable::ShenandoahNMethodTable() :
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   251
  _heap(ShenandoahHeap::heap()),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   252
  _size(minSize),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   253
  _index(0),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   254
  _iteration_in_progress(false) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   255
  _array = NEW_C_HEAP_ARRAY(ShenandoahNMethod*, _size, mtGC);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   256
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   257
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   258
ShenandoahNMethodTable::~ShenandoahNMethodTable() {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   259
  assert(_array != NULL, "Sanity");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   260
  FREE_C_HEAP_ARRAY(ShenandoahNMethod*, _array);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   261
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   262
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   263
void ShenandoahNMethodTable::register_nmethod(nmethod* nm) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   264
  assert(CodeCache_lock->owned_by_self(), "Must have CodeCache_lock held");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   265
  assert(_index >= 0 && _index <= _size, "Sanity");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   266
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   267
  ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   268
  ShenandoahReentrantLocker data_locker(data != NULL ? data->lock() : NULL);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   269
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   270
  if (data != NULL) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   271
    assert(contain(nm), "Must have been registered");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   272
    data->update();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   273
  } else {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   274
    data = ShenandoahNMethod::for_nmethod(nm);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   275
    if (data == NULL) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   276
      assert(!ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   277
             "Only possible when concurrent class unloading is off");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   278
      return;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   279
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   280
    ShenandoahNMethod::attach_gc_data(nm, data);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   281
    ShenandoahLocker locker(&_lock);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   282
    log_register_nmethod(nm);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   283
    append(data);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   284
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   285
  // Disarm new nmethod
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   286
  ShenandoahNMethod::disarm_nmethod(nm);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   287
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   288
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   289
void ShenandoahNMethodTable::unregister_nmethod(nmethod* nm) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   290
  assert_locked_or_safepoint(CodeCache_lock);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   291
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   292
  ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   293
  if (data == NULL) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   294
    assert(!ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   295
           "Only possible when concurrent class unloading is off");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   296
    ShenandoahNMethod::assert_no_oops(nm, true /*allow_dead*/);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   297
    return;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   298
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   299
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   300
  if (Thread::current()->is_Code_cache_sweeper_thread()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   301
    wait_until_concurrent_iteration_done();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   302
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   303
  log_unregister_nmethod(nm);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   304
  ShenandoahLocker locker(&_lock);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   305
  assert(contain(nm), "Must have been registered");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   306
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   307
  ShenandoahReentrantLocker data_locker(data->lock());
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   308
  data->mark_unregistered();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   309
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   310
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   311
void ShenandoahNMethodTable::flush_nmethod(nmethod* nm) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   312
  assert(CodeCache_lock->owned_by_self(), "Must have CodeCache_lock held");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   313
  assert(Thread::current()->is_Code_cache_sweeper_thread(), "Must from Sweep thread");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   314
  ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   315
  assert(data != NULL || !ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   316
         "Only possible when concurrent class unloading is off");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   317
  if (data == NULL) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   318
    ShenandoahNMethod::assert_no_oops(nm, true /*allow_dead*/);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   319
    return;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   320
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   321
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   322
  // Can not alter the array when iteration is in progress
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   323
  wait_until_concurrent_iteration_done();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   324
  log_flush_nmethod(nm);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   325
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   326
  ShenandoahLocker locker(&_lock);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   327
  int idx = index_of(nm);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   328
  assert(idx >= 0 && idx < _index, "Invalid index");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   329
  ShenandoahNMethod::attach_gc_data(nm, NULL);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   330
  remove(idx);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   331
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   332
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   333
bool ShenandoahNMethodTable::contain(nmethod* nm) const {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   334
  return index_of(nm) != -1;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   335
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   336
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   337
ShenandoahNMethod* ShenandoahNMethodTable::at(int index) const {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   338
  assert(index >= 0 && index < _index, "Out of bound");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   339
  return _array[index];
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   340
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   341
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   342
int ShenandoahNMethodTable::index_of(nmethod* nm) const {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   343
  for (int index = 0; index < length(); index ++) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   344
    if (_array[index]->nm() == nm) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   345
      return index;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   346
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   347
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   348
  return -1;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   349
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   350
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   351
void ShenandoahNMethodTable::remove(int idx) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   352
  shenandoah_assert_locked_or_safepoint(CodeCache_lock);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   353
  assert(!_iteration_in_progress, "Can not happen");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   354
  assert(_index >= 0 && _index <= _size, "Sanity");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   355
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   356
  assert(idx >= 0 && idx < _index, "Out of bound");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   357
  ShenandoahNMethod* snm = _array[idx];
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   358
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   359
  _index --;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   360
  _array[idx] = _array[_index];
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   361
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   362
  delete snm;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   363
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   364
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   365
void ShenandoahNMethodTable::wait_until_concurrent_iteration_done() {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   366
  assert(CodeCache_lock->owned_by_self(), "Lock must be held");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   367
  while (iteration_in_progress()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   368
    CodeCache_lock->wait_without_safepoint_check();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   369
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   370
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   371
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   372
void ShenandoahNMethodTable::append(ShenandoahNMethod* snm) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   373
  if (is_full()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   374
    int new_size = 2 * _size;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   375
    ShenandoahNMethod** old_table = _array;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   376
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   377
    // Rebuild table and replace current one
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   378
    rebuild(new_size);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   379
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   380
    // An iteration is in progress over early snapshot,
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   381
    // can not release the array until iteration is completed
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   382
    if (!iteration_in_progress()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   383
      FREE_C_HEAP_ARRAY(ShenandoahNMethod*, old_table);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   384
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   385
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   386
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   387
  _array[_index ++] = snm;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   388
  assert(_index >= 0 && _index <= _size, "Sanity");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   389
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   390
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   391
void ShenandoahNMethodTable::rebuild(int size) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   392
  ShenandoahNMethod** arr = NEW_C_HEAP_ARRAY(ShenandoahNMethod*, size, mtGC);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   393
  for (int index = 0; index < _index; index ++) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   394
      arr[index] = _array[index];
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   395
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   396
  _array = arr;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   397
  _size = size;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   398
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   399
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   400
ShenandoahNMethodTableSnapshot* ShenandoahNMethodTable::snapshot_for_iteration() {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   401
  assert(!iteration_in_progress(), "Already in progress");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   402
  _iteration_in_progress = true;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   403
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   404
  return new ShenandoahNMethodTableSnapshot(this);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   405
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   406
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   407
void ShenandoahNMethodTable::finish_iteration(ShenandoahNMethodTableSnapshot* snapshot) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   408
  assert(iteration_in_progress(), "Why we here?");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   409
  assert(snapshot != NULL, "No snapshot");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   410
  _iteration_in_progress = false;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   411
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   412
  // Table has been rebuilt during iteration, free old table
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   413
  if (snapshot->_array != _array) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   414
    FREE_C_HEAP_ARRAY(ShenandoahNMethod*, snapshot->_array);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   415
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   416
  delete snapshot;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   417
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   418
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   419
void ShenandoahNMethodTable::log_register_nmethod(nmethod* nm) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   420
  LogTarget(Debug, gc, nmethod) log;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   421
  if (!log.is_enabled()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   422
    return;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   423
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   424
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   425
  ResourceMark rm;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   426
  log.print("Register NMethod: %s.%s [" PTR_FORMAT "] (%s)",
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   427
            nm->method()->method_holder()->external_name(),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   428
            nm->method()->name()->as_C_string(),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   429
            p2i(nm),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   430
            nm->compiler_name());
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   431
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   432
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   433
void ShenandoahNMethodTable::log_unregister_nmethod(nmethod* nm) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   434
  LogTarget(Debug, gc, nmethod) log;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   435
  if (!log.is_enabled()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   436
    return;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   437
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   438
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   439
  ResourceMark rm;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   440
  log.print("Unregister NMethod: %s.%s [" PTR_FORMAT "]",
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   441
            nm->method()->method_holder()->external_name(),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   442
            nm->method()->name()->as_C_string(),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   443
            p2i(nm));
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   444
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   445
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   446
void ShenandoahNMethodTable::log_flush_nmethod(nmethod* nm) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   447
  LogTarget(Debug, gc, nmethod) log;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   448
  if (!log.is_enabled()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   449
    return;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   450
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   451
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   452
  ResourceMark rm;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   453
  log.print("Flush NMethod: (" PTR_FORMAT ")", p2i(nm));
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   454
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   455
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   456
#ifdef ASSERT
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   457
void ShenandoahNMethodTable::assert_nmethods_alive_and_correct() {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   458
  assert_locked_or_safepoint(CodeCache_lock);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   459
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   460
  for (int index = 0; index < length(); index ++) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   461
    ShenandoahNMethod* m = _array[index];
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   462
    // Concurrent unloading may have dead nmethods to be cleaned by sweeper
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   463
    if (m->is_unregistered()) continue;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   464
    m->assert_alive_and_correct();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   465
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   466
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   467
#endif
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   468
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   469
ShenandoahNMethodTableSnapshot::ShenandoahNMethodTableSnapshot(ShenandoahNMethodTable* table) :
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   470
  _heap(ShenandoahHeap::heap()), _table(table), _array(table->_array), _length(table->_index), _claimed(0) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   471
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   472
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   473
void ShenandoahNMethodTableSnapshot::concurrent_nmethods_do(NMethodClosure* cl) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   474
  size_t stride = 256; // educated guess
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   475
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   476
  ShenandoahNMethod** list = _array;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   477
  size_t max = (size_t)_length;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   478
  while (_claimed < max) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   479
    size_t cur = Atomic::add(&_claimed, stride) - stride;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   480
    size_t start = cur;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   481
    size_t end = MIN2(cur + stride, max);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   482
    if (start >= max) break;
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   483
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   484
    for (size_t idx = start; idx < end; idx++) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   485
      ShenandoahNMethod* data = list[idx];
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   486
      assert(data != NULL, "Should not be NULL");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   487
      if (!data->is_unregistered()) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   488
        cl->do_nmethod(data->nm());
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   489
      }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   490
    }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   491
  }
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   492
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   493
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   494
ShenandoahConcurrentNMethodIterator::ShenandoahConcurrentNMethodIterator(ShenandoahNMethodTable* table) :
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   495
  _table(table), _table_snapshot(NULL) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   496
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   497
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   498
void ShenandoahConcurrentNMethodIterator::nmethods_do_begin() {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   499
  assert(CodeCache_lock->owned_by_self(), "Lock must be held");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   500
  assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   501
         "Only for concurrent class unloading");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   502
  _table_snapshot = _table->snapshot_for_iteration();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   503
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   504
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   505
void ShenandoahConcurrentNMethodIterator::nmethods_do(NMethodClosure* cl) {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   506
  assert(_table_snapshot != NULL, "Must first call nmethod_do_begin()");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   507
  _table_snapshot->concurrent_nmethods_do(cl);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   508
}
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   509
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   510
void ShenandoahConcurrentNMethodIterator::nmethods_do_end() {
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   511
  assert(CodeCache_lock->owned_by_self(), "Lock must be held");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   512
  assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(),
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   513
         "Only for concurrent class unloading");
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   514
  _table->finish_iteration(_table_snapshot);
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   515
  CodeCache_lock->notify_all();
9186be5c78ba 8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff changeset
   516
}