hotspot/src/share/vm/memory/gcLocker.cpp
author ysr
Thu, 03 Dec 2009 15:01:57 -0800
changeset 4461 c17c526d36ef
parent 670 ddf3e9583f2f
child 5547 f4b087cbb361
permissions -rw-r--r--
6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
670
ddf3e9583f2f 6719955: Update copyright year
xdono
parents: 386
diff changeset
     2
 * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_gcLocker.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
volatile jint GC_locker::_jni_lock_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
volatile jint GC_locker::_lock_count     = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
volatile bool GC_locker::_needs_gc       = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
volatile bool GC_locker::_doing_gc       = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
void GC_locker::stall_until_clear() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
  assert(!JavaThread::current()->in_critical(), "Would deadlock");
386
7f121b1192f2 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 1
diff changeset
    35
  if (PrintJNIGCStalls && PrintGCDetails) {
7f121b1192f2 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 1
diff changeset
    36
    ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
7f121b1192f2 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 1
diff changeset
    37
    gclog_or_tty->print_cr(
7f121b1192f2 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 1
diff changeset
    38
      "Allocation failed. Thread \"%s\" is stalled by JNI critical section.",
7f121b1192f2 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 1
diff changeset
    39
      JavaThread::current()->name());
7f121b1192f2 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 1
diff changeset
    40
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
  MutexLocker   ml(JNICritical_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
  // Wait for _needs_gc  to be cleared
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  while (GC_locker::needs_gc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
    JNICritical_lock->wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
void GC_locker::jni_lock_slow() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  MutexLocker mu(JNICritical_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  // Block entering threads if we know at least one thread is in a
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  // JNI critical region and we need a GC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  // We check that at least one thread is in a critical region before
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
  // blocking because blocked threads are woken up by a thread exiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  // a JNI critical region.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  while ((is_jni_active() && needs_gc()) || _doing_gc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
    JNICritical_lock->wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  jni_lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
void GC_locker::jni_unlock_slow() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  MutexLocker mu(JNICritical_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  jni_unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  if (needs_gc() && !is_jni_active()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
    // We're the last thread out. Cause a GC to occur.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
    // GC will also check is_active, so this check is not
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
    // strictly needed. It's added here to make it clear that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
    // the GC will NOT be performed if any other caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
    // of GC_locker::lock() still needs GC locked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
    if (!is_active()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
      _doing_gc = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
        // Must give up the lock while at a safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
        MutexUnlocker munlock(JNICritical_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
        Universe::heap()->collect(GCCause::_gc_locker);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
      _doing_gc = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
    clear_needs_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
    JNICritical_lock->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
// Implementation of No_GC_Verifier
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
No_GC_Verifier::No_GC_Verifier(bool verifygc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  _verifygc = verifygc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  if (_verifygc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    CollectedHeap* h = Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
    assert(!h->is_gc_active(), "GC active during No_GC_Verifier");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    _old_invocations = h->total_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
No_GC_Verifier::~No_GC_Verifier() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  if (_verifygc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
    CollectedHeap* h = Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
    assert(!h->is_gc_active(), "GC active during No_GC_Verifier");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
    if (_old_invocations != h->total_collections()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
      fatal("collection in a No_GC_Verifier secured function");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
Pause_No_GC_Verifier::Pause_No_GC_Verifier(No_GC_Verifier * ngcv) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  _ngcv = ngcv;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  if (_ngcv->_verifygc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
    // if we were verifying, then make sure that nothing is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
    // wrong before we "pause" verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
    CollectedHeap* h = Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
    assert(!h->is_gc_active(), "GC active during No_GC_Verifier");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
    if (_ngcv->_old_invocations != h->total_collections()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
      fatal("collection in a No_GC_Verifier secured function");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
Pause_No_GC_Verifier::~Pause_No_GC_Verifier() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  if (_ngcv->_verifygc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
    // if we were verifying before, then reenable verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
    CollectedHeap* h = Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
    assert(!h->is_gc_active(), "GC active during No_GC_Verifier");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
    _ngcv->_old_invocations = h->total_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
// JRT_LEAF rules:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
// A JRT_LEAF method may not interfere with safepointing by
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
//   1) acquiring or blocking on a Mutex or JavaLock - checked
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
//   2) allocating heap memory - checked
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
//   3) executing a VM operation - checked
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
//   4) executing a system call (including malloc) that could block or grab a lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
//   5) invoking GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
//   6) reaching a safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
//   7) running too long
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
// Nor may any method it calls.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
JRT_Leaf_Verifier::JRT_Leaf_Verifier()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  : No_Safepoint_Verifier(true, JRT_Leaf_Verifier::should_verify_GC())
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
JRT_Leaf_Verifier::~JRT_Leaf_Verifier()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
bool JRT_Leaf_Verifier::should_verify_GC() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  switch (JavaThread::current()->thread_state()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  case _thread_in_Java:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
    // is in a leaf routine, there must be no safepoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  case _thread_in_native:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
    // A native thread is not subject to safepoints.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    // Even while it is in a leaf routine, GC is ok
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    // Leaf routines cannot be called from other contexts.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
    ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
#endif