home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / vm / vm_object.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-07  |  34.5 KB  |  1,450 lines

  1. /* 
  2.  * Copyright (c) 1991 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * The Mach Operating System project at Carnegie-Mellon University.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  *
  36.  *    @(#)vm_object.c    7.4 (Berkeley) 5/7/91
  37.  *
  38.  *
  39.  * Copyright (c) 1987, 1990 Carnegie-Mellon University.
  40.  * All rights reserved.
  41.  *
  42.  * Authors: Avadis Tevanian, Jr., Michael Wayne Young
  43.  * 
  44.  * Permission to use, copy, modify and distribute this software and
  45.  * its documentation is hereby granted, provided that both the copyright
  46.  * notice and this permission notice appear in all copies of the
  47.  * software, derivative works or modified versions, and any portions
  48.  * thereof, and that both notices appear in supporting documentation.
  49.  * 
  50.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
  51.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
  52.  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  53.  * 
  54.  * Carnegie Mellon requests users of this software to return to
  55.  *
  56.  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  57.  *  School of Computer Science
  58.  *  Carnegie Mellon University
  59.  *  Pittsburgh PA 15213-3890
  60.  *
  61.  * any improvements or extensions that they make and grant Carnegie the
  62.  * rights to redistribute these changes.
  63.  */
  64.  
  65. /*
  66.  *    Virtual memory object module.
  67.  */
  68.  
  69. #include "param.h"
  70. #include "malloc.h"
  71.  
  72. #include "vm.h"
  73. #include "vm_page.h"
  74.  
  75. /*
  76.  *    Virtual memory objects maintain the actual data
  77.  *    associated with allocated virtual memory.  A given
  78.  *    page of memory exists within exactly one object.
  79.  *
  80.  *    An object is only deallocated when all "references"
  81.  *    are given up.  Only one "reference" to a given
  82.  *    region of an object should be writeable.
  83.  *
  84.  *    Associated with each object is a list of all resident
  85.  *    memory pages belonging to that object; this list is
  86.  *    maintained by the "vm_page" module, and locked by the object's
  87.  *    lock.
  88.  *
  89.  *    Each object also records a "pager" routine which is
  90.  *    used to retrieve (and store) pages to the proper backing
  91.  *    storage.  In addition, objects may be backed by other
  92.  *    objects from which they were virtual-copied.
  93.  *
  94.  *    The only items within the object structure which are
  95.  *    modified after time of creation are:
  96.  *        reference count        locked by object's lock
  97.  *        pager routine        locked by object's lock
  98.  *
  99.  */
  100.  
  101. struct vm_object    kernel_object_store;
  102. struct vm_object    kmem_object_store;
  103.  
  104. #define    VM_OBJECT_HASH_COUNT    157
  105.  
  106. int        vm_cache_max = 100;    /* can patch if necessary */
  107. queue_head_t    vm_object_hashtable[VM_OBJECT_HASH_COUNT];
  108.  
  109. long    object_collapses = 0;
  110. long    object_bypasses  = 0;
  111.  
  112. /*
  113.  *    vm_object_init:
  114.  *
  115.  *    Initialize the VM objects module.
  116.  */
  117. void vm_object_init()
  118. {
  119.     register int    i;
  120.  
  121.     queue_init(&vm_object_cached_list);
  122.     queue_init(&vm_object_list);
  123.     vm_object_count = 0;
  124.     simple_lock_init(&vm_cache_lock);
  125.     simple_lock_init(&vm_object_list_lock);
  126.  
  127.     for (i = 0; i < VM_OBJECT_HASH_COUNT; i++)
  128.         queue_init(&vm_object_hashtable[i]);
  129.  
  130.     kernel_object = &kernel_object_store;
  131.     _vm_object_allocate(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS,
  132.             kernel_object);
  133.  
  134.     kmem_object = &kmem_object_store;
  135.     _vm_object_allocate(VM_KMEM_SIZE + VM_MBUF_SIZE, kmem_object);
  136. }
  137.  
  138. /*
  139.  *    vm_object_allocate:
  140.  *
  141.  *    Returns a new object with the given size.
  142.  */
  143.  
  144. vm_object_t vm_object_allocate(size)
  145.     vm_size_t    size;
  146. {
  147.     register vm_object_t    result;
  148.  
  149.     result = (vm_object_t)
  150.         malloc((u_long)sizeof *result, M_VMOBJ, M_WAITOK);
  151.  
  152.     _vm_object_allocate(size, result);
  153.  
  154.     return(result);
  155. }
  156.  
  157. _vm_object_allocate(size, object)
  158.     vm_size_t        size;
  159.     register vm_object_t    object;
  160. {
  161.     queue_init(&object->memq);
  162.     vm_object_lock_init(object);
  163.     object->ref_count = 1;
  164.     object->resident_page_count = 0;
  165.     object->size = size;
  166.     object->can_persist = FALSE;
  167.     object->paging_in_progress = 0;
  168.     object->copy = NULL;
  169.  
  170.     /*
  171.      *    Object starts out read-write, with no pager.
  172.      */
  173.  
  174.     object->pager = NULL;
  175.     object->pager_ready = FALSE;
  176.     object->internal = TRUE;    /* vm_allocate_with_pager will reset */
  177.     object->paging_offset = 0;
  178.     object->shadow = NULL;
  179.     object->shadow_offset = (vm_offset_t) 0;
  180.  
  181.     simple_lock(&vm_object_list_lock);
  182.     queue_enter(&vm_object_list, object, vm_object_t, object_list);
  183.     vm_object_count++;
  184.     simple_unlock(&vm_object_list_lock);
  185. }
  186.  
  187. /*
  188.  *    vm_object_reference:
  189.  *
  190.  *    Gets another reference to the given object.
  191.  */
  192. void vm_object_reference(object)
  193.     register vm_object_t    object;
  194. {
  195.     if (object == NULL)
  196.         return;
  197.  
  198.     vm_object_lock(object);
  199.     object->ref_count++;
  200.     vm_object_unlock(object);
  201. }
  202.  
  203. /*
  204.  *    vm_object_deallocate:
  205.  *
  206.  *    Release a reference to the specified object,
  207.  *    gained either through a vm_object_allocate
  208.  *    or a vm_object_reference call.  When all references
  209.  *    are gone, storage associated with this object
  210.  *    may be relinquished.
  211.  *
  212.  *    No object may be locked.
  213.  */
  214. void vm_object_deallocate(object)
  215.     register vm_object_t    object;
  216. {
  217.     vm_object_t    temp;
  218.  
  219.     while (object != NULL) {
  220.  
  221.         /*
  222.          *    The cache holds a reference (uncounted) to
  223.          *    the object; we must lock it before removing
  224.          *    the object.
  225.          */
  226.  
  227.         vm_object_cache_lock();
  228.  
  229.         /*
  230.          *    Lose the reference
  231.          */
  232.         vm_object_lock(object);
  233.         if (--(object->ref_count) != 0) {
  234.  
  235.             /*
  236.              *    If there are still references, then
  237.              *    we are done.
  238.              */
  239.             vm_object_unlock(object);
  240.             vm_object_cache_unlock();
  241.             return;
  242.         }
  243.  
  244.         /*
  245.          *    See if this object can persist.  If so, enter
  246.          *    it in the cache, then deactivate all of its
  247.          *    pages.
  248.          */
  249.  
  250.         if (object->can_persist) {
  251.  
  252.             queue_enter(&vm_object_cached_list, object,
  253.                 vm_object_t, cached_list);
  254.             vm_object_cached++;
  255.             vm_object_cache_unlock();
  256.  
  257.             vm_object_deactivate_pages(object);
  258.             vm_object_unlock(object);
  259.  
  260.             vm_object_cache_trim();
  261.             return;
  262.         }
  263.  
  264.         /*
  265.          *    Make sure no one can look us up now.
  266.          */
  267.         vm_object_remove(object->pager);
  268.         vm_object_cache_unlock();
  269.  
  270.         temp = object->shadow;
  271.         vm_object_terminate(object);
  272.             /* unlocks and deallocates object */
  273.         object = temp;
  274.     }
  275. }
  276.  
  277.  
  278. /*
  279.  *    vm_object_terminate actually destroys the specified object, freeing
  280.  *    up all previously used resources.
  281.  *
  282.  *    The object must be locked.
  283.  */
  284. void vm_object_terminate(object)
  285.     register vm_object_t    object;
  286. {
  287.     register vm_page_t    p;
  288.     vm_object_t        shadow_object;
  289.  
  290.     /*
  291.      *    Detach the object from its shadow if we are the shadow's
  292.      *    copy.
  293.      */
  294.     if ((shadow_object = object->shadow) != NULL) {
  295.         vm_object_lock(shadow_object);
  296.         if (shadow_object->copy == object)
  297.             shadow_object->copy = NULL;
  298. #if 0
  299.         else if (shadow_object->copy != NULL)
  300.             panic("vm_object_terminate: copy/shadow inconsistency");
  301. #endif
  302.         vm_object_unlock(shadow_object);
  303.     }
  304.  
  305.     /*
  306.      *    Wait until the pageout daemon is through
  307.      *    with the object.
  308.      */
  309.  
  310.     while (object->paging_in_progress != 0) {
  311.         vm_object_sleep(object, object, FALSE);
  312.         vm_object_lock(object);
  313.     }
  314.  
  315.  
  316.     /*
  317.      *    While the paging system is locked,
  318.      *    pull the object's pages off the active
  319.      *    and inactive queues.  This keeps the
  320.      *    pageout daemon from playing with them
  321.      *    during vm_pager_deallocate.
  322.      *
  323.      *    We can't free the pages yet, because the
  324.      *    object's pager may have to write them out
  325.      *    before deallocating the paging space.
  326.      */
  327.  
  328.     p = (vm_page_t) queue_first(&object->memq);
  329.     while (!queue_end(&object->memq, (queue_entry_t) p)) {
  330.         VM_PAGE_CHECK(p);
  331.  
  332.         vm_page_lock_queues();
  333.         if (p->active) {
  334.             queue_remove(&vm_page_queue_active, p, vm_page_t,
  335.                         pageq);
  336.             p->active = FALSE;
  337.             vm_page_active_count--;
  338.         }
  339.  
  340.         if (p->inactive) {
  341.             queue_remove(&vm_page_queue_inactive, p, vm_page_t,
  342.                         pageq);
  343.             p->inactive = FALSE;
  344.             vm_page_inactive_count--;
  345.         }
  346.         vm_page_unlock_queues();
  347.         p = (vm_page_t) queue_next(&p->listq);
  348.     }
  349.                 
  350.     vm_object_unlock(object);
  351.  
  352.     if (object->paging_in_progress != 0)
  353.         panic("vm_object_deallocate: pageout in progress");
  354.  
  355.     /*
  356.      *    Clean and free the pages, as appropriate.
  357.      *    All references to the object are gone,
  358.      *    so we don't need to lock it.
  359.      */
  360.  
  361.     if (!object->internal) {
  362.         vm_object_lock(object);
  363.         vm_object_page_clean(object, 0, 0);
  364.         vm_object_unlock(object);
  365.     }
  366.     while (!queue_empty(&object->memq)) {
  367.         p = (vm_page_t) queue_first(&object->memq);
  368.  
  369.         VM_PAGE_CHECK(p);
  370.  
  371.         vm_page_lock_queues();
  372.         vm_page_free(p);
  373.         vm_page_unlock_queues();
  374.     }
  375.  
  376.     /*
  377.      *    Let the pager know object is dead.
  378.      */
  379.  
  380.     if (object->pager != NULL)
  381.         vm_pager_deallocate(object->pager);
  382.  
  383.  
  384.     simple_lock(&vm_object_list_lock);
  385.     queue_remove(&vm_object_list, object, vm_object_t, object_list);
  386.     vm_object_count--;
  387.     simple_unlock(&vm_object_list_lock);
  388.  
  389.     /*
  390.      *    Free the space for the object.
  391.      */
  392.  
  393.     free((caddr_t)object, M_VMOBJ);
  394. }
  395.  
  396. /*
  397.  *    vm_object_page_clean
  398.  *
  399.  *    Clean all dirty pages in the specified range of object.
  400.  *    Leaves page on whatever queue it is currently on.
  401.  *
  402.  *    Odd semantics: if start == end, we clean everything.
  403.  *
  404.  *    The object must be locked.
  405.  */
  406. vm_object_page_clean(object, start, end)
  407.     register vm_object_t    object;
  408.     register vm_offset_t    start;
  409.     register vm_offset_t    end;
  410. {
  411.     register vm_page_t    p;
  412.  
  413.     if (object->pager == NULL)
  414.         return;
  415.  
  416. again:
  417.     p = (vm_page_t) queue_first(&object->memq);
  418.     while (!queue_end(&object->memq, (queue_entry_t) p)) {
  419.         if (start == end ||
  420.             p->offset >= start && p->offset < end) {
  421.             if (p->clean && pmap_is_modified(VM_PAGE_TO_PHYS(p)))
  422.                 p->clean = FALSE;
  423.             pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE);
  424.             if (!p->clean) {
  425.                 p->busy = TRUE;
  426.                 object->paging_in_progress++;
  427.                 vm_object_unlock(object);
  428.                 (void) vm_pager_put(object->pager, p, TRUE);
  429.                 vm_object_lock(object);
  430.                 object->paging_in_progress--;
  431.                 p->busy = FALSE;
  432.                 PAGE_WAKEUP(p);
  433.                 goto again;
  434.             }
  435.         }
  436.         p = (vm_page_t) queue_next(&p->listq);
  437.     }
  438. }
  439.  
  440. /*
  441.  *    vm_object_deactivate_pages
  442.  *
  443.  *    Deactivate all pages in the specified object.  (Keep its pages
  444.  *    in memory even though it is no longer referenced.)
  445.  *
  446.  *    The object must be locked.
  447.  */
  448. vm_object_deactivate_pages(object)
  449.     register vm_object_t    object;
  450. {
  451.     register vm_page_t    p, next;
  452.  
  453.     p = (vm_page_t) queue_first(&object->memq);
  454.     while (!queue_end(&object->memq, (queue_entry_t) p)) {
  455.         next = (vm_page_t) queue_next(&p->listq);
  456.         vm_page_lock_queues();
  457.         vm_page_deactivate(p);
  458.         vm_page_unlock_queues();
  459.         p = next;
  460.     }
  461. }
  462.  
  463. /*
  464.  *    Trim the object cache to size.
  465.  */
  466. vm_object_cache_trim()
  467. {
  468.     register vm_object_t    object;
  469.  
  470.     vm_object_cache_lock();
  471.     while (vm_object_cached > vm_cache_max) {
  472.         object = (vm_object_t) queue_first(&vm_object_cached_list);
  473.         vm_object_cache_unlock();
  474.  
  475.         if (object != vm_object_lookup(object->pager))
  476.             panic("vm_object_deactivate: I'm sooo confused.");
  477.  
  478.         pager_cache(object, FALSE);
  479.  
  480.         vm_object_cache_lock();
  481.     }
  482.     vm_object_cache_unlock();
  483. }
  484.  
  485.  
  486. /*
  487.  *    vm_object_shutdown()
  488.  *
  489.  *    Shut down the object system.  Unfortunately, while we
  490.  *    may be trying to do this, init is happily waiting for
  491.  *    processes to exit, and therefore will be causing some objects
  492.  *    to be deallocated.  To handle this, we gain a fake reference
  493.  *    to all objects we release paging areas for.  This will prevent
  494.  *    a duplicate deallocation.  This routine is probably full of
  495.  *    race conditions!
  496.  */
  497.  
  498. void vm_object_shutdown()
  499. {
  500.     register vm_object_t    object;
  501.  
  502.     /*
  503.      *    Clean up the object cache *before* we screw up the reference
  504.      *    counts on all of the objects.
  505.      */
  506.  
  507.     vm_object_cache_clear();
  508.  
  509.     printf("free paging spaces: ");
  510.  
  511.     /*
  512.      *    First we gain a reference to each object so that
  513.      *    no one else will deallocate them.
  514.      */
  515.  
  516.     simple_lock(&vm_object_list_lock);
  517.     object = (vm_object_t) queue_first(&vm_object_list);
  518.     while (!queue_end(&vm_object_list, (queue_entry_t) object)) {
  519.         vm_object_reference(object);
  520.         object = (vm_object_t) queue_next(&object->object_list);
  521.     }
  522.     simple_unlock(&vm_object_list_lock);
  523.  
  524.     /*
  525.      *    Now we deallocate all the paging areas.  We don't need
  526.      *    to lock anything because we've reduced to a single
  527.      *    processor while shutting down.    This also assumes that
  528.      *    no new objects are being created.
  529.      */
  530.  
  531.     object = (vm_object_t) queue_first(&vm_object_list);
  532.     while (!queue_end(&vm_object_list, (queue_entry_t) object)) {
  533.         if (object->pager != NULL)
  534.             vm_pager_deallocate(object->pager);
  535.         object = (vm_object_t) queue_next(&object->object_list);
  536.         printf(".");
  537.     }
  538.     printf("done.\n");
  539. }
  540.  
  541. /*
  542.  *    vm_object_pmap_copy:
  543.  *
  544.  *    Makes all physical pages in the specified
  545.  *    object range copy-on-write.  No writeable
  546.  *    references to these pages should remain.
  547.  *
  548.  *    The object must *not* be locked.
  549.  */
  550. void vm_object_pmap_copy(object, start, end)
  551.     register vm_object_t    object;
  552.     register vm_offset_t    start;
  553.     register vm_offset_t    end;
  554. {
  555.     register vm_page_t    p;
  556.  
  557.     if (object == NULL)
  558.         return;
  559.  
  560.     vm_object_lock(object);
  561.     p = (vm_page_t) queue_first(&object->memq);
  562.     while (!queue_end(&object->memq, (queue_entry_t) p)) {
  563.         if ((start <= p->offset) && (p->offset < end)) {
  564.             pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_READ);
  565.             p->copy_on_write = TRUE;
  566.         }
  567.         p = (vm_page_t) queue_next(&p->listq);
  568.     }
  569.     vm_object_unlock(object);
  570. }
  571.  
  572. /*
  573.  *    vm_object_pmap_remove:
  574.  *
  575.  *    Removes all physical pages in the specified
  576.  *    object range from all physical maps.
  577.  *
  578.  *    The object must *not* be locked.
  579.  */
  580. void vm_object_pmap_remove(object, start, end)
  581.     register vm_object_t    object;
  582.     register vm_offset_t    start;
  583.     register vm_offset_t    end;
  584. {
  585.     register vm_page_t    p;
  586.  
  587.     if (object == NULL)
  588.         return;
  589.  
  590.     vm_object_lock(object);
  591.     p = (vm_page_t) queue_first(&object->memq);
  592.     while (!queue_end(&object->memq, (queue_entry_t) p)) {
  593.         if ((start <= p->offset) && (p->offset < end))
  594.             pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE);
  595.         p = (vm_page_t) queue_next(&p->listq);
  596.     }
  597.     vm_object_unlock(object);
  598. }
  599.  
  600. /*
  601.  *    vm_object_copy:
  602.  *
  603.  *    Create a new object which is a copy of an existing
  604.  *    object, and mark all of the pages in the existing
  605.  *    object 'copy-on-write'.  The new object has one reference.
  606.  *    Returns the new object.
  607.  *
  608.  *    May defer the copy until later if the object is not backed
  609.  *    up by a non-default pager.
  610.  */
  611. void vm_object_copy(src_object, src_offset, size,
  612.             dst_object, dst_offset, src_needs_copy)
  613.     register vm_object_t    src_object;
  614.     vm_offset_t        src_offset;
  615.     vm_size_t        size;
  616.     vm_object_t        *dst_object;    /* OUT */
  617.     vm_offset_t        *dst_offset;    /* OUT */
  618.     boolean_t        *src_needs_copy;    /* OUT */
  619. {
  620.     register vm_object_t    new_copy;
  621.     register vm_object_t    old_copy;
  622.     vm_offset_t        new_start, new_end;
  623.  
  624.     register vm_page_t    p;
  625.  
  626.     if (src_object == NULL) {
  627.         /*
  628.          *    Nothing to copy
  629.          */
  630.         *dst_object = NULL;
  631.         *dst_offset = 0;
  632.         *src_needs_copy = FALSE;
  633.         return;
  634.     }
  635.  
  636.     /*
  637.      *    If the object's pager is null_pager or the
  638.      *    default pager, we don't have to make a copy
  639.      *    of it.  Instead, we set the needs copy flag and
  640.      *    make a shadow later.
  641.      */
  642.  
  643.     vm_object_lock(src_object);
  644.     if (src_object->pager == NULL ||
  645.         src_object->internal) {
  646.  
  647.         /*
  648.          *    Make another reference to the object
  649.          */
  650.         src_object->ref_count++;
  651.  
  652.         /*
  653.          *    Mark all of the pages copy-on-write.
  654.          */
  655.         for (p = (vm_page_t) queue_first(&src_object->memq);
  656.              !queue_end(&src_object->memq, (queue_entry_t)p);
  657.              p = (vm_page_t) queue_next(&p->listq)) {
  658.             if (src_offset <= p->offset &&
  659.                 p->offset < src_offset + size)
  660.                 p->copy_on_write = TRUE;
  661.         }
  662.         vm_object_unlock(src_object);
  663.  
  664.         *dst_object = src_object;
  665.         *dst_offset = src_offset;
  666.         
  667.         /*
  668.          *    Must make a shadow when write is desired
  669.          */
  670.         *src_needs_copy = TRUE;
  671.         return;
  672.     }
  673.  
  674.     /*
  675.      *    Try to collapse the object before copying it.
  676.      */
  677.     vm_object_collapse(src_object);
  678.  
  679.     /*
  680.      *    If the object has a pager, the pager wants to
  681.      *    see all of the changes.  We need a copy-object
  682.      *    for the changed pages.
  683.      *
  684.      *    If there is a copy-object, and it is empty,
  685.      *    no changes have been made to the object since the
  686.      *    copy-object was made.  We can use the same copy-
  687.      *    object.
  688.      */
  689.  
  690.     Retry1:
  691.     old_copy = src_object->copy;
  692.     if (old_copy != NULL) {
  693.         /*
  694.          *    Try to get the locks (out of order)
  695.          */
  696.         if (!vm_object_lock_try(old_copy)) {
  697.             vm_object_unlock(src_object);
  698.  
  699.             /* should spin a bit here... */
  700.             vm_object_lock(src_object);
  701.             goto Retry1;
  702.         }
  703.  
  704.         if (old_copy->resident_page_count == 0 &&
  705.             old_copy->pager == NULL) {
  706.             /*
  707.              *    Return another reference to
  708.              *    the existing copy-object.
  709.              */
  710.             old_copy->ref_count++;
  711.             vm_object_unlock(old_copy);
  712.             vm_object_unlock(src_object);
  713.             *dst_object = old_copy;
  714.             *dst_offset = src_offset;
  715.             *src_needs_copy = FALSE;
  716.             return;
  717.         }
  718.         vm_object_unlock(old_copy);
  719.     }
  720.     vm_object_unlock(src_object);
  721.  
  722.     /*
  723.      *    If the object has a pager, the pager wants
  724.      *    to see all of the changes.  We must make
  725.      *    a copy-object and put the changed pages there.
  726.      *
  727.      *    The copy-object is always made large enough to
  728.      *    completely shadow the original object, since
  729.      *    it may have several users who want to shadow
  730.      *    the original object at different points.
  731.      */
  732.  
  733.     new_copy = vm_object_allocate(src_object->size);
  734.  
  735.     Retry2:
  736.     vm_object_lock(src_object);
  737.     /*
  738.      *    Copy object may have changed while we were unlocked
  739.      */
  740.     old_copy = src_object->copy;
  741.     if (old_copy != NULL) {
  742.         /*
  743.          *    Try to get the locks (out of order)
  744.          */
  745.         if (!vm_object_lock_try(old_copy)) {
  746.             vm_object_unlock(src_object);
  747.             goto Retry2;
  748.         }
  749.  
  750.         /*
  751.          *    Consistency check
  752.          */
  753.         if (old_copy->shadow != src_object ||
  754.             old_copy->shadow_offset != (vm_offset_t) 0)
  755.             panic("vm_object_copy: copy/shadow inconsistency");
  756.  
  757.         /*
  758.          *    Make the old copy-object shadow the new one.
  759.          *    It will receive no more pages from the original
  760.          *    object.
  761.          */
  762.  
  763.         src_object->ref_count--;    /* remove ref. from old_copy */
  764.         old_copy->shadow = new_copy;
  765.         new_copy->ref_count++;        /* locking not needed - we
  766.                            have the only pointer */
  767.         vm_object_unlock(old_copy);    /* done with old_copy */
  768.     }
  769.  
  770.     new_start = (vm_offset_t) 0;    /* always shadow original at 0 */
  771.     new_end   = (vm_offset_t) new_copy->size; /* for the whole object */
  772.  
  773.     /*
  774.      *    Point the new copy at the existing object.
  775.      */
  776.  
  777.     new_copy->shadow = src_object;
  778.     new_copy->shadow_offset = new_start;
  779.     src_object->ref_count++;
  780.     src_object->copy = new_copy;
  781.  
  782.     /*
  783.      *    Mark all the affected pages of the existing object
  784.      *    copy-on-write.
  785.      */
  786.     p = (vm_page_t) queue_first(&src_object->memq);
  787.     while (!queue_end(&src_object->memq, (queue_entry_t) p)) {
  788.         if ((new_start <= p->offset) && (p->offset < new_end))
  789.             p->copy_on_write = TRUE;
  790.         p = (vm_page_t) queue_next(&p->listq);
  791.     }
  792.  
  793.     vm_object_unlock(src_object);
  794.  
  795.     *dst_object = new_copy;
  796.     *dst_offset = src_offset - new_start;
  797.     *src_needs_copy = FALSE;
  798. }
  799.  
  800. /*
  801.  *    vm_object_shadow:
  802.  *
  803.  *    Create a new object which is backed by the
  804.  *    specified existing object range.  The source
  805.  *    object reference is deallocated.
  806.  *
  807.  *    The new object and offset into that object
  808.  *    are returned in the source parameters.
  809.  */
  810.  
  811. void vm_object_shadow(object, offset, length)
  812.     vm_object_t    *object;    /* IN/OUT */
  813.     vm_offset_t    *offset;    /* IN/OUT */
  814.     vm_size_t    length;
  815. {
  816.     register vm_object_t    source;
  817.     register vm_object_t    result;
  818.  
  819.     source = *object;
  820.  
  821.     /*
  822.      *    Allocate a new object with the given length
  823.      */
  824.  
  825.     if ((result = vm_object_allocate(length)) == NULL)
  826.         panic("vm_object_shadow: no object for shadowing");
  827.  
  828.     /*
  829.      *    The new object shadows the source object, adding
  830.      *    a reference to it.  Our caller changes his reference
  831.      *    to point to the new object, removing a reference to
  832.      *    the source object.  Net result: no change of reference
  833.      *    count.
  834.      */
  835.     result->shadow = source;
  836.     
  837.     /*
  838.      *    Store the offset into the source object,
  839.      *    and fix up the offset into the new object.
  840.      */
  841.  
  842.     result->shadow_offset = *offset;
  843.  
  844.     /*
  845.      *    Return the new things
  846.      */
  847.  
  848.     *offset = 0;
  849.     *object = result;
  850. }
  851.  
  852. /*
  853.  *    Set the specified object's pager to the specified pager.
  854.  */
  855.  
  856. void vm_object_setpager(object, pager, paging_offset,
  857.             read_only)
  858.     vm_object_t    object;
  859.     vm_pager_t    pager;
  860.     vm_offset_t    paging_offset;
  861.     boolean_t    read_only;
  862. {
  863. #ifdef    lint
  864.     read_only++;    /* No longer used */
  865. #endif    lint
  866.  
  867.     vm_object_lock(object);            /* XXX ? */
  868.     object->pager = pager;
  869.     object->paging_offset = paging_offset;
  870.     vm_object_unlock(object);            /* XXX ? */
  871. }
  872.  
  873. /*
  874.  *    vm_object_hash hashes the pager/id pair.
  875.  */
  876.  
  877. #define vm_object_hash(pager) \
  878.     (((unsigned)pager)%VM_OBJECT_HASH_COUNT)
  879.  
  880. /*
  881.  *    vm_object_lookup looks in the object cache for an object with the
  882.  *    specified pager and paging id.
  883.  */
  884.  
  885. vm_object_t vm_object_lookup(pager)
  886.     vm_pager_t    pager;
  887. {
  888.     register queue_t        bucket;
  889.     register vm_object_hash_entry_t    entry;
  890.     vm_object_t            object;
  891.  
  892.     bucket = &vm_object_hashtable[vm_object_hash(pager)];
  893.  
  894.     vm_object_cache_lock();
  895.  
  896.     entry = (vm_object_hash_entry_t) queue_first(bucket);
  897.     while (!queue_end(bucket, (queue_entry_t) entry)) {
  898.         object = entry->object;
  899.         if (object->pager == pager) {
  900.             vm_object_lock(object);
  901.             if (object->ref_count == 0) {
  902.                 queue_remove(&vm_object_cached_list, object,
  903.                         vm_object_t, cached_list);
  904.                 vm_object_cached--;
  905.             }
  906.             object->ref_count++;
  907.             vm_object_unlock(object);
  908.             vm_object_cache_unlock();
  909.             return(object);
  910.         }
  911.         entry = (vm_object_hash_entry_t) queue_next(&entry->hash_links);
  912.     }
  913.  
  914.     vm_object_cache_unlock();
  915.     return(NULL);
  916. }
  917.  
  918. /*
  919.  *    vm_object_enter enters the specified object/pager/id into
  920.  *    the hash table.
  921.  */
  922.  
  923. void vm_object_enter(object, pager)
  924.     vm_object_t    object;
  925.     vm_pager_t    pager;
  926. {
  927.     register queue_t        bucket;
  928.     register vm_object_hash_entry_t    entry;
  929.  
  930.     /*
  931.      *    We don't cache null objects, and we can't cache
  932.      *    objects with the null pager.
  933.      */
  934.  
  935.     if (object == NULL)
  936.         return;
  937.     if (pager == NULL)
  938.         return;
  939.  
  940.     bucket = &vm_object_hashtable[vm_object_hash(pager)];
  941.     entry = (vm_object_hash_entry_t)
  942.         malloc((u_long)sizeof *entry, M_VMOBJHASH, M_WAITOK);
  943.     entry->object = object;
  944.     object->can_persist = TRUE;
  945.  
  946.     vm_object_cache_lock();
  947.     queue_enter(bucket, entry, vm_object_hash_entry_t, hash_links);
  948.     vm_object_cache_unlock();
  949. }
  950.  
  951. /*
  952.  *    vm_object_remove:
  953.  *
  954.  *    Remove the pager from the hash table.
  955.  *    Note:  This assumes that the object cache
  956.  *    is locked.  XXX this should be fixed
  957.  *    by reorganizing vm_object_deallocate.
  958.  */
  959. vm_object_remove(pager)
  960.     register vm_pager_t    pager;
  961. {
  962.     register queue_t        bucket;
  963.     register vm_object_hash_entry_t    entry;
  964.     register vm_object_t        object;
  965.  
  966.     bucket = &vm_object_hashtable[vm_object_hash(pager)];
  967.  
  968.     entry = (vm_object_hash_entry_t) queue_first(bucket);
  969.     while (!queue_end(bucket, (queue_entry_t) entry)) {
  970.         object = entry->object;
  971.         if (object->pager == pager) {
  972.             queue_remove(bucket, entry, vm_object_hash_entry_t,
  973.                     hash_links);
  974.             free((caddr_t)entry, M_VMOBJHASH);
  975.             break;
  976.         }
  977.         entry = (vm_object_hash_entry_t) queue_next(&entry->hash_links);
  978.     }
  979. }
  980.  
  981. /*
  982.  *    vm_object_cache_clear removes all objects from the cache.
  983.  *
  984.  */
  985.  
  986. void vm_object_cache_clear()
  987. {
  988.     register vm_object_t    object;
  989.  
  990.     /*
  991.      *    Remove each object in the cache by scanning down the
  992.      *    list of cached objects.
  993.      */
  994.     vm_object_cache_lock();
  995.     while (!queue_empty(&vm_object_cached_list)) {
  996.         object = (vm_object_t) queue_first(&vm_object_cached_list);
  997.         vm_object_cache_unlock();
  998.  
  999.         /* 
  1000.          * Note: it is important that we use vm_object_lookup
  1001.          * to gain a reference, and not vm_object_reference, because
  1002.          * the logic for removing an object from the cache lies in 
  1003.          * lookup.
  1004.          */
  1005.         if (object != vm_object_lookup(object->pager))
  1006.             panic("vm_object_cache_clear: I'm sooo confused.");
  1007.         pager_cache(object, FALSE);
  1008.  
  1009.         vm_object_cache_lock();
  1010.     }
  1011.     vm_object_cache_unlock();
  1012. }
  1013.  
  1014. boolean_t    vm_object_collapse_allowed = TRUE;
  1015. /*
  1016.  *    vm_object_collapse:
  1017.  *
  1018.  *    Collapse an object with the object backing it.
  1019.  *    Pages in the backing object are moved into the
  1020.  *    parent, and the backing object is deallocated.
  1021.  *
  1022.  *    Requires that the object be locked and the page
  1023.  *    queues be unlocked.
  1024.  *
  1025.  */
  1026. void vm_object_collapse(object)
  1027.     register vm_object_t    object;
  1028.  
  1029. {
  1030.     register vm_object_t    backing_object;
  1031.     register vm_offset_t    backing_offset;
  1032.     register vm_size_t    size;
  1033.     register vm_offset_t    new_offset;
  1034.     register vm_page_t    p, pp;
  1035.  
  1036.     if (!vm_object_collapse_allowed)
  1037.         return;
  1038.  
  1039.     while (TRUE) {
  1040.         /*
  1041.          *    Verify that the conditions are right for collapse:
  1042.          *
  1043.          *    The object exists and no pages in it are currently
  1044.          *    being paged out (or have ever been paged out).
  1045.          */
  1046.         if (object == NULL ||
  1047.             object->paging_in_progress != 0 ||
  1048.             object->pager != NULL)
  1049.             return;
  1050.  
  1051.         /*
  1052.          *        There is a backing object, and
  1053.          */
  1054.     
  1055.         if ((backing_object = object->shadow) == NULL)
  1056.             return;
  1057.     
  1058.         vm_object_lock(backing_object);
  1059.         /*
  1060.          *    ...
  1061.          *        The backing object is not read_only,
  1062.          *        and no pages in the backing object are
  1063.          *        currently being paged out.
  1064.          *        The backing object is internal.
  1065.          */
  1066.     
  1067.         if (!backing_object->internal ||
  1068.             backing_object->paging_in_progress != 0) {
  1069.             vm_object_unlock(backing_object);
  1070.             return;
  1071.         }
  1072.     
  1073.         /*
  1074.          *    The backing object can't be a copy-object:
  1075.          *    the shadow_offset for the copy-object must stay
  1076.          *    as 0.  Furthermore (for the 'we have all the
  1077.          *    pages' case), if we bypass backing_object and
  1078.          *    just shadow the next object in the chain, old
  1079.          *    pages from that object would then have to be copied
  1080.          *    BOTH into the (former) backing_object and into the
  1081.          *    parent object.
  1082.          */
  1083.         if (backing_object->shadow != NULL &&
  1084.             backing_object->shadow->copy != NULL) {
  1085.             vm_object_unlock(backing_object);
  1086.             return;
  1087.         }
  1088.  
  1089.         /*
  1090.          *    We know that we can either collapse the backing
  1091.          *    object (if the parent is the only reference to
  1092.          *    it) or (perhaps) remove the parent's reference
  1093.          *    to it.
  1094.          */
  1095.  
  1096.         backing_offset = object->shadow_offset;
  1097.         size = object->size;
  1098.  
  1099.         /*
  1100.          *    If there is exactly one reference to the backing
  1101.          *    object, we can collapse it into the parent.
  1102.          */
  1103.     
  1104.         if (backing_object->ref_count == 1) {
  1105.  
  1106.             /*
  1107.              *    We can collapse the backing object.
  1108.              *
  1109.              *    Move all in-memory pages from backing_object
  1110.              *    to the parent.  Pages that have been paged out
  1111.              *    will be overwritten by any of the parent's
  1112.              *    pages that shadow them.
  1113.              */
  1114.  
  1115.             while (!queue_empty(&backing_object->memq)) {
  1116.  
  1117.                 p = (vm_page_t)
  1118.                     queue_first(&backing_object->memq);
  1119.  
  1120.                 new_offset = (p->offset - backing_offset);
  1121.  
  1122.                 /*
  1123.                  *    If the parent has a page here, or if
  1124.                  *    this page falls outside the parent,
  1125.                  *    dispose of it.
  1126.                  *
  1127.                  *    Otherwise, move it as planned.
  1128.                  */
  1129.  
  1130.                 if (p->offset < backing_offset ||
  1131.                     new_offset >= size) {
  1132.                     vm_page_lock_queues();
  1133.                     vm_page_free(p);
  1134.                     vm_page_unlock_queues();
  1135.                 } else {
  1136.                     pp = vm_page_lookup(object, new_offset);
  1137.                     if (pp != NULL && !pp->fake) {
  1138.                     vm_page_lock_queues();
  1139.                     vm_page_free(p);
  1140.                     vm_page_unlock_queues();
  1141.                     }
  1142.                     else {
  1143.                     if (pp) {
  1144.                         /* may be someone waiting for it */
  1145.                         PAGE_WAKEUP(pp);
  1146.                         vm_page_lock_queues();
  1147.                         vm_page_free(pp);
  1148.                         vm_page_unlock_queues();
  1149.                     }
  1150.                     vm_page_rename(p, object, new_offset);
  1151.                     }
  1152.                 }
  1153.             }
  1154.  
  1155.             /*
  1156.              *    Move the pager from backing_object to object.
  1157.              *
  1158.              *    XXX We're only using part of the paging space
  1159.              *    for keeps now... we ought to discard the
  1160.              *    unused portion.
  1161.              */
  1162.  
  1163.             object->pager = backing_object->pager;
  1164.             object->paging_offset += backing_offset;
  1165.  
  1166.             backing_object->pager = NULL;
  1167.  
  1168.             /*
  1169.              *    Object now shadows whatever backing_object did.
  1170.              *    Note that the reference to backing_object->shadow
  1171.              *    moves from within backing_object to within object.
  1172.              */
  1173.  
  1174.             object->shadow = backing_object->shadow;
  1175.             object->shadow_offset += backing_object->shadow_offset;
  1176.             if (object->shadow != NULL &&
  1177.                 object->shadow->copy != NULL) {
  1178.                 panic("vm_object_collapse: we collapsed a copy-object!");
  1179.             }
  1180.             /*
  1181.              *    Discard backing_object.
  1182.              *
  1183.              *    Since the backing object has no pages, no
  1184.              *    pager left, and no object references within it,
  1185.              *    all that is necessary is to dispose of it.
  1186.              */
  1187.  
  1188.             vm_object_unlock(backing_object);
  1189.  
  1190.             simple_lock(&vm_object_list_lock);
  1191.             queue_remove(&vm_object_list, backing_object,
  1192.                         vm_object_t, object_list);
  1193.             vm_object_count--;
  1194.             simple_unlock(&vm_object_list_lock);
  1195.  
  1196.             free((caddr_t)backing_object, M_VMOBJ);
  1197.  
  1198.             object_collapses++;
  1199.         }
  1200.         else {
  1201.             /*
  1202.              *    If all of the pages in the backing object are
  1203.              *    shadowed by the parent object, the parent
  1204.              *    object no longer has to shadow the backing
  1205.              *    object; it can shadow the next one in the
  1206.              *    chain.
  1207.              *
  1208.              *    The backing object must not be paged out - we'd
  1209.              *    have to check all of the paged-out pages, as
  1210.              *    well.
  1211.              */
  1212.  
  1213.             if (backing_object->pager != NULL) {
  1214.                 vm_object_unlock(backing_object);
  1215.                 return;
  1216.             }
  1217.  
  1218.             /*
  1219.              *    Should have a check for a 'small' number
  1220.              *    of pages here.
  1221.              */
  1222.  
  1223.             p = (vm_page_t) queue_first(&backing_object->memq);
  1224.             while (!queue_end(&backing_object->memq,
  1225.                       (queue_entry_t) p)) {
  1226.  
  1227.                 new_offset = (p->offset - backing_offset);
  1228.  
  1229.                 /*
  1230.                  *    If the parent has a page here, or if
  1231.                  *    this page falls outside the parent,
  1232.                  *    keep going.
  1233.                  *
  1234.                  *    Otherwise, the backing_object must be
  1235.                  *    left in the chain.
  1236.                  */
  1237.  
  1238.                 if (p->offset >= backing_offset &&
  1239.                     new_offset <= size &&
  1240.                     ((pp = vm_page_lookup(object, new_offset))
  1241.                       == NULL ||
  1242.                      pp->fake)) {
  1243.                     /*
  1244.                      *    Page still needed.
  1245.                      *    Can't go any further.
  1246.                      */
  1247.                     vm_object_unlock(backing_object);
  1248.                     return;
  1249.                 }
  1250.                 p = (vm_page_t) queue_next(&p->listq);
  1251.             }
  1252.  
  1253.             /*
  1254.              *    Make the parent shadow the next object
  1255.              *    in the chain.  Deallocating backing_object
  1256.              *    will not remove it, since its reference
  1257.              *    count is at least 2.
  1258.              */
  1259.  
  1260.             vm_object_reference(object->shadow = backing_object->shadow);
  1261.             object->shadow_offset += backing_object->shadow_offset;
  1262.  
  1263.             /*    Drop the reference count on backing_object.
  1264.              *    Since its ref_count was at least 2, it
  1265.              *    will not vanish; so we don't need to call
  1266.              *    vm_object_deallocate.
  1267.              */
  1268.             backing_object->ref_count--;
  1269.             vm_object_unlock(backing_object);
  1270.  
  1271.             object_bypasses ++;
  1272.  
  1273.         }
  1274.  
  1275.         /*
  1276.          *    Try again with this object's new backing object.
  1277.          */
  1278.     }
  1279. }
  1280.  
  1281. /*
  1282.  *    vm_object_page_remove: [internal]
  1283.  *
  1284.  *    Removes all physical pages in the specified
  1285.  *    object range from the object's list of pages.
  1286.  *
  1287.  *    The object must be locked.
  1288.  */
  1289. void vm_object_page_remove(object, start, end)
  1290.     register vm_object_t    object;
  1291.     register vm_offset_t    start;
  1292.     register vm_offset_t    end;
  1293. {
  1294.     register vm_page_t    p, next;
  1295.  
  1296.     if (object == NULL)
  1297.         return;
  1298.  
  1299.     p = (vm_page_t) queue_first(&object->memq);
  1300.     while (!queue_end(&object->memq, (queue_entry_t) p)) {
  1301.         next = (vm_page_t) queue_next(&p->listq);
  1302.         if ((start <= p->offset) && (p->offset < end)) {
  1303.             pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE);
  1304.             vm_page_lock_queues();
  1305.             vm_page_free(p);
  1306.             vm_page_unlock_queues();
  1307.         }
  1308.         p = next;
  1309.     }
  1310. }
  1311.  
  1312. /*
  1313.  *    Routine:    vm_object_coalesce
  1314.  *    Function:    Coalesces two objects backing up adjoining
  1315.  *            regions of memory into a single object.
  1316.  *
  1317.  *    returns TRUE if objects were combined.
  1318.  *
  1319.  *    NOTE:    Only works at the moment if the second object is NULL -
  1320.  *        if it's not, which object do we lock first?
  1321.  *
  1322.  *    Parameters:
  1323.  *        prev_object    First object to coalesce
  1324.  *        prev_offset    Offset into prev_object
  1325.  *        next_object    Second object into coalesce
  1326.  *        next_offset    Offset into next_object
  1327.  *
  1328.  *        prev_size    Size of reference to prev_object
  1329.  *        next_size    Size of reference to next_object
  1330.  *
  1331.  *    Conditions:
  1332.  *    The object must *not* be locked.
  1333.  */
  1334. boolean_t vm_object_coalesce(prev_object, next_object,
  1335.             prev_offset, next_offset,
  1336.             prev_size, next_size)
  1337.  
  1338.     register vm_object_t    prev_object;
  1339.     vm_object_t    next_object;
  1340.     vm_offset_t    prev_offset, next_offset;
  1341.     vm_size_t    prev_size, next_size;
  1342. {
  1343.     vm_size_t    newsize;
  1344.  
  1345. #ifdef    lint
  1346.     next_offset++;
  1347. #endif    lint
  1348.  
  1349.     if (next_object != NULL) {
  1350.         return(FALSE);
  1351.     }
  1352.  
  1353.     if (prev_object == NULL) {
  1354.         return(TRUE);
  1355.     }
  1356.  
  1357.     vm_object_lock(prev_object);
  1358.  
  1359.     /*
  1360.      *    Try to collapse the object first
  1361.      */
  1362.     vm_object_collapse(prev_object);
  1363.  
  1364.     /*
  1365.      *    Can't coalesce if:
  1366.      *    . more than one reference
  1367.      *    . paged out
  1368.      *    . shadows another object
  1369.      *    . has a copy elsewhere
  1370.      *    (any of which mean that the pages not mapped to
  1371.      *    prev_entry may be in use anyway)
  1372.      */
  1373.  
  1374.     if (prev_object->ref_count > 1 ||
  1375.         prev_object->pager != NULL ||
  1376.         prev_object->shadow != NULL ||
  1377.         prev_object->copy != NULL) {
  1378.         vm_object_unlock(prev_object);
  1379.         return(FALSE);
  1380.     }
  1381.  
  1382.     /*
  1383.      *    Remove any pages that may still be in the object from
  1384.      *    a previous deallocation.
  1385.      */
  1386.  
  1387.     vm_object_page_remove(prev_object,
  1388.             prev_offset + prev_size,
  1389.             prev_offset + prev_size + next_size);
  1390.  
  1391.     /*
  1392.      *    Extend the object if necessary.
  1393.      */
  1394.     newsize = prev_offset + prev_size + next_size;
  1395.     if (newsize > prev_object->size)
  1396.         prev_object->size = newsize;
  1397.  
  1398.     vm_object_unlock(prev_object);
  1399.     return(TRUE);
  1400. }
  1401.  
  1402. /*
  1403.  *    vm_object_print:    [ debug ]
  1404.  */
  1405. void vm_object_print(object, full)
  1406.     vm_object_t    object;
  1407.     boolean_t    full;
  1408. {
  1409.     register vm_page_t    p;
  1410.     extern indent;
  1411.  
  1412.     register int count;
  1413.  
  1414.     if (object == NULL)
  1415.         return;
  1416.  
  1417.     iprintf("Object 0x%x: size=0x%x, res=%d, ref=%d, ",
  1418.         (int) object, (int) object->size,
  1419.         object->resident_page_count, object->ref_count);
  1420.     printf("pager=0x%x+0x%x, shadow=(0x%x)+0x%x\n",
  1421.            (int) object->pager, (int) object->paging_offset,
  1422.            (int) object->shadow, (int) object->shadow_offset);
  1423.     printf("cache: next=0x%x, prev=0x%x\n",
  1424.            object->cached_list.next, object->cached_list.prev);
  1425.  
  1426.     if (!full)
  1427.         return;
  1428.  
  1429.     indent += 2;
  1430.     count = 0;
  1431.     p = (vm_page_t) queue_first(&object->memq);
  1432.     while (!queue_end(&object->memq, (queue_entry_t) p)) {
  1433.         if (count == 0)
  1434.             iprintf("memory:=");
  1435.         else if (count == 6) {
  1436.             printf("\n");
  1437.             iprintf(" ...");
  1438.             count = 0;
  1439.         } else
  1440.             printf(",");
  1441.         count++;
  1442.  
  1443.         printf("(off=0x%x,page=0x%x)", p->offset, VM_PAGE_TO_PHYS(p));
  1444.         p = (vm_page_t) queue_next(&p->listq);
  1445.     }
  1446.     if (count != 0)
  1447.         printf("\n");
  1448.     indent -= 2;
  1449. }
  1450.