24 #include "precompiled.hpp" |
24 #include "precompiled.hpp" |
25 #include "code/codeCache.hpp" |
25 #include "code/codeCache.hpp" |
26 #include "code/nmethod.hpp" |
26 #include "code/nmethod.hpp" |
27 #include "gc/shenandoah/shenandoahHeap.inline.hpp" |
27 #include "gc/shenandoah/shenandoahHeap.inline.hpp" |
28 #include "gc/shenandoah/shenandoahCodeRoots.hpp" |
28 #include "gc/shenandoah/shenandoahCodeRoots.hpp" |
|
29 #include "gc/shenandoah/shenandoahUtils.hpp" |
29 #include "memory/resourceArea.hpp" |
30 #include "memory/resourceArea.hpp" |
30 #include "memory/universe.hpp" |
31 #include "memory/universe.hpp" |
31 |
32 |
32 ShenandoahParallelCodeCacheIterator::ShenandoahParallelCodeCacheIterator(const GrowableArray<CodeHeap*>* heaps) { |
33 ShenandoahParallelCodeCacheIterator::ShenandoahParallelCodeCacheIterator(const GrowableArray<CodeHeap*>* heaps) { |
33 _length = heaps->length(); |
34 _length = heaps->length(); |
119 return !_oops.is_empty(); |
120 return !_oops.is_empty(); |
120 } |
121 } |
121 }; |
122 }; |
122 |
123 |
123 GrowableArray<ShenandoahNMethod*>* ShenandoahCodeRoots::_recorded_nms; |
124 GrowableArray<ShenandoahNMethod*>* ShenandoahCodeRoots::_recorded_nms; |
|
125 ShenandoahLock ShenandoahCodeRoots::_recorded_nms_lock; |
124 |
126 |
125 void ShenandoahCodeRoots::initialize() { |
127 void ShenandoahCodeRoots::initialize() { |
126 _recorded_nms = new (ResourceObj::C_HEAP, mtGC) GrowableArray<ShenandoahNMethod*>(100, true, mtGC); |
128 _recorded_nms = new (ResourceObj::C_HEAP, mtGC) GrowableArray<ShenandoahNMethod*>(100, true, mtGC); |
127 } |
129 } |
128 |
130 |
129 void ShenandoahCodeRoots::add_nmethod(nmethod* nm) { |
131 void ShenandoahCodeRoots::add_nmethod(nmethod* nm) { |
130 assert(CodeCache_lock->owned_by_self(), "Must own CodeCache_lock"); |
|
131 switch (ShenandoahCodeRootsStyle) { |
132 switch (ShenandoahCodeRootsStyle) { |
132 case 0: |
133 case 0: |
133 case 1: |
134 case 1: |
134 break; |
135 break; |
135 case 2: { |
136 case 2: { |
|
137 assert_locked_or_safepoint(CodeCache_lock); |
|
138 ShenandoahLocker locker(CodeCache_lock->owned_by_self() ? NULL : &_recorded_nms_lock); |
|
139 |
136 ShenandoahNMethodOopDetector detector; |
140 ShenandoahNMethodOopDetector detector; |
137 nm->oops_do(&detector); |
141 nm->oops_do(&detector); |
138 |
142 |
139 if (detector.has_oops()) { |
143 if (detector.has_oops()) { |
140 ShenandoahNMethod* nmr = new ShenandoahNMethod(nm, detector.oops()); |
144 ShenandoahNMethod* nmr = new ShenandoahNMethod(nm, detector.oops()); |
154 ShouldNotReachHere(); |
158 ShouldNotReachHere(); |
155 } |
159 } |
156 }; |
160 }; |
157 |
161 |
158 void ShenandoahCodeRoots::remove_nmethod(nmethod* nm) { |
162 void ShenandoahCodeRoots::remove_nmethod(nmethod* nm) { |
159 assert(CodeCache_lock->owned_by_self(), "Must own CodeCache_lock"); |
|
160 switch (ShenandoahCodeRootsStyle) { |
163 switch (ShenandoahCodeRootsStyle) { |
161 case 0: |
164 case 0: |
162 case 1: { |
165 case 1: { |
163 break; |
166 break; |
164 } |
167 } |
165 case 2: { |
168 case 2: { |
|
169 assert_locked_or_safepoint(CodeCache_lock); |
|
170 ShenandoahLocker locker(CodeCache_lock->owned_by_self() ? NULL : &_recorded_nms_lock); |
|
171 |
166 ShenandoahNMethodOopDetector detector; |
172 ShenandoahNMethodOopDetector detector; |
167 nm->oops_do(&detector, /* allow_zombie = */ true); |
173 nm->oops_do(&detector, /* allow_zombie = */ true); |
168 |
174 |
169 if (detector.has_oops()) { |
175 if (detector.has_oops()) { |
170 int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod); |
176 int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod); |