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
37class 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
59class 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//
81class 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
118class 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
155class 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