45
46 VM_GC_Operation::~VM_GC_Operation() {
47 CollectedHeap* ch = Universe::heap();
48 ch->collector_policy()->set_all_soft_refs_clear(false);
49 }
50
51 // The same dtrace probe can't be inserted in two different files, so we
52 // have to call it here, so it's only in one file. Can't create new probes
53 // for the other file anymore. The dtrace probes have to remain stable.
54 void VM_GC_Operation::notify_gc_begin(bool full) {
55 HOTSPOT_GC_BEGIN(
56 full);
57 HS_DTRACE_WORKAROUND_TAIL_CALL_BUG();
58 }
59
60 void VM_GC_Operation::notify_gc_end() {
61 HOTSPOT_GC_END();
62 HS_DTRACE_WORKAROUND_TAIL_CALL_BUG();
63 }
64
65 void VM_GC_Operation::acquire_pending_list_lock() {
66 _pending_list_locker.lock();
67 }
68
69 void VM_GC_Operation::release_and_notify_pending_list_lock() {
70 _pending_list_locker.unlock();
71 }
72
73 // Allocations may fail in several threads at about the same time,
74 // resulting in multiple gc requests. We only want to do one of them.
75 // In case a GC locker is active and the need for a GC is already signaled,
76 // we want to skip this GC attempt altogether, without doing a futile
77 // safepoint operation.
78 bool VM_GC_Operation::skip_operation() const {
79 bool skip = (_gc_count_before != Universe::heap()->total_collections());
80 if (_full && skip) {
81 skip = (_full_gc_count_before != Universe::heap()->total_full_collections());
82 }
83 if (!skip && GCLocker::is_active_and_needs_gc()) {
84 skip = Universe::heap()->is_maximal_no_gc();
85 assert(!(skip && (_gc_cause == GCCause::_gc_locker)),
86 "GCLocker cannot be active when initiating GC");
87 }
88 return skip;
89 }
90
91 bool VM_GC_Operation::doit_prologue() {
92 assert(Thread::current()->is_Java_thread(), "just checking");
93 assert(((_gc_cause != GCCause::_no_gc) &&
94 (_gc_cause != GCCause::_no_cause_specified)), "Illegal GCCause");
95
96 // To be able to handle a GC the VM initialization needs to be completed.
97 if (!is_init_completed()) {
98 vm_exit_during_initialization(
99 err_msg("GC triggered before VM initialization completed. Try increasing "
100 "NewSize, current value " SIZE_FORMAT "%s.",
101 byte_size_in_proper_unit(NewSize),
102 proper_unit_for_byte_size(NewSize)));
103 }
104
105 acquire_pending_list_lock();
106 // If the GC count has changed someone beat us to the collection
107 // Get the Heap_lock after the pending_list_lock.
108 Heap_lock->lock();
109
110 // Check invocations
111 if (skip_operation()) {
112 // skip collection
113 Heap_lock->unlock();
114 release_and_notify_pending_list_lock();
115 _prologue_succeeded = false;
116 } else {
117 _prologue_succeeded = true;
118 }
119 return _prologue_succeeded;
120 }
121
122
123 void VM_GC_Operation::doit_epilogue() {
124 assert(Thread::current()->is_Java_thread(), "just checking");
125 // Release the Heap_lock first.
126 Heap_lock->unlock();
127 release_and_notify_pending_list_lock();
128 }
129
130 bool VM_GC_HeapInspection::skip_operation() const {
131 return false;
132 }
133
134 bool VM_GC_HeapInspection::collect() {
135 if (GCLocker::is_active()) {
136 return false;
137 }
138 Universe::heap()->collect_as_vm_thread(GCCause::_heap_inspection);
139 return true;
140 }
141
142 void VM_GC_HeapInspection::doit() {
143 HandleMark hm;
144 Universe::heap()->ensure_parsability(false); // must happen, even if collection does
145 // not happen (e.g. due to GCLocker)
146 // or _full_gc being false
147 if (_full_gc) {
|
45
46 VM_GC_Operation::~VM_GC_Operation() {
47 CollectedHeap* ch = Universe::heap();
48 ch->collector_policy()->set_all_soft_refs_clear(false);
49 }
50
51 // The same dtrace probe can't be inserted in two different files, so we
52 // have to call it here, so it's only in one file. Can't create new probes
53 // for the other file anymore. The dtrace probes have to remain stable.
54 void VM_GC_Operation::notify_gc_begin(bool full) {
55 HOTSPOT_GC_BEGIN(
56 full);
57 HS_DTRACE_WORKAROUND_TAIL_CALL_BUG();
58 }
59
60 void VM_GC_Operation::notify_gc_end() {
61 HOTSPOT_GC_END();
62 HS_DTRACE_WORKAROUND_TAIL_CALL_BUG();
63 }
64
65 // Allocations may fail in several threads at about the same time,
66 // resulting in multiple gc requests. We only want to do one of them.
67 // In case a GC locker is active and the need for a GC is already signaled,
68 // we want to skip this GC attempt altogether, without doing a futile
69 // safepoint operation.
70 bool VM_GC_Operation::skip_operation() const {
71 bool skip = (_gc_count_before != Universe::heap()->total_collections());
72 if (_full && skip) {
73 skip = (_full_gc_count_before != Universe::heap()->total_full_collections());
74 }
75 if (!skip && GCLocker::is_active_and_needs_gc()) {
76 skip = Universe::heap()->is_maximal_no_gc();
77 assert(!(skip && (_gc_cause == GCCause::_gc_locker)),
78 "GCLocker cannot be active when initiating GC");
79 }
80 return skip;
81 }
82
83 bool VM_GC_Operation::doit_prologue() {
84 assert(Thread::current()->is_Java_thread(), "just checking");
85 assert(((_gc_cause != GCCause::_no_gc) &&
86 (_gc_cause != GCCause::_no_cause_specified)), "Illegal GCCause");
87
88 // To be able to handle a GC the VM initialization needs to be completed.
89 if (!is_init_completed()) {
90 vm_exit_during_initialization(
91 err_msg("GC triggered before VM initialization completed. Try increasing "
92 "NewSize, current value " SIZE_FORMAT "%s.",
93 byte_size_in_proper_unit(NewSize),
94 proper_unit_for_byte_size(NewSize)));
95 }
96
97 // If the GC count has changed someone beat us to the collection
98 Heap_lock->lock();
99
100 // Check invocations
101 if (skip_operation()) {
102 // skip collection
103 Heap_lock->unlock();
104 _prologue_succeeded = false;
105 } else {
106 _prologue_succeeded = true;
107 }
108 return _prologue_succeeded;
109 }
110
111
112 void VM_GC_Operation::doit_epilogue() {
113 assert(Thread::current()->is_Java_thread(), "just checking");
114 if (Universe::has_reference_pending_list()) {
115 Heap_lock->notify_all();
116 }
117 Heap_lock->unlock();
118 }
119
120 bool VM_GC_HeapInspection::skip_operation() const {
121 return false;
122 }
123
124 bool VM_GC_HeapInspection::collect() {
125 if (GCLocker::is_active()) {
126 return false;
127 }
128 Universe::heap()->collect_as_vm_thread(GCCause::_heap_inspection);
129 return true;
130 }
131
132 void VM_GC_HeapInspection::doit() {
133 HandleMark hm;
134 Universe::heap()->ensure_parsability(false); // must happen, even if collection does
135 // not happen (e.g. due to GCLocker)
136 // or _full_gc being false
137 if (_full_gc) {
|