src/share/vm/memory/metaspace.cpp

changeset 7089
6e0cb14ce59b
parent 6911
ce8f6bb717c9
child 7103
622c6e0ad4d6
     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  

mercurial