When entering an object into a map, try to extend the next entry backward, in addition to the previously existing attempt to extend the previous entry forward. --- vm/vm_map.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-)
diff --git a/vm/vm_map.c b/vm/vm_map.c index a41e6434..0d3b11f2 100644 --- a/vm/vm_map.c +++ b/vm/vm_map.c @@ -992,6 +992,7 @@ kern_return_t vm_map_enter( vm_inherit_t inheritance) { vm_map_entry_t entry; + vm_map_entry_t next_entry; vm_offset_t start; vm_offset_t end; kern_return_t result = KERN_SUCCESS; @@ -1012,6 +1013,7 @@ kern_return_t vm_map_enter( end = start + size; *address = start; + next_entry = entry->vme_next; } else { vm_map_entry_t temp_entry; @@ -1046,14 +1048,15 @@ kern_return_t vm_map_enter( RETURN(KERN_NO_SPACE); entry = temp_entry; + next_entry = entry->vme_next; /* * ... the next region doesn't overlap the * end point. */ - if ((entry->vme_next != vm_map_to_entry(map)) && - (entry->vme_next->vme_start < end)) + if ((next_entry != vm_map_to_entry(map)) && + (next_entry->vme_start < end)) RETURN(KERN_NO_SPACE); } @@ -1069,8 +1072,7 @@ kern_return_t vm_map_enter( /* * See whether we can avoid creating a new entry (and object) by - * extending one of our neighbors. [So far, we only attempt to - * extend from below.] + * extending one of our neighbors. */ if ((entry != vm_map_to_entry(map)) && @@ -1101,6 +1103,35 @@ kern_return_t vm_map_enter( RETURN(KERN_SUCCESS); } } + if ((next_entry != vm_map_to_entry(map)) && + (next_entry->vme_start == end) && + (!next_entry->is_shared) && + (!next_entry->is_sub_map) && + (next_entry->inheritance == inheritance) && + (next_entry->protection == cur_protection) && + (next_entry->max_protection == max_protection) && + (next_entry->wired_count == 0) && + (next_entry->projected_on == 0)) { + if (vm_object_coalesce(object, + next_entry->object.vm_object, + offset, + next_entry->offset, + size, + (vm_size_t)(next_entry->vme_end - next_entry->vme_start))) { + + /* + * Coalesced the two objects - can extend + * the next map entry to include the + * new range. + */ + map->size += size; + next_entry->vme_start = start; + next_entry->offset -= size; + vm_map_gap_update(&map->hdr, entry); + vm_object_deallocate(object); + RETURN(KERN_SUCCESS); + } + } /* * Create a new entry -- 2.41.0