Mercurial > hg > truffle
comparison src/share/vm/memory/metaspace.cpp @ 10376:a1ebd310d5c1
8014912: Restore PrintSharedSpaces functionality after NPG
Summary: Added dumping of object sizes in CDS archive, sorted by MetaspaceObj::Type
Reviewed-by: coleenp, acorn
author | iklam |
---|---|
date | Tue, 28 May 2013 16:36:19 -0700 |
parents | 2b1a9d972fc2 |
children | df7e1c0e3dc1 de2d15ce3d4a |
comparison
equal
deleted
inserted
replaced
10353:9ea643afcaaf | 10376:a1ebd310d5c1 |
---|---|
711 void verify_chunk_size(Metachunk* chunk); | 711 void verify_chunk_size(Metachunk* chunk); |
712 NOT_PRODUCT(void mangle_freed_chunks();) | 712 NOT_PRODUCT(void mangle_freed_chunks();) |
713 #ifdef ASSERT | 713 #ifdef ASSERT |
714 void verify_allocated_blocks_words(); | 714 void verify_allocated_blocks_words(); |
715 #endif | 715 #endif |
716 | |
717 size_t get_raw_word_size(size_t word_size) { | |
718 // If only the dictionary is going to be used (i.e., no | |
719 // indexed free list), then there is a minimum size requirement. | |
720 // MinChunkSize is a placeholder for the real minimum size JJJ | |
721 size_t byte_size = word_size * BytesPerWord; | |
722 | |
723 size_t byte_size_with_overhead = byte_size + Metablock::overhead(); | |
724 | |
725 size_t raw_bytes_size = MAX2(byte_size_with_overhead, | |
726 Metablock::min_block_byte_size()); | |
727 raw_bytes_size = ARENA_ALIGN(raw_bytes_size); | |
728 size_t raw_word_size = raw_bytes_size / BytesPerWord; | |
729 assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem"); | |
730 | |
731 return raw_word_size; | |
732 } | |
716 }; | 733 }; |
717 | 734 |
718 uint const SpaceManager::_small_chunk_limit = 4; | 735 uint const SpaceManager::_small_chunk_limit = 4; |
719 | 736 |
720 const char* SpaceManager::_expand_lock_name = | 737 const char* SpaceManager::_expand_lock_name = |
2318 } | 2335 } |
2319 | 2336 |
2320 MetaWord* SpaceManager::allocate(size_t word_size) { | 2337 MetaWord* SpaceManager::allocate(size_t word_size) { |
2321 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); | 2338 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); |
2322 | 2339 |
2323 // If only the dictionary is going to be used (i.e., no | 2340 size_t raw_word_size = get_raw_word_size(word_size); |
2324 // indexed free list), then there is a minimum size requirement. | |
2325 // MinChunkSize is a placeholder for the real minimum size JJJ | |
2326 size_t byte_size = word_size * BytesPerWord; | |
2327 | |
2328 size_t byte_size_with_overhead = byte_size + Metablock::overhead(); | |
2329 | |
2330 size_t raw_bytes_size = MAX2(byte_size_with_overhead, | |
2331 Metablock::min_block_byte_size()); | |
2332 raw_bytes_size = ARENA_ALIGN(raw_bytes_size); | |
2333 size_t raw_word_size = raw_bytes_size / BytesPerWord; | |
2334 assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem"); | |
2335 | |
2336 BlockFreelist* fl = block_freelists(); | 2341 BlockFreelist* fl = block_freelists(); |
2337 MetaWord* p = NULL; | 2342 MetaWord* p = NULL; |
2338 // Allocation from the dictionary is expensive in the sense that | 2343 // Allocation from the dictionary is expensive in the sense that |
2339 // the dictionary has to be searched for a size. Don't allocate | 2344 // the dictionary has to be searched for a size. Don't allocate |
2340 // from the dictionary until it starts to get fat. Is this | 2345 // from the dictionary until it starts to get fat. Is this |
2894 class_space_list()->get_initialization_chunk(class_word_size, | 2899 class_space_list()->get_initialization_chunk(class_word_size, |
2895 class_vsm()->medium_chunk_bunch()); | 2900 class_vsm()->medium_chunk_bunch()); |
2896 if (class_chunk != NULL) { | 2901 if (class_chunk != NULL) { |
2897 class_vsm()->add_chunk(class_chunk, true); | 2902 class_vsm()->add_chunk(class_chunk, true); |
2898 } | 2903 } |
2904 | |
2905 _alloc_record_head = NULL; | |
2906 _alloc_record_tail = NULL; | |
2899 } | 2907 } |
2900 | 2908 |
2901 size_t Metaspace::align_word_size_up(size_t word_size) { | 2909 size_t Metaspace::align_word_size_up(size_t word_size) { |
2902 size_t byte_size = word_size * wordSize; | 2910 size_t byte_size = word_size * wordSize; |
2903 return ReservedSpace::allocation_align_size_up(byte_size) / wordSize; | 2911 return ReservedSpace::allocation_align_size_up(byte_size) / wordSize; |
2998 } | 3006 } |
2999 } | 3007 } |
3000 } | 3008 } |
3001 | 3009 |
3002 Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, | 3010 Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, |
3003 bool read_only, MetadataType mdtype, TRAPS) { | 3011 bool read_only, MetaspaceObj::Type type, TRAPS) { |
3004 if (HAS_PENDING_EXCEPTION) { | 3012 if (HAS_PENDING_EXCEPTION) { |
3005 assert(false, "Should not allocate with exception pending"); | 3013 assert(false, "Should not allocate with exception pending"); |
3006 return NULL; // caller does a CHECK_NULL too | 3014 return NULL; // caller does a CHECK_NULL too |
3007 } | 3015 } |
3016 | |
3017 MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType; | |
3008 | 3018 |
3009 // SSS: Should we align the allocations and make sure the sizes are aligned. | 3019 // SSS: Should we align the allocations and make sure the sizes are aligned. |
3010 MetaWord* result = NULL; | 3020 MetaWord* result = NULL; |
3011 | 3021 |
3012 assert(loader_data != NULL, "Should never pass around a NULL loader_data. " | 3022 assert(loader_data != NULL, "Should never pass around a NULL loader_data. " |
3013 "ClassLoaderData::the_null_class_loader_data() should have been used."); | 3023 "ClassLoaderData::the_null_class_loader_data() should have been used."); |
3014 // Allocate in metaspaces without taking out a lock, because it deadlocks | 3024 // Allocate in metaspaces without taking out a lock, because it deadlocks |
3015 // with the SymbolTable_lock. Dumping is single threaded for now. We'll have | 3025 // with the SymbolTable_lock. Dumping is single threaded for now. We'll have |
3016 // to revisit this for application class data sharing. | 3026 // to revisit this for application class data sharing. |
3017 if (DumpSharedSpaces) { | 3027 if (DumpSharedSpaces) { |
3018 if (read_only) { | 3028 assert(type > MetaspaceObj::UnknownType && type < MetaspaceObj::_number_of_types, "sanity"); |
3019 result = loader_data->ro_metaspace()->allocate(word_size, NonClassType); | 3029 Metaspace* space = read_only ? loader_data->ro_metaspace() : loader_data->rw_metaspace(); |
3020 } else { | 3030 result = space->allocate(word_size, NonClassType); |
3021 result = loader_data->rw_metaspace()->allocate(word_size, NonClassType); | |
3022 } | |
3023 if (result == NULL) { | 3031 if (result == NULL) { |
3024 report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite); | 3032 report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite); |
3033 } else { | |
3034 space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size)); | |
3025 } | 3035 } |
3026 return Metablock::initialize(result, word_size); | 3036 return Metablock::initialize(result, word_size); |
3027 } | 3037 } |
3028 | 3038 |
3029 result = loader_data->metaspace_non_null()->allocate(word_size, mdtype); | 3039 result = loader_data->metaspace_non_null()->allocate(word_size, mdtype); |
3054 } | 3064 } |
3055 } | 3065 } |
3056 return Metablock::initialize(result, word_size); | 3066 return Metablock::initialize(result, word_size); |
3057 } | 3067 } |
3058 | 3068 |
3069 void Metaspace::record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size) { | |
3070 assert(DumpSharedSpaces, "sanity"); | |
3071 | |
3072 AllocRecord *rec = new AllocRecord((address)ptr, type, (int)word_size * HeapWordSize); | |
3073 if (_alloc_record_head == NULL) { | |
3074 _alloc_record_head = _alloc_record_tail = rec; | |
3075 } else { | |
3076 _alloc_record_tail->_next = rec; | |
3077 _alloc_record_tail = rec; | |
3078 } | |
3079 } | |
3080 | |
3081 void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) { | |
3082 assert(DumpSharedSpaces, "unimplemented for !DumpSharedSpaces"); | |
3083 | |
3084 address last_addr = (address)bottom(); | |
3085 | |
3086 for (AllocRecord *rec = _alloc_record_head; rec; rec = rec->_next) { | |
3087 address ptr = rec->_ptr; | |
3088 if (last_addr < ptr) { | |
3089 closure->doit(last_addr, MetaspaceObj::UnknownType, ptr - last_addr); | |
3090 } | |
3091 closure->doit(ptr, rec->_type, rec->_byte_size); | |
3092 last_addr = ptr + rec->_byte_size; | |
3093 } | |
3094 | |
3095 address top = ((address)bottom()) + used_bytes_slow(Metaspace::NonClassType); | |
3096 if (last_addr < top) { | |
3097 closure->doit(last_addr, MetaspaceObj::UnknownType, top - last_addr); | |
3098 } | |
3099 } | |
3100 | |
3059 void Metaspace::purge() { | 3101 void Metaspace::purge() { |
3060 MutexLockerEx cl(SpaceManager::expand_lock(), | 3102 MutexLockerEx cl(SpaceManager::expand_lock(), |
3061 Mutex::_no_safepoint_check_flag); | 3103 Mutex::_no_safepoint_check_flag); |
3062 space_list()->purge(); | 3104 space_list()->purge(); |
3063 class_space_list()->purge(); | 3105 class_space_list()->purge(); |