sweeper.cpp 24.9 KB
Newer Older
D
duke 已提交
1
/*
S
sla 已提交
2
 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26
#include "precompiled.hpp"
#include "code/codeCache.hpp"
27 28
#include "code/compiledIC.hpp"
#include "code/icBuffer.hpp"
29 30 31
#include "code/nmethod.hpp"
#include "compiler/compileBroker.hpp"
#include "memory/resourceArea.hpp"
32
#include "oops/method.hpp"
33 34 35 36 37 38
#include "runtime/atomic.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "runtime/sweeper.hpp"
#include "runtime/vm_operations.hpp"
S
sla 已提交
39
#include "trace/tracing.hpp"
40
#include "utilities/events.hpp"
41
#include "utilities/ticks.inline.hpp"
42
#include "utilities/xmlstream.hpp"
D
duke 已提交
43

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
#ifdef ASSERT

#define SWEEP(nm) record_sweep(nm, __LINE__)
// Sweeper logging code
class SweeperRecord {
 public:
  int traversal;
  int invocation;
  int compile_id;
  long traversal_mark;
  int state;
  const char* kind;
  address vep;
  address uep;
  int line;

  void print() {
      tty->print_cr("traversal = %d invocation = %d compile_id = %d %s uep = " PTR_FORMAT " vep = "
                    PTR_FORMAT " state = %d traversal_mark %d line = %d",
                    traversal,
                    invocation,
                    compile_id,
                    kind == NULL ? "" : kind,
                    uep,
                    vep,
                    state,
                    traversal_mark,
                    line);
  }
};

static int _sweep_index = 0;
static SweeperRecord* _records = NULL;

void NMethodSweeper::report_events(int id, address entry) {
  if (_records != NULL) {
    for (int i = _sweep_index; i < SweeperLogEntries; i++) {
      if (_records[i].uep == entry ||
          _records[i].vep == entry ||
          _records[i].compile_id == id) {
        _records[i].print();
      }
    }
    for (int i = 0; i < _sweep_index; i++) {
      if (_records[i].uep == entry ||
          _records[i].vep == entry ||
          _records[i].compile_id == id) {
        _records[i].print();
      }
    }
  }
}

void NMethodSweeper::report_events() {
  if (_records != NULL) {
    for (int i = _sweep_index; i < SweeperLogEntries; i++) {
      // skip empty records
      if (_records[i].vep == NULL) continue;
      _records[i].print();
    }
    for (int i = 0; i < _sweep_index; i++) {
      // skip empty records
      if (_records[i].vep == NULL) continue;
      _records[i].print();
    }
  }
}

void NMethodSweeper::record_sweep(nmethod* nm, int line) {
  if (_records != NULL) {
    _records[_sweep_index].traversal = _traversals;
    _records[_sweep_index].traversal_mark = nm->_stack_traversal_mark;
116
    _records[_sweep_index].invocation = _sweep_fractions_left;
117 118 119 120 121 122 123 124 125 126 127 128 129
    _records[_sweep_index].compile_id = nm->compile_id();
    _records[_sweep_index].kind = nm->compile_kind();
    _records[_sweep_index].state = nm->_state;
    _records[_sweep_index].vep = nm->verified_entry_point();
    _records[_sweep_index].uep = nm->entry_point();
    _records[_sweep_index].line = line;
    _sweep_index = (_sweep_index + 1) % SweeperLogEntries;
  }
}
#else
#define SWEEP(nm)
#endif

130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
nmethod* NMethodSweeper::_current                      = NULL; // Current nmethod
long     NMethodSweeper::_traversals                   = 0;    // Stack scan count, also sweep ID.
long     NMethodSweeper::_time_counter                 = 0;    // Virtual time used to periodically invoke sweeper
long     NMethodSweeper::_last_sweep                   = 0;    // Value of _time_counter when the last sweep happened
int      NMethodSweeper::_seen                         = 0;    // Nof. nmethod we have currently processed in current pass of CodeCache
int      NMethodSweeper::_flushed_count                = 0;    // Nof. nmethods flushed in current sweep
int      NMethodSweeper::_zombified_count              = 0;    // Nof. nmethods made zombie in current sweep
int      NMethodSweeper::_marked_for_reclamation_count = 0;    // Nof. nmethods marked for reclaim in current sweep

volatile bool NMethodSweeper::_should_sweep            = true; // Indicates if we should invoke the sweeper
volatile int  NMethodSweeper::_sweep_fractions_left    = 0;    // Nof. invocations left until we are completed with this pass
volatile int  NMethodSweeper::_sweep_started           = 0;    // Flag to control conc sweeper
volatile int  NMethodSweeper::_bytes_changed           = 0;    // Counts the total nmethod size if the nmethod changed from:
                                                               //   1) alive       -> not_entrant
                                                               //   2) not_entrant -> zombie
                                                               //   3) zombie      -> marked_for_reclamation

int   NMethodSweeper::_total_nof_methods_reclaimed     = 0;    // Accumulated nof methods flushed
148 149 150 151
Tickspan NMethodSweeper::_total_time_sweeping;                 // Accumulated time sweeping
Tickspan NMethodSweeper::_total_time_this_sweep;               // Total time this sweep
Tickspan NMethodSweeper::_peak_sweep_time;                     // Peak time for a full sweep
Tickspan NMethodSweeper::_peak_sweep_fraction_time;            // Peak time sweeping one fraction
152
int   NMethodSweeper::_hotness_counter_reset_val       = 0;
153

S
sla 已提交
154

155 156 157
class MarkActivationClosure: public CodeBlobClosure {
public:
  virtual void do_code_blob(CodeBlob* cb) {
158 159 160 161 162 163 164
    if (cb->is_nmethod()) {
      nmethod* nm = (nmethod*)cb;
      nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
      // If we see an activation belonging to a non_entrant nmethod, we mark it.
      if (nm->is_not_entrant()) {
        nm->mark_as_seen_on_stack();
      }
165 166 167 168 169
    }
  }
};
static MarkActivationClosure mark_activation_closure;

170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
class SetHotnessClosure: public CodeBlobClosure {
public:
  virtual void do_code_blob(CodeBlob* cb) {
    if (cb->is_nmethod()) {
      nmethod* nm = (nmethod*)cb;
      nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
    }
  }
};
static SetHotnessClosure set_hotness_closure;


int NMethodSweeper::hotness_counter_reset_val() {
  if (_hotness_counter_reset_val == 0) {
    _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
  }
  return _hotness_counter_reset_val;
}
188 189 190 191
bool NMethodSweeper::sweep_in_progress() {
  return (_current != NULL);
}

192 193 194 195
// Scans the stacks of all Java threads and marks activations of not-entrant methods.
// No need to synchronize access, since 'mark_active_nmethods' is always executed at a
// safepoint.
void NMethodSweeper::mark_active_nmethods() {
D
duke 已提交
196
  assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
197 198 199 200 201
  // If we do not want to reclaim not-entrant or zombie methods there is no need
  // to scan stacks
  if (!MethodFlushing) {
    return;
  }
D
duke 已提交
202

203 204 205
  // Increase time so that we can estimate when to invoke the sweeper again.
  _time_counter++;

D
duke 已提交
206 207
  // Check for restart
  assert(CodeCache::find_blob_unsafe(_current) == _current, "Sweeper nmethod cached state invalid");
208 209 210 211 212
  if (!sweep_in_progress()) {
    _seen = 0;
    _sweep_fractions_left = NmethodSweepFraction;
    _current = CodeCache::first_nmethod();
    _traversals += 1;
213
    _total_time_this_sweep = Tickspan();
S
sla 已提交
214

D
duke 已提交
215 216 217
    if (PrintMethodFlushing) {
      tty->print_cr("### Sweep: stack traversal %d", _traversals);
    }
218
    Threads::nmethods_do(&mark_activation_closure);
D
duke 已提交
219

220 221 222
  } else {
    // Only set hotness counter
    Threads::nmethods_do(&set_hotness_closure);
D
duke 已提交
223 224
  }

225
  OrderAccess::storestore();
D
duke 已提交
226
}
227 228 229 230 231 232
/**
 * This function invokes the sweeper if at least one of the three conditions is met:
 *    (1) The code cache is getting full
 *    (2) There are sufficient state changes in/since the last sweep.
 *    (3) We have not been sweeping for 'some time'
 */
233
void NMethodSweeper::possibly_sweep() {
234
  assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode");
235 236
  // Only compiler threads are allowed to sweep
  if (!MethodFlushing || !sweep_in_progress() || !Thread::current()->is_Compiler_thread()) {
237 238
    return;
  }
239

240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
  // If there was no state change while nmethod sweeping, 'should_sweep' will be false.
  // This is one of the two places where should_sweep can be set to true. The general
  // idea is as follows: If there is enough free space in the code cache, there is no
  // need to invoke the sweeper. The following formula (which determines whether to invoke
  // the sweeper or not) depends on the assumption that for larger ReservedCodeCacheSizes
  // we need less frequent sweeps than for smaller ReservedCodecCacheSizes. Furthermore,
  // the formula considers how much space in the code cache is currently used. Here are
  // some examples that will (hopefully) help in understanding.
  //
  // Small ReservedCodeCacheSizes:  (e.g., < 16M) We invoke the sweeper every time, since
  //                                              the result of the division is 0. This
  //                                              keeps the used code cache size small
  //                                              (important for embedded Java)
  // Large ReservedCodeCacheSize :  (e.g., 256M + code cache is 10% full). The formula
  //                                              computes: (256 / 16) - 1 = 15
  //                                              As a result, we invoke the sweeper after
  //                                              15 invocations of 'mark_active_nmethods.
  // Large ReservedCodeCacheSize:   (e.g., 256M + code Cache is 90% full). The formula
  //                                              computes: (256 / 16) - 10 = 6.
  if (!_should_sweep) {
260 261 262 263 264 265 266 267
    const int time_since_last_sweep = _time_counter - _last_sweep;
    // ReservedCodeCacheSize has an 'unsigned' type. We need a 'signed' type for max_wait_time,
    // since 'time_since_last_sweep' can be larger than 'max_wait_time'. If that happens using
    // an unsigned type would cause an underflow (wait_until_next_sweep becomes a large positive
    // value) that disables the intended periodic sweeps.
    const int max_wait_time = ReservedCodeCacheSize / (16 * M);
    double wait_until_next_sweep = max_wait_time - time_since_last_sweep - CodeCache::reverse_free_ratio();
    assert(wait_until_next_sweep <= (double)max_wait_time, "Calculation of code cache sweeper interval is incorrect");
268 269 270 271 272 273 274

    if ((wait_until_next_sweep <= 0.0) || !CompileBroker::should_compile_new_jobs()) {
      _should_sweep = true;
    }
  }

  if (_should_sweep && _sweep_fractions_left > 0) {
275 276 277 278 279
    // Only one thread at a time will sweep
    jint old = Atomic::cmpxchg( 1, &_sweep_started, 0 );
    if (old != 0) {
      return;
    }
280 281 282
#ifdef ASSERT
    if (LogSweeper && _records == NULL) {
      // Create the ring buffer for the logging code
Z
zgu 已提交
283
      _records = NEW_C_HEAP_ARRAY(SweeperRecord, SweeperLogEntries, mtGC);
284 285 286
      memset(_records, 0, sizeof(SweeperRecord) * SweeperLogEntries);
    }
#endif
287 288

    if (_sweep_fractions_left > 0) {
289
      sweep_code_cache();
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
      _sweep_fractions_left--;
    }

    // We are done with sweeping the code cache once.
    if (_sweep_fractions_left == 0) {
      _last_sweep = _time_counter;
      // Reset flag; temporarily disables sweeper
      _should_sweep = false;
      // If there was enough state change, 'possibly_enable_sweeper()'
      // sets '_should_sweep' to true
      possibly_enable_sweeper();
      // Reset _bytes_changed only if there was enough state change. _bytes_changed
      // can further increase by calls to 'report_state_change'.
      if (_should_sweep) {
        _bytes_changed = 0;
      }
306 307
    }
    _sweep_started = 0;
308 309 310 311
  }
}

void NMethodSweeper::sweep_code_cache() {
312
  Ticks sweep_start_counter = Ticks::now();
S
sla 已提交
313

314 315 316
  _flushed_count                = 0;
  _zombified_count              = 0;
  _marked_for_reclamation_count = 0;
S
sla 已提交
317

318
  if (PrintMethodFlushing && Verbose) {
319
    tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _sweep_fractions_left);
320 321
  }

322 323 324
  if (!CompileBroker::should_compile_new_jobs()) {
    // If we have turned off compilations we might as well do full sweeps
    // in order to reach the clean state faster. Otherwise the sleeping compiler
325
    // threads will slow down sweeping.
326
    _sweep_fractions_left = 1;
327 328
  }

329 330 331 332 333
  // We want to visit all nmethods after NmethodSweepFraction
  // invocations so divide the remaining number of nmethods by the
  // remaining number of invocations.  This is only an estimate since
  // the number of nmethods changes during the sweep so the final
  // stage must iterate until it there are no more nmethods.
334
  int todo = (CodeCache::nof_nmethods() - _seen) / _sweep_fractions_left;
335
  int swept_count = 0;
336

337

338 339 340
  assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
  assert(!CodeCache_lock->owned_by_self(), "just checking");

341
  int freed_memory = 0;
342 343 344
  {
    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);

345
    // The last invocation iterates until there are no more nmethods
346
    for (int i = 0; (i < todo || _sweep_fractions_left == 1) && _current != NULL; i++) {
347
      swept_count++;
348 349
      if (SafepointSynchronize::is_synchronizing()) { // Safepoint request
        if (PrintMethodFlushing && Verbose) {
350
          tty->print_cr("### Sweep at %d out of %d, invocation: %d, yielding to safepoint", _seen, CodeCache::nof_nmethods(), _sweep_fractions_left);
351 352
        }
        MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
353

354 355 356 357 358
        assert(Thread::current()->is_Java_thread(), "should be java thread");
        JavaThread* thread = (JavaThread*)Thread::current();
        ThreadBlockInVM tbivm(thread);
        thread->java_suspend_self();
      }
359 360 361
      // Since we will give up the CodeCache_lock, always skip ahead
      // to the next nmethod.  Other blobs can be deleted by other
      // threads but nmethods are only reclaimed by the sweeper.
362
      nmethod* next = CodeCache::next_nmethod(_current);
363 364 365 366

      // Now ready to process nmethod and give up CodeCache_lock
      {
        MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
367
        freed_memory += process_nmethod(_current);
368 369 370 371 372 373
      }
      _seen++;
      _current = next;
    }
  }

374
  assert(_sweep_fractions_left > 1 || _current == NULL, "must have scanned the whole cache");
375

376 377
  const Ticks sweep_end_counter = Ticks::now();
  const Tickspan sweep_time = sweep_end_counter - sweep_start_counter;
S
sla 已提交
378 379 380 381 382 383 384 385 386 387
  _total_time_sweeping  += sweep_time;
  _total_time_this_sweep += sweep_time;
  _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time);
  _total_nof_methods_reclaimed += _flushed_count;

  EventSweepCodeCache event(UNTIMED);
  if (event.should_commit()) {
    event.set_starttime(sweep_start_counter);
    event.set_endtime(sweep_end_counter);
    event.set_sweepIndex(_traversals);
388
    event.set_sweepFractionIndex(NmethodSweepFraction - _sweep_fractions_left + 1);
389
    event.set_sweptCount(swept_count);
S
sla 已提交
390
    event.set_flushedCount(_flushed_count);
391
    event.set_markedCount(_marked_for_reclamation_count);
S
sla 已提交
392 393 394 395
    event.set_zombifiedCount(_zombified_count);
    event.commit();
  }

396 397
#ifdef ASSERT
  if(PrintMethodFlushing) {
398 399
    tty->print_cr("### sweeper:      sweep time(%d): "
      INT64_FORMAT, _sweep_fractions_left, (jlong)sweep_time.value());
400 401
  }
#endif
402

403
  if (_sweep_fractions_left == 1) {
S
sla 已提交
404
    _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
405 406
    log_sweep("finished");
  }
407

408 409 410 411 412 413 414 415 416
  // Sweeper is the only case where memory is released, check here if it
  // is time to restart the compiler. Only checking if there is a certain
  // amount of free memory in the code cache might lead to re-enabling
  // compilation although no memory has been released. For example, there are
  // cases when compilation was disabled although there is 4MB (or more) free
  // memory in the code cache. The reason is code cache fragmentation. Therefore,
  // it only makes sense to re-enable compilation if we have actually freed memory.
  // Note that typically several kB are released for sweeping 16MB of the code
  // cache. As a result, 'freed_memory' > 0 to restart the compiler.
417
  if (!CompileBroker::should_compile_new_jobs() && (freed_memory > 0)) {
418 419 420
    CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation);
    log_sweep("restart_compiler");
  }
421 422
}

423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
/**
 * This function updates the sweeper statistics that keep track of nmethods
 * state changes. If there is 'enough' state change, the sweeper is invoked
 * as soon as possible. There can be data races on _bytes_changed. The data
 * races are benign, since it does not matter if we loose a couple of bytes.
 * In the worst case we call the sweeper a little later. Also, we are guaranteed
 * to invoke the sweeper if the code cache gets full.
 */
void NMethodSweeper::report_state_change(nmethod* nm) {
  _bytes_changed += nm->total_size();
  possibly_enable_sweeper();
}

/**
 * Function determines if there was 'enough' state change in the code cache to invoke
 * the sweeper again. Currently, we determine 'enough' as more than 1% state change in
 * the code cache since the last sweep.
 */
void NMethodSweeper::possibly_enable_sweeper() {
  double percent_changed = ((double)_bytes_changed / (double)ReservedCodeCacheSize) * 100;
  if (percent_changed > 1.0) {
    _should_sweep = true;
  }
}

448 449 450 451 452 453
class NMethodMarker: public StackObj {
 private:
  CompilerThread* _thread;
 public:
  NMethodMarker(nmethod* nm) {
    _thread = CompilerThread::current();
454 455
    if (!nm->is_zombie() && !nm->is_unloaded()) {
      // Only expose live nmethods for scanning
456 457
      _thread->set_scanned_nmethod(nm);
    }
458
  }
459 460 461 462 463
  ~NMethodMarker() {
    _thread->set_scanned_nmethod(NULL);
  }
};

464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479
void NMethodSweeper::release_nmethod(nmethod *nm) {
  // Clean up any CompiledICHolders
  {
    ResourceMark rm;
    MutexLocker ml_patch(CompiledIC_lock);
    RelocIterator iter(nm);
    while (iter.next()) {
      if (iter.type() == relocInfo::virtual_call_type) {
        CompiledIC::cleanup_call_site(iter.virtual_call_reloc());
      }
    }
  }

  MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
  nm->flush();
}
D
duke 已提交
480

481
int NMethodSweeper::process_nmethod(nmethod *nm) {
482 483
  assert(!CodeCache_lock->owned_by_self(), "just checking");

484
  int freed_memory = 0;
485
  // Make sure this nmethod doesn't get unloaded during the scan,
486
  // since safepoints may happen during acquired below locks.
487 488 489
  NMethodMarker nmm(nm);
  SWEEP(nm);

D
duke 已提交
490 491 492 493
  // Skip methods that are currently referenced by the VM
  if (nm->is_locked_by_vm()) {
    // But still remember to clean-up inline caches for alive nmethods
    if (nm->is_alive()) {
494
      // Clean inline caches that point to zombie/non-entrant methods
495
      MutexLocker cl(CompiledIC_lock);
D
duke 已提交
496
      nm->cleanup_inline_caches();
497
      SWEEP(nm);
D
duke 已提交
498
    }
499
    return freed_memory;
D
duke 已提交
500 501 502
  }

  if (nm->is_zombie()) {
503 504
    // If it is the first time we see nmethod then we mark it. Otherwise,
    // we reclaim it. When we have seen a zombie method twice, we know that
505
    // there are no inline caches that refer to it.
D
duke 已提交
506 507
    if (nm->is_marked_for_reclamation()) {
      assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
Y
ysr 已提交
508
      if (PrintMethodFlushing && Verbose) {
509
        tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
Y
ysr 已提交
510
      }
511
      freed_memory = nm->total_size();
512
      release_nmethod(nm);
S
sla 已提交
513
      _flushed_count++;
D
duke 已提交
514
    } else {
Y
ysr 已提交
515
      if (PrintMethodFlushing && Verbose) {
516
        tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
Y
ysr 已提交
517
      }
D
duke 已提交
518
      nm->mark_for_reclamation();
519 520 521
      // Keep track of code cache state change
      _bytes_changed += nm->total_size();
      _marked_for_reclamation_count++;
522
      SWEEP(nm);
D
duke 已提交
523 524
    }
  } else if (nm->is_not_entrant()) {
525
    // If there are no current activations of this method on the
D
duke 已提交
526 527
    // stack we can safely convert it to a zombie method
    if (nm->can_not_entrant_be_converted()) {
Y
ysr 已提交
528
      if (PrintMethodFlushing && Verbose) {
529
        tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm);
Y
ysr 已提交
530
      }
531
      // Code cache state change is tracked in make_zombie()
D
duke 已提交
532
      nm->make_zombie();
S
sla 已提交
533
      _zombified_count++;
534
      SWEEP(nm);
D
duke 已提交
535 536
    } else {
      // Still alive, clean up its inline caches
537
      MutexLocker cl(CompiledIC_lock);
D
duke 已提交
538
      nm->cleanup_inline_caches();
539
      SWEEP(nm);
D
duke 已提交
540 541 542
    }
  } else if (nm->is_unloaded()) {
    // Unloaded code, just make it a zombie
543
    if (PrintMethodFlushing && Verbose) {
544
      tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm);
545
    }
Y
ysr 已提交
546
    if (nm->is_osr_method()) {
547
      SWEEP(nm);
548
      // No inline caches will ever point to osr methods, so we can just remove it
549
      freed_memory = nm->total_size();
550
      release_nmethod(nm);
S
sla 已提交
551
      _flushed_count++;
D
duke 已提交
552
    } else {
553
      // Code cache state change is tracked in make_zombie()
D
duke 已提交
554
      nm->make_zombie();
S
sla 已提交
555
      _zombified_count++;
556
      SWEEP(nm);
D
duke 已提交
557 558
    }
  } else {
559
    if (UseCodeCacheFlushing) {
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
      if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) {
        // Do not make native methods and OSR-methods not-entrant
        nm->dec_hotness_counter();
        // Get the initial value of the hotness counter. This value depends on the
        // ReservedCodeCacheSize
        int reset_val = hotness_counter_reset_val();
        int time_since_reset = reset_val - nm->hotness_counter();
        double threshold = -reset_val + (CodeCache::reverse_free_ratio() * NmethodSweepActivity);
        // The less free space in the code cache we have - the bigger reverse_free_ratio() is.
        // I.e., 'threshold' increases with lower available space in the code cache and a higher
        // NmethodSweepActivity. If the current hotness counter - which decreases from its initial
        // value until it is reset by stack walking - is smaller than the computed threshold, the
        // corresponding nmethod is considered for removal.
        if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > 10)) {
          // A method is marked as not-entrant if the method is
          // 1) 'old enough': nm->hotness_counter() < threshold
          // 2) The method was in_use for a minimum amount of time: (time_since_reset > 10)
          //    The second condition is necessary if we are dealing with very small code cache
          //    sizes (e.g., <10m) and the code cache size is too small to hold all hot methods.
          //    The second condition ensures that methods are not immediately made not-entrant
          //    after compilation.
          nm->make_not_entrant();
582 583 584 585 586
          // Code cache state change is tracked in make_not_entrant()
          if (PrintMethodFlushing && Verbose) {
            tty->print_cr("### Nmethod %d/" PTR_FORMAT "made not-entrant: hotness counter %d/%d threshold %f",
                          nm->compile_id(), nm, nm->hotness_counter(), reset_val, threshold);
          }
587
        }
588 589
      }
    }
590
    // Clean-up all inline caches that point to zombie/non-reentrant methods
591
    MutexLocker cl(CompiledIC_lock);
D
duke 已提交
592
    nm->cleanup_inline_caches();
593
    SWEEP(nm);
D
duke 已提交
594
  }
595
  return freed_memory;
D
duke 已提交
596
}
597

598 599 600 601
// Print out some state information about the current sweep and the
// state of the code cache if it's requested.
void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) {
  if (PrintMethodFlushing) {
602 603 604 605 606
    stringStream s;
    // Dump code cache state into a buffer before locking the tty,
    // because log_state() will use locks causing lock conflicts.
    CodeCache::log_state(&s);

607 608 609 610 611 612 613 614
    ttyLocker ttyl;
    tty->print("### sweeper: %s ", msg);
    if (format != NULL) {
      va_list ap;
      va_start(ap, format);
      tty->vprint(format, ap);
      va_end(ap);
    }
615
    tty->print_cr(s.as_string());
616 617 618
  }

  if (LogCompilation && (xtty != NULL)) {
619 620 621 622 623
    stringStream s;
    // Dump code cache state into a buffer before locking the tty,
    // because log_state() will use locks causing lock conflicts.
    CodeCache::log_state(&s);

624
    ttyLocker ttyl;
625
    xtty->begin_elem("sweeper state='%s' traversals='" INTX_FORMAT "' ", msg, (intx)traversal_count());
626 627 628 629 630 631
    if (format != NULL) {
      va_list ap;
      va_start(ap, format);
      xtty->vprint(format, ap);
      va_end(ap);
    }
632
    xtty->print(s.as_string());
633 634 635 636
    xtty->stamp();
    xtty->end_elem();
  }
}