1 | /* |
2 | * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
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 |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #ifndef SHARE_RUNTIME_SAFEPOINTVERIFIERS_HPP |
26 | #define SHARE_RUNTIME_SAFEPOINTVERIFIERS_HPP |
27 | |
28 | #include "memory/allocation.hpp" |
29 | #include "runtime/thread.hpp" |
30 | |
31 | // A NoGCVerifier object can be placed in methods where one assumes that |
32 | // no garbage collection will occur. The destructor will verify this property |
33 | // unless the constructor is called with argument false (not verifygc). |
34 | // |
35 | // The check will only be done in debug mode and if verifygc true. |
36 | |
37 | class NoGCVerifier: public StackObj { |
38 | friend class PauseNoGCVerifier; |
39 | |
40 | protected: |
41 | bool _verifygc; |
42 | unsigned int _old_invocations; |
43 | |
44 | public: |
45 | #ifdef ASSERT |
46 | NoGCVerifier(bool verifygc = true); |
47 | ~NoGCVerifier(); |
48 | #else |
49 | NoGCVerifier(bool verifygc = true) {} |
50 | ~NoGCVerifier() {} |
51 | #endif |
52 | }; |
53 | |
54 | // A PauseNoGCVerifier is used to temporarily pause the behavior |
55 | // of a NoGCVerifier object. If we are not in debug mode or if the |
56 | // NoGCVerifier object has a _verifygc value of false, then there |
57 | // is nothing to do. |
58 | |
59 | class PauseNoGCVerifier: public StackObj { |
60 | private: |
61 | NoGCVerifier * _ngcv; |
62 | |
63 | public: |
64 | #ifdef ASSERT |
65 | PauseNoGCVerifier(NoGCVerifier * ngcv); |
66 | ~PauseNoGCVerifier(); |
67 | #else |
68 | PauseNoGCVerifier(NoGCVerifier * ngcv) {} |
69 | ~PauseNoGCVerifier() {} |
70 | #endif |
71 | }; |
72 | |
73 | |
74 | // A NoSafepointVerifier object will throw an assertion failure if |
75 | // the current thread passes a possible safepoint while this object is |
76 | // instantiated. A safepoint, will either be: an oop allocation, blocking |
77 | // on a Mutex or JavaLock, or executing a VM operation. |
78 | // |
79 | // If StrictSafepointChecks is turned off, it degrades into a NoGCVerifier |
80 | // |
81 | class NoSafepointVerifier : public NoGCVerifier { |
82 | friend class PauseNoSafepointVerifier; |
83 | |
84 | private: |
85 | bool _activated; |
86 | Thread *_thread; |
87 | public: |
88 | #ifdef ASSERT |
89 | NoSafepointVerifier(bool activated = true, bool verifygc = true ) : |
90 | NoGCVerifier(verifygc), |
91 | _activated(activated) { |
92 | _thread = Thread::current(); |
93 | if (_activated) { |
94 | _thread->_allow_allocation_count++; |
95 | _thread->_allow_safepoint_count++; |
96 | } |
97 | } |
98 | |
99 | ~NoSafepointVerifier() { |
100 | if (_activated) { |
101 | _thread->_allow_allocation_count--; |
102 | _thread->_allow_safepoint_count--; |
103 | } |
104 | } |
105 | #else |
106 | NoSafepointVerifier(bool activated = true, bool verifygc = true) : NoGCVerifier(verifygc){} |
107 | ~NoSafepointVerifier() {} |
108 | #endif |
109 | }; |
110 | |
111 | // A PauseNoSafepointVerifier is used to temporarily pause the |
112 | // behavior of a NoSafepointVerifier object. If we are not in debug |
113 | // mode then there is nothing to do. If the NoSafepointVerifier |
114 | // object has an _activated value of false, then there is nothing to |
115 | // do for safepoint and allocation checking, but there may still be |
116 | // something to do for the underlying NoGCVerifier object. |
117 | |
118 | class PauseNoSafepointVerifier : public PauseNoGCVerifier { |
119 | private: |
120 | NoSafepointVerifier * _nsv; |
121 | |
122 | public: |
123 | #ifdef ASSERT |
124 | PauseNoSafepointVerifier(NoSafepointVerifier * nsv) |
125 | : PauseNoGCVerifier(nsv) { |
126 | |
127 | _nsv = nsv; |
128 | if (_nsv->_activated) { |
129 | _nsv->_thread->_allow_allocation_count--; |
130 | _nsv->_thread->_allow_safepoint_count--; |
131 | } |
132 | } |
133 | |
134 | ~PauseNoSafepointVerifier() { |
135 | if (_nsv->_activated) { |
136 | _nsv->_thread->_allow_allocation_count++; |
137 | _nsv->_thread->_allow_safepoint_count++; |
138 | } |
139 | } |
140 | #else |
141 | PauseNoSafepointVerifier(NoSafepointVerifier * nsv) |
142 | : PauseNoGCVerifier(nsv) {} |
143 | ~PauseNoSafepointVerifier() {} |
144 | #endif |
145 | }; |
146 | |
147 | // A NoAllocVerifier object can be placed in methods where one assumes that |
148 | // no allocation will occur. The destructor will verify this property |
149 | // unless the constructor is called with argument false (not activated). |
150 | // |
151 | // The check will only be done in debug mode and if activated. |
152 | // Note: this only makes sense at safepoints (otherwise, other threads may |
153 | // allocate concurrently.) |
154 | |
155 | class NoAllocVerifier : public StackObj { |
156 | private: |
157 | bool _activated; |
158 | |
159 | public: |
160 | #ifdef ASSERT |
161 | NoAllocVerifier(bool activated = true) { |
162 | _activated = activated; |
163 | if (_activated) Thread::current()->_allow_allocation_count++; |
164 | } |
165 | |
166 | ~NoAllocVerifier() { |
167 | if (_activated) Thread::current()->_allow_allocation_count--; |
168 | } |
169 | #else |
170 | NoAllocVerifier(bool activated = true) {} |
171 | ~NoAllocVerifier() {} |
172 | #endif |
173 | }; |
174 | |
175 | #endif // SHARE_RUNTIME_SAFEPOINTVERIFIERS_HPP |
176 | |