bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH gnumach 5/6] ipc: replace the IPC table with a radix tree


From: Justus Winter
Subject: [PATCH gnumach 5/6] ipc: replace the IPC table with a radix tree
Date: Tue, 19 May 2015 17:39:03 +0200

Currently, the port names are mapped to an IPC object (e.g. a port)
using a table.  This, however, requires large chunks of continuous
memory, and leads to scalability problems as virtual kernel memory is
a scarce resource.  To avoid excessive overhead, non-contiguous port
names are spilled into a splay tree.

Replace the IPC table with a radix tree.  As the radix tree is able to
store non-contiguous names with reasonable overhead, we can drop the
splay tree as well.

* ipc/ipc_entry.c (ipc_entry_tree_collision): Remove function.
(ipc_entry_cache): New variable.
(ipc_entry_lookup): Replace with a radix tree lookup.
(ipc_entry_get): The free list handling is changed a little.  Adopt
accordingly.
(ipc_entry_free_name): New function.
(ipc_entry_alloc): Adopt accordingly.
(ipc_entry_alloc_name): Likewise.
(ipc_entry_dealloc): Likewise.
(ipc_entry_grow_table): Remove function.
* ipc/ipc_entry.h (struct ipc_entry): Update comment, add field for
name and free list, remove unused fields.
(ipc_entry_cache, ie_alloc, ie_free): New declarations.
(struct ipc_tree_entry): Remove.  Also remove any related declarations.
(ipc_entry_grow_table): Remove declaration.
* ipc/ipc_init.c (ipc_bootstrap): Adopt initialization.
* ipc/ipc_kmsg.c (ipc_kmsg_copyout_header): Use `ipc_entry_alloc'
instead of re-coding it.  Adopt free list handling.
(ipc_kmsg_copyout_object): Adopt free list handling, store the name.
* ipc/ipc_object.c (ipc_object_copyout): Likewise.
(ipc_object_copyout_multiname): Likewise.
* ipc/ipc_space.c (ipc_space_create): Initialize radix tree and free list.
Drop table and splay tree initialization.
(ipc_space_destroy): Free ipc entries and radix tree, remove table and
splay tree cleanup.
* ipc/ipc_space.h (struct ipc_space): Add radix tree, free list, and size.
Remove all fields related to the table and splay tree.
* ddb/db_print.c (db_port_iterate): Adopt iteration.
(db_lookup_port): Adopt lookup.
* include/mach_debug/ipc_info.h: Remove unused parts of the debug interface.
* include/mach_debug/mach_debug.defs: Likewise.
* include/mach_debug/mach_debug_types.defs: Likewise.
* ipc/mach_debug.c: Likewise.
* ipc/ipc_right.c (ipc_right_reverse): Adopt lookup, store name.
(ipc_right_check): Adopt removal.
(ipc_right_destroy): Likewise.
(ipc_right_dealloc): Likewise.
(ipc_right_delta): Likewise.
(ipc_right_copyin): Adopt insertion, adopt removal.
(ipc_right_copyin_two): Adopt removal.
(ipc_right_copyout): Adopt insertion, adopt removal.
(ipc_right_rename): Likewise, also update comment.
* ipc/mach_port.c (mach_port_names): Adopt iteration.
(mach_port_get_set_status): Likewise.
* ipc/port.h: Update comment.
* ipc/ipc_hash.c: Delete file.
* ipc/ipc_hash.h: Likewise.
* ipc/ipc_splay.c: Likewise.
* ipc/ipc_splay.h: Likewise.
* Makefrag.am (libkernel_a_SOURCES): Remove these files.
---
 Makefrag.am                              |   4 -
 ddb/db_print.c                           |  20 +-
 include/mach_debug/ipc_info.h            |  23 -
 include/mach_debug/mach_debug.defs       |  21 +-
 include/mach_debug/mach_debug_types.defs |   7 +-
 ipc/ipc_entry.c                          | 720 ++++--------------------
 ipc/ipc_entry.h                          |  55 +-
 ipc/ipc_hash.c                           | 486 ----------------
 ipc/ipc_hash.h                           |  96 ----
 ipc/ipc_init.c                           |   6 +-
 ipc/ipc_kmsg.c                           |  32 +-
 ipc/ipc_object.c                         |  23 +-
 ipc/ipc_right.c                          |  39 +-
 ipc/ipc_space.c                          | 104 +---
 ipc/ipc_space.h                          |  18 +-
 ipc/ipc_splay.c                          | 920 -------------------------------
 ipc/ipc_splay.h                          | 114 ----
 ipc/mach_debug.c                         | 325 -----------
 ipc/mach_port.c                          |  60 +-
 ipc/port.h                               |   5 +-
 20 files changed, 198 insertions(+), 2880 deletions(-)
 delete mode 100644 ipc/ipc_hash.c
 delete mode 100644 ipc/ipc_hash.h
 delete mode 100644 ipc/ipc_splay.c
 delete mode 100644 ipc/ipc_splay.h

diff --git a/Makefrag.am b/Makefrag.am
index 2eb835e..023a4d1 100644
--- a/Makefrag.am
+++ b/Makefrag.am
@@ -80,8 +80,6 @@ endif
 libkernel_a_SOURCES += \
        ipc/ipc_entry.c \
        ipc/ipc_entry.h \
-       ipc/ipc_hash.c \
-       ipc/ipc_hash.h \
        ipc/ipc_init.c \
        ipc/ipc_init.h \
        ipc/ipc_kmsg.c \
@@ -105,8 +103,6 @@ libkernel_a_SOURCES += \
        ipc/ipc_right.h \
        ipc/ipc_space.c \
        ipc/ipc_space.h \
-       ipc/ipc_splay.c \
-       ipc/ipc_splay.h \
        ipc/ipc_table.c \
        ipc/ipc_table.h \
        ipc/ipc_target.c \
diff --git a/ddb/db_print.c b/ddb/db_print.c
index 24a3e33..fb4efaa 100644
--- a/ddb/db_print.c
+++ b/ddb/db_print.c
@@ -439,17 +439,11 @@ db_port_iterate(thread, func)
        void (*func)();
 {
        ipc_entry_t entry;
-       int index;
        int n = 0;
-       int size;
-       ipc_space_t space;
-
-       space = thread->task->itk_space;
-       entry = space->is_table;
-       size = space->is_table_size;
-       for (index = 0; index < size; index++, entry++) {
+       struct rdxtree_iter iter;
+       rdxtree_for_each(&thread->task->itk_space->is_map, &iter, entry) {
            if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
-               (*func)(index, (ipc_port_t) entry->ie_object,
+               (*func)(entry->ie_name, (ipc_port_t) entry->ie_object,
                        entry->ie_bits, n++);
        }
        return(n);
@@ -460,16 +454,14 @@ db_lookup_port(
        thread_t        thread,
        int             id)
 {
-       ipc_space_t space;
        ipc_entry_t entry;
 
        if (thread == THREAD_NULL)
            return(0);
-       space = thread->task->itk_space;
-       if (id < 0 || id >= space->is_table_size)
+       if (id < 0)
            return(0);
-       entry = &space->is_table[id];
-       if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
+       entry = ipc_entry_lookup(thread->task->itk_space, (mach_port_t) id);
+       if (entry && entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
            return((ipc_port_t)entry->ie_object);
        return(0);
 }
diff --git a/include/mach_debug/ipc_info.h b/include/mach_debug/ipc_info.h
index ef0b0c6..a47ae7b 100644
--- a/include/mach_debug/ipc_info.h
+++ b/include/mach_debug/ipc_info.h
@@ -43,40 +43,17 @@
  *     in mach_debug_types.defs when adding/removing fields.
  */
 
-
-typedef struct ipc_info_space {
-       natural_t iis_genno_mask;       /* generation number mask */
-       natural_t iis_table_size;       /* size of table */
-       natural_t iis_table_next;       /* next possible size of table */
-       natural_t iis_tree_size;        /* size of tree */
-       natural_t iis_tree_small;       /* # of small entries in tree */
-       natural_t iis_tree_hash;        /* # of hashed entries in tree */
-} ipc_info_space_t;
-
-
 typedef struct ipc_info_name {
        mach_port_t iin_name;           /* port name, including gen number */
-/*boolean_t*/integer_t iin_collision;  /* collision at this entry? */
-/*boolean_t*/integer_t iin_compat;     /* is this a compat-mode entry? */
 /*boolean_t*/integer_t iin_marequest;  /* extant msg-accepted request? */
        mach_port_type_t iin_type;      /* straight port type */
        mach_port_urefs_t iin_urefs;    /* user-references */
        vm_offset_t iin_object;         /* object pointer */
        natural_t iin_next;             /* marequest/next in free list */
-       natural_t iin_hash;             /* hash index */
 } ipc_info_name_t;
 
 typedef ipc_info_name_t *ipc_info_name_array_t;
 
-
-typedef struct ipc_info_tree_name {
-       ipc_info_name_t iitn_name;
-       mach_port_t iitn_lchild;        /* name of left child */
-       mach_port_t iitn_rchild;        /* name of right child */
-} ipc_info_tree_name_t;
-
-typedef ipc_info_tree_name_t *ipc_info_tree_name_array_t;
-
 /*
  *     Type definitions for mach_port_kernel_object.
  *     By remarkable coincidence, these closely resemble
diff --git a/include/mach_debug/mach_debug.defs 
b/include/mach_debug/mach_debug.defs
index fb6e3a9..c8e8b1b 100644
--- a/include/mach_debug/mach_debug.defs
+++ b/include/mach_debug/mach_debug.defs
@@ -57,14 +57,7 @@ routine      mach_port_get_srights(
                name            : mach_port_name_t;
        out     srights         : mach_port_rights_t);
 
-/*
- *     Returns information about the global reverse hash table.
- */
-
-routine host_ipc_hash_info(
-               host            : host_t;
-       out     info            : hash_info_bucket_array_t,
-                                       CountInOut, Dealloc);
+skip;  /* host_ipc_hash_info */
 
 /*
  *     Returns information about the marequest hash table.
@@ -76,17 +69,7 @@ routine host_ipc_marequest_info(
        out     info            : hash_info_bucket_array_t,
                                        CountInOut, Dealloc);
 
-/*
- *     Returns information about an IPC space.
- */
-
-routine mach_port_space_info(
-               task            : ipc_space_t;
-       out     info            : ipc_info_space_t;
-       out     table_info      : ipc_info_name_array_t,
-                                       CountInOut, Dealloc;
-       out     tree_info       : ipc_info_tree_name_array_t,
-                                       CountInOut, Dealloc);
+skip;  /* mach_port_space_info */
 
 /*
  *     Returns information about the dead-name requests
diff --git a/include/mach_debug/mach_debug_types.defs 
b/include/mach_debug/mach_debug_types.defs
index d24b6f9..8df2f34 100644
--- a/include/mach_debug/mach_debug_types.defs
+++ b/include/mach_debug/mach_debug_types.defs
@@ -38,14 +38,9 @@ type cache_info_array_t = array[] of cache_info_t;
 type hash_info_bucket_t = struct[1] of natural_t;
 type hash_info_bucket_array_t = array[] of hash_info_bucket_t;
 
-type ipc_info_space_t = struct[6] of natural_t;
-
-type ipc_info_name_t = struct[9] of natural_t;
+type ipc_info_name_t = struct[6] of natural_t;
 type ipc_info_name_array_t = array[] of ipc_info_name_t;
 
-type ipc_info_tree_name_t = struct[11] of natural_t;
-type ipc_info_tree_name_array_t = array[] of ipc_info_tree_name_t;
-
 type vm_region_info_t = struct[11] of natural_t;
 type vm_region_info_array_t = array[] of vm_region_info_t;
 
diff --git a/ipc/ipc_entry.c b/ipc/ipc_entry.c
index 5b9fd98..2d6e665 100644
--- a/ipc/ipc_entry.c
+++ b/ipc/ipc_entry.c
@@ -46,45 +46,10 @@
 #include <ipc/ipc_types.h>
 #include <ipc/ipc_entry.h>
 #include <ipc/ipc_space.h>
-#include <ipc/ipc_splay.h>
-#include <ipc/ipc_hash.h>
 #include <ipc/ipc_table.h>
 #include <ipc/ipc_object.h>
 
-struct kmem_cache ipc_tree_entry_cache;
-
-/*
- *     Routine:        ipc_entry_tree_collision
- *     Purpose:
- *             Checks if "name" collides with an allocated name
- *             in the space's tree.  That is, returns TRUE
- *             if the splay tree contains a name with the same
- *             index as "name".
- *     Conditions:
- *             The space is locked (read or write) and active.
- */
-
-boolean_t
-ipc_entry_tree_collision(
-       ipc_space_t     space,
-       mach_port_t     name)
-{
-       mach_port_index_t index;
-       mach_port_t lower, upper;
-
-       assert(space->is_active);
-
-       /*
-        *      Check if we collide with the next smaller name
-        *      or the next larger name.
-        */
-
-       ipc_splay_tree_bounds(&space->is_tree, name, &lower, &upper);
-
-       index = MACH_PORT_INDEX(name);
-       return (((lower != ~0) && (MACH_PORT_INDEX(lower) == index)) ||
-               ((upper != 0) && (MACH_PORT_INDEX(upper) == index)));
-}
+struct kmem_cache ipc_entry_cache;
 
 /*
  *     Routine:        ipc_entry_lookup
@@ -100,29 +65,13 @@ ipc_entry_lookup(
        ipc_space_t space,
        mach_port_t name)
 {
-       mach_port_index_t index;
        ipc_entry_t entry;
 
        assert(space->is_active);
-
-       index = MACH_PORT_INDEX(name);
-       if (index < space->is_table_size) {
-               entry = &space->is_table[index];
-               if (IE_BITS_GEN(entry->ie_bits) != MACH_PORT_GEN(name))
-                       if (entry->ie_bits & IE_BITS_COLLISION) {
-                               assert(space->is_tree_total > 0);
-                               goto tree_lookup;
-                       } else
-                               entry = IE_NULL;
-               else if (IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE)
-                       entry = IE_NULL;
-       } else if (space->is_tree_total == 0)
-               entry = IE_NULL;
-       else
-           tree_lookup:
-               entry = (ipc_entry_t)
-                               ipc_splay_tree_lookup(&space->is_tree, name);
-
+       entry = rdxtree_lookup(&space->is_map, (rdxtree_key_t) name);
+       if (entry != IE_NULL
+           && IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE)
+               entry = NULL;
        assert((entry == IE_NULL) || IE_BITS_TYPE(entry->ie_bits));
        return entry;
 }
@@ -145,21 +94,18 @@ ipc_entry_get(
        mach_port_t *namep,
        ipc_entry_t *entryp)
 {
-       ipc_entry_t table;
-       mach_port_index_t first_free;
        mach_port_t new_name;
        ipc_entry_t free_entry;
 
        assert(space->is_active);
 
-       table = space->is_table;
-       first_free = table->ie_next;
-
-       if (first_free == 0)
+       /* Get entry from the free list.  */
+       free_entry = space->is_free_list;
+       if (free_entry == IE_NULL)
                return KERN_NO_SPACE;
 
-       free_entry = &table[first_free];
-       table->ie_next = free_entry->ie_next;
+       space->is_free_list = free_entry->ie_next_free;
+       space->is_free_list_size -= 1;
 
        /*
         *      Initialize the new entry.  We need only
@@ -173,7 +119,7 @@ ipc_entry_get(
        gen = free_entry->ie_bits + IE_BITS_GEN_ONE;
        free_entry->ie_bits = gen;
        free_entry->ie_request = 0;
-       new_name = MACH_PORT_MAKE(first_free, gen);
+       new_name = MACH_PORT_MAKE(free_entry->ie_name, gen);
     }
 
        /*
@@ -186,6 +132,7 @@ ipc_entry_get(
        assert(MACH_PORT_VALID(new_name));
        assert(free_entry->ie_object == IO_NULL);
 
+       space->is_size += 1;
        *namep = new_name;
        *entryp = free_entry;
        return KERN_SUCCESS;
@@ -212,23 +159,44 @@ ipc_entry_alloc(
        ipc_entry_t     *entryp)
 {
        kern_return_t kr;
+       ipc_entry_t entry;
+       rdxtree_key_t key;
 
        is_write_lock(space);
 
-       for (;;) {
-               if (!space->is_active) {
-                       is_write_unlock(space);
-                       return KERN_INVALID_TASK;
-               }
+       if (!space->is_active) {
+               is_write_unlock(space);
+               return KERN_INVALID_TASK;
+       }
 
-               kr = ipc_entry_get(space, namep, entryp);
-               if (kr == KERN_SUCCESS)
-                       return kr;
+       kr = ipc_entry_get(space, namep, entryp);
+       if (kr == KERN_SUCCESS)
+               /* Success.  Space is write-locked.  */
+               return kr;
 
-               kr = ipc_entry_grow_table(space);
-               if (kr != KERN_SUCCESS)
-                       return kr; /* space is unlocked */
+       entry = ie_alloc();
+       if (entry == IE_NULL) {
+               is_write_unlock(space);
+               return KERN_RESOURCE_SHORTAGE;
+       }
+
+       kr = rdxtree_insert_alloc(&space->is_map, entry, &key);
+       if (kr) {
+               is_write_unlock(space);
+               ie_free(entry);
+               return kr;
        }
+       space->is_size += 1;
+
+       entry->ie_bits = 0;
+       entry->ie_object = IO_NULL;
+       entry->ie_request = 0;
+       entry->ie_name = (mach_port_t) key;
+
+       *entryp = entry;
+       *namep = (mach_port_t) key;
+       /* Success.  Space is write-locked.  */
+       return KERN_SUCCESS;
 }
 
 /*
@@ -252,166 +220,77 @@ ipc_entry_alloc_name(
        mach_port_t     name,
        ipc_entry_t     *entryp)
 {
-       mach_port_index_t index = MACH_PORT_INDEX(name);
-       mach_port_gen_t gen = MACH_PORT_GEN(name);
-       ipc_tree_entry_t tree_entry = ITE_NULL;
-
+       kern_return_t kr;
+       ipc_entry_t entry, e, *prevp;
+       void **slot;
        assert(MACH_PORT_VALID(name));
 
-
        is_write_lock(space);
 
-       for (;;) {
-               ipc_entry_t entry;
-               ipc_tree_entry_t tentry;
-               ipc_table_size_t its;
+       if (!space->is_active) {
+               is_write_unlock(space);
+               return KERN_INVALID_TASK;
+       }
+
+       slot = rdxtree_lookup_slot(&space->is_map, (rdxtree_key_t) name);
+       if (slot != NULL)
+               entry = *(ipc_entry_t *) slot;
 
-               if (!space->is_active) {
+       if (slot == NULL || entry == IE_NULL) {
+               entry = ie_alloc();
+               if (entry == IE_NULL) {
                        is_write_unlock(space);
-                       if (tree_entry) ite_free(tree_entry);
-                       return KERN_INVALID_TASK;
-               }
-
-               /*
-                *      If we are under the table cutoff,
-                *      there are three cases:
-                *              1) The entry is inuse, for the same name
-                *              2) The entry is inuse, for a different name
-                *              3) The entry is free
-                */
-
-               if ((0 < index) && (index < space->is_table_size)) {
-                       ipc_entry_t table = space->is_table;
-
-                       entry = &table[index];
-
-                       if (IE_BITS_TYPE(entry->ie_bits)) {
-                               if (IE_BITS_GEN(entry->ie_bits) == gen) {
-                                       *entryp = entry;
-                                       if (tree_entry) ite_free(tree_entry);
-                                       return KERN_SUCCESS;
-                               }
-                       } else {
-                               mach_port_index_t free_index, next_index;
-
-                               /*
-                                *      Rip the entry out of the free list.
-                                */
-
-                               for (free_index = 0;
-                                    (next_index = table[free_index].ie_next)
-                                                       != index;
-                                    free_index = next_index)
-                                       continue;
-
-                               table[free_index].ie_next =
-                                       table[next_index].ie_next;
-
-                               entry->ie_bits = gen;
-                               assert(entry->ie_object == IO_NULL);
-                               entry->ie_request = 0;
-
-                               *entryp = entry;
-                               if (tree_entry) ite_free(tree_entry);
-                               return KERN_SUCCESS;
-                       }
+                       return KERN_RESOURCE_SHORTAGE;
                }
 
-               /*
-                *      Before trying to allocate any memory,
-                *      check if the entry already exists in the tree.
-                *      This avoids spurious resource errors.
-                *      The splay tree makes a subsequent lookup/insert
-                *      of the same name cheap, so this costs little.
-                */
-
-               if ((space->is_tree_total > 0) &&
-                   ((tentry = ipc_splay_tree_lookup(&space->is_tree, name))
-                                                       != ITE_NULL)) {
-                       assert(tentry->ite_space == space);
-                       assert(IE_BITS_TYPE(tentry->ite_bits));
-
-                       *entryp = &tentry->ite_entry;
-                       if (tree_entry) ite_free(tree_entry);
-                       return KERN_SUCCESS;
-               }
+               entry->ie_bits = 0;
+               entry->ie_object = IO_NULL;
+               entry->ie_request = 0;
+               entry->ie_name = name;
 
-               its = space->is_table_next;
-
-               /*
-                *      Check if the table should be grown.
-                *
-                *      Note that if space->is_table_size == its->its_size,
-                *      then we won't ever try to grow the table.
-                *
-                *      Note that we are optimistically assuming that name
-                *      doesn't collide with any existing names.  (So if
-                *      it were entered into the tree, is_tree_small would
-                *      be incremented.)  This is OK, because even in that
-                *      case, we don't lose memory by growing the table.
-                */
-
-               if ((space->is_table_size <= index) &&
-                   (index < its->its_size) &&
-                   (((its->its_size - space->is_table_size) *
-                     sizeof(struct ipc_entry)) <
-                    ((space->is_tree_small + 1) *
-                     sizeof(struct ipc_tree_entry)))) {
-                       kern_return_t kr;
-
-                       /*
-                        *      Can save space by growing the table.
-                        *      Because the space will be unlocked,
-                        *      we must restart.
-                        */
-
-                       kr = ipc_entry_grow_table(space);
-                       assert(kr != KERN_NO_SPACE);
+               if (slot != NULL)
+                       rdxtree_replace_slot(slot, entry);
+               else {
+                       kr = rdxtree_insert(&space->is_map,
+                                           (rdxtree_key_t) name, entry);
                        if (kr != KERN_SUCCESS) {
-                               /* space is unlocked */
-                               if (tree_entry) ite_free(tree_entry);
+                               is_write_unlock(space);
+                               ie_free(entry);
                                return kr;
                        }
-
-                       continue;
-               }
-
-               /*
-                *      If a splay-tree entry was allocated previously,
-                *      go ahead and insert it into the tree.
-                */
-
-               if (tree_entry != ITE_NULL) {
-                       space->is_tree_total++;
-
-                       if (index < space->is_table_size)
-                               space->is_table[index].ie_bits |=
-                                       IE_BITS_COLLISION;
-                       else if ((index < its->its_size) &&
-                                !ipc_entry_tree_collision(space, name))
-                               space->is_tree_small++;
-
-                       ipc_splay_tree_insert(&space->is_tree,
-                                             name, tree_entry);
-
-                       tree_entry->ite_bits = 0;
-                       tree_entry->ite_object = IO_NULL;
-                       tree_entry->ite_request = 0;
-                       tree_entry->ite_space = space;
-                       *entryp = &tree_entry->ite_entry;
-                       return KERN_SUCCESS;
                }
+               space->is_size += 1;
 
-               /*
-                *      Allocate a tree entry and try again.
-                */
+               *entryp = entry;
+               /* Success.  Space is write-locked.  */
+               return KERN_SUCCESS;
+       }
 
-               is_write_unlock(space);
-               tree_entry = ite_alloc();
-               if (tree_entry == ITE_NULL)
-                       return KERN_RESOURCE_SHORTAGE;
-               is_write_lock(space);
+       if (IE_BITS_TYPE(entry->ie_bits)) {
+               /* Used entry.  */
+               *entryp = entry;
+               /* Success.  Space is write-locked.  */
+               return KERN_SUCCESS;
        }
+
+       /* Free entry.  Rip the entry out of the free list.  */
+       for (prevp = &space->is_free_list, e = space->is_free_list;
+            e != entry;
+            ({ prevp = &e->ie_next_free; e = e->ie_next_free; }))
+               continue;
+
+       *prevp = entry->ie_next_free;
+       space->is_free_list_size -= 1;
+
+       entry->ie_bits = 0;
+       assert(entry->ie_object == IO_NULL);
+       assert(entry->ie_name == name);
+       entry->ie_request = 0;
+
+       space->is_size += 1;
+       *entryp = entry;
+       /* Success.  Space is write-locked.  */
+       return KERN_SUCCESS;
 }
 
 /*
@@ -429,405 +308,20 @@ ipc_entry_dealloc(
        mach_port_t     name,
        ipc_entry_t     entry)
 {
-       ipc_entry_t table;
-       ipc_entry_num_t size;
-       mach_port_index_t index;
-
        assert(space->is_active);
        assert(entry->ie_object == IO_NULL);
        assert(entry->ie_request == 0);
 
-       index = MACH_PORT_INDEX(name);
-       table = space->is_table;
-       size = space->is_table_size;
-
-       if ((index < size) && (entry == &table[index])) {
-               assert(IE_BITS_GEN(entry->ie_bits) == MACH_PORT_GEN(name));
-
-               if (entry->ie_bits & IE_BITS_COLLISION) {
-                       struct ipc_splay_tree small, collisions;
-                       ipc_tree_entry_t tentry;
-                       mach_port_t tname;
-                       boolean_t pick;
-                       ipc_entry_bits_t bits;
-                       ipc_object_t obj;
-
-                       /* must move an entry from tree to table */
-
-                       ipc_splay_tree_split(&space->is_tree,
-                                            MACH_PORT_MAKE(index+1, 0),
-                                            &collisions);
-                       ipc_splay_tree_split(&collisions,
-                                            MACH_PORT_MAKE(index, 0),
-                                            &small);
-
-                       pick = ipc_splay_tree_pick(&collisions,
-                                                  &tname, &tentry);
-                       assert(pick);
-                       assert(MACH_PORT_INDEX(tname) == index);
-
-                       bits = tentry->ite_bits;
-                       entry->ie_bits = bits | MACH_PORT_GEN(tname);
-                       entry->ie_object = obj = tentry->ite_object;
-                       entry->ie_request = tentry->ite_request;
-                       assert(tentry->ite_space == space);
-
-                       if (IE_BITS_TYPE(bits) == MACH_PORT_TYPE_SEND) {
-                               ipc_hash_global_delete(space, obj,
-                                                      tname, tentry);
-                               ipc_hash_local_insert(space, obj,
-                                                     index, entry);
-                       }
-
-                       ipc_splay_tree_delete(&collisions, tname, tentry);
-
-                       assert(space->is_tree_total > 0);
-                       space->is_tree_total--;
-
-                       /* check if collision bit should still be on */
-
-                       pick = ipc_splay_tree_pick(&collisions,
-                                                  &tname, &tentry);
-                       if (pick) {
-                               entry->ie_bits |= IE_BITS_COLLISION;
-                               ipc_splay_tree_join(&space->is_tree,
-                                                   &collisions);
-                       }
-
-                       ipc_splay_tree_join(&space->is_tree, &small);
-               } else {
-                       entry->ie_bits &= IE_BITS_GEN_MASK;
-                       entry->ie_next = table->ie_next;
-                       table->ie_next = index;
-               }
+       if (space->is_free_list_size < IS_FREE_LIST_SIZE_LIMIT) {
+               space->is_free_list_size += 1;
+               entry->ie_bits &= IE_BITS_GEN_MASK;
+               entry->ie_next_free = space->is_free_list;
+               space->is_free_list = entry;
        } else {
-               ipc_tree_entry_t tentry = (ipc_tree_entry_t) entry;
-
-               assert(tentry->ite_space == space);
-
-               ipc_splay_tree_delete(&space->is_tree, name, tentry);
-
-               assert(space->is_tree_total > 0);
-               space->is_tree_total--;
-
-               if (index < size) {
-                       ipc_entry_t ientry = &table[index];
-
-                       assert(ientry->ie_bits & IE_BITS_COLLISION);
-
-                       if (!ipc_entry_tree_collision(space, name))
-                               ientry->ie_bits &= ~IE_BITS_COLLISION;
-               } else if ((index < space->is_table_next->its_size) &&
-                          !ipc_entry_tree_collision(space, name)) {
-                       assert(space->is_tree_small > 0);
-                       space->is_tree_small--;
-               }
+               rdxtree_remove(&space->is_map, (rdxtree_key_t) name);
+               ie_free(entry);
        }
-}
-
-/*
- *     Routine:        ipc_entry_grow_table
- *     Purpose:
- *             Grows the table in a space.
- *     Conditions:
- *             The space must be write-locked and active before.
- *             If successful, it is also returned locked.
- *             Allocates memory.
- *     Returns:
- *             KERN_SUCCESS            Grew the table.
- *             KERN_SUCCESS            Somebody else grew the table.
- *             KERN_SUCCESS            The space died.
- *             KERN_NO_SPACE           Table has maximum size already.
- *             KERN_RESOURCE_SHORTAGE  Couldn't allocate a new table.
- */
-
-kern_return_t
-ipc_entry_grow_table(ipc_space_t space)
-{
-       ipc_entry_num_t osize, size, nsize;
-
-       do {
-               ipc_entry_t otable, table;
-               ipc_table_size_t oits, its, nits;
-               mach_port_index_t i, free_index;
-
-               assert(space->is_active);
-
-               if (space->is_growing) {
-                       /*
-                        *      Somebody else is growing the table.
-                        *      We just wait for them to finish.
-                        */
-
-                       assert_wait((event_t) space, FALSE);
-                       is_write_unlock(space);
-                       thread_block((void (*)()) 0);
-                       is_write_lock(space);
-                       return KERN_SUCCESS;
-               }
-
-               otable = space->is_table;
-               its = space->is_table_next;
-               size = its->its_size;
-               oits = its - 1;
-               osize = oits->its_size;
-               nits = its + 1;
-               nsize = nits->its_size;
-
-               if (osize == size) {
-                       is_write_unlock(space);
-                       printf_once("no more room for ipc_entry_grow_table in 
space %p\n", space);
-                       return KERN_NO_SPACE;
-               }
-
-               assert((osize < size) && (size <= nsize));
-
-               /*
-                *      OK, we'll attempt to grow the table.
-                *      The realloc requires that the old table
-                *      remain in existence.
-                */
-
-               space->is_growing = TRUE;
-               is_write_unlock(space);
-               if (it_entries_reallocable(oits))
-                       table = it_entries_realloc(oits, otable, its);
-               else
-                       table = it_entries_alloc(its);
-               is_write_lock(space);
-               space->is_growing = FALSE;
-
-               /*
-                *      We need to do a wakeup on the space,
-                *      to rouse waiting threads.  We defer
-                *      this until the space is unlocked,
-                *      because we don't want them to spin.
-                */
-
-               if (table == IE_NULL) {
-                       is_write_unlock(space);
-                       thread_wakeup((event_t) space);
-                       return KERN_RESOURCE_SHORTAGE;
-               }
-
-               if (!space->is_active) {
-                       /*
-                        *      The space died while it was unlocked.
-                        */
-
-                       is_write_unlock(space);
-                       thread_wakeup((event_t) space);
-                       it_entries_free(its, table);
-                       ipc_reverse_remove_all(space);
-                       is_write_lock(space);
-                       return KERN_SUCCESS;
-               }
-
-               assert(space->is_table == otable);
-               assert(space->is_table_next == its);
-               assert(space->is_table_size == osize);
-
-               space->is_table = table;
-               space->is_table_size = size;
-               space->is_table_next = nits;
-
-               /*
-                *      If we did a realloc, it remapped the data.
-                *      Otherwise we copy by hand first.  Then we have
-                *      to clear the index fields in the old part and
-                *      zero the new part.
-                */
-
-               if (!it_entries_reallocable(oits))
-                       memcpy(table, otable,
-                             osize * sizeof(struct ipc_entry));
-
-               (void) memset((void *) (table + osize), 0,
-                     (size - osize) * sizeof(struct ipc_entry));
-
-               /*
-                *      Put old entries into the reverse hash table.
-                */
-
-               ipc_reverse_remove_all(space);
-               for (i = 0; i < osize; i++) {
-                       ipc_entry_t entry = &table[i];
-
-                       if (IE_BITS_TYPE(entry->ie_bits) ==
-                                               MACH_PORT_TYPE_SEND)
-                               ipc_hash_local_insert(space, entry->ie_object,
-                                                     i, entry);
-               }
-
-               /*
-                *      If there are entries in the splay tree,
-                *      then we have work to do:
-                *              1) transfer entries to the table
-                *              2) update is_tree_small
-                */
-
-               if (space->is_tree_total > 0) {
-                       mach_port_index_t index;
-                       boolean_t delete;
-                       struct ipc_splay_tree ignore;
-                       struct ipc_splay_tree move;
-                       struct ipc_splay_tree small;
-                       ipc_entry_num_t nosmall;
-                       ipc_tree_entry_t tentry;
-
-                       /*
-                        *      The splay tree divides into four regions,
-                        *      based on the index of the entries:
-                        *              1) 0 <= index < osize
-                        *              2) osize <= index < size
-                        *              3) size <= index < nsize
-                        *              4) nsize <= index
-                        *
-                        *      Entries in the first part are ignored.
-                        *      Entries in the second part, that don't
-                        *      collide, are moved into the table.
-                        *      Entries in the third part, that don't
-                        *      collide, are counted for is_tree_small.
-                        *      Entries in the fourth part are ignored.
-                        */
-
-                       ipc_splay_tree_split(&space->is_tree,
-                                            MACH_PORT_MAKE(nsize, 0),
-                                            &small);
-                       ipc_splay_tree_split(&small,
-                                            MACH_PORT_MAKE(size, 0),
-                                            &move);
-                       ipc_splay_tree_split(&move,
-                                            MACH_PORT_MAKE(osize, 0),
-                                            &ignore);
-
-                       /* move entries into the table */
-
-                       for (tentry = ipc_splay_traverse_start(&move);
-                            tentry != ITE_NULL;
-                            tentry = ipc_splay_traverse_next(&move, delete)) {
-                               mach_port_t name;
-                               mach_port_gen_t gen;
-                               mach_port_type_t type;
-                               ipc_entry_bits_t bits;
-                               ipc_object_t obj;
-                               ipc_entry_t entry;
-
-                               name = tentry->ite_name;
-                               gen = MACH_PORT_GEN(name);
-                               index = MACH_PORT_INDEX(name);
-
-                               assert(tentry->ite_space == space);
-                               assert((osize <= index) && (index < size));
-
-                               entry = &table[index];
-
-                               /* collision with previously moved entry? */
-
-                               bits = entry->ie_bits;
-                               if (bits != 0) {
-                                       assert(IE_BITS_TYPE(bits));
-                                       assert(IE_BITS_GEN(bits) != gen);
-
-                                       entry->ie_bits =
-                                               bits | IE_BITS_COLLISION;
-                                       delete = FALSE;
-                                       continue;
-                               }
-
-                               bits = tentry->ite_bits;
-                               type = IE_BITS_TYPE(bits);
-                               assert(type != MACH_PORT_TYPE_NONE);
-
-                               entry->ie_bits = bits | gen;
-                               entry->ie_object = obj = tentry->ite_object;
-                               entry->ie_request = tentry->ite_request;
-
-                               if (type == MACH_PORT_TYPE_SEND) {
-                                       ipc_hash_global_delete(space, obj,
-                                                              name, tentry);
-                                       ipc_hash_local_insert(space, obj,
-                                                             index, entry);
-                               }
-
-                               space->is_tree_total--;
-                               delete = TRUE;
-                       }
-                       ipc_splay_traverse_finish(&move);
-
-                       /* count entries for is_tree_small */
-
-                       nosmall = 0; index = 0;
-                       for (tentry = ipc_splay_traverse_start(&small);
-                            tentry != ITE_NULL;
-                            tentry = ipc_splay_traverse_next(&small, FALSE)) {
-                               mach_port_index_t nindex;
-
-                               nindex = MACH_PORT_INDEX(tentry->ite_name);
-
-                               if (nindex != index) {
-                                       nosmall++;
-                                       index = nindex;
-                               }
-                       }
-                       ipc_splay_traverse_finish(&small);
-
-                       assert(nosmall <= (nsize - size));
-                       assert(nosmall <= space->is_tree_total);
-                       space->is_tree_small = nosmall;
-
-                       /* put the splay tree back together */
-
-                       ipc_splay_tree_join(&space->is_tree, &small);
-                       ipc_splay_tree_join(&space->is_tree, &move);
-                       ipc_splay_tree_join(&space->is_tree, &ignore);
-               }
-
-               /*
-                *      Add entries in the new part which still aren't used
-                *      to the free list.  Add them in reverse order,
-                *      and set the generation number to -1, so that
-                *      early allocations produce "natural" names.
-                */
-
-               free_index = table[0].ie_next;
-               for (i = size-1; i >= osize; --i) {
-                       ipc_entry_t entry = &table[i];
-
-                       if (entry->ie_bits == 0) {
-                               entry->ie_bits = IE_BITS_GEN_MASK;
-                               entry->ie_next = free_index;
-                               free_index = i;
-                       }
-               }
-               table[0].ie_next = free_index;
-
-               /*
-                *      Now we need to free the old table.
-                *      If the space dies or grows while unlocked,
-                *      then we can quit here.
-                */
-
-               is_write_unlock(space);
-               thread_wakeup((event_t) space);
-               it_entries_free(oits, otable);
-               is_write_lock(space);
-               if (!space->is_active || (space->is_table_next != nits))
-                       return KERN_SUCCESS;
-
-               /*
-                *      We might have moved enough entries from
-                *      the splay tree into the table that
-                *      the table can be profitably grown again.
-                *
-                *      Note that if size == nsize, then
-                *      space->is_tree_small == 0.
-                */
-       } while ((space->is_tree_small > 0) &&
-                (((nsize - size) * sizeof(struct ipc_entry)) <
-                 (space->is_tree_small * sizeof(struct ipc_tree_entry))));
-
-       return KERN_SUCCESS;
+       space->is_size -= 1;
 }
 
 
diff --git a/ipc/ipc_entry.h b/ipc/ipc_entry.h
index 0caa70b..5c1f8fd 100644
--- a/ipc/ipc_entry.h
+++ b/ipc/ipc_entry.h
@@ -48,42 +48,27 @@
 
 /*
  *     Spaces hold capabilities for ipc_object_t's (ports and port sets).
- *     Each ipc_entry_t records a capability.  Most capabilities have
- *     small names, and the entries are elements of a table.
- *     Capabilities can have large names, and a splay tree holds
- *     those entries.  The cutoff point between the table and the tree
- *     is adjusted dynamically to minimize memory consumption.
- *
- *     Free (unallocated) entries in the table have null ie_object
- *     fields.  The ie_bits field is zero except for IE_BITS_GEN.
- *     The ie_next (ie_request) field links free entries into a free list.
- *
- *     The first entry in the table (index 0) is always free.
- *     It is used as the head of the free list.
+ *     Each ipc_entry_t records a capability.
  */
 
 typedef unsigned int ipc_entry_bits_t;
 typedef ipc_table_elems_t ipc_entry_num_t;     /* number of entries */
 
 typedef struct ipc_entry {
+       mach_port_t ie_name;
        ipc_entry_bits_t ie_bits;
        struct ipc_object *ie_object;
        union {
-               mach_port_index_t next;
+               struct ipc_entry *next_free;
                /*XXX ipc_port_request_index_t request;*/
                unsigned int request;
        } index;
-       union {
-               mach_port_index_t table;
-               struct ipc_tree_entry *tree;
-       } hash;
 } *ipc_entry_t;
 
 #define        IE_NULL         ((ipc_entry_t) 0)
 
 #define        ie_request      index.request
-#define        ie_next         index.next
-#define        ie_index        hash.table
+#define        ie_next_free    index.next_free
 
 #define        IE_BITS_UREFS_MASK      0x0000ffff      /* 16 bits of 
user-reference */
 #define        IE_BITS_UREFS(bits)     ((bits) & IE_BITS_UREFS_MASK)
@@ -93,12 +78,10 @@ typedef struct ipc_entry {
 
 #define        IE_BITS_MAREQUEST       0x00200000      /* 1 bit for 
msg-accepted */
 
-#define        IE_BITS_COMPAT          0x00400000      /* 1 bit for 
compatibility */
-
-#define        IE_BITS_COLLISION       0x00800000      /* 1 bit for collisions 
*/
-#define        IE_BITS_RIGHT_MASK      0x007fffff      /* relevant to the 
right */
+#define        IE_BITS_RIGHT_MASK      0x003fffff      /* relevant to the 
right */
 
 #if PORT_GENERATIONS
+#error "not supported"
 #define        IE_BITS_GEN_MASK        0xff000000U     /* 8 bits for 
generation */
 #define        IE_BITS_GEN(bits)       ((bits) & IE_BITS_GEN_MASK)
 #define        IE_BITS_GEN_ONE         0x01000000      /* low bit of 
generation */
@@ -109,26 +92,9 @@ typedef struct ipc_entry {
 #endif
 
 
-typedef struct ipc_tree_entry {
-       struct ipc_entry ite_entry;
-       mach_port_t ite_name;
-       struct ipc_space *ite_space;
-       struct ipc_tree_entry *ite_lchild;
-       struct ipc_tree_entry *ite_rchild;
-} *ipc_tree_entry_t;
-
-#define        ITE_NULL        ((ipc_tree_entry_t) 0)
-
-#define        ite_bits        ite_entry.ie_bits
-#define        ite_object      ite_entry.ie_object
-#define        ite_request     ite_entry.ie_request
-#define        ite_next        ite_entry.hash.tree
-
-extern struct kmem_cache ipc_tree_entry_cache;
-
-#define ite_alloc()    ((ipc_tree_entry_t) 
kmem_cache_alloc(&ipc_tree_entry_cache))
-#define        ite_free(ite)   kmem_cache_free(&ipc_tree_entry_cache, 
(vm_offset_t) (ite))
-
+extern struct kmem_cache ipc_entry_cache;
+#define ie_alloc()     ((ipc_entry_t) kmem_cache_alloc(&ipc_entry_cache))
+#define        ie_free(e)      kmem_cache_free(&ipc_entry_cache, (vm_offset_t) 
(e))
 
 extern ipc_entry_t
 ipc_entry_lookup(ipc_space_t space, mach_port_t name);
@@ -145,9 +111,6 @@ ipc_entry_alloc_name(ipc_space_t space, mach_port_t name, 
ipc_entry_t *entryp);
 extern void
 ipc_entry_dealloc(ipc_space_t space, mach_port_t name, ipc_entry_t entry);
 
-extern kern_return_t
-ipc_entry_grow_table(ipc_space_t space);
-
 ipc_entry_t
 db_ipc_object_by_name(
        task_t          task,
diff --git a/ipc/ipc_hash.c b/ipc/ipc_hash.c
deleted file mode 100644
index 87952a7..0000000
--- a/ipc/ipc_hash.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/* 
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- *     File:   ipc/ipc_hash.c
- *     Author: Rich Draves
- *     Date:   1989
- *
- *     Entry hash table operations.
- */
-
-#include <kern/printf.h>
-#include <mach/boolean.h>
-#include <mach/port.h>
-#include <kern/lock.h>
-#include <kern/kalloc.h>
-#include <ipc/port.h>
-#include <ipc/ipc_space.h>
-#include <ipc/ipc_object.h>
-#include <ipc/ipc_entry.h>
-#include <ipc/ipc_hash.h>
-#include <ipc/ipc_init.h>
-#include <ipc/ipc_types.h>
-
-#if    MACH_IPC_DEBUG
-#include <mach/kern_return.h>
-#include <mach_debug/hash_info.h>
-#include <vm/vm_map.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_user.h>
-#endif
-
-
-
-/*
- *     Routine:        ipc_hash_lookup
- *     Purpose:
- *             Converts (space, obj) -> (name, entry).
- *             Returns TRUE if an entry was found.
- *     Conditions:
- *             The space must be locked (read or write) throughout.
- */
-
-boolean_t
-ipc_hash_lookup(
-       ipc_space_t space,
-       ipc_object_t obj,
-       mach_port_t *namep,
-       ipc_entry_t *entryp)
-{
-       return (ipc_hash_local_lookup(space, obj, namep, entryp) ||
-               ((space->is_tree_hash > 0) &&
-                ipc_hash_global_lookup(space, obj, namep,
-                                       (ipc_tree_entry_t *) entryp)));
-}
-
-/*
- *     Routine:        ipc_hash_insert
- *     Purpose:
- *             Inserts an entry into the appropriate reverse hash table,
- *             so that ipc_hash_lookup will find it.
- *     Conditions:
- *             The space must be write-locked.
- */
-
-void
-ipc_hash_insert(
-       ipc_space_t     space,
-       ipc_object_t    obj,
-       mach_port_t     name,
-       ipc_entry_t     entry)
-{
-       mach_port_index_t index;
-
-       index = MACH_PORT_INDEX(name);
-       if ((index < space->is_table_size) &&
-           (entry == &space->is_table[index]))
-               ipc_hash_local_insert(space, obj, index, entry);
-       else
-               ipc_hash_global_insert(space, obj, name,
-                                      (ipc_tree_entry_t) entry);
-}
-
-/*
- *     Routine:        ipc_hash_delete
- *     Purpose:
- *             Deletes an entry from the appropriate reverse hash table.
- *     Conditions:
- *             The space must be write-locked.
- */
-
-void
-ipc_hash_delete(
-       ipc_space_t     space,
-       ipc_object_t    obj,
-       mach_port_t     name,
-       ipc_entry_t     entry)
-{
-       mach_port_index_t index;
-
-       index = MACH_PORT_INDEX(name);
-       if ((index < space->is_table_size) &&
-           (entry == &space->is_table[index]))
-               ipc_hash_local_delete(space, obj, index, entry);
-       else
-               ipc_hash_global_delete(space, obj, name,
-                                      (ipc_tree_entry_t) entry);
-}
-
-/*
- *     The global reverse hash table holds splay tree entries.
- *     It is a simple open-chaining hash table with singly-linked buckets.
- *     Each bucket is locked separately, with an exclusive lock.
- *     Within each bucket, move-to-front is used.
- */
-
-ipc_hash_index_t ipc_hash_global_size;
-ipc_hash_index_t ipc_hash_global_mask;
-
-#define IH_GLOBAL_HASH(space, obj)                                     \
-       (((((ipc_hash_index_t) ((vm_offset_t)space)) >> 4) +            \
-         (((ipc_hash_index_t) ((vm_offset_t)obj)) >> 6)) &             \
-        ipc_hash_global_mask)
-
-typedef struct ipc_hash_global_bucket {
-       decl_simple_lock_data(, ihgb_lock_data)
-       ipc_tree_entry_t ihgb_head;
-} *ipc_hash_global_bucket_t;
-
-#define        IHGB_NULL       ((ipc_hash_global_bucket_t) 0)
-
-#define        ihgb_lock_init(ihgb)    
simple_lock_init(&(ihgb)->ihgb_lock_data)
-#define        ihgb_lock(ihgb)         simple_lock(&(ihgb)->ihgb_lock_data)
-#define        ihgb_unlock(ihgb)       simple_unlock(&(ihgb)->ihgb_lock_data)
-
-ipc_hash_global_bucket_t ipc_hash_global_table;
-
-/*
- *     Routine:        ipc_hash_global_lookup
- *     Purpose:
- *             Converts (space, obj) -> (name, entry).
- *             Looks in the global table, for splay tree entries.
- *             Returns TRUE if an entry was found.
- *     Conditions:
- *             The space must be locked (read or write) throughout.
- */
-
-boolean_t
-ipc_hash_global_lookup(
-       ipc_space_t             space,
-       ipc_object_t            obj,
-       mach_port_t             *namep,
-       ipc_tree_entry_t        *entryp)
-{
-       ipc_hash_global_bucket_t bucket;
-       ipc_tree_entry_t this, *last;
-
-       assert(space != IS_NULL);
-       assert(obj != IO_NULL);
-
-       bucket = &ipc_hash_global_table[IH_GLOBAL_HASH(space, obj)];
-       ihgb_lock(bucket);
-
-       if ((this = bucket->ihgb_head) != ITE_NULL) {
-               if ((this->ite_object == obj) &&
-                   (this->ite_space == space)) {
-                       /* found it at front; no need to move */
-
-                       *namep = this->ite_name;
-                       *entryp = this;
-               } else for (last = &this->ite_next;
-                           (this = *last) != ITE_NULL;
-                           last = &this->ite_next) {
-                       if ((this->ite_object == obj) &&
-                           (this->ite_space == space)) {
-                               /* found it; move to front */
-
-                               *last = this->ite_next;
-                               this->ite_next = bucket->ihgb_head;
-                               bucket->ihgb_head = this;
-
-                               *namep = this->ite_name;
-                               *entryp = this;
-                               break;
-                       }
-               }
-       }
-
-       ihgb_unlock(bucket);
-       return this != ITE_NULL;
-}
-
-/*
- *     Routine:        ipc_hash_global_insert
- *     Purpose:
- *             Inserts an entry into the global reverse hash table.
- *     Conditions:
- *             The space must be write-locked.
- */
-
-void
-ipc_hash_global_insert(
-       ipc_space_t             space,
-       ipc_object_t            obj,
-       mach_port_t             name,
-       ipc_tree_entry_t        entry)
-{
-       ipc_hash_global_bucket_t bucket;
-
-
-       assert(entry->ite_name == name);
-       assert(space != IS_NULL);
-       assert(entry->ite_space == space);
-       assert(obj != IO_NULL);
-       assert(entry->ite_object == obj);
-
-       space->is_tree_hash++;
-       assert(space->is_tree_hash <= space->is_tree_total);
-
-       bucket = &ipc_hash_global_table[IH_GLOBAL_HASH(space, obj)];
-       ihgb_lock(bucket);
-
-       /* insert at front of bucket */
-
-       entry->ite_next = bucket->ihgb_head;
-       bucket->ihgb_head = entry;
-
-       ihgb_unlock(bucket);
-}
-
-/*
- *     Routine:        ipc_hash_global_delete
- *     Purpose:
- *             Deletes an entry from the global reverse hash table.
- *     Conditions:
- *             The space must be write-locked.
- */
-
-void
-ipc_hash_global_delete(
-       ipc_space_t             space,
-       ipc_object_t            obj,
-       mach_port_t             name,
-       ipc_tree_entry_t        entry)
-{
-       ipc_hash_global_bucket_t bucket;
-       ipc_tree_entry_t this, *last;
-
-       assert(entry->ite_name == name);
-       assert(space != IS_NULL);
-       assert(entry->ite_space == space);
-       assert(obj != IO_NULL);
-       assert(entry->ite_object == obj);
-
-       assert(space->is_tree_hash > 0);
-       space->is_tree_hash--;
-
-       bucket = &ipc_hash_global_table[IH_GLOBAL_HASH(space, obj)];
-       ihgb_lock(bucket);
-
-       for (last = &bucket->ihgb_head;
-            (this = *last) != ITE_NULL;
-            last = &this->ite_next) {
-               if (this == entry) {
-                       /* found it; remove from bucket */
-
-                       *last = this->ite_next;
-                       break;
-               }
-       }
-       assert(this != ITE_NULL);
-
-       ihgb_unlock(bucket);
-}
-
-/*
- *     Each space has a local reverse mapping from objects to entries
- *     from the space's table.  This used to be a hash table.
- */
-
-#define IPC_LOCAL_HASH_INVARIANT(S, O, N, E)                           \
-       MACRO_BEGIN                                                     \
-       assert(IE_BITS_TYPE((E)->ie_bits) == MACH_PORT_TYPE_SEND ||     \
-              IE_BITS_TYPE((E)->ie_bits) == MACH_PORT_TYPE_SEND_RECEIVE || \
-              IE_BITS_TYPE((E)->ie_bits) == MACH_PORT_TYPE_NONE);      \
-       assert((E)->ie_object == (O));                                  \
-       assert((E)->ie_index == (N));                                   \
-       assert(&(S)->is_table[N] == (E));                               \
-       MACRO_END
-
-/*
- *     Routine:        ipc_hash_local_lookup
- *     Purpose:
- *             Converts (space, obj) -> (name, entry).
- *             Looks in the space's local table, for table entries.
- *             Returns TRUE if an entry was found.
- *     Conditions:
- *             The space must be locked (read or write) throughout.
- */
-
-boolean_t
-ipc_hash_local_lookup(
-       ipc_space_t     space,
-       ipc_object_t    obj,
-       mach_port_t     *namep,
-       ipc_entry_t     *entryp)
-{
-       assert(space != IS_NULL);
-       assert(obj != IO_NULL);
-
-       *entryp = ipc_reverse_lookup(space, obj);
-       if (*entryp != IE_NULL) {
-               *namep = (*entryp)->ie_index;
-               IPC_LOCAL_HASH_INVARIANT(space, obj, *namep, *entryp);
-               return TRUE;
-       }
-       return FALSE;
-}
-
-/*
- *     Routine:        ipc_hash_local_insert
- *     Purpose:
- *             Inserts an entry into the space's reverse hash table.
- *     Conditions:
- *             The space must be write-locked.
- */
-
-void
-ipc_hash_local_insert(
-       ipc_space_t             space,
-       ipc_object_t            obj,
-       mach_port_index_t       index,
-       ipc_entry_t             entry)
-{
-       kern_return_t kr;
-       assert(index != 0);
-       assert(space != IS_NULL);
-       assert(obj != IO_NULL);
-
-       entry->ie_index = index;
-       IPC_LOCAL_HASH_INVARIANT(space, obj, index, entry);
-       kr = ipc_reverse_insert(space, obj, entry);
-       assert(kr == 0);
-}
-
-/*
- *     Routine:        ipc_hash_local_delete
- *     Purpose:
- *             Deletes an entry from the space's reverse hash table.
- *     Conditions:
- *             The space must be write-locked.
- */
-
-void
-ipc_hash_local_delete(
-       ipc_space_t             space,
-       ipc_object_t            obj,
-       mach_port_index_t       index,
-       ipc_entry_t             entry)
-{
-       ipc_entry_t removed;
-       assert(index != MACH_PORT_NULL);
-       assert(space != IS_NULL);
-       assert(obj != IO_NULL);
-
-       IPC_LOCAL_HASH_INVARIANT(space, obj, index, entry);
-       removed = ipc_reverse_remove(space, obj);
-       assert(removed == entry);
-}
-
-/*
- *     Routine:        ipc_hash_init
- *     Purpose:
- *             Initialize the reverse hash table implementation.
- */
-
-void
-ipc_hash_init(void)
-{
-       ipc_hash_index_t i;
-
-       /* initialize ipc_hash_global_size */
-
-       ipc_hash_global_size = IPC_HASH_GLOBAL_SIZE;
-
-       /* make sure it is a power of two */
-
-       ipc_hash_global_mask = ipc_hash_global_size - 1;
-       if ((ipc_hash_global_size & ipc_hash_global_mask) != 0) {
-               natural_t bit;
-
-               /* round up to closest power of two */
-
-               for (bit = 1;; bit <<= 1) {
-                       ipc_hash_global_mask |= bit;
-                       ipc_hash_global_size = ipc_hash_global_mask + 1;
-
-                       if ((ipc_hash_global_size & ipc_hash_global_mask) == 0)
-                               break;
-               }
-       }
-
-       /* allocate ipc_hash_global_table */
-
-       ipc_hash_global_table = (ipc_hash_global_bucket_t)
-               kalloc((vm_size_t) (ipc_hash_global_size *
-                                   sizeof(struct ipc_hash_global_bucket)));
-       assert(ipc_hash_global_table != IHGB_NULL);
-
-       /* and initialize it */
-
-       for (i = 0; i < ipc_hash_global_size; i++) {
-               ipc_hash_global_bucket_t bucket;
-
-               bucket = &ipc_hash_global_table[i];
-               ihgb_lock_init(bucket);
-               bucket->ihgb_head = ITE_NULL;
-       }
-}
-
-#if    MACH_IPC_DEBUG
-
-/*
- *     Routine:        ipc_hash_info
- *     Purpose:
- *             Return information about the global reverse hash table.
- *             Fills the buffer with as much information as possible
- *             and returns the desired size of the buffer.
- *     Conditions:
- *             Nothing locked.  The caller should provide
- *             possibly-pageable memory.
- */
-
-
-ipc_hash_index_t
-ipc_hash_info(
-       hash_info_bucket_t      *info,
-       mach_msg_type_number_t count)
-{
-       ipc_hash_index_t i;
-
-       if (ipc_hash_global_size < count)
-               count = ipc_hash_global_size;
-
-       for (i = 0; i < count; i++) {
-               ipc_hash_global_bucket_t bucket = &ipc_hash_global_table[i];
-               unsigned int bucket_count = 0;
-               ipc_tree_entry_t entry;
-
-               ihgb_lock(bucket);
-               for (entry = bucket->ihgb_head;
-                    entry != ITE_NULL;
-                    entry = entry->ite_next)
-                       bucket_count++;
-               ihgb_unlock(bucket);
-
-               /* don't touch pageable memory while holding locks */
-               info[i].hib_count = bucket_count;
-       }
-
-       return ipc_hash_global_size;
-}
-
-#endif /* MACH_IPC_DEBUG */
diff --git a/ipc/ipc_hash.h b/ipc/ipc_hash.h
deleted file mode 100644
index 929ba77..0000000
--- a/ipc/ipc_hash.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- *     File:   ipc/ipc_hash.h
- *     Author: Rich Draves
- *     Date:   1989
- *
- *     Declarations of entry hash table operations.
- */
-
-#ifndef        _IPC_IPC_HASH_H_
-#define _IPC_IPC_HASH_H_
-
-#include <mach/boolean.h>
-#include <mach/kern_return.h>
-
-typedef natural_t ipc_hash_index_t;
-
-extern void
-ipc_hash_init(void);
-
-#if    MACH_IPC_DEBUG
-
-extern ipc_hash_index_t
-ipc_hash_info(hash_info_bucket_t *, mach_msg_type_number_t);
-
-#endif /* MACH_IPC_DEBUG */
-
-extern boolean_t
-ipc_hash_lookup(ipc_space_t space, ipc_object_t obj,
-               mach_port_t *namep, ipc_entry_t *entryp);
-
-extern void
-ipc_hash_insert(ipc_space_t space, ipc_object_t obj,
-               mach_port_t name, ipc_entry_t entry);
-
-extern void
-ipc_hash_delete(ipc_space_t space, ipc_object_t obj,
-               mach_port_t name, ipc_entry_t entry);
-
-/*
- *     For use by functions that know what they're doing:
- *     the global primitives, for splay tree entries,
- *     and the local primitives, for table entries.
- */
-
-#define        IPC_HASH_GLOBAL_SIZE    256
-
-extern boolean_t
-ipc_hash_global_lookup(ipc_space_t space, ipc_object_t obj,
-                      mach_port_t *namep, ipc_tree_entry_t *entryp);
-
-extern void
-ipc_hash_global_insert(ipc_space_t space, ipc_object_t obj,
-                      mach_port_t name, ipc_tree_entry_t entry);
-
-extern void
-ipc_hash_global_delete(ipc_space_t space, ipc_object_t obj,
-                      mach_port_t name, ipc_tree_entry_t entry);
-
-extern boolean_t
-ipc_hash_local_lookup(ipc_space_t space, ipc_object_t obj,
-                     mach_port_t *namep, ipc_entry_t *entryp);
-
-extern void
-ipc_hash_local_insert(ipc_space_t space, ipc_object_t obj,
-                     mach_port_index_t index, ipc_entry_t entry);
-
-extern void
-ipc_hash_local_delete(ipc_space_t space, ipc_object_t obj,
-                     mach_port_index_t index, ipc_entry_t entry);
-
-#endif /* _IPC_IPC_HASH_H_ */
diff --git a/ipc/ipc_init.c b/ipc/ipc_init.c
index debda47..2c58a6e 100644
--- a/ipc/ipc_init.c
+++ b/ipc/ipc_init.c
@@ -47,7 +47,6 @@
 #include <ipc/ipc_marequest.h>
 #include <ipc/ipc_notify.h>
 #include <ipc/ipc_kmsg.h>
-#include <ipc/ipc_hash.h>
 #include <ipc/ipc_init.h>
 
 
@@ -76,8 +75,8 @@ ipc_bootstrap(void)
        kmem_cache_init(&ipc_space_cache, "ipc_space",
                        sizeof(struct ipc_space), 0, NULL, NULL, NULL, 0);
 
-       kmem_cache_init(&ipc_tree_entry_cache, "ipc_tree_entry",
-                       sizeof(struct ipc_tree_entry), 0, NULL, NULL, NULL, 0);
+       kmem_cache_init(&ipc_entry_cache, "ipc_entry",
+                       sizeof(struct ipc_entry), 0, NULL, NULL, NULL, 0);
 
        kmem_cache_init(&ipc_object_caches[IOT_PORT], "ipc_port",
                        sizeof(struct ipc_port), 0, NULL, NULL, NULL, 0);
@@ -97,7 +96,6 @@ ipc_bootstrap(void)
 
        ipc_table_init();
        ipc_notify_init();
-       ipc_hash_init();
        ipc_marequest_init();
 }
 
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
index cae700f..5076809 100644
--- a/ipc/ipc_kmsg.c
+++ b/ipc/ipc_kmsg.c
@@ -50,7 +50,6 @@
 #include <vm/vm_user.h>
 #include <ipc/port.h>
 #include <ipc/ipc_entry.h>
-#include <ipc/ipc_hash.h>
 #include <ipc/ipc_kmsg.h>
 #include <ipc/ipc_thread.h>
 #include <ipc/ipc_marequest.h>
@@ -1774,7 +1773,7 @@ ipc_kmsg_copyout_header(
                        break;
 
                is_write_lock(space);
-               if (!space->is_active || space->is_table->ie_next == 0) {
+               if (!space->is_active || space->is_free_list == NULL) {
                        is_write_unlock(space);
                        break;
                }
@@ -2003,28 +2002,20 @@ ipc_kmsg_copyout_header(
                                goto copyout_dest;
                        }
 
-                       kr = ipc_entry_get(space, &reply_name, &entry);
+                       kr = ipc_entry_alloc(space, &reply_name, &entry);
                        if (kr != KERN_SUCCESS) {
                                ip_unlock(reply);
 
                                if (notify_port != IP_NULL)
                                        ipc_port_release_sonce(notify_port);
 
-                               /* space is locked */
-                               kr = ipc_entry_grow_table(space);
-                               if (kr != KERN_SUCCESS) {
-                                       /* space is unlocked */
-
-                                       if (kr == KERN_RESOURCE_SHORTAGE)
-                                               return (MACH_RCV_HEADER_ERROR|
-                                                       MACH_MSG_IPC_KERNEL);
-                                       else
-                                               return (MACH_RCV_HEADER_ERROR|
-                                                       MACH_MSG_IPC_SPACE);
-                               }
-                               /* space is locked again; start over */
-
-                               continue;
+                               is_write_unlock(space);
+                               if (kr == KERN_RESOURCE_SHORTAGE)
+                                       return (MACH_RCV_HEADER_ERROR|
+                                               MACH_MSG_IPC_KERNEL);
+                               else
+                                       return (MACH_RCV_HEADER_ERROR|
+                                               MACH_MSG_IPC_SPACE);
                        }
 
                        assert(IE_BITS_TYPE(entry->ie_bits)
@@ -2266,12 +2257,13 @@ ipc_kmsg_copyout_object(
 
        ip_lock(port);
        if (!ip_active(port) ||
-           !ipc_hash_local_lookup(space, (ipc_object_t) port,
-                                  namep, &entry)) {
+           (entry = ipc_reverse_lookup(space,
+                                       (ipc_object_t) port)) == NULL) {
                ip_unlock(port);
                is_write_unlock(space);
                goto slow_copyout;
        }
+       *namep = entry->ie_name;
 
        /*
         *      Copyout the send right, incrementing urefs
diff --git a/ipc/ipc_object.c b/ipc/ipc_object.c
index db6ef01..2d84cf5 100644
--- a/ipc/ipc_object.c
+++ b/ipc/ipc_object.c
@@ -41,7 +41,6 @@
 #include <ipc/ipc_space.h>
 #include <ipc/ipc_entry.h>
 #include <ipc/ipc_object.h>
-#include <ipc/ipc_hash.h>
 #include <ipc/ipc_right.h>
 #include <ipc/ipc_notify.h>
 #include <ipc/ipc_pset.h>
@@ -630,15 +629,10 @@ ipc_object_copyout(
                        break;
                }
 
-               kr = ipc_entry_get(space, &name, &entry);
+               kr = ipc_entry_alloc(space, &name, &entry);
                if (kr != KERN_SUCCESS) {
-                       /* unlocks/locks space, so must start again */
-
-                       kr = ipc_entry_grow_table(space);
-                       if (kr != KERN_SUCCESS)
-                               return kr; /* space is unlocked */
-
-                       continue;
+                       is_write_unlock(space);
+                       return kr;
                }
 
                assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE);
@@ -691,15 +685,10 @@ ipc_object_copyout_multiname(space, object, namep)
                        return KERN_INVALID_TASK;
                }
 
-               kr = ipc_entry_get(space, &name, &entry);
+               kr = ipc_entry_alloc(space, &name, &entry);
                if (kr != KERN_SUCCESS) {
-                       /* unlocks/locks space, so must start again */
-
-                       kr = ipc_entry_grow_table(space);
-                       if (kr != KERN_SUCCESS)
-                               return kr; /* space is unlocked */
-
-                       continue;
+                       is_write_unlock(space);
+                       return kr; /* space is unlocked */
                }
 
                assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE);
diff --git a/ipc/ipc_right.c b/ipc/ipc_right.c
index 35061c9..773b3b1 100644
--- a/ipc/ipc_right.c
+++ b/ipc/ipc_right.c
@@ -43,7 +43,6 @@
 #include <ipc/ipc_entry.h>
 #include <ipc/ipc_space.h>
 #include <ipc/ipc_object.h>
-#include <ipc/ipc_hash.h>
 #include <ipc/ipc_port.h>
 #include <ipc/ipc_pset.h>
 #include <ipc/ipc_marequest.h>
@@ -142,7 +141,8 @@ ipc_right_reverse(
                return TRUE;
        }
 
-       if (ipc_hash_lookup(space, (ipc_object_t) port, namep, entryp)) {
+       if ((*entryp = ipc_reverse_lookup(space, (ipc_object_t) port))) {
+               *namep = (*entryp)->ie_name;
                assert((entry = *entryp) != IE_NULL);
                assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_SEND);
                assert(port == (ipc_port_t) entry->ie_object);
@@ -392,7 +392,7 @@ ipc_right_check(
                        ipc_marequest_cancel(space, name);
                }
 
-               ipc_hash_delete(space, (ipc_object_t) port, name, entry);
+               ipc_reverse_remove(space, (ipc_object_t) port);
        } else {
                assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_SEND_ONCE);
                assert(IE_BITS_UREFS(bits) == 1);
@@ -609,8 +609,7 @@ ipc_right_destroy(
                }
 
                if (type == MACH_PORT_TYPE_SEND)
-                       ipc_hash_delete(space, (ipc_object_t) port,
-                                       name, entry);
+                       ipc_reverse_remove(space, (ipc_object_t) port);
 
                ip_lock(port);
 
@@ -789,8 +788,7 @@ ipc_right_dealloc(
                        dnrequest = ipc_right_dncancel_macro(space, port,
                                                             name, entry);
 
-                       ipc_hash_delete(space, (ipc_object_t) port,
-                                       name, entry);
+                       ipc_reverse_remove(space, (ipc_object_t) port);
 
                        if (bits & IE_BITS_MAREQUEST)
                                ipc_marequest_cancel(space, name);
@@ -1134,8 +1132,7 @@ ipc_right_delta(
                                dnrequest = ipc_right_dncancel_macro(
                                                space, port, name, entry);
 
-                               ipc_hash_delete(space, (ipc_object_t) port,
-                                               name, entry);
+                               ipc_reverse_remove(space, (ipc_object_t) port);
 
                                if (bits & IE_BITS_MAREQUEST)
                                        ipc_marequest_cancel(space, name);
@@ -1410,8 +1407,8 @@ ipc_right_copyin(
                        assert(IE_BITS_UREFS(bits) > 0);
                        assert(port->ip_srights > 0);
 
-                       ipc_hash_insert(space, (ipc_object_t) port,
-                                       name, entry);
+                       entry->ie_name = name;
+                       ipc_reverse_insert(space, (ipc_object_t) port, entry);
 
                        ip_reference(port);
                } else {
@@ -1534,8 +1531,7 @@ ipc_right_copyin(
                                dnrequest = ipc_right_dncancel_macro(
                                                space, port, name, entry);
 
-                               ipc_hash_delete(space, (ipc_object_t) port,
-                                               name, entry);
+                               ipc_reverse_remove(space, (ipc_object_t) port);
 
                                if (bits & IE_BITS_MAREQUEST)
                                        ipc_marequest_cancel(space, name);
@@ -1796,8 +1792,7 @@ ipc_right_copyin_two(
                        dnrequest = ipc_right_dncancel_macro(space, port,
                                                             name, entry);
 
-                       ipc_hash_delete(space, (ipc_object_t) port,
-                                       name, entry);
+                       ipc_reverse_remove(space, (ipc_object_t) port);
 
                        if (bits & IE_BITS_MAREQUEST)
                                ipc_marequest_cancel(space, name);
@@ -1921,8 +1916,8 @@ ipc_right_copyout(
 
                        /* entry is locked holding ref, so can use port */
 
-                       ipc_hash_insert(space, (ipc_object_t) port,
-                                       name, entry);
+                       entry->ie_name = name;
+                       ipc_reverse_insert(space, (ipc_object_t) port, entry);
                }
 
                entry->ie_bits = (bits | MACH_PORT_TYPE_SEND) + 1;
@@ -1956,8 +1951,7 @@ ipc_right_copyout(
 
                        /* entry is locked holding ref, so can use port */
 
-                       ipc_hash_delete(space, (ipc_object_t) port,
-                                       name, entry);
+                       ipc_reverse_remove(space, (ipc_object_t) port);
                } else {
                        assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_NONE);
                        assert(IE_BITS_UREFS(bits) == 0);
@@ -2083,7 +2077,7 @@ ipc_right_rename(
                ipc_marequest_rename(space, oname, nname);
        }
 
-       /* initialize nentry before letting ipc_hash_insert see it */
+       /* initialize nentry before letting ipc_reverse_insert see it */
 
        assert((nentry->ie_bits & IE_BITS_RIGHT_MASK) == 0);
        nentry->ie_bits |= bits & IE_BITS_RIGHT_MASK;
@@ -2097,8 +2091,9 @@ ipc_right_rename(
                port = (ipc_port_t) object;
                assert(port != IP_NULL);
 
-               ipc_hash_delete(space, (ipc_object_t) port, oname, oentry);
-               ipc_hash_insert(space, (ipc_object_t) port, nname, nentry);
+               ipc_reverse_remove(space, (ipc_object_t) port);
+               nentry->ie_name = nname;
+               ipc_reverse_insert(space, (ipc_object_t) port, nentry);
                break;
            }
 
diff --git a/ipc/ipc_space.c b/ipc/ipc_space.c
index dcc96b3..ea3cb3b 100644
--- a/ipc/ipc_space.c
+++ b/ipc/ipc_space.c
@@ -46,8 +46,6 @@
 #include <kern/slab.h>
 #include <ipc/port.h>
 #include <ipc/ipc_entry.h>
-#include <ipc/ipc_splay.h>
-#include <ipc/ipc_hash.h>
 #include <ipc/ipc_table.h>
 #include <ipc/ipc_port.h>
 #include <ipc/ipc_space.h>
@@ -82,6 +80,9 @@ ipc_space_release(
        ipc_space_release_macro(space);
 }
 
+/* A place-holder object for the zeroth entry.  */
+struct ipc_entry zero_entry;
+
 /*
  *     Routine:        ipc_space_create
  *     Purpose:
@@ -102,53 +103,24 @@ ipc_space_create(
        ipc_space_t             *spacep)
 {
        ipc_space_t space;
-       ipc_entry_t table;
-       ipc_entry_num_t new_size;
-       mach_port_index_t index;
 
        space = is_alloc();
        if (space == IS_NULL)
                return KERN_RESOURCE_SHORTAGE;
 
-       table = it_entries_alloc(initial);
-       if (table == IE_NULL) {
-               is_free(space);
-               return KERN_RESOURCE_SHORTAGE;
-       }
-
-       new_size = initial->its_size;
-       memset((void *) table, 0, new_size * sizeof(struct ipc_entry));
-
-       /*
-        *      Initialize the free list in the table.
-        *      Add the entries in reverse order, and
-        *      set the generation number to -1, so that
-        *      initial allocations produce "natural" names.
-        */
-
-       for (index = 0; index < new_size; index++) {
-               ipc_entry_t entry = &table[index];
-
-               entry->ie_bits = IE_BITS_GEN_MASK;
-               entry->ie_next = index+1;
-       }
-       table[new_size-1].ie_next = 0;
-
        is_ref_lock_init(space);
        space->is_references = 2;
 
        is_lock_init(space);
        space->is_active = TRUE;
-       space->is_growing = FALSE;
-       space->is_table = table;
-       space->is_table_size = new_size;
-       space->is_table_next = initial+1;
-
-       ipc_splay_tree_init(&space->is_tree);
-       space->is_tree_total = 0;
-       space->is_tree_small = 0;
-       space->is_tree_hash = 0;
+
+       rdxtree_init(&space->is_map);
        rdxtree_init(&space->is_reverse_map);
+       /* The zeroth entry is reserved.  */
+       rdxtree_insert(&space->is_map, 0, &zero_entry);
+       space->is_size = 1;
+       space->is_free_list = NULL;
+       space->is_free_list_size = 0;
 
        *spacep = space;
        return KERN_SUCCESS;
@@ -202,10 +174,6 @@ void
 ipc_space_destroy(
        ipc_space_t     space)
 {
-       ipc_tree_entry_t tentry;
-       ipc_entry_t table;
-       ipc_entry_num_t size;
-       mach_port_index_t index;
        boolean_t active;
 
        assert(space != IS_NULL);
@@ -218,60 +186,24 @@ ipc_space_destroy(
        if (!active)
                return;
 
-       /*
-        *      If somebody is trying to grow the table,
-        *      we must wait until they finish and figure
-        *      out the space died.
-        */
+       ipc_entry_t entry;
+       struct rdxtree_iter iter;
+       rdxtree_for_each(&space->is_map, &iter, entry) {
+               if (entry->ie_name == MACH_PORT_NULL)
+                       continue;
 
-       is_read_lock(space);
-       while (space->is_growing) {
-               assert_wait((event_t) space, FALSE);
-               is_read_unlock(space);
-               thread_block((void (*)(void)) 0);
-               is_read_lock(space);
-       }
-       is_read_unlock(space);
-
-       /*
-        *      Now we can futz with it without having it locked.
-        */
-
-       table = space->is_table;
-       size = space->is_table_size;
-
-       for (index = 0; index < size; index++) {
-               ipc_entry_t entry = &table[index];
                mach_port_type_t type = IE_BITS_TYPE(entry->ie_bits);
 
                if (type != MACH_PORT_TYPE_NONE) {
                        mach_port_t name =
-                               MACH_PORT_MAKEB(index, entry->ie_bits);
+                               MACH_PORT_MAKEB(entry->ie_name, entry->ie_bits);
 
                        ipc_right_clean(space, name, entry);
                }
-       }
 
-       it_entries_free(space->is_table_next-1, table);
-
-       for (tentry = ipc_splay_traverse_start(&space->is_tree);
-            tentry != ITE_NULL;
-            tentry = ipc_splay_traverse_next(&space->is_tree, TRUE)) {
-               mach_port_type_t type = IE_BITS_TYPE(tentry->ite_bits);
-               mach_port_t name = tentry->ite_name;
-
-               assert(type != MACH_PORT_TYPE_NONE);
-
-               /* use object before ipc_right_clean releases ref */
-
-               if (type == MACH_PORT_TYPE_SEND)
-                       ipc_hash_global_delete(space, tentry->ite_object,
-                                              name, tentry);
-
-               ipc_right_clean(space, name, &tentry->ite_entry);
+               ie_free(entry);
        }
-       ipc_splay_traverse_finish(&space->is_tree);
-
+       rdxtree_remove_all(&space->is_map);
        rdxtree_remove_all(&space->is_reverse_map);
 
        /*
diff --git a/ipc/ipc_space.h b/ipc/ipc_space.h
index f41c64c..20b9d57 100644
--- a/ipc/ipc_space.h
+++ b/ipc/ipc_space.h
@@ -47,7 +47,7 @@
 #include <kern/lock.h>
 #include <kern/rdxtree.h>
 #include <kern/slab.h>
-#include <ipc/ipc_splay.h>
+#include <ipc/ipc_entry.h>
 #include <ipc/ipc_types.h>
 
 /*
@@ -73,18 +73,16 @@ struct ipc_space {
 
        decl_simple_lock_data(,is_lock_data)
        boolean_t is_active;            /* is the space alive? */
-       boolean_t is_growing;           /* is the space growing? */
-       ipc_entry_t is_table;           /* an array of entries */
-       ipc_entry_num_t is_table_size;  /* current size of table */
-       struct ipc_table_size *is_table_next; /* info for larger table */
-       struct ipc_splay_tree is_tree;  /* a splay tree of entries */
-       ipc_entry_num_t is_tree_total;  /* number of entries in the tree */
-       ipc_entry_num_t is_tree_small;  /* # of small entries in the tree */
-       ipc_entry_num_t is_tree_hash;   /* # of hashed entries in the tree */
+       struct rdxtree is_map;          /* a map of entries */
+       size_t is_size;                 /* number of entries */
        struct rdxtree is_reverse_map;  /* maps objects to entries */
-
+       ipc_entry_t is_free_list;       /* a linked list of free entries */
+       size_t is_free_list_size;       /* number of free entries */
+#define IS_FREE_LIST_SIZE_LIMIT        64      /* maximum number of entries
+                                          in the free list */
 };
 
+
 #define        IS_NULL                 ((ipc_space_t) 0)
 
 extern struct kmem_cache ipc_space_cache;
diff --git a/ipc/ipc_splay.c b/ipc/ipc_splay.c
deleted file mode 100644
index 062a69f..0000000
--- a/ipc/ipc_splay.c
+++ /dev/null
@@ -1,920 +0,0 @@
-/* 
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- */
-/*
- *     File:   ipc/ipc_splay.c
- *     Author: Rich Draves
- *     Date:   1989
- *
- *     Primitive splay tree operations.
- */
-
-#include <mach/port.h>
-#include <kern/assert.h>
-#include <kern/macros.h>
-#include <ipc/ipc_entry.h>
-#include <ipc/ipc_splay.h>
-
-/*
- *     Splay trees are self-adjusting binary search trees.
- *     They have the following attractive properties:
- *             1) Space efficient; only two pointers per entry.
- *             2) Robust performance; amortized O(log n) per operation.
- *             3) Recursion not needed.
- *     This makes them a good fall-back data structure for those
- *     entries that don't fit into the lookup table.
- *
- *     The paper by Sleator and Tarjan, JACM v. 32, no. 3, pp. 652-686,
- *     describes the splaying operation.  ipc_splay_prim_lookup
- *     and ipc_splay_prim_assemble implement the top-down splay
- *     described on p. 669.
- *
- *     The tree is stored in an unassembled form.  If ist_root is null,
- *     then the tree has no entries.  Otherwise, ist_name records
- *     the value used for the last lookup.  ist_root points to the
- *     middle tree obtained from the top-down splay.  ist_ltree and
- *     ist_rtree point to left and right subtrees, whose entries
- *     are all smaller (larger) than those in the middle tree.
- *     ist_ltreep and ist_rtreep are pointers to fields in the
- *     left and right subtrees.  ist_ltreep points to the rchild field
- *     of the largest entry in ltree, and ist_rtreep points to the
- *     lchild field of the smallest entry in rtree.  The pointed-to
- *     fields aren't initialized.  If the left (right) subtree is null,
- *     then ist_ltreep (ist_rtreep) points to the ist_ltree (ist_rtree)
- *     field in the splay structure itself.
- *
- *     The primary advantage of the unassembled form is that repeated
- *     unsuccessful lookups are efficient.  In particular, an unsuccessful
- *     lookup followed by an insert only requires one splaying operation.
- *
- *     The traversal algorithm works via pointer inversion.
- *     When descending down the tree, child pointers are reversed
- *     to point back to the parent entry.  When ascending,
- *     the pointers are restored to their original value.
- *
- *     The biggest potential problem with the splay tree implementation
- *     is that the operations, even lookup, require an exclusive lock.
- *     If IPC spaces are protected with exclusive locks, then
- *     the splay tree doesn't require its own lock, and ist_lock/ist_unlock
- *     needn't do anything.  If IPC spaces are protected with read/write
- *     locks then ist_lock/ist_unlock should provide exclusive access.
- *
- *     If it becomes important to let lookups run in parallel,
- *     or if the restructuring makes lookups too expensive, then
- *     there is hope.  Use a read/write lock on the splay tree.
- *     Keep track of the number of entries in the tree.  When doing
- *     a lookup, first try a non-restructuring lookup with a read lock held,
- *     with a bound (based on log of size of the tree) on the number of
- *     entries to traverse.  If the lookup runs up against the bound,
- *     then take a write lock and do a reorganizing lookup.
- *     This way, if lookups only access roughly balanced parts
- *     of the tree, then lookups run in parallel and do no restructuring.
- *
- *     The traversal algorithm currently requires an exclusive lock.
- *     If that is a problem, the tree could be changed from an lchild/rchild
- *     representation to a leftmost child/right sibling representation.
- *     In conjunction with non-restructing lookups, this would let
- *     lookups and traversals all run in parallel.  But this representation
- *     is more complicated and would slow down the operations.
- */
-
-/*
- *     Boundary values to hand to ipc_splay_prim_lookup:
- */
-
-#define        MACH_PORT_SMALLEST      ((mach_port_t) 0)
-#define MACH_PORT_LARGEST      ((mach_port_t) ~0)
-
-/*
- *     Routine:        ipc_splay_prim_lookup
- *     Purpose:
- *             Searches for the node labeled name in the splay tree.
- *             Returns three nodes (treep, ltreep, rtreep) and
- *             two pointers to nodes (ltreepp, rtreepp).
- *
- *             ipc_splay_prim_lookup splits the supplied tree into
- *             three subtrees, left, middle, and right, returned
- *             in ltreep, treep, and rtreep.
- *
- *             If name is present in the tree, then it is at
- *             the root of the middle tree.  Otherwise, the root
- *             of the middle tree is the last node traversed.
- *
- *             ipc_splay_prim_lookup returns a pointer into
- *             the left subtree, to the rchild field of its
- *             largest node, in ltreepp.  It returns a pointer
- *             into the right subtree, to the lchild field of its
- *             smallest node, in rtreepp.
- */
-
-static void
-ipc_splay_prim_lookup(
-       mach_port_t             name,
-       ipc_tree_entry_t        tree,
-       ipc_tree_entry_t        *treep,
-       ipc_tree_entry_t        *ltreep,
-       ipc_tree_entry_t        **ltreepp,
-       ipc_tree_entry_t        *rtreep,
-       ipc_tree_entry_t        **rtreepp)
-{
-       mach_port_t tname;                      /* temp name */
-       ipc_tree_entry_t lchild, rchild;        /* temp child pointers */
-
-       assert(tree != ITE_NULL);
-
-#define        link_left                                       \
-MACRO_BEGIN                                            \
-       *ltreep = tree;                                 \
-       ltreep = &tree->ite_rchild;                     \
-       tree = *ltreep;                                 \
-MACRO_END
-
-#define        link_right                                      \
-MACRO_BEGIN                                            \
-       *rtreep = tree;                                 \
-       rtreep = &tree->ite_lchild;                     \
-       tree = *rtreep;                                 \
-MACRO_END
-
-#define rotate_left                                    \
-MACRO_BEGIN                                            \
-       ipc_tree_entry_t temp = tree;                   \
-                                                       \
-       tree = temp->ite_rchild;                        \
-       temp->ite_rchild = tree->ite_lchild;            \
-       tree->ite_lchild = temp;                        \
-MACRO_END
-
-#define rotate_right                                   \
-MACRO_BEGIN                                            \
-       ipc_tree_entry_t temp = tree;                   \
-                                                       \
-       tree = temp->ite_lchild;                        \
-       temp->ite_lchild = tree->ite_rchild;            \
-       tree->ite_rchild = temp;                        \
-MACRO_END
-
-       while (name != (tname = tree->ite_name)) {
-               if (name < tname) {
-                       /* descend to left */
-
-                       lchild = tree->ite_lchild;
-                       if (lchild == ITE_NULL)
-                               break;
-                       tname = lchild->ite_name;
-
-                       if ((name < tname) &&
-                           (lchild->ite_lchild != ITE_NULL))
-                               rotate_right;
-                       link_right;
-                       if ((name > tname) &&
-                           (lchild->ite_rchild != ITE_NULL))
-                               link_left;
-               } else {
-                       /* descend to right */
-
-                       rchild = tree->ite_rchild;
-                       if (rchild == ITE_NULL)
-                               break;
-                       tname = rchild->ite_name;
-
-                       if ((name > tname) &&
-                           (rchild->ite_rchild != ITE_NULL))
-                               rotate_left;
-                       link_left;
-                       if ((name < tname) &&
-                           (rchild->ite_lchild != ITE_NULL))
-                               link_right;
-               }
-
-               assert(tree != ITE_NULL);
-       }
-
-       *treep = tree;
-       *ltreepp = ltreep;
-       *rtreepp = rtreep;
-
-#undef link_left
-#undef link_right
-#undef rotate_left
-#undef rotate_right
-}
-
-/*
- *     Routine:        ipc_splay_prim_assemble
- *     Purpose:
- *             Assembles the results of ipc_splay_prim_lookup
- *             into a splay tree with the found node at the root.
- *
- *             ltree and rtree are by-reference so storing
- *             through ltreep and rtreep can change them.
- */
-
-static void
-ipc_splay_prim_assemble(
-       ipc_tree_entry_t        tree,
-       ipc_tree_entry_t        *ltree,
-       ipc_tree_entry_t        *ltreep,
-       ipc_tree_entry_t        *rtree,
-       ipc_tree_entry_t        *rtreep)
-{
-       assert(tree != ITE_NULL);
-
-       *ltreep = tree->ite_lchild;
-       *rtreep = tree->ite_rchild;
-
-       tree->ite_lchild = *ltree;
-       tree->ite_rchild = *rtree;
-}
-
-/*
- *     Routine:        ipc_splay_tree_init
- *     Purpose:
- *             Initialize a raw splay tree for use.
- */
-
-void
-ipc_splay_tree_init(
-       ipc_splay_tree_t        splay)
-{
-       splay->ist_root = ITE_NULL;
-}
-
-/*
- *     Routine:        ipc_splay_tree_pick
- *     Purpose:
- *             Picks and returns a random entry in a splay tree.
- *             Returns FALSE if the splay tree is empty.
- */
-
-boolean_t
-ipc_splay_tree_pick(
-       ipc_splay_tree_t        splay,
-       mach_port_t             *namep,
-       ipc_tree_entry_t        *entryp)
-{
-       ipc_tree_entry_t root;
-
-       ist_lock(splay);
-
-       root = splay->ist_root;
-       if (root != ITE_NULL) {
-               *namep = root->ite_name;
-               *entryp = root;
-       }
-
-       ist_unlock(splay);
-
-       return root != ITE_NULL;
-}
-
-/*
- *     Routine:        ipc_splay_tree_lookup
- *     Purpose:
- *             Finds an entry in a splay tree.
- *             Returns ITE_NULL if not found.
- */
-
-ipc_tree_entry_t
-ipc_splay_tree_lookup(
-       ipc_splay_tree_t        splay,
-       mach_port_t             name)
-{
-       ipc_tree_entry_t root;
-
-       ist_lock(splay);
-
-       root = splay->ist_root;
-       if (root != ITE_NULL) {
-               if (splay->ist_name != name) {
-                       ipc_splay_prim_assemble(root,
-                               &splay->ist_ltree, splay->ist_ltreep,
-                               &splay->ist_rtree, splay->ist_rtreep);
-                       ipc_splay_prim_lookup(name, root, &root,
-                               &splay->ist_ltree, &splay->ist_ltreep,
-                               &splay->ist_rtree, &splay->ist_rtreep);
-                       splay->ist_name = name;
-                       splay->ist_root = root;
-               }
-
-               if (name != root->ite_name)
-                       root = ITE_NULL;
-       }
-
-       ist_unlock(splay);
-
-       return root;
-}
-
-/*
- *     Routine:        ipc_splay_tree_insert
- *     Purpose:
- *             Inserts a new entry into a splay tree.
- *             The caller supplies a new entry.
- *             The name can't already be present in the tree.
- */
-
-void
-ipc_splay_tree_insert(
-       ipc_splay_tree_t        splay,
-       mach_port_t             name,
-       ipc_tree_entry_t        entry)
-{
-       ipc_tree_entry_t root;
-
-       assert(entry != ITE_NULL);
-
-       ist_lock(splay);
-
-       root = splay->ist_root;
-       if (root == ITE_NULL) {
-               entry->ite_lchild = ITE_NULL;
-               entry->ite_rchild = ITE_NULL;
-       } else {
-               if (splay->ist_name != name) {
-                       ipc_splay_prim_assemble(root,
-                               &splay->ist_ltree, splay->ist_ltreep,
-                               &splay->ist_rtree, splay->ist_rtreep);
-                       ipc_splay_prim_lookup(name, root, &root,
-                               &splay->ist_ltree, &splay->ist_ltreep,
-                               &splay->ist_rtree, &splay->ist_rtreep);
-               }
-
-               assert(root->ite_name != name);
-
-               if (name < root->ite_name) {
-                       assert(root->ite_lchild == ITE_NULL);
-
-                       *splay->ist_ltreep = ITE_NULL;
-                       *splay->ist_rtreep = root;
-               } else {
-                       assert(root->ite_rchild == ITE_NULL);
-
-                       *splay->ist_ltreep = root;
-                       *splay->ist_rtreep = ITE_NULL;
-               }
-
-               entry->ite_lchild = splay->ist_ltree;
-               entry->ite_rchild = splay->ist_rtree;
-       }
-
-       entry->ite_name = name;
-       splay->ist_root = entry;
-       splay->ist_name = name;
-       splay->ist_ltreep = &splay->ist_ltree;
-       splay->ist_rtreep = &splay->ist_rtree;
-
-       ist_unlock(splay);
-}
-
-/*
- *     Routine:        ipc_splay_tree_delete
- *     Purpose:
- *             Deletes an entry from a splay tree.
- *             The name must be present in the tree.
- *             Frees the entry.
- *
- *             The "entry" argument isn't currently used.
- *             Other implementations might want it, though.
- */
-
-void
-ipc_splay_tree_delete(
-       ipc_splay_tree_t        splay,
-       mach_port_t             name,
-       ipc_tree_entry_t        entry)
-{
-       ipc_tree_entry_t root, saved;
-
-       ist_lock(splay);
-
-       root = splay->ist_root;
-       assert(root != ITE_NULL);
-
-       if (splay->ist_name != name) {
-               ipc_splay_prim_assemble(root,
-                       &splay->ist_ltree, splay->ist_ltreep,
-                       &splay->ist_rtree, splay->ist_rtreep);
-               ipc_splay_prim_lookup(name, root, &root,
-                       &splay->ist_ltree, &splay->ist_ltreep,
-                       &splay->ist_rtree, &splay->ist_rtreep);
-       }
-
-       assert(root->ite_name == name);
-       assert(root == entry);
-
-       *splay->ist_ltreep = root->ite_lchild;
-       *splay->ist_rtreep = root->ite_rchild;
-       ite_free(root);
-
-       root = splay->ist_ltree;
-       saved = splay->ist_rtree;
-
-       if (root == ITE_NULL)
-               root = saved;
-       else if (saved != ITE_NULL) {
-               /*
-                *      Find the largest node in the left subtree, and splay it
-                *      to the root.  Then add the saved right subtree.
-                */
-
-               ipc_splay_prim_lookup(MACH_PORT_LARGEST, root, &root,
-                       &splay->ist_ltree, &splay->ist_ltreep,
-                       &splay->ist_rtree, &splay->ist_rtreep);
-               ipc_splay_prim_assemble(root,
-                       &splay->ist_ltree, splay->ist_ltreep,
-                       &splay->ist_rtree, splay->ist_rtreep);
-
-               assert(root->ite_rchild == ITE_NULL);
-               root->ite_rchild = saved;
-       }
-
-       splay->ist_root = root;
-       if (root != ITE_NULL) {
-               splay->ist_name = root->ite_name;
-               splay->ist_ltreep = &splay->ist_ltree;
-               splay->ist_rtreep = &splay->ist_rtree;
-       }
-
-       ist_unlock(splay);
-}
-
-/*
- *     Routine:        ipc_splay_tree_split
- *     Purpose:
- *             Split a splay tree.  Puts all entries smaller than "name"
- *             into a new tree, "small".
- *
- *             Doesn't do locking on "small", because nobody else
- *             should be fiddling with the uninitialized tree.
- */
-
-void
-ipc_splay_tree_split(
-       ipc_splay_tree_t        splay,
-       mach_port_t             name,
-       ipc_splay_tree_t        small)
-{
-       ipc_tree_entry_t root;
-
-       ipc_splay_tree_init(small);
-
-       ist_lock(splay);
-
-       root = splay->ist_root;
-       if (root != ITE_NULL) {
-               /* lookup name, to get it (or last traversed) to the top */
-
-               if (splay->ist_name != name) {
-                       ipc_splay_prim_assemble(root,
-                               &splay->ist_ltree, splay->ist_ltreep,
-                               &splay->ist_rtree, splay->ist_rtreep);
-                       ipc_splay_prim_lookup(name, root, &root,
-                               &splay->ist_ltree, &splay->ist_ltreep,
-                               &splay->ist_rtree, &splay->ist_rtreep);
-               }
-
-               if (root->ite_name < name) {
-                       /* root goes into small */
-
-                       *splay->ist_ltreep = root->ite_lchild;
-                       *splay->ist_rtreep = ITE_NULL;
-                       root->ite_lchild = splay->ist_ltree;
-                       assert(root->ite_rchild == ITE_NULL);
-
-                       small->ist_root = root;
-                       small->ist_name = root->ite_name;
-                       small->ist_ltreep = &small->ist_ltree;
-                       small->ist_rtreep = &small->ist_rtree;
-
-                       /* rtree goes into splay */
-
-                       root = splay->ist_rtree;
-                       splay->ist_root = root;
-                       if (root != ITE_NULL) {
-                               splay->ist_name = root->ite_name;
-                               splay->ist_ltreep = &splay->ist_ltree;
-                               splay->ist_rtreep = &splay->ist_rtree;
-                       }
-               } else {
-                       /* root stays in splay */
-
-                       *splay->ist_ltreep = root->ite_lchild;
-                       root->ite_lchild = ITE_NULL;
-
-                       splay->ist_root = root;
-                       splay->ist_name = name;
-                       splay->ist_ltreep = &splay->ist_ltree;
-
-                       /* ltree goes into small */
-
-                       root = splay->ist_ltree;
-                       small->ist_root = root;
-                       if (root != ITE_NULL) {
-                               small->ist_name = root->ite_name;
-                               small->ist_ltreep = &small->ist_ltree;
-                               small->ist_rtreep = &small->ist_rtree;
-                       }
-               }               
-       }
-
-       ist_unlock(splay);
-}
-
-/*
- *     Routine:        ipc_splay_tree_join
- *     Purpose:
- *             Joins two splay trees.  Merges the entries in "small",
- *             which must all be smaller than the entries in "splay",
- *             into "splay".
- */
-
-void
-ipc_splay_tree_join(
-       ipc_splay_tree_t        splay,
-       ipc_splay_tree_t        small)
-{
-       ipc_tree_entry_t sroot;
-
-       /* pull entries out of small */
-
-       ist_lock(small);
-
-       sroot = small->ist_root;
-       if (sroot != ITE_NULL) {
-               ipc_splay_prim_assemble(sroot,
-                       &small->ist_ltree, small->ist_ltreep,
-                       &small->ist_rtree, small->ist_rtreep);
-               small->ist_root = ITE_NULL;
-       }
-
-       ist_unlock(small);
-
-       /* put entries, if any, into splay */
-
-       if (sroot != ITE_NULL) {
-               ipc_tree_entry_t root;
-
-               ist_lock(splay);
-
-               root = splay->ist_root;
-               if (root == ITE_NULL) {
-                       root = sroot;
-               } else {
-                       /* get smallest entry in splay tree to top */
-
-                       if (splay->ist_name != MACH_PORT_SMALLEST) {
-                               ipc_splay_prim_assemble(root,
-                                       &splay->ist_ltree, splay->ist_ltreep,
-                                       &splay->ist_rtree, splay->ist_rtreep);
-                               ipc_splay_prim_lookup(MACH_PORT_SMALLEST,
-                                       root, &root,
-                                       &splay->ist_ltree, &splay->ist_ltreep,
-                                       &splay->ist_rtree, &splay->ist_rtreep);
-                       }
-
-                       ipc_splay_prim_assemble(root,
-                               &splay->ist_ltree, splay->ist_ltreep,
-                               &splay->ist_rtree, splay->ist_rtreep);
-
-                       assert(root->ite_lchild == ITE_NULL);
-                       assert(sroot->ite_name < root->ite_name);
-                       root->ite_lchild = sroot;
-               }
-
-               splay->ist_root = root;
-               splay->ist_name = root->ite_name;
-               splay->ist_ltreep = &splay->ist_ltree;
-               splay->ist_rtreep = &splay->ist_rtree;
-
-               ist_unlock(splay);
-       }
-}
-
-/*
- *     Routine:        ipc_splay_tree_bounds
- *     Purpose:
- *             Given a name, returns the largest value present
- *             in the tree that is smaller than or equal to the name,
- *             or ~0 if no such value exists.  Similarly, returns
- *             the smallest value present that is greater than or
- *             equal to the name, or 0 if no such value exists.
- *
- *             Hence, if
- *             lower = upper, then lower = name = upper
- *                             and name is present in the tree
- *             lower = ~0 and upper = 0,
- *                             then the tree is empty
- *             lower = ~0 and upper > 0, then name < upper
- *                             and upper is smallest value in tree
- *             lower < ~0 and upper = 0, then lower < name
- *                             and lower is largest value in tree
- *             lower < ~0 and upper > 0, then lower < name < upper
- *                             and they are tight bounds on name
- *
- *             (Note MACH_PORT_SMALLEST = 0 and MACH_PORT_LARGEST = ~0.)
- */
-
-void
-ipc_splay_tree_bounds(
-       ipc_splay_tree_t        splay,
-       mach_port_t             name,
-       mach_port_t             *lowerp, 
-       mach_port_t             *upperp)
-{
-       ipc_tree_entry_t root;
-
-       ist_lock(splay);
-
-       root = splay->ist_root;
-       if (root == ITE_NULL) {
-               *lowerp = MACH_PORT_LARGEST;
-               *upperp = MACH_PORT_SMALLEST;
-       } else {
-               mach_port_t rname;
-
-               if (splay->ist_name != name) {
-                       ipc_splay_prim_assemble(root,
-                               &splay->ist_ltree, splay->ist_ltreep,
-                               &splay->ist_rtree, splay->ist_rtreep);
-                       ipc_splay_prim_lookup(name, root, &root,
-                               &splay->ist_ltree, &splay->ist_ltreep,
-                               &splay->ist_rtree, &splay->ist_rtreep);
-                       splay->ist_name = name;
-                       splay->ist_root = root;
-               }
-
-               rname = root->ite_name;
-
-               /*
-                *      OK, it's a hack.  We convert the ltreep and rtreep
-                *      pointers back into real entry pointers,
-                *      so we can pick the names out of the entries.
-                */
-
-               if (rname <= name)
-                       *lowerp = rname;
-               else if (splay->ist_ltreep == &splay->ist_ltree)
-                       *lowerp = MACH_PORT_LARGEST;
-               else {
-                       ipc_tree_entry_t entry;
-
-                       entry = (ipc_tree_entry_t)
-                               ((char *)splay->ist_ltreep -
-                                ((char *)&root->ite_rchild -
-                                 (char *)root));
-                       *lowerp = entry->ite_name;
-               }
-
-               if (rname >= name)
-                       *upperp = rname;
-               else if (splay->ist_rtreep == &splay->ist_rtree)
-                       *upperp = MACH_PORT_SMALLEST;
-               else {
-                       ipc_tree_entry_t entry;
-
-                       entry = (ipc_tree_entry_t)
-                               ((char *)splay->ist_rtreep -
-                                ((char *)&root->ite_lchild -
-                                 (char *)root));
-                       *upperp = entry->ite_name;
-               }
-       }
-
-       ist_unlock(splay);
-}
-
-/*
- *     Routine:        ipc_splay_traverse_start
- *     Routine:        ipc_splay_traverse_next
- *     Routine:        ipc_splay_traverse_finish
- *     Purpose:
- *             Perform a symmetric order traversal of a splay tree.
- *     Usage:
- *             for (entry = ipc_splay_traverse_start(splay);
- *                  entry != ITE_NULL;
- *                  entry = ipc_splay_traverse_next(splay, delete)) {
- *                     do something with entry
- *             }
- *             ipc_splay_traverse_finish(splay);
- *
- *             If "delete" is TRUE, then the current entry
- *             is removed from the tree and deallocated.
- *
- *             During the traversal, the splay tree is locked.
- */
-
-ipc_tree_entry_t
-ipc_splay_traverse_start(
-       ipc_splay_tree_t        splay)
-{
-       ipc_tree_entry_t current, parent;
-
-       ist_lock(splay);
-
-       current = splay->ist_root;
-       if (current != ITE_NULL) {
-               ipc_splay_prim_assemble(current,
-                       &splay->ist_ltree, splay->ist_ltreep,
-                       &splay->ist_rtree, splay->ist_rtreep);
-
-               parent = ITE_NULL;
-
-               while (current->ite_lchild != ITE_NULL) {
-                       ipc_tree_entry_t next;
-
-                       next = current->ite_lchild;
-                       current->ite_lchild = parent;
-                       parent = current;
-                       current = next;
-               }
-
-               splay->ist_ltree = current;
-               splay->ist_rtree = parent;
-       }
-
-       return current;
-}
-
-ipc_tree_entry_t
-ipc_splay_traverse_next(
-       ipc_splay_tree_t        splay,
-       boolean_t               delete)
-{
-       ipc_tree_entry_t current, parent;
-
-       /* pick up where traverse_entry left off */
-
-       current = splay->ist_ltree;
-       parent = splay->ist_rtree;
-       assert(current != ITE_NULL);
-
-       if (!delete)
-               goto traverse_right;
-
-       /* we must delete current and patch the tree */
-
-       if (current->ite_lchild == ITE_NULL) {
-               if (current->ite_rchild == ITE_NULL) {
-                       /* like traverse_back, but with deletion */
-
-                       if (parent == ITE_NULL) {
-                               ite_free(current);
-
-                               splay->ist_root = ITE_NULL;
-                               return ITE_NULL;
-                       }
-
-                       if (current->ite_name < parent->ite_name) {
-                               ite_free(current);
-
-                               current = parent;
-                               parent = current->ite_lchild;
-                               current->ite_lchild = ITE_NULL;
-                               goto traverse_entry;
-                       } else {
-                               ite_free(current);
-
-                               current = parent;
-                               parent = current->ite_rchild;
-                               current->ite_rchild = ITE_NULL;
-                               goto traverse_back;
-                       }
-               } else {
-                       ipc_tree_entry_t prev;
-
-                       prev = current;
-                       current = current->ite_rchild;
-                       ite_free(prev);
-                       goto traverse_left;
-               }
-       } else {
-               if (current->ite_rchild == ITE_NULL) {
-                       ipc_tree_entry_t prev;
-
-                       prev = current;
-                       current = current->ite_lchild;
-                       ite_free(prev);
-                       goto traverse_back;
-               } else {
-                       ipc_tree_entry_t prev;
-                       ipc_tree_entry_t ltree, rtree;
-                       ipc_tree_entry_t *ltreep, *rtreep;
-
-                       /* replace current with largest of left children */
-
-                       prev = current;
-                       ipc_splay_prim_lookup(MACH_PORT_LARGEST,
-                               current->ite_lchild, &current,
-                               &ltree, &ltreep, &rtree, &rtreep);
-                       ipc_splay_prim_assemble(current,
-                               &ltree, ltreep, &rtree, rtreep);
-
-                       assert(current->ite_rchild == ITE_NULL);
-                       current->ite_rchild = prev->ite_rchild;
-                       ite_free(prev);
-                       goto traverse_right;
-               }
-       }
-       /*NOTREACHED*/
-
-       /*
-        *      A state machine:  for each entry, we
-        *              1) traverse left subtree
-        *              2) traverse the entry
-        *              3) traverse right subtree
-        *              4) traverse back to parent
-        */
-
-    traverse_left:
-       if (current->ite_lchild != ITE_NULL) {
-               ipc_tree_entry_t next;
-
-               next = current->ite_lchild;
-               current->ite_lchild = parent;
-               parent = current;
-               current = next;
-               goto traverse_left;
-       }
-
-    traverse_entry:
-       splay->ist_ltree = current;
-       splay->ist_rtree = parent;
-       return current;
-
-    traverse_right:
-       if (current->ite_rchild != ITE_NULL) {
-               ipc_tree_entry_t next;
-
-               next = current->ite_rchild;
-               current->ite_rchild = parent;
-               parent = current;
-               current = next;
-               goto traverse_left;
-       }
-
-    traverse_back:
-       if (parent == ITE_NULL) {
-               splay->ist_root = current;
-               return ITE_NULL;
-       }
-
-       if (current->ite_name < parent->ite_name) {
-               ipc_tree_entry_t prev;
-
-               prev = current;
-               current = parent;
-               parent = current->ite_lchild;
-               current->ite_lchild = prev;
-               goto traverse_entry;
-       } else {
-               ipc_tree_entry_t prev;
-
-               prev = current;
-               current = parent;
-               parent = current->ite_rchild;
-               current->ite_rchild = prev;
-               goto traverse_back;
-       }
-}
-
-void
-ipc_splay_traverse_finish(
-       ipc_splay_tree_t        splay)
-{
-       ipc_tree_entry_t root;
-
-       root = splay->ist_root;
-       if (root != ITE_NULL) {
-               splay->ist_name = root->ite_name;
-               splay->ist_ltreep = &splay->ist_ltree;
-               splay->ist_rtreep = &splay->ist_rtree;
-       }
-
-       ist_unlock(splay);
-}
-
diff --git a/ipc/ipc_splay.h b/ipc/ipc_splay.h
deleted file mode 100644
index 42e5a80..0000000
--- a/ipc/ipc_splay.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* 
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- */
-/*
- *     File:   ipc/ipc_splay.h
- *     Author: Rich Draves
- *     Date:   1989
- *
- *     Declarations of primitive splay tree operations.
- */
-
-#ifndef        _IPC_IPC_SPLAY_H_
-#define _IPC_IPC_SPLAY_H_
-
-#include <mach/port.h>
-#include <kern/assert.h>
-#include <kern/macros.h>
-#include <ipc/ipc_entry.h>
-
-typedef struct ipc_splay_tree {
-       mach_port_t ist_name;           /* name used in last lookup */
-       ipc_tree_entry_t ist_root;      /* root of middle tree */
-       ipc_tree_entry_t ist_ltree;     /* root of left tree */
-       ipc_tree_entry_t *ist_ltreep;   /* pointer into left tree */
-       ipc_tree_entry_t ist_rtree;     /* root of right tree */
-       ipc_tree_entry_t *ist_rtreep;   /* pointer into right tree */
-} *ipc_splay_tree_t;
-
-#define        ist_lock(splay)         /* no locking */
-#define ist_unlock(splay)      /* no locking */
-
-/* Initialize a raw splay tree */
-extern void ipc_splay_tree_init(
-       ipc_splay_tree_t        splay);
-
-/* Pick a random entry in a splay tree */
-extern boolean_t ipc_splay_tree_pick(
-       ipc_splay_tree_t        splay,
-       mach_port_t             *namep,
-       ipc_tree_entry_t        *entryp);
-
-/* Find an entry in a splay tree */
-extern ipc_tree_entry_t ipc_splay_tree_lookup(
-       ipc_splay_tree_t        splay,
-       mach_port_t             name);
-
-/* Insert a new entry into a splay tree */
-extern void ipc_splay_tree_insert(
-       ipc_splay_tree_t        splay,
-       mach_port_t             name,
-       ipc_tree_entry_t        entry);
-
-/* Delete an entry from a splay tree */
-extern void ipc_splay_tree_delete(
-       ipc_splay_tree_t        splay,
-       mach_port_t             name,
-       ipc_tree_entry_t        entry);
-
-/* Split a splay tree */
-extern void ipc_splay_tree_split(
-       ipc_splay_tree_t        splay,
-       mach_port_t             name,
-       ipc_splay_tree_t        entry);
-
-/* Join two splay trees */
-extern void ipc_splay_tree_join(
-       ipc_splay_tree_t        splay,
-       ipc_splay_tree_t        small);
-
-/* Do a bounded splay tree lookup */
-extern void ipc_splay_tree_bounds(
-       ipc_splay_tree_t        splay,
-       mach_port_t             name,
-       mach_port_t             *lowerp, 
-       mach_port_t             *upperp);
-
-/* Initialize a symmetric order traversal of a splay tree */
-extern ipc_tree_entry_t ipc_splay_traverse_start(
-       ipc_splay_tree_t        splay);
-
-/* Return the next entry in a symmetric order traversal of a splay tree */
-extern ipc_tree_entry_t ipc_splay_traverse_next(
-       ipc_splay_tree_t        splay,
-       boolean_t               delete);
-
-/* Terminate a symmetric order traversal of a splay tree */
-extern void ipc_splay_traverse_finish(
-       ipc_splay_tree_t        splay);
-
-#endif /* _IPC_IPC_SPLAY_H_ */
diff --git a/ipc/mach_debug.c b/ipc/mach_debug.c
index eb52e1c..efb07a4 100644
--- a/ipc/mach_debug.c
+++ b/ipc/mach_debug.c
@@ -46,7 +46,6 @@
 #include <vm/vm_kern.h>
 #include <ipc/ipc_space.h>
 #include <ipc/ipc_port.h>
-#include <ipc/ipc_hash.h>
 #include <ipc/ipc_marequest.h>
 #include <ipc/ipc_table.h>
 #include <ipc/ipc_right.h>
@@ -94,85 +93,6 @@ mach_port_get_srights(
 }
 
 /*
- *     Routine:        host_ipc_hash_info
- *     Purpose:
- *             Return information about the global reverse hash table.
- *     Conditions:
- *             Nothing locked.  Obeys CountInOut protocol.
- *     Returns:
- *             KERN_SUCCESS            Returned information.
- *             KERN_INVALID_HOST       The host is null.
- *             KERN_RESOURCE_SHORTAGE  Couldn't allocate memory.
- */
-
-kern_return_t
-host_ipc_hash_info(
-       host_t                          host,
-       hash_info_bucket_array_t        *infop,
-       mach_msg_type_number_t          *countp)
-{
-       vm_offset_t addr;
-       vm_size_t size = 0;     /* Suppress gcc warning */
-       hash_info_bucket_t *info;
-       unsigned int potential, actual;
-       kern_return_t kr;
-
-       if (host == HOST_NULL)
-               return KERN_INVALID_HOST;
-
-       /* start with in-line data */
-
-       info = *infop;
-       potential = *countp;
-
-       for (;;) {
-               actual = ipc_hash_info(info, potential);
-               if (actual <= potential)
-                       break;
-
-               /* allocate more memory */
-
-               if (info != *infop)
-                       kmem_free(ipc_kernel_map, addr, size);
-
-               size = round_page(actual * sizeof *info);
-               kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size);
-               if (kr != KERN_SUCCESS)
-                       return KERN_RESOURCE_SHORTAGE;
-
-               info = (hash_info_bucket_t *) addr;
-               potential = size/sizeof *info;
-       }
-
-       if (info == *infop) {
-               /* data fit in-line; nothing to deallocate */
-
-               *countp = actual;
-       } else if (actual == 0) {
-               kmem_free(ipc_kernel_map, addr, size);
-
-               *countp = 0;
-       } else {
-               vm_map_copy_t copy;
-               vm_size_t used;
-
-               used = round_page(actual * sizeof *info);
-
-               if (used != size)
-                       kmem_free(ipc_kernel_map, addr + used, size - used);
-
-               kr = vm_map_copyin(ipc_kernel_map, addr, used,
-                                  TRUE, &copy);
-               assert(kr == KERN_SUCCESS);
-
-               *infop = (hash_info_bucket_t *) copy;
-               *countp = actual;
-       }
-
-       return KERN_SUCCESS;
-}
-
-/*
  *     Routine:        host_ipc_marequest_info
  *     Purpose:
  *             Return information about the marequest hash table.
@@ -253,251 +173,6 @@ host_ipc_marequest_info(
 }
 
 /*
- *     Routine:        mach_port_space_info
- *     Purpose:
- *             Returns information about an IPC space.
- *     Conditions:
- *             Nothing locked.  Obeys CountInOut protocol.
- *     Returns:
- *             KERN_SUCCESS            Returned information.
- *             KERN_INVALID_TASK       The space is null.
- *             KERN_INVALID_TASK       The space is dead.
- *             KERN_RESOURCE_SHORTAGE  Couldn't allocate memory.
- */
-
-kern_return_t
-mach_port_space_info(
-       ipc_space_t                     space,
-       ipc_info_space_t                *infop,
-       ipc_info_name_array_t           *tablep,
-       mach_msg_type_number_t          *tableCntp,
-       ipc_info_tree_name_array_t      *treep,
-       mach_msg_type_number_t          *treeCntp)
-{
-       ipc_info_name_t *table_info;
-       unsigned int table_potential, table_actual;
-       vm_offset_t table_addr;
-       vm_size_t table_size = 0;       /* Suppress gcc warning */
-       ipc_info_tree_name_t *tree_info;
-       unsigned int tree_potential, tree_actual;
-       vm_offset_t tree_addr;
-       vm_size_t tree_size = 0;        /* Suppress gcc warning */
-       ipc_tree_entry_t tentry;
-       ipc_entry_t table;
-       ipc_entry_num_t tsize;
-       mach_port_index_t index;
-       kern_return_t kr;
-
-       if (space == IS_NULL)
-               return KERN_INVALID_TASK;
-
-       /* start with in-line memory */
-
-       table_info = *tablep;
-       table_potential = *tableCntp;
-       tree_info = *treep;
-       tree_potential = *treeCntp;
-
-       for (;;) {
-               is_read_lock(space);
-               if (!space->is_active) {
-                       is_read_unlock(space);
-                       if (table_info != *tablep)
-                               kmem_free(ipc_kernel_map,
-                                         table_addr, table_size);
-                       if (tree_info != *treep)
-                               kmem_free(ipc_kernel_map,
-                                         tree_addr, tree_size);
-                       return KERN_INVALID_TASK;
-               }
-
-               table_actual = space->is_table_size;
-               tree_actual = space->is_tree_total;
-
-               if ((table_actual <= table_potential) &&
-                   (tree_actual <= tree_potential))
-                       break;
-
-               is_read_unlock(space);
-
-               if (table_actual > table_potential) {
-                       if (table_info != *tablep)
-                               kmem_free(ipc_kernel_map,
-                                         table_addr, table_size);
-
-                       table_size = round_page(table_actual *
-                                               sizeof *table_info);
-                       kr = kmem_alloc(ipc_kernel_map,
-                                       &table_addr, table_size);
-                       if (kr != KERN_SUCCESS) {
-                               if (tree_info != *treep)
-                                       kmem_free(ipc_kernel_map,
-                                                 tree_addr, tree_size);
-
-                               return KERN_RESOURCE_SHORTAGE;
-                       }
-
-                       table_info = (ipc_info_name_t *) table_addr;
-                       table_potential = table_size/sizeof *table_info;
-               }
-
-               if (tree_actual > tree_potential) {
-                       if (tree_info != *treep)
-                               kmem_free(ipc_kernel_map,
-                                         tree_addr, tree_size);
-
-                       tree_size = round_page(tree_actual *
-                                              sizeof *tree_info);
-                       kr = kmem_alloc(ipc_kernel_map,
-                                       &tree_addr, tree_size);
-                       if (kr != KERN_SUCCESS) {
-                               if (table_info != *tablep)
-                                       kmem_free(ipc_kernel_map,
-                                                 table_addr, table_size);
-
-                               return KERN_RESOURCE_SHORTAGE;
-                       }
-
-                       tree_info = (ipc_info_tree_name_t *) tree_addr;
-                       tree_potential = tree_size/sizeof *tree_info;
-               }
-       }
-       /* space is read-locked and active; we have enough wired memory */
-
-       infop->iis_genno_mask = MACH_PORT_NGEN(MACH_PORT_DEAD);
-       infop->iis_table_size = space->is_table_size;
-       infop->iis_table_next = space->is_table_next->its_size;
-       infop->iis_tree_size = space->is_tree_total;
-       infop->iis_tree_small = space->is_tree_small;
-       infop->iis_tree_hash = space->is_tree_hash;
-
-       table = space->is_table;
-       tsize = space->is_table_size;
-
-       for (index = 0; index < tsize; index++) {
-               ipc_info_name_t *iin = &table_info[index];
-               ipc_entry_t entry = &table[index];
-               ipc_entry_bits_t bits = entry->ie_bits;
-
-               iin->iin_name = MACH_PORT_MAKEB(index, bits);
-               iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
-               iin->iin_compat = FALSE;
-               iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE;
-               iin->iin_type = IE_BITS_TYPE(bits);
-               iin->iin_urefs = IE_BITS_UREFS(bits);
-               iin->iin_object = (vm_offset_t) entry->ie_object;
-               iin->iin_next = entry->ie_next;
-               iin->iin_hash = entry->ie_index;
-       }
-
-       for (tentry = ipc_splay_traverse_start(&space->is_tree), index = 0;
-            tentry != ITE_NULL;
-            tentry = ipc_splay_traverse_next(&space->is_tree, FALSE)) {
-               ipc_info_tree_name_t *iitn = &tree_info[index++];
-               ipc_info_name_t *iin = &iitn->iitn_name;
-               ipc_entry_t entry = &tentry->ite_entry;
-               ipc_entry_bits_t bits = entry->ie_bits;
-
-               assert(IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE);
-
-               iin->iin_name = tentry->ite_name;
-               iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
-               iin->iin_compat = FALSE;
-               iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE;
-               iin->iin_type = IE_BITS_TYPE(bits);
-               iin->iin_urefs = IE_BITS_UREFS(bits);
-               iin->iin_object = (vm_offset_t) entry->ie_object;
-               iin->iin_next = entry->ie_next;
-               iin->iin_hash = entry->ie_index;
-
-               if (tentry->ite_lchild == ITE_NULL)
-                       iitn->iitn_lchild = MACH_PORT_NULL;
-               else
-                       iitn->iitn_lchild = tentry->ite_lchild->ite_name;
-
-               if (tentry->ite_rchild == ITE_NULL)
-                       iitn->iitn_rchild = MACH_PORT_NULL;
-               else
-                       iitn->iitn_rchild = tentry->ite_rchild->ite_name;
-
-       }
-       ipc_splay_traverse_finish(&space->is_tree);
-       is_read_unlock(space);
-
-       if (table_info == *tablep) {
-               /* data fit in-line; nothing to deallocate */
-
-               *tableCntp = table_actual;
-       } else if (table_actual == 0) {
-               kmem_free(ipc_kernel_map, table_addr, table_size);
-
-               *tableCntp = 0;
-       } else {
-               vm_size_t size_used, rsize_used;
-               vm_map_copy_t copy;
-
-               /* kmem_alloc doesn't zero memory */
-
-               size_used = table_actual * sizeof *table_info;
-               rsize_used = round_page(size_used);
-
-               if (rsize_used != table_size)
-                       kmem_free(ipc_kernel_map,
-                                 table_addr + rsize_used,
-                                 table_size - rsize_used);
-
-               if (size_used != rsize_used)
-                       memset((void *) (table_addr + size_used), 0,
-                             rsize_used - size_used);
-
-               kr = vm_map_copyin(ipc_kernel_map, table_addr, rsize_used,
-                                  TRUE, &copy);
-
-               assert(kr == KERN_SUCCESS);
-
-               *tablep = (ipc_info_name_t *) copy;
-               *tableCntp = table_actual;
-       }
-
-       if (tree_info == *treep) {
-               /* data fit in-line; nothing to deallocate */
-
-               *treeCntp = tree_actual;
-       } else if (tree_actual == 0) {
-               kmem_free(ipc_kernel_map, tree_addr, tree_size);
-
-               *treeCntp = 0;
-       } else {
-               vm_size_t size_used, rsize_used;
-               vm_map_copy_t copy;
-
-               /* kmem_alloc doesn't zero memory */
-
-               size_used = tree_actual * sizeof *tree_info;
-               rsize_used = round_page(size_used);
-
-               if (rsize_used != tree_size)
-                       kmem_free(ipc_kernel_map,
-                                 tree_addr + rsize_used,
-                                 tree_size - rsize_used);
-
-               if (size_used != rsize_used)
-                       memset((void *) (tree_addr + size_used), 0,
-                             rsize_used - size_used);
-
-               kr = vm_map_copyin(ipc_kernel_map, tree_addr, rsize_used,
-                                  TRUE, &copy);
-
-               assert(kr == KERN_SUCCESS);
-
-               *treep = (ipc_info_tree_name_t *) copy;
-               *treeCntp = tree_actual;
-       }
-
-       return KERN_SUCCESS;
-}
-
-/*
  *     Routine:        mach_port_dnrequest_info
  *     Purpose:
  *             Returns information about the dead-name requests
diff --git a/ipc/mach_port.c b/ipc/mach_port.c
index 4e89527..93a1248 100644
--- a/ipc/mach_port.c
+++ b/ipc/mach_port.c
@@ -150,10 +150,6 @@ mach_port_names(
        mach_port_type_t        **typesp,
        mach_msg_type_number_t  *typesCnt)
 {
-       ipc_tree_entry_t tentry;
-       ipc_entry_t table;
-       ipc_entry_num_t tsize;
-       mach_port_index_t index;
        ipc_entry_num_t actual; /* this many names */
        ipc_port_timestamp_t timestamp; /* logical time of this operation */
        mach_port_t *names;
@@ -190,7 +186,7 @@ mach_port_names(
 
                /* upper bound on number of names in the space */
 
-               bound = space->is_table_size + space->is_tree_total;
+               bound = space->is_size;
                size_needed = round_page(bound * sizeof(mach_port_t));
 
                if (size_needed <= size)
@@ -235,33 +231,16 @@ mach_port_names(
 
        timestamp = ipc_port_timestamp();
 
-       table = space->is_table;
-       tsize = space->is_table_size;
-
-       for (index = 0; index < tsize; index++) {
-               ipc_entry_t entry = &table[index];
+       ipc_entry_t entry;
+       struct rdxtree_iter iter;
+       rdxtree_for_each(&space->is_map, &iter, entry) {
                ipc_entry_bits_t bits = entry->ie_bits;
 
                if (IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE) {
-                       mach_port_t name = MACH_PORT_MAKEB(index, bits);
-
-                       mach_port_names_helper(timestamp, entry, name,
+                       mach_port_names_helper(timestamp, entry, entry->ie_name,
                                               names, types, &actual);
                }
        }
-
-       for (tentry = ipc_splay_traverse_start(&space->is_tree);
-            tentry != ITE_NULL;
-            tentry = ipc_splay_traverse_next(&space->is_tree, FALSE)) {
-               ipc_entry_t entry = &tentry->ite_entry;
-               mach_port_t name = tentry->ite_name;
-
-               assert(IE_BITS_TYPE(tentry->ite_bits) != MACH_PORT_TYPE_NONE);
-
-               mach_port_names_helper(timestamp, entry, name,
-                                      names, types, &actual);
-       }
-       ipc_splay_traverse_finish(&space->is_tree);
        is_read_unlock(space);
 
        if (actual == 0) {
@@ -946,10 +925,7 @@ mach_port_get_set_status(
        size = PAGE_SIZE;       /* initial guess */
 
        for (;;) {
-               ipc_tree_entry_t tentry;
-               ipc_entry_t entry, table;
-               ipc_entry_num_t tsize;
-               mach_port_index_t index;
+               ipc_entry_t entry;
                mach_port_t *names;
                ipc_pset_t pset;
 
@@ -986,11 +962,9 @@ mach_port_get_set_status(
                maxnames = size / sizeof(mach_port_t);
                actual = 0;
 
-               table = space->is_table;
-               tsize = space->is_table_size;
-
-               for (index = 0; index < tsize; index++) {
-                       ipc_entry_t ientry = &table[index];
+               ipc_entry_t ientry;
+               struct rdxtree_iter iter;
+               rdxtree_for_each(&space->is_map, &iter, ientry) {
                        ipc_entry_bits_t bits = ientry->ie_bits;
 
                        if (bits & MACH_PORT_TYPE_RECEIVE) {
@@ -1002,22 +976,6 @@ mach_port_get_set_status(
                        }
                }
 
-               for (tentry = ipc_splay_traverse_start(&space->is_tree);
-                    tentry != ITE_NULL;
-                    tentry = ipc_splay_traverse_next(&space->is_tree,FALSE)) {
-                       ipc_entry_bits_t bits = tentry->ite_bits;
-
-                       assert(IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE);
-
-                       if (bits & MACH_PORT_TYPE_RECEIVE) {
-                               ipc_port_t port =
-                                       (ipc_port_t) tentry->ite_object;
-
-                               mach_port_gst_helper(pset, port, maxnames,
-                                                    names, &actual);
-                       }
-               }
-               ipc_splay_traverse_finish(&space->is_tree);
                is_read_unlock(space);
 
                if (actual <= maxnames)
diff --git a/ipc/port.h b/ipc/port.h
index d359115..49af6e2 100644
--- a/ipc/port.h
+++ b/ipc/port.h
@@ -45,10 +45,7 @@
  *     mach_port_t must be an unsigned type.  Port values
  *     have two parts, a generation number and an index.
  *     These macros encapsulate all knowledge of how
- *     a mach_port_t is laid out.  However, ipc/ipc_entry.c
- *     implicitly assumes when it uses the splay tree functions
- *     that the generation number is in the low bits, so that
- *     names are ordered first by index and then by generation.
+ *     a mach_port_t is laid out.
  *
  *     If the size of generation numbers changes,
  *     be sure to update IE_BITS_GEN_MASK and friends
-- 
2.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]