comparison src/share/vm/memory/metaspace.cpp @ 14190:ce86c36b8921

8029178: Parallel class loading test anonymous-simple gets SIGSEGV in Metaspace::contains Summary: Metaspace::contains cannot look at purged metaspaces while CMS concurrently deallocates them. Reviewed-by: mgerdin, sspitsyn, jmasa
author coleenp
date Tue, 07 Jan 2014 13:26:56 -0500
parents 11b116661830
children db1ff6781ab4
comparison
equal deleted inserted replaced
14189:1a899ea6b7ed 14190:ce86c36b8921
511 void dec_virtual_space_count(); 511 void dec_virtual_space_count();
512 512
513 // Unlink empty VirtualSpaceNodes and free it. 513 // Unlink empty VirtualSpaceNodes and free it.
514 void purge(ChunkManager* chunk_manager); 514 void purge(ChunkManager* chunk_manager);
515 515
516 bool contains(const void *ptr);
517
518 void print_on(outputStream* st) const; 516 void print_on(outputStream* st) const;
519 517
520 class VirtualSpaceListIterator : public StackObj { 518 class VirtualSpaceListIterator : public StackObj {
521 VirtualSpaceNode* _virtual_spaces; 519 VirtualSpaceNode* _virtual_spaces;
522 public: 520 public:
556 friend class Metaspace; 554 friend class Metaspace;
557 friend class Metadebug; 555 friend class Metadebug;
558 556
559 private: 557 private:
560 558
561 // protects allocations and contains. 559 // protects allocations
562 Mutex* const _lock; 560 Mutex* const _lock;
563 561
564 // Type of metadata allocated. 562 // Type of metadata allocated.
565 Metaspace::MetadataType _mdtype; 563 Metaspace::MetadataType _mdtype;
566 564
593 static Mutex* const _expand_lock; 591 static Mutex* const _expand_lock;
594 592
595 private: 593 private:
596 // Accessors 594 // Accessors
597 Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; } 595 Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; }
598 void set_chunks_in_use(ChunkIndex index, Metachunk* v) { _chunks_in_use[index] = v; } 596 void set_chunks_in_use(ChunkIndex index, Metachunk* v) {
597 // ensure lock-free iteration sees fully initialized node
598 OrderAccess::storestore();
599 _chunks_in_use[index] = v;
600 }
599 601
600 BlockFreelist* block_freelists() const { 602 BlockFreelist* block_freelists() const {
601 return (BlockFreelist*) &_block_freelists; 603 return (BlockFreelist*) &_block_freelists;
602 } 604 }
603 605
705 // debugging support. 707 // debugging support.
706 708
707 void dump(outputStream* const out) const; 709 void dump(outputStream* const out) const;
708 void print_on(outputStream* st) const; 710 void print_on(outputStream* st) const;
709 void locked_print_chunks_in_use_on(outputStream* st) const; 711 void locked_print_chunks_in_use_on(outputStream* st) const;
712
713 bool contains(const void *ptr);
710 714
711 void verify(); 715 void verify();
712 void verify_chunk_size(Metachunk* chunk); 716 void verify_chunk_size(Metachunk* chunk);
713 NOT_PRODUCT(void mangle_freed_chunks();) 717 NOT_PRODUCT(void mangle_freed_chunks();)
714 #ifdef ASSERT 718 #ifdef ASSERT
1157 delete new_entry; 1161 delete new_entry;
1158 return false; 1162 return false;
1159 } else { 1163 } else {
1160 assert(new_entry->reserved_words() == vs_word_size, 1164 assert(new_entry->reserved_words() == vs_word_size,
1161 "Reserved memory size differs from requested memory size"); 1165 "Reserved memory size differs from requested memory size");
1162 // ensure lock-free iteration sees fully initialized node
1163 OrderAccess::storestore();
1164 link_vs(new_entry); 1166 link_vs(new_entry);
1165 return true; 1167 return true;
1166 } 1168 }
1167 } 1169 }
1168 1170
1284 VirtualSpaceNode* node = iter.get_next(); 1286 VirtualSpaceNode* node = iter.get_next();
1285 node->print_on(st); 1287 node->print_on(st);
1286 } 1288 }
1287 } 1289 }
1288 } 1290 }
1289
1290 bool VirtualSpaceList::contains(const void *ptr) {
1291 VirtualSpaceNode* list = virtual_space_list();
1292 VirtualSpaceListIterator iter(list);
1293 while (iter.repeat()) {
1294 VirtualSpaceNode* node = iter.get_next();
1295 if (node->reserved()->contains(ptr)) {
1296 return true;
1297 }
1298 }
1299 return false;
1300 }
1301
1302 1291
1303 // MetaspaceGC methods 1292 // MetaspaceGC methods
1304 1293
1305 // VM_CollectForMetadataAllocation is the vm operation used to GC. 1294 // VM_CollectForMetadataAllocation is the vm operation used to GC.
1306 // Within the VM operation after the GC the attempt to allocate the metadata 1295 // Within the VM operation after the GC the attempt to allocate the metadata
2390 } 2379 }
2391 2380
2392 return result; 2381 return result;
2393 } 2382 }
2394 2383
2384 // This function looks at the chunks in the metaspace without locking.
2385 // The chunks are added with store ordering and not deleted except for at
2386 // unloading time.
2387 bool SpaceManager::contains(const void *ptr) {
2388 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i))
2389 {
2390 Metachunk* curr = chunks_in_use(i);
2391 while (curr != NULL) {
2392 if (curr->contains(ptr)) return true;
2393 curr = curr->next();
2394 }
2395 }
2396 return false;
2397 }
2398
2395 void SpaceManager::verify() { 2399 void SpaceManager::verify() {
2396 // If there are blocks in the dictionary, then 2400 // If there are blocks in the dictionary, then
2397 // verfication of chunks does not work since 2401 // verfication of chunks does not work since
2398 // being in the dictionary alters a chunk. 2402 // being in the dictionary alters a chunk.
2399 if (block_freelists()->total_size() == 0) { 2403 if (block_freelists()->total_size() == 0) {
3461 class_vsm()->print_on(out); 3465 class_vsm()->print_on(out);
3462 } 3466 }
3463 } 3467 }
3464 } 3468 }
3465 3469
3466 bool Metaspace::contains(const void * ptr) { 3470 bool Metaspace::contains(const void* ptr) {
3467 if (MetaspaceShared::is_in_shared_space(ptr)) { 3471 if (vsm()->contains(ptr)) return true;
3468 return true; 3472 if (using_class_space()) {
3469 } 3473 return class_vsm()->contains(ptr);
3470 // This is checked while unlocked. As long as the virtualspaces are added 3474 }
3471 // at the end, the pointer will be in one of them. The virtual spaces 3475 return false;
3472 // aren't deleted presently. When they are, some sort of locking might
3473 // be needed. Note, locking this can cause inversion problems with the
3474 // caller in MetaspaceObj::is_metadata() function.
3475 return space_list()->contains(ptr) ||
3476 (using_class_space() && class_space_list()->contains(ptr));
3477 } 3476 }
3478 3477
3479 void Metaspace::verify() { 3478 void Metaspace::verify() {
3480 vsm()->verify(); 3479 vsm()->verify();
3481 if (using_class_space()) { 3480 if (using_class_space()) {