TR::MemorySegment & TR::DebugSegmentProvider::request(size_t requiredSize) { size_t adjustedSize = ( ( requiredSize + (defaultSegmentSize() - 1) ) / defaultSegmentSize() ) * defaultSegmentSize(); #if defined(LINUX) || defined(__APPLE__) || defined(_AIX) void *newSegmentArea = mmap(NULL, adjustedSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if (newSegmentArea == MAP_FAILED) throw std::bad_alloc(); #elif defined(_WIN32) void *newSegmentArea = VirtualAlloc(NULL, adjustedSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (!newSegmentArea) throw std::bad_alloc(); #else void *newSegmentArea = _rawAllocator.allocate(requiredSize); #endif try { auto result = _segments.insert( TR::MemorySegment(newSegmentArea, adjustedSize) ); TR_ASSERT(result.first != _segments.end(), "Bad iterator"); TR_ASSERT(result.second, "Insertion failed"); _bytesAllocated += adjustedSize; return const_cast<TR::MemorySegment &>(*(result.first)); } catch (...) { #if defined(LINUX) || defined(__APPLE__) || defined(_AIX) munmap(newSegmentArea, adjustedSize); #elif defined(_WIN32) VirtualFree(newSegmentArea, 0, MEM_RELEASE); #else _rawAllocator.deallocate(newSegmentArea, adjustedSize); #endif throw; } }
TR::MemorySegment & OMR::SystemSegmentProvider::request(size_t requiredSize) { size_t adjustedSize = ( ( requiredSize + (defaultSegmentSize() - 1) ) / defaultSegmentSize() ) * defaultSegmentSize(); void *newSegmentArea = _rawAllocator.allocate(adjustedSize); try { auto result = _segments.insert( TR::MemorySegment(newSegmentArea, adjustedSize) ); TR_ASSERT(result.first != _segments.end(), "Bad iterator"); TR_ASSERT(result.second, "Insertion failed"); _currentBytesAllocated += adjustedSize; _highWaterMark = _currentBytesAllocated > _highWaterMark ? _currentBytesAllocated : _highWaterMark; return const_cast<TR::MemorySegment &>(*(result.first)); } catch (...) { _rawAllocator.deallocate(newSegmentArea); throw; } }
TR::MemorySegment & TR::SegmentPool::request(size_t requiredSize) { if ( requiredSize <= defaultSegmentSize() && !_segmentStack.empty() ) { --_storedSegments; TR_ASSERT(0 <= _storedSegments, "We lost a segment"); TR::MemorySegment &recycledSegment = _segmentStack.top().get(); _segmentStack.pop(); recycledSegment.reset(); return recycledSegment; } return _backingProvider.request(requiredSize); }
void TR::SegmentPool::release(TR::MemorySegment &segment) throw() { if ( segment.size() == defaultSegmentSize() && _storedSegments < _poolSize ) { try { _segmentStack.push(TR::ref(segment)); ++_storedSegments; } catch (...) { _backingProvider.release(segment); } } else { _backingProvider.release(segment); } }