1 /*
2 * Copyright (c) 2018, 2019, Red Hat, Inc. 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_GC_SHENANDOAH_SHENANDOAHEVACOOMHANDLER_HPP
26 #define SHARE_GC_SHENANDOAH_SHENANDOAHEVACOOMHANDLER_HPP
27
28 #include "gc/shenandoah/shenandoahPadding.hpp"
29 #include "memory/allocation.hpp"
30 #include "utilities/globalDefinitions.hpp"
31
32 /**
33 * Provides safe handling of out-of-memory situations during evacuation.
34 *
35 * When a Java thread encounters out-of-memory while evacuating an object in a
36 * load-reference-barrier (i.e. it cannot copy the object to to-space), it does not
37 * necessarily follow we can return immediately from the LRB (and store to from-space).
38 *
39 * In very basic case, on such failure we may wait until the the evacuation is over,
40 * and then resolve the forwarded copy, and to the store there. This is possible
41 * because other threads might still have space in their GCLABs, and successfully
42 * evacuate the object.
43 *
44 * But, there is a race due to non-atomic evac_in_progress transition. Consider
45 * thread A is stuck waiting for the evacuation to be over -- it cannot leave with
46 * from-space copy yet. Control thread drops evacuation_in_progress preparing for
47 * next STW phase that has to recover from OOME. Thread B misses that update, and
48 * successfully evacuates the object, does the write to to-copy. But, before
49 * Thread B is able to install the fwdptr, thread A discovers evac_in_progress is
81 class ShenandoahEvacOOMHandler {
82 private:
83 static const jint OOM_MARKER_MASK;
84
85 shenandoah_padding(0);
86 volatile jint _threads_in_evac;
87 shenandoah_padding(1);
88
89 void wait_for_no_evac_threads();
90
91 public:
92 ShenandoahEvacOOMHandler();
93
94 /**
95 * Attempt to enter the protected evacuation path.
96 *
97 * When this returns true, it is safe to continue with normal evacuation.
98 * When this method returns false, evacuation must not be entered, and caller
99 * may safely continue with a simple resolve (if Java thread).
100 */
101 void enter_evacuation();
102
103 /**
104 * Leave evacuation path.
105 */
106 void leave_evacuation();
107
108 /**
109 * Signal out-of-memory during evacuation. It will prevent any other threads
110 * from entering the evacuation path, then wait until all threads have left the
111 * evacuation path, and then return. It is then safe to continue with a simple resolve.
112 */
113 void handle_out_of_memory_during_evacuation();
114
115 void clear();
116 };
117
118 class ShenandoahEvacOOMScope : public StackObj {
119 public:
120 ShenandoahEvacOOMScope();
121 ~ShenandoahEvacOOMScope();
122 };
123
124 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHEVACOOMHANDLER_HPP
|
1 /*
2 * Copyright (c) 2018, 2020, Red Hat, Inc. 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_GC_SHENANDOAH_SHENANDOAHEVACOOMHANDLER_HPP
26 #define SHARE_GC_SHENANDOAH_SHENANDOAHEVACOOMHANDLER_HPP
27
28 #include "gc/shenandoah/shenandoahPadding.hpp"
29 #include "memory/allocation.hpp"
30 #include "runtime/thread.hpp"
31 #include "utilities/globalDefinitions.hpp"
32
33 /**
34 * Provides safe handling of out-of-memory situations during evacuation.
35 *
36 * When a Java thread encounters out-of-memory while evacuating an object in a
37 * load-reference-barrier (i.e. it cannot copy the object to to-space), it does not
38 * necessarily follow we can return immediately from the LRB (and store to from-space).
39 *
40 * In very basic case, on such failure we may wait until the the evacuation is over,
41 * and then resolve the forwarded copy, and to the store there. This is possible
42 * because other threads might still have space in their GCLABs, and successfully
43 * evacuate the object.
44 *
45 * But, there is a race due to non-atomic evac_in_progress transition. Consider
46 * thread A is stuck waiting for the evacuation to be over -- it cannot leave with
47 * from-space copy yet. Control thread drops evacuation_in_progress preparing for
48 * next STW phase that has to recover from OOME. Thread B misses that update, and
49 * successfully evacuates the object, does the write to to-copy. But, before
50 * Thread B is able to install the fwdptr, thread A discovers evac_in_progress is
82 class ShenandoahEvacOOMHandler {
83 private:
84 static const jint OOM_MARKER_MASK;
85
86 shenandoah_padding(0);
87 volatile jint _threads_in_evac;
88 shenandoah_padding(1);
89
90 void wait_for_no_evac_threads();
91
92 public:
93 ShenandoahEvacOOMHandler();
94
95 /**
96 * Attempt to enter the protected evacuation path.
97 *
98 * When this returns true, it is safe to continue with normal evacuation.
99 * When this method returns false, evacuation must not be entered, and caller
100 * may safely continue with a simple resolve (if Java thread).
101 */
102 inline void enter_evacuation(Thread* t);
103
104 /**
105 * Leave evacuation path.
106 */
107 inline void leave_evacuation(Thread* t);
108
109 /**
110 * Signal out-of-memory during evacuation. It will prevent any other threads
111 * from entering the evacuation path, then wait until all threads have left the
112 * evacuation path, and then return. It is then safe to continue with a simple resolve.
113 */
114 void handle_out_of_memory_during_evacuation();
115
116 void clear();
117
118 private:
119 // Register/Unregister thread to evacuation OOM protocol
120 void register_thread_to_protocol(Thread* t);
121 void unregister_thread_to_protocol(Thread* t);
122 };
123
124 class ShenandoahHeap;
125
126 class ShenandoahEvacOOMScope : public StackObj {
127 private:
128 ShenandoahHeap* const _heap;
129 Thread* const _thread;
130 public:
131 inline ShenandoahEvacOOMScope();
132 inline ShenandoahEvacOOMScope(Thread* t);
133 inline ShenandoahEvacOOMScope(ShenandoahHeap* heap);
134 inline ShenandoahEvacOOMScope(ShenandoahHeap* heap, Thread* t);
135 inline ~ShenandoahEvacOOMScope();
136 };
137
138 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHEVACOOMHANDLER_HPP
|