diff options
author | Sergey Bugaev <bugaevc@gmail.com> | 2023-06-26 14:26:53 +0300 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-07-03 02:14:43 +0200 |
commit | d57189313d359bfa4033d24b3c4248b539826763 (patch) | |
tree | 6c059a0407e5d932f382dfaeebdbd7443066e6c8 /vm | |
parent | ee65849bec5da261be90f565bee096abb4117bdd (diff) | |
download | gnumach-d57189313d359bfa4033d24b3c4248b539826763.tar.gz gnumach-d57189313d359bfa4033d24b3c4248b539826763.tar.bz2 gnumach-d57189313d359bfa4033d24b3c4248b539826763.zip |
vm: Allow coalescing entries forward
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.
Message-Id: <20230626112656.435622-5-bugaevc@gmail.com>
Diffstat (limited to 'vm')
-rw-r--r-- | vm/vm_map.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/vm/vm_map.c b/vm/vm_map.c index f701a4cf..a708b7eb 100644 --- a/vm/vm_map.c +++ b/vm/vm_map.c @@ -967,6 +967,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; @@ -987,6 +988,7 @@ kern_return_t vm_map_enter( end = start + size; *address = start; + next_entry = entry->vme_next; } else { vm_map_entry_t temp_entry; @@ -1021,14 +1023,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); } @@ -1044,8 +1047,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)) && @@ -1076,6 +1078,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 |