Mercurial > hg > truffle
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 |