1.1 --- a/src/share/vm/memory/metaspace.cpp Fri Aug 22 12:03:49 2014 -0700 1.2 +++ b/src/share/vm/memory/metaspace.cpp Thu Aug 21 13:57:51 2014 -0700 1.3 @@ -413,6 +413,7 @@ 1.4 VirtualSpaceNode::VirtualSpaceNode(size_t bytes) : _top(NULL), _next(NULL), _rs(), _container_count(0) { 1.5 assert_is_size_aligned(bytes, Metaspace::reserve_alignment()); 1.6 1.7 +#if INCLUDE_CDS 1.8 // This allocates memory with mmap. For DumpSharedspaces, try to reserve 1.9 // configurable address, generally at the top of the Java heap so other 1.10 // memory addresses don't conflict. 1.11 @@ -428,7 +429,9 @@ 1.12 _rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages); 1.13 } 1.14 MetaspaceShared::set_shared_rs(&_rs); 1.15 - } else { 1.16 + } else 1.17 +#endif 1.18 + { 1.19 bool large_pages = should_commit_large_pages_when_reserving(bytes); 1.20 1.21 _rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages); 1.22 @@ -2937,11 +2940,14 @@ 1.23 // between the lower base and higher address. 1.24 address lower_base; 1.25 address higher_address; 1.26 +#if INCLUDE_CDS 1.27 if (UseSharedSpaces) { 1.28 higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()), 1.29 (address)(metaspace_base + compressed_class_space_size())); 1.30 lower_base = MIN2(metaspace_base, cds_base); 1.31 - } else { 1.32 + } else 1.33 +#endif 1.34 + { 1.35 higher_address = metaspace_base + compressed_class_space_size(); 1.36 lower_base = metaspace_base; 1.37 1.38 @@ -2962,6 +2968,7 @@ 1.39 } 1.40 } 1.41 1.42 +#if INCLUDE_CDS 1.43 // Return TRUE if the specified metaspace_base and cds_base are close enough 1.44 // to work with compressed klass pointers. 1.45 bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base) { 1.46 @@ -2972,6 +2979,7 @@ 1.47 (address)(metaspace_base + compressed_class_space_size())); 1.48 return ((uint64_t)(higher_address - lower_base) <= UnscaledClassSpaceMax); 1.49 } 1.50 +#endif 1.51 1.52 // Try to allocate the metaspace at the requested addr. 1.53 void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base) { 1.54 @@ -2991,6 +2999,7 @@ 1.55 large_pages, 1.56 requested_addr, 0); 1.57 if (!metaspace_rs.is_reserved()) { 1.58 +#if INCLUDE_CDS 1.59 if (UseSharedSpaces) { 1.60 size_t increment = align_size_up(1*G, _reserve_alignment); 1.61 1.62 @@ -3005,7 +3014,7 @@ 1.63 _reserve_alignment, large_pages, addr, 0); 1.64 } 1.65 } 1.66 - 1.67 +#endif 1.68 // If no successful allocation then try to allocate the space anywhere. If 1.69 // that fails then OOM doom. At this point we cannot try allocating the 1.70 // metaspace as if UseCompressedClassPointers is off because too much 1.71 @@ -3024,12 +3033,13 @@ 1.72 // If we got here then the metaspace got allocated. 1.73 MemTracker::record_virtual_memory_type((address)metaspace_rs.base(), mtClass); 1.74 1.75 +#if INCLUDE_CDS 1.76 // Verify that we can use shared spaces. Otherwise, turn off CDS. 1.77 if (UseSharedSpaces && !can_use_cds_with_metaspace_addr(metaspace_rs.base(), cds_base)) { 1.78 FileMapInfo::stop_sharing_and_unmap( 1.79 "Could not allocate metaspace at a compatible address"); 1.80 } 1.81 - 1.82 +#endif 1.83 set_narrow_klass_base_and_shift((address)metaspace_rs.base(), 1.84 UseSharedSpaces ? (address)cds_base : 0); 1.85 1.86 @@ -3113,6 +3123,7 @@ 1.87 MetaspaceShared::set_max_alignment(max_alignment); 1.88 1.89 if (DumpSharedSpaces) { 1.90 +#if INCLUDE_CDS 1.91 SharedReadOnlySize = align_size_up(SharedReadOnlySize, max_alignment); 1.92 SharedReadWriteSize = align_size_up(SharedReadWriteSize, max_alignment); 1.93 SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment); 1.94 @@ -3150,23 +3161,22 @@ 1.95 } 1.96 1.97 Universe::set_narrow_klass_shift(0); 1.98 -#endif 1.99 - 1.100 +#endif // _LP64 1.101 +#endif // INCLUDE_CDS 1.102 } else { 1.103 +#if INCLUDE_CDS 1.104 // If using shared space, open the file that contains the shared space 1.105 // and map in the memory before initializing the rest of metaspace (so 1.106 // the addresses don't conflict) 1.107 address cds_address = NULL; 1.108 if (UseSharedSpaces) { 1.109 FileMapInfo* mapinfo = new FileMapInfo(); 1.110 - memset(mapinfo, 0, sizeof(FileMapInfo)); 1.111 1.112 // Open the shared archive file, read and validate the header. If 1.113 // initialization fails, shared spaces [UseSharedSpaces] are 1.114 // disabled and the file is closed. 1.115 // Map in spaces now also 1.116 if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) { 1.117 - FileMapInfo::set_current_info(mapinfo); 1.118 cds_total = FileMapInfo::shared_spaces_size(); 1.119 cds_address = (address)mapinfo->region_base(0); 1.120 } else { 1.121 @@ -3174,21 +3184,23 @@ 1.122 "archive file not closed or shared spaces not disabled."); 1.123 } 1.124 } 1.125 - 1.126 +#endif // INCLUDE_CDS 1.127 #ifdef _LP64 1.128 // If UseCompressedClassPointers is set then allocate the metaspace area 1.129 // above the heap and above the CDS area (if it exists). 1.130 if (using_class_space()) { 1.131 if (UseSharedSpaces) { 1.132 +#if INCLUDE_CDS 1.133 char* cds_end = (char*)(cds_address + cds_total); 1.134 cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment); 1.135 allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address); 1.136 +#endif 1.137 } else { 1.138 char* base = (char*)align_ptr_up(Universe::heap()->reserved_region().end(), _reserve_alignment); 1.139 allocate_metaspace_compressed_klass_ptrs(base, 0); 1.140 } 1.141 } 1.142 -#endif 1.143 +#endif // _LP64 1.144 1.145 // Initialize these before initializing the VirtualSpaceList 1.146 _first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord; 1.147 @@ -3366,6 +3378,10 @@ 1.148 1.149 void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) { 1.150 if (SafepointSynchronize::is_at_safepoint()) { 1.151 + if (DumpSharedSpaces && PrintSharedSpaces) { 1.152 + record_deallocation(ptr, vsm()->get_raw_word_size(word_size)); 1.153 + } 1.154 + 1.155 assert(Thread::current()->is_VM_thread(), "should be the VM thread"); 1.156 // Don't take Heap_lock 1.157 MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag); 1.158 @@ -3420,8 +3436,9 @@ 1.159 if (result == NULL) { 1.160 report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite); 1.161 } 1.162 - 1.163 - space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size)); 1.164 + if (PrintSharedSpaces) { 1.165 + space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size)); 1.166 + } 1.167 1.168 // Zero initialize. 1.169 Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0); 1.170 @@ -3520,15 +3537,55 @@ 1.171 void Metaspace::record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size) { 1.172 assert(DumpSharedSpaces, "sanity"); 1.173 1.174 - AllocRecord *rec = new AllocRecord((address)ptr, type, (int)word_size * HeapWordSize); 1.175 + int byte_size = (int)word_size * HeapWordSize; 1.176 + AllocRecord *rec = new AllocRecord((address)ptr, type, byte_size); 1.177 + 1.178 if (_alloc_record_head == NULL) { 1.179 _alloc_record_head = _alloc_record_tail = rec; 1.180 - } else { 1.181 + } else if (_alloc_record_tail->_ptr + _alloc_record_tail->_byte_size == (address)ptr) { 1.182 _alloc_record_tail->_next = rec; 1.183 _alloc_record_tail = rec; 1.184 + } else { 1.185 + // slow linear search, but this doesn't happen that often, and only when dumping 1.186 + for (AllocRecord *old = _alloc_record_head; old; old = old->_next) { 1.187 + if (old->_ptr == ptr) { 1.188 + assert(old->_type == MetaspaceObj::DeallocatedType, "sanity"); 1.189 + int remain_bytes = old->_byte_size - byte_size; 1.190 + assert(remain_bytes >= 0, "sanity"); 1.191 + old->_type = type; 1.192 + 1.193 + if (remain_bytes == 0) { 1.194 + delete(rec); 1.195 + } else { 1.196 + address remain_ptr = address(ptr) + byte_size; 1.197 + rec->_ptr = remain_ptr; 1.198 + rec->_byte_size = remain_bytes; 1.199 + rec->_type = MetaspaceObj::DeallocatedType; 1.200 + rec->_next = old->_next; 1.201 + old->_byte_size = byte_size; 1.202 + old->_next = rec; 1.203 + } 1.204 + return; 1.205 + } 1.206 + } 1.207 + assert(0, "reallocating a freed pointer that was not recorded"); 1.208 } 1.209 } 1.210 1.211 +void Metaspace::record_deallocation(void* ptr, size_t word_size) { 1.212 + assert(DumpSharedSpaces, "sanity"); 1.213 + 1.214 + for (AllocRecord *rec = _alloc_record_head; rec; rec = rec->_next) { 1.215 + if (rec->_ptr == ptr) { 1.216 + assert(rec->_byte_size == (int)word_size * HeapWordSize, "sanity"); 1.217 + rec->_type = MetaspaceObj::DeallocatedType; 1.218 + return; 1.219 + } 1.220 + } 1.221 + 1.222 + assert(0, "deallocating a pointer that was not recorded"); 1.223 +} 1.224 + 1.225 void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) { 1.226 assert(DumpSharedSpaces, "unimplemented for !DumpSharedSpaces"); 1.227