comparison src/share/vm/memory/gcLocker.cpp @ 18041:52b4284cb496

Merge with jdk8u20-b26
author Gilles Duboscq <duboscq@ssw.jku.at>
date Wed, 15 Oct 2014 16:02:50 +0200
parents 89152779163c 78bbf4d43a14
children 7848fc12602b
comparison
equal deleted inserted replaced
17606:45d7b2c7029d 18041:52b4284cb496
1 /* 1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
26 #include "memory/gcLocker.inline.hpp" 26 #include "memory/gcLocker.inline.hpp"
27 #include "memory/resourceArea.hpp" 27 #include "memory/resourceArea.hpp"
28 #include "memory/sharedHeap.hpp" 28 #include "memory/sharedHeap.hpp"
29 29
30 volatile jint GC_locker::_jni_lock_count = 0; 30 volatile jint GC_locker::_jni_lock_count = 0;
31 volatile jint GC_locker::_lock_count = 0;
32 volatile bool GC_locker::_needs_gc = false; 31 volatile bool GC_locker::_needs_gc = false;
33 volatile bool GC_locker::_doing_gc = false; 32 volatile bool GC_locker::_doing_gc = false;
34 33
35 #ifdef ASSERT 34 #ifdef ASSERT
36 volatile jint GC_locker::_debug_jni_lock_count = 0; 35 volatile jint GC_locker::_debug_jni_lock_count = 0;
50 } 49 }
51 if (_jni_lock_count != count) { 50 if (_jni_lock_count != count) {
52 tty->print_cr("critical counts don't match: %d != %d", _jni_lock_count, count); 51 tty->print_cr("critical counts don't match: %d != %d", _jni_lock_count, count);
53 for (JavaThread* thr = Threads::first(); thr; thr = thr->next()) { 52 for (JavaThread* thr = Threads::first(); thr; thr = thr->next()) {
54 if (thr->in_critical()) { 53 if (thr->in_critical()) {
55 tty->print_cr(INTPTR_FORMAT " in_critical %d", thr, thr->in_critical()); 54 tty->print_cr(INTPTR_FORMAT " in_critical %d", p2i(thr), thr->in_critical());
56 } 55 }
57 } 56 }
58 } 57 }
59 assert(_jni_lock_count == count, "must be equal"); 58 assert(_jni_lock_count == count, "must be equal");
60 } 59 }
100 // Block entering threads if we know at least one thread is in a 99 // Block entering threads if we know at least one thread is in a
101 // JNI critical region and we need a GC. 100 // JNI critical region and we need a GC.
102 // We check that at least one thread is in a critical region before 101 // We check that at least one thread is in a critical region before
103 // blocking because blocked threads are woken up by a thread exiting 102 // blocking because blocked threads are woken up by a thread exiting
104 // a JNI critical region. 103 // a JNI critical region.
105 while ((needs_gc() && is_jni_active()) || _doing_gc) { 104 while (is_active_and_needs_gc() || _doing_gc) {
106 JNICritical_lock->wait(); 105 JNICritical_lock->wait();
107 } 106 }
108 thread->enter_critical(); 107 thread->enter_critical();
109 _jni_lock_count++; 108 _jni_lock_count++;
110 increment_debug_jni_lock_count(); 109 increment_debug_jni_lock_count();
114 assert(thread->in_last_critical(), "should be exiting critical region"); 113 assert(thread->in_last_critical(), "should be exiting critical region");
115 MutexLocker mu(JNICritical_lock); 114 MutexLocker mu(JNICritical_lock);
116 _jni_lock_count--; 115 _jni_lock_count--;
117 decrement_debug_jni_lock_count(); 116 decrement_debug_jni_lock_count();
118 thread->exit_critical(); 117 thread->exit_critical();
119 if (needs_gc() && !is_jni_active()) { 118 if (needs_gc() && !is_active_internal()) {
120 // We're the last thread out. Cause a GC to occur. 119 // We're the last thread out. Cause a GC to occur.
121 // GC will also check is_active, so this check is not 120 _doing_gc = true;
122 // strictly needed. It's added here to make it clear that 121 {
123 // the GC will NOT be performed if any other caller 122 // Must give up the lock while at a safepoint
124 // of GC_locker::lock() still needs GC locked. 123 MutexUnlocker munlock(JNICritical_lock);
125 if (!is_active_internal()) { 124 if (PrintJNIGCStalls && PrintGCDetails) {
126 _doing_gc = true; 125 ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
127 { 126 gclog_or_tty->print_cr("%.3f: Thread \"%s\" is performing GC after exiting critical section, %d locked",
128 // Must give up the lock while at a safepoint 127 gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
129 MutexUnlocker munlock(JNICritical_lock);
130 if (PrintJNIGCStalls && PrintGCDetails) {
131 ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
132 gclog_or_tty->print_cr("%.3f: Thread \"%s\" is performing GC after exiting critical section, %d locked",
133 gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
134 }
135 Universe::heap()->collect(GCCause::_gc_locker);
136 } 128 }
137 _doing_gc = false; 129 Universe::heap()->collect(GCCause::_gc_locker);
138 } 130 }
139 131 _doing_gc = false;
140 _needs_gc = false; 132 _needs_gc = false;
141 JNICritical_lock->notify_all(); 133 JNICritical_lock->notify_all();
142 } 134 }
143 } 135 }
144 136