+
+vm_map_offset_t
+vm_map_round_page_mask(
+ vm_map_offset_t offset,
+ vm_map_offset_t mask)
+{
+ return VM_MAP_ROUND_PAGE(offset, mask);
+}
+
+vm_map_offset_t
+vm_map_trunc_page_mask(
+ vm_map_offset_t offset,
+ vm_map_offset_t mask)
+{
+ return VM_MAP_TRUNC_PAGE(offset, mask);
+}
+
+boolean_t
+vm_map_page_aligned(
+ vm_map_offset_t offset,
+ vm_map_offset_t mask)
+{
+ return ((offset) & mask) == 0;
+}
+
+int
+vm_map_page_shift(
+ vm_map_t map)
+{
+ return VM_MAP_PAGE_SHIFT(map);
+}
+
+int
+vm_map_page_size(
+ vm_map_t map)
+{
+ return VM_MAP_PAGE_SIZE(map);
+}
+
+vm_map_offset_t
+vm_map_page_mask(
+ vm_map_t map)
+{
+ return VM_MAP_PAGE_MASK(map);
+}
+
+kern_return_t
+vm_map_set_page_shift(
+ vm_map_t map,
+ int pageshift)
+{
+ if (map->hdr.nentries != 0) {
+ /* too late to change page size */
+ return KERN_FAILURE;
+ }
+
+ map->hdr.page_shift = pageshift;
+
+ return KERN_SUCCESS;
+}
+
+int
+vm_map_purge(
+ vm_map_t map)
+{
+ int num_object_purged;
+ vm_map_entry_t entry;
+ vm_map_offset_t next_address;
+ vm_object_t object;
+ int state;
+ kern_return_t kr;
+
+ num_object_purged = 0;
+
+ vm_map_lock_read(map);
+ entry = vm_map_first_entry(map);
+ while (entry != vm_map_to_entry(map)) {
+ if (entry->is_sub_map) {
+ goto next;
+ }
+ if (! (entry->protection & VM_PROT_WRITE)) {
+ goto next;
+ }
+ object = VME_OBJECT(entry);
+ if (object == VM_OBJECT_NULL) {
+ goto next;
+ }
+ if (object->purgable != VM_PURGABLE_VOLATILE) {
+ goto next;
+ }
+
+ vm_object_lock(object);
+#if 00
+ if (VME_OFFSET(entry) != 0 ||
+ (entry->vme_end - entry->vme_start) != object->vo_size) {
+ vm_object_unlock(object);
+ goto next;
+ }
+#endif
+ next_address = entry->vme_end;
+ vm_map_unlock_read(map);
+ state = VM_PURGABLE_EMPTY;
+ kr = vm_object_purgable_control(object,
+ VM_PURGABLE_SET_STATE,
+ &state);
+ if (kr == KERN_SUCCESS) {
+ num_object_purged++;
+ }
+ vm_object_unlock(object);
+
+ vm_map_lock_read(map);
+ if (vm_map_lookup_entry(map, next_address, &entry)) {
+ continue;
+ }
+ next:
+ entry = entry->vme_next;
+ }
+ vm_map_unlock_read(map);
+
+ return num_object_purged;
+}
+
+kern_return_t
+vm_map_query_volatile(
+ vm_map_t map,
+ mach_vm_size_t *volatile_virtual_size_p,
+ mach_vm_size_t *volatile_resident_size_p,
+ mach_vm_size_t *volatile_compressed_size_p,
+ mach_vm_size_t *volatile_pmap_size_p,
+ mach_vm_size_t *volatile_compressed_pmap_size_p)
+{
+ mach_vm_size_t volatile_virtual_size;
+ mach_vm_size_t volatile_resident_count;
+ mach_vm_size_t volatile_compressed_count;
+ mach_vm_size_t volatile_pmap_count;
+ mach_vm_size_t volatile_compressed_pmap_count;
+ mach_vm_size_t resident_count;
+ vm_map_entry_t entry;
+ vm_object_t object;
+
+ /* map should be locked by caller */
+
+ volatile_virtual_size = 0;
+ volatile_resident_count = 0;
+ volatile_compressed_count = 0;
+ volatile_pmap_count = 0;
+ volatile_compressed_pmap_count = 0;
+
+ for (entry = vm_map_first_entry(map);
+ entry != vm_map_to_entry(map);
+ entry = entry->vme_next) {
+ mach_vm_size_t pmap_resident_bytes, pmap_compressed_bytes;
+
+ if (entry->is_sub_map) {
+ continue;
+ }
+ if (! (entry->protection & VM_PROT_WRITE)) {
+ continue;
+ }
+ object = VME_OBJECT(entry);
+ if (object == VM_OBJECT_NULL) {
+ continue;
+ }
+ if (object->purgable != VM_PURGABLE_VOLATILE &&
+ object->purgable != VM_PURGABLE_EMPTY) {
+ continue;
+ }
+ if (VME_OFFSET(entry)) {
+ /*
+ * If the map entry has been split and the object now
+ * appears several times in the VM map, we don't want
+ * to count the object's resident_page_count more than
+ * once. We count it only for the first one, starting
+ * at offset 0 and ignore the other VM map entries.
+ */
+ continue;
+ }
+ resident_count = object->resident_page_count;
+ if ((VME_OFFSET(entry) / PAGE_SIZE) >= resident_count) {
+ resident_count = 0;
+ } else {
+ resident_count -= (VME_OFFSET(entry) / PAGE_SIZE);
+ }
+
+ volatile_virtual_size += entry->vme_end - entry->vme_start;
+ volatile_resident_count += resident_count;
+ if (object->pager) {
+ volatile_compressed_count +=
+ vm_compressor_pager_get_count(object->pager);
+ }
+ pmap_compressed_bytes = 0;
+ pmap_resident_bytes =
+ pmap_query_resident(map->pmap,
+ entry->vme_start,
+ entry->vme_end,
+ &pmap_compressed_bytes);
+ volatile_pmap_count += (pmap_resident_bytes / PAGE_SIZE);
+ volatile_compressed_pmap_count += (pmap_compressed_bytes
+ / PAGE_SIZE);
+ }
+
+ /* map is still locked on return */
+
+ *volatile_virtual_size_p = volatile_virtual_size;
+ *volatile_resident_size_p = volatile_resident_count * PAGE_SIZE;
+ *volatile_compressed_size_p = volatile_compressed_count * PAGE_SIZE;
+ *volatile_pmap_size_p = volatile_pmap_count * PAGE_SIZE;
+ *volatile_compressed_pmap_size_p = volatile_compressed_pmap_count * PAGE_SIZE;
+
+ return KERN_SUCCESS;
+}
+
+void
+vm_map_sizes(vm_map_t map,
+ vm_map_size_t * psize,
+ vm_map_size_t * pfree,
+ vm_map_size_t * plargest_free)
+{
+ vm_map_entry_t entry;
+ vm_map_offset_t prev;
+ vm_map_size_t free, total_free, largest_free;
+ boolean_t end;
+
+ total_free = largest_free = 0;
+
+ vm_map_lock_read(map);
+ if (psize) *psize = map->max_offset - map->min_offset;
+
+ prev = map->min_offset;
+ for (entry = vm_map_first_entry(map);; entry = entry->vme_next)
+ {
+ end = (entry == vm_map_to_entry(map));
+
+ if (end) free = entry->vme_end - prev;
+ else free = entry->vme_start - prev;
+
+ total_free += free;
+ if (free > largest_free) largest_free = free;
+
+ if (end) break;
+ prev = entry->vme_end;
+ }
+ vm_map_unlock_read(map);
+ if (pfree) *pfree = total_free;
+ if (plargest_free) *plargest_free = largest_free;
+}
+
+#if VM_SCAN_FOR_SHADOW_CHAIN
+int vm_map_shadow_max(vm_map_t map);
+int vm_map_shadow_max(
+ vm_map_t map)
+{
+ int shadows, shadows_max;
+ vm_map_entry_t entry;
+ vm_object_t object, next_object;
+
+ if (map == NULL)
+ return 0;
+
+ shadows_max = 0;
+
+ vm_map_lock_read(map);
+
+ for (entry = vm_map_first_entry(map);
+ entry != vm_map_to_entry(map);
+ entry = entry->vme_next) {
+ if (entry->is_sub_map) {
+ continue;
+ }
+ object = VME_OBJECT(entry);
+ if (object == NULL) {
+ continue;
+ }
+ vm_object_lock_shared(object);
+ for (shadows = 0;
+ object->shadow != NULL;
+ shadows++, object = next_object) {
+ next_object = object->shadow;
+ vm_object_lock_shared(next_object);
+ vm_object_unlock(object);
+ }
+ vm_object_unlock(object);
+ if (shadows > shadows_max) {
+ shadows_max = shadows;
+ }
+ }
+
+ vm_map_unlock_read(map);
+
+ return shadows_max;
+}
+#endif /* VM_SCAN_FOR_SHADOW_CHAIN */