1 /*
2 * Copyright (c) 2013, 2021, 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
26 #include "gc/shenandoah/shenandoahConcurrentGC.hpp"
27 #include "gc/shenandoah/shenandoahDegeneratedGC.hpp"
28 #include "gc/shenandoah/shenandoahFullGC.hpp"
29 #include "gc/shenandoah/shenandoahGeneration.hpp"
30 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
31 #include "gc/shenandoah/shenandoahUtils.hpp"
32 #include "gc/shenandoah/shenandoahVMOperations.hpp"
33 #include "interpreter/oopMapCache.hpp"
34 #include "logging/log.hpp"
35 #include "memory/universe.hpp"
36
37 bool VM_ShenandoahOperation::doit_prologue() {
38 log_active_generation("Prologue");
39 assert(!ShenandoahHeap::heap()->has_gc_state_changed(), "GC State can only be changed on a safepoint.");
40 return true;
41 }
42
43 void VM_ShenandoahOperation::doit_epilogue() {
44 log_active_generation("Epilogue");
45 assert(!ShenandoahHeap::heap()->has_gc_state_changed(), "GC State was not synchronized to java threads.");
46 // GC thread root traversal likely used OopMapCache a lot, which
47 // might have created lots of old entries. Trigger the cleanup now.
48 OopMapCache::try_trigger_cleanup();
49 }
50
51 void VM_ShenandoahOperation::log_active_generation(const char* prefix) {
52 ShenandoahGeneration* agen = ShenandoahHeap::heap()->active_generation();
53 log_debug(gc, heap)("%s: active_generation is %s", prefix,
54 agen == nullptr ? "nullptr" : shenandoah_generation_name(agen->type()));
55 }
56
57 void VM_ShenandoahOperation::set_active_generation() {
58 if (evaluate_at_safepoint()) {
59 assert(SafepointSynchronize::is_at_safepoint(), "Error??");
60 ShenandoahHeap::heap()->set_active_generation(_generation);
61 }
62 }
63
64 bool VM_ShenandoahReferenceOperation::doit_prologue() {
65 VM_ShenandoahOperation::doit_prologue();
66 Heap_lock->lock();
67 return true;
68 }
69
70 void VM_ShenandoahReferenceOperation::doit_epilogue() {
71 VM_ShenandoahOperation::doit_epilogue();
72 if (Universe::has_reference_pending_list()) {
73 Heap_lock->notify_all();
74 }
75 Heap_lock->unlock();
76 }
77
78 VM_ShenandoahInitMark::VM_ShenandoahInitMark(ShenandoahConcurrentGC* gc)
79 : VM_ShenandoahOperation(gc->generation()), _gc(gc) {
80 }
81
82 void VM_ShenandoahInitMark::doit() {
83 ShenandoahGCPauseMark mark(_gc_id, "Init Mark", SvcGCMarker::CONCURRENT);
84 set_active_generation();
85 _gc->entry_init_mark();
86 }
87
88 VM_ShenandoahFinalMarkStartEvac::VM_ShenandoahFinalMarkStartEvac(ShenandoahConcurrentGC* gc)
89 : VM_ShenandoahOperation(gc->generation()), _gc(gc) {
90 }
91
92 void VM_ShenandoahFinalMarkStartEvac::doit() {
93 ShenandoahGCPauseMark mark(_gc_id, "Final Mark", SvcGCMarker::CONCURRENT);
94 set_active_generation();
95 _gc->entry_final_mark();
96 }
97
98 VM_ShenandoahFullGC::VM_ShenandoahFullGC(GCCause::Cause gc_cause, ShenandoahFullGC* full_gc)
99 : VM_ShenandoahReferenceOperation(full_gc->generation()), _gc_cause(gc_cause), _full_gc(full_gc) {
100 }
101
102 void VM_ShenandoahFullGC::doit() {
103 ShenandoahGCPauseMark mark(_gc_id, "Full GC", SvcGCMarker::FULL);
104 set_active_generation();
105 _full_gc->entry_full(_gc_cause);
106 }
107
108 VM_ShenandoahDegeneratedGC::VM_ShenandoahDegeneratedGC(ShenandoahDegenGC* gc)
109 : VM_ShenandoahReferenceOperation(gc->generation()), _gc(gc) {
110 }
111
112 void VM_ShenandoahDegeneratedGC::doit() {
113 ShenandoahGCPauseMark mark(_gc_id, "Degenerated GC", SvcGCMarker::CONCURRENT);
114 set_active_generation();
115 _gc->entry_degenerated();
116 }
117
118 VM_ShenandoahInitUpdateRefs::VM_ShenandoahInitUpdateRefs(ShenandoahConcurrentGC* gc)
119 : VM_ShenandoahOperation(gc->generation()), _gc(gc) {
120 }
121
122 void VM_ShenandoahInitUpdateRefs::doit() {
123 ShenandoahGCPauseMark mark(_gc_id, "Init Update Refs", SvcGCMarker::CONCURRENT);
124 set_active_generation();
125 _gc->entry_init_update_refs();
126 }
127
128 VM_ShenandoahFinalUpdateRefs::VM_ShenandoahFinalUpdateRefs(ShenandoahConcurrentGC* gc)
129 : VM_ShenandoahOperation(gc->generation()), _gc(gc) {
130 }
131
132 void VM_ShenandoahFinalUpdateRefs::doit() {
133 ShenandoahGCPauseMark mark(_gc_id, "Final Update Refs", SvcGCMarker::CONCURRENT);
134 set_active_generation();
135 _gc->entry_final_update_refs();
136 }
137
138 VM_ShenandoahFinalVerify::VM_ShenandoahFinalVerify(ShenandoahConcurrentGC* gc)
139 : VM_ShenandoahOperation(gc->generation()), _gc(gc) {
140 }
141
142 void VM_ShenandoahFinalVerify::doit() {
143 ShenandoahGCPauseMark mark(_gc_id, "Final Verify", SvcGCMarker::CONCURRENT);
144 set_active_generation();
145 _gc->entry_final_verify();
146 }