@@ -245,8 +245,10 @@ class ZCacheState {
245245 void decrease_used_generation (ZGenerationId id, size_t size);
246246
247247 void reset_statistics (ZGenerationId id);
248- };
249248
249+ bool claim_mapped_or_increase_capacity (ZPageAllocation* allocation);
250+ bool claim_physical (ZPageAllocation* allocation);
251+ };
250252
251253void ZCacheState::initialize (size_t max_capacity) {
252254 _current_max_capacity = max_capacity;
@@ -340,6 +342,65 @@ void ZCacheState::reset_statistics(ZGenerationId id) {
340342 _collection_stats[(int )id]._used_low = _used;
341343}
342344
345+ bool ZCacheState::claim_mapped_or_increase_capacity (ZPageAllocation* allocation) {
346+ const size_t size = allocation->size ();
347+ ZArray<ZMemoryRange>* mappings = allocation->claimed_mappings ();
348+
349+ // Try to allocate a contiguous mapping.
350+ ZMemoryRange mapping;
351+ if (_cache.remove_mapping_contiguous (&mapping, size)) {
352+ mappings->append (mapping);
353+ return true ;
354+ }
355+
356+ // If we've failed to allocate a contiguous range from the mapped cache,
357+ // there is still a possibility that the cache holds enough memory for the
358+ // allocation dispersed over more than one mapping if the capacity cannot be
359+ // increased to satisfy the allocation.
360+
361+ // Try increase capacity
362+ const size_t increased = increase_capacity (size);
363+ if (increased == size) {
364+ // Capacity increase covered the entire request, done.
365+ return true ;
366+ }
367+
368+ // Could not increase capacity enough to satisfy the allocation completely.
369+ // Try removing multiple mappings from the mapped cache. We only remove if
370+ // cache has enough remaining to cover the request.
371+ const size_t remaining = size - increased;
372+ if (_cache.size () >= remaining) {
373+ const size_t removed = _cache.remove_mappings (mappings, remaining);
374+ allocation->set_harvested (removed);
375+ assert (removed == remaining, " must be %zu != %zu" , removed, remaining);
376+ return true ;
377+ }
378+
379+ // Could not claim enough memory from the cache or increase capacity to
380+ // fulfill the request.
381+ return false ;
382+ }
383+
384+ bool ZCacheState::claim_physical (ZPageAllocation* allocation) {
385+ const size_t size = allocation->size ();
386+
387+ if (available_capacity () < size) {
388+ // Out of memory
389+ return false ;
390+ }
391+
392+ if (!claim_mapped_or_increase_capacity (allocation)) {
393+ // Failed to claim enough memory or increase capacity
394+ return false ;
395+ }
396+
397+ // Updated used statistics
398+ increase_used (size);
399+
400+ // Success
401+ return true ;
402+ }
403+
343404ZPageAllocator::ZPageAllocator (size_t min_capacity,
344405 size_t initial_capacity,
345406 size_t soft_max_capacity,
@@ -722,84 +783,20 @@ bool ZPageAllocator::alloc_page_stall(ZPageAllocation* allocation) {
722783 return result;
723784}
724785
725- bool ZPageAllocator::claim_mapped_or_increase_capacity (ZCacheState& state, ZPageAllocation* allocation) {
726- ZMappedCache& cache = state._cache ;
727- const size_t size = allocation->size ();
728- ZArray<ZMemoryRange>* mappings = allocation->claimed_mappings ();
729-
730- // Try to allocate a contiguous mapping.
731- ZMemoryRange mapping;
732- if (cache.remove_mapping_contiguous (&mapping, size)) {
733- mappings->append (mapping);
734- return true ;
735- }
736-
737- // If we've failed to allocate a contiguous range from the mapped cache,
738- // there is still a possibility that the cache holds enough memory for the
739- // allocation dispersed over more than one mapping if the capacity cannot be
740- // increased to satisfy the allocation.
741-
742- // Try increase capacity
743- const size_t increased = state.increase_capacity (size);
744- if (increased == size) {
745- // Capacity increase covered the entire request, done.
746- return true ;
747- }
748-
749- // Could not increase capacity enough to satisfy the allocation completely.
750- // Try removing multiple mappings from the mapped cache. We only remove if
751- // cache has enough remaining to cover the request.
752- const size_t remaining = size - increased;
753- if (cache.size () >= remaining) {
754- const size_t removed = cache.remove_mappings (mappings, remaining);
755- allocation->set_harvested (removed);
756-
757- assert (removed == remaining, " must be %zu != %zu" , removed, remaining);
758- return true ;
759- }
760-
761- // Could not claim enough memory from the cache or increase capacity to
762- // fulfill the request.
763- return false ;
764- }
765-
766- bool ZPageAllocator::claim_physical (ZPageAllocation* allocation, ZCacheState& state) {
767- const size_t size = allocation->size ();
768-
769- if (state.available_capacity () < size) {
770- // Out of memory
771- return false ;
772- }
773-
774- if (!claim_mapped_or_increase_capacity (state, allocation)) {
775- // Failed to claim enough memory or increase capacity
776- return false ;
777- }
778-
779- // Updated used statistics
780- state.increase_used (size);
781-
782- // Success
783- return true ;
784- }
785-
786786bool ZPageAllocator::claim_physical_round_robin (ZPageAllocation* allocation) {
787- const size_t numa_nodes = ZNUMA::count ();
788787 const int start_node = allocation->numa_id ();
789788 int current_node = start_node;
790789
791790 do {
792791 ZCacheState& state = _states.get (current_node);
793-
794- if (claim_physical (allocation, state)) {
795- // Success
792+ if (state.claim_physical (allocation)) {
793+ // Record which state the allocation was made on
796794 allocation->set_numa_id (current_node);
797795 return true ;
798796 }
799797
800- // Could not claim physical memory on current node, potentially move on to
801- // the next node
802- current_node = (current_node + 1 ) % numa_nodes;
798+ // Could not claim physical memory on current node, move on to next node
799+ current_node = (current_node + 1 ) % ZNUMA::count ();
803800 } while (current_node != start_node);
804801
805802 return false ;
@@ -844,9 +841,8 @@ void ZPageAllocator::harvest_claimed_physical(ZPageAllocation* allocation) {
844841 // Stash segments
845842 segments.stash (allocation->claimed_mappings ());
846843
847- // Shuffle vmem. We allocate enough memory to cover the entire allocation size, not just the harvested memory.
848- // If we fail to allocate additional virtual memory, the allocated virtual memory will match the harvested amount
849- // instead of the allocation request.
844+ // Shuffle vmem. We attempt to allocate enough memory to cover the entire allocation
845+ // size, not just the harvested memory.
850846 _virtual.shuffle_vmem_to_low_addresses_contiguous (allocation->size (), allocation->claimed_mappings ());
851847
852848 // Restore segments
@@ -882,19 +878,18 @@ bool ZPageAllocator::claim_virtual_memory(ZPageAllocation* allocation) {
882878 // mappings, and perhaps also allocate more to match the allocation request.
883879 harvest_claimed_physical (allocation);
884880 } else {
885- // If we have not harvested anything, we have only increased capacity.
886- // Allocate new virtual memory from the manager.
881+ // If we have not harvested anything, we only increased capacity. Allocate
882+ // new virtual memory from the manager.
887883 ZMemoryRange vmem = _virtual.alloc (allocation->size (), allocation->numa_id (), true /* force_low_address */ );
888884 allocation->claimed_mappings ()->append (vmem);
889885 }
890886
891- // If we have enough virtual memory to cover the allocation request,
892- // we're done.
887+ // If the virtual memory covers the allocation request, we're done.
893888 if (is_alloc_satisfied (allocation)) {
894889 return true ;
895890 }
896891
897- // Before returning the harvested memory to the cache it must be mapped.
892+ // Before returning harvested memory to the cache it must be mapped.
898893 if (allocation->harvested () > 0 ) {
899894 ZArrayIterator<ZMemoryRange> iter (allocation->claimed_mappings ());
900895 for (ZMemoryRange vmem; iter.next (&vmem);) {
@@ -958,26 +953,26 @@ ZPage* ZPageAllocator::alloc_page_inner(ZPageAllocation* allocation) {
958953 // If we have claimed a large enough contiguous mapping from the cache,
959954 // we're done.
960955 if (is_alloc_satisfied (allocation)) {
961- ZMemoryRange vmem = allocation->claimed_mappings ()->pop ();
956+ const ZMemoryRange vmem = allocation->claimed_mappings ()->pop ();
962957 return new ZPage (allocation->type (), vmem);
963958 }
964959
965- // Claim virtual memory, either by harvesting or by allocating new from the
960+ // Claim virtual memory, either by harvesting or by allocating from the
966961 // virtual manager.
967962 if (!claim_virtual_memory (allocation)) {
968963 log_error (gc)(" Out of address space" );
969964 free_memory_alloc_failed (allocation);
970965 return nullptr ;
971966 }
972967
973- ZMemoryRange vmem = allocation->claimed_mappings ()->pop ();
968+ const ZMemoryRange vmem = allocation->claimed_mappings ()->pop ();
974969
975970 // Allocate any remaining physical memory. Capacity and used has already been
976971 // adjusted, we just need to fetch the memory, which is guaranteed to succeed.
977972 const size_t remaining_physical = allocation->size () - allocation->harvested ();
978973 if (remaining_physical > 0 ) {
979974 allocation->set_committed (remaining_physical);
980- ZMemoryRange uncommitted_range = ZMemoryRange (vmem.start () + allocation->harvested (), remaining_physical);
975+ const ZMemoryRange uncommitted_range = ZMemoryRange (vmem.start () + allocation->harvested (), remaining_physical);
981976 alloc_physical (uncommitted_range, allocation->numa_id ());
982977 }
983978
0 commit comments