220 }
221 void do_oop(narrowOop* o) {
222 fatal("NMethods should not have compressed oops embedded.");
223 }
224
225 GrowableArray<oop*>* oops() {
226 return &_oops;
227 }
228
229 bool has_oops() {
230 return !_oops.is_empty();
231 }
232 };
233
234 void ShenandoahNMethod::assert_same_oops(bool allow_dead) {
235 ShenandoahNMethodOopDetector detector;
236 nm()->oops_do(&detector, allow_dead);
237
238 GrowableArray<oop*>* oops = detector.oops();
239
240 assert(oops->length() == oop_count(), "Must match");
241
242 for (int index = 0; index < _oops_count; index ++) {
243 assert(oops->contains(_oops[index]), "Must contain this oop");
244 }
245
246 for (oop* p = nm()->oops_begin(); p < nm()->oops_end(); p ++) {
247 assert(oops->contains(p), "Must contain this oop");
248 }
249 }
250
251 void ShenandoahNMethod::assert_no_oops(nmethod* nm, bool allow_dead) {
252 ShenandoahNMethodOopDetector detector;
253 nm->oops_do(&detector, allow_dead);
254 assert(detector.oops()->length() == 0, "Should not have oops");
255 }
256 #endif
257
258 ShenandoahNMethodTable::ShenandoahNMethodTable() :
259 _heap(ShenandoahHeap::heap()),
260 _size(minSize),
261 _index(0),
262 _iteration_in_progress(false) {
263 _array = NEW_C_HEAP_ARRAY(ShenandoahNMethod*, _size, mtGC);
264 }
265
266 ShenandoahNMethodTable::~ShenandoahNMethodTable() {
267 assert(_array != NULL, "Sanity");
268 FREE_C_HEAP_ARRAY(ShenandoahNMethod*, _array);
269 }
270
271 void ShenandoahNMethodTable::register_nmethod(nmethod* nm) {
272 assert(CodeCache_lock->owned_by_self(), "Must have CodeCache_lock held");
273 assert(_index >= 0 && _index <= _size, "Sanity");
274
275 ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm);
276 ShenandoahReentrantLocker data_locker(data != NULL ? data->lock() : NULL);
277
278 if (data != NULL) {
279 assert(contain(nm), "Must have been registered");
280 data->update();
281 } else {
282 data = ShenandoahNMethod::for_nmethod(nm);
283 if (data == NULL) {
284 assert(!ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(),
285 "Only possible when concurrent class unloading is off");
286 return;
287 }
288 ShenandoahNMethod::attach_gc_data(nm, data);
289 ShenandoahLocker locker(&_lock);
290 log_register_nmethod(nm);
291 append(data);
292 }
293 // Disarm new nmethod
294 ShenandoahNMethod::disarm_nmethod(nm);
295 }
296
297 void ShenandoahNMethodTable::unregister_nmethod(nmethod* nm) {
298 assert_locked_or_safepoint(CodeCache_lock);
299
|
220 }
221 void do_oop(narrowOop* o) {
222 fatal("NMethods should not have compressed oops embedded.");
223 }
224
225 GrowableArray<oop*>* oops() {
226 return &_oops;
227 }
228
229 bool has_oops() {
230 return !_oops.is_empty();
231 }
232 };
233
234 void ShenandoahNMethod::assert_same_oops(bool allow_dead) {
235 ShenandoahNMethodOopDetector detector;
236 nm()->oops_do(&detector, allow_dead);
237
238 GrowableArray<oop*>* oops = detector.oops();
239
240 int count = 0;
241 for (int index = 0; index < _oops_count; index ++) {
242 count++;
243 assert(oops->contains(_oops[index]), "Must contain this oop");
244 }
245
246 for (oop* p = nm()->oops_begin(); p < nm()->oops_end(); p ++) {
247 if (*p == Universe::non_oop_word()) continue;
248 count++;
249 assert(oops->contains(p), "Must contain this oop");
250 }
251 #ifdef ASSERT_DISABLED
252 if (oops->length() < count) {
253 tty->print_cr("detected locs: %d", oops->length());
254 for (int i = 0; i < oops->length(); i++) {
255 tty->print_cr("-> " PTR_FORMAT, p2i(oops->at(i)));
256 }
257 tty->print_cr("recorded oops: %d", _oops_count);
258 for (int i = 0; i < _oops_count; i++) {
259 tty->print_cr("-> " PTR_FORMAT, p2i(_oops[i]));
260 }
261 GrowableArray<oop*> check;
262 bool non_immed;
263 detect_reloc_oops(nm(), check, non_immed);
264 tty->print_cr("check oops: %d", check.length());
265 for (int i = 0; i < check.length(); i++) {
266 tty->print_cr("-> " PTR_FORMAT, p2i(check.at(i)));
267 }
268 assert(false, "Must match #detected: %d, #recorded: %d, #total: %d, begin: " PTR_FORMAT ", end: " PTR_FORMAT, oops->length(), _oops_count, count, p2i(nm()->oops_begin()), p2i(nm()->oops_end()));
269 }
270 #endif
271 assert(oops->length() >= count,
272 "Must match #detected: %d, #recorded: %d, #total: %d, begin: " PTR_FORMAT ", end: " PTR_FORMAT,
273 oops->length(), _oops_count, count, p2i(nm()->oops_begin()), p2i(nm()->oops_end()));
274 }
275
276 void ShenandoahNMethod::assert_no_oops(nmethod* nm, bool allow_dead) {
277 ShenandoahNMethodOopDetector detector;
278 nm->oops_do(&detector, allow_dead);
279 assert(detector.oops()->length() == 0, "Should not have oops");
280 }
281 #endif
282
283 ShenandoahNMethodTable::ShenandoahNMethodTable() :
284 _heap(ShenandoahHeap::heap()),
285 _size(minSize),
286 _index(0),
287 _iteration_in_progress(false) {
288 _array = NEW_C_HEAP_ARRAY(ShenandoahNMethod*, _size, mtGC);
289 }
290
291 ShenandoahNMethodTable::~ShenandoahNMethodTable() {
292 assert(_array != NULL, "Sanity");
293 FREE_C_HEAP_ARRAY(ShenandoahNMethod*, _array);
294 }
295
296 void ShenandoahNMethodTable::register_nmethod(nmethod* nm) {
297 assert(CodeCache_lock->owned_by_self(), "Must have CodeCache_lock held");
298 assert(_index >= 0 && _index <= _size, "Sanity");
299
300 ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm);
301 ShenandoahReentrantLocker data_locker(data != NULL ? data->lock() : NULL);
302
303 if (data != NULL) {
304 assert(contain(nm), "Must have been registered");
305 assert(nm == data->nm(), "must be same nmethod");
306 data->update();
307 } else {
308 data = ShenandoahNMethod::for_nmethod(nm);
309 if (data == NULL) {
310 assert(!ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(),
311 "Only possible when concurrent class unloading is off");
312 return;
313 }
314 ShenandoahNMethod::attach_gc_data(nm, data);
315 ShenandoahLocker locker(&_lock);
316 log_register_nmethod(nm);
317 append(data);
318 }
319 // Disarm new nmethod
320 ShenandoahNMethod::disarm_nmethod(nm);
321 }
322
323 void ShenandoahNMethodTable::unregister_nmethod(nmethod* nm) {
324 assert_locked_or_safepoint(CodeCache_lock);
325
|