Author: alc
Date: Wed Apr  3 06:37:25 2013
New Revision: 249038
URL: http://svnweb.freebsd.org/changeset/base/249038

Log:
  Replace the remaining uses of vm_radix_node_page() by vm_radix_isleaf() and
  vm_radix_topage().  This transformation eliminates some unnecessary
  conditional branches from the inner loops of vm_radix_insert(),
  vm_radix_lookup{,_ge,_le}(), and vm_radix_remove().
  
  Simplify the control flow of vm_radix_lookup_{ge,le}().
  
  Reviewed by:  attilio (an earlier version)
  Tested by:    pho
  Sponsored by: EMC / Isilon Storage Division

Modified:
  head/sys/vm/vm_radix.c

Modified: head/sys/vm/vm_radix.c
==============================================================================
--- head/sys/vm/vm_radix.c      Wed Apr  3 06:29:26 2013        (r249037)
+++ head/sys/vm/vm_radix.c      Wed Apr  3 06:37:25 2013        (r249038)
@@ -199,15 +199,13 @@ vm_radix_isleaf(struct vm_radix_node *rn
 }
 
 /*
- * Returns the associated page extracted from rnode if available,
- * and NULL otherwise.
+ * Returns the associated page extracted from rnode.
  */
 static __inline vm_page_t
-vm_radix_node_page(struct vm_radix_node *rnode)
+vm_radix_topage(struct vm_radix_node *rnode)
 {
 
-       return ((((uintptr_t)rnode & VM_RADIX_ISLEAF) != 0) ?
-           (vm_page_t)((uintptr_t)rnode & ~VM_RADIX_FLAGS) : NULL);
+       return ((vm_page_t)((uintptr_t)rnode & ~VM_RADIX_FLAGS));
 }
 
 /*
@@ -428,8 +426,8 @@ vm_radix_insert(struct vm_radix *rtree, 
        }
        do {
                slot = vm_radix_slot(index, rnode->rn_clev);
-               m = vm_radix_node_page(rnode->rn_child[slot]);
-               if (m != NULL) {
+               if (vm_radix_isleaf(rnode->rn_child[slot])) {
+                       m = vm_radix_topage(rnode->rn_child[slot]);
                        if (m->pindex == index)
                                panic("%s: key %jx is already present",
                                    __func__, (uintmax_t)index);
@@ -503,8 +501,8 @@ vm_radix_lookup(struct vm_radix *rtree, 
                        return (NULL);
                slot = vm_radix_slot(index, rnode->rn_clev);
                rnode = rnode->rn_child[slot];
-               m = vm_radix_node_page(rnode);
-               if (m != NULL) {
+               if (vm_radix_isleaf(rnode)) {
+                       m = vm_radix_topage(rnode);
                        if (m->pindex == index)
                                return (m);
                        else
@@ -522,7 +520,7 @@ vm_radix_lookup_ge(struct vm_radix *rtre
 {
        vm_pindex_t inc;
        vm_page_t m;
-       struct vm_radix_node *rnode;
+       struct vm_radix_node *child, *rnode;
        int slot;
        uint16_t difflev;
        boolean_t maplevels[VM_RADIX_LIMIT + 1];
@@ -560,13 +558,13 @@ restart:
                        goto restart;
                }
                slot = vm_radix_slot(index, rnode->rn_clev);
-               m = vm_radix_node_page(rnode->rn_child[slot]);
-               if (m != NULL && m->pindex >= index)
-                       return (m);
-               if (rnode->rn_child[slot] != NULL && m == NULL) {
-                       rnode = rnode->rn_child[slot];
-                       continue;
-               }
+               child = rnode->rn_child[slot];
+               if (vm_radix_isleaf(child)) {
+                       m = vm_radix_topage(child);
+                       if (m->pindex >= index)
+                               return (m);
+               } else if (child != NULL)
+                       goto descend;
 
                /*
                 * Look for an available edge or page within the current
@@ -575,30 +573,31 @@ restart:
                 if (slot < (VM_RADIX_COUNT - 1)) {
                        inc = VM_RADIX_UNITLEVEL(rnode->rn_clev);
                        index = vm_radix_trimkey(index, rnode->rn_clev);
-                       index += inc;
-                       slot++;
-                       for (;; index += inc, slot++) {
-                               m = vm_radix_node_page(rnode->rn_child[slot]);
-                               if (m != NULL && m->pindex >= index)
-                                       return (m);
-                               if ((rnode->rn_child[slot] != NULL &&
-                                   m == NULL) || slot == (VM_RADIX_COUNT - 1))
-                                       break;
-                       }
+                       do {
+                               index += inc;
+                               slot++;
+                               child = rnode->rn_child[slot];
+                               if (vm_radix_isleaf(child)) {
+                                       m = vm_radix_topage(child);
+                                       if (m->pindex >= index)
+                                               return (m);
+                               } else if (child != NULL)
+                                       goto descend;
+                       } while (slot < (VM_RADIX_COUNT - 1));
                }
+               KASSERT(child == NULL || vm_radix_isleaf(child),
+                   ("vm_radix_lookup_ge: child is radix node"));
 
                /*
                 * If a valid page or edge bigger than the search slot is
                 * found in the traversal, skip to the next higher-level key.
                 */
-               if (slot == (VM_RADIX_COUNT - 1) &&
-                   (rnode->rn_child[slot] == NULL || m != NULL)) {
-                       if (rnode->rn_clev == 0  || vm_radix_addlev(&index,
-                           maplevels, rnode->rn_clev - 1) > 0)
-                               break;
-                       goto restart;
-               }
-               rnode = rnode->rn_child[slot];
+               if (rnode->rn_clev == 0 || vm_radix_addlev(&index, maplevels,
+                   rnode->rn_clev - 1) > 0)
+                       break;
+               goto restart;
+descend:
+               rnode = child;
        }
        return (NULL);
 }
@@ -611,7 +610,7 @@ vm_radix_lookup_le(struct vm_radix *rtre
 {
        vm_pindex_t inc;
        vm_page_t m;
-       struct vm_radix_node *rnode;
+       struct vm_radix_node *child, *rnode;
        int slot;
        uint16_t difflev;
        boolean_t maplevels[VM_RADIX_LIMIT + 1];
@@ -649,13 +648,13 @@ restart:
                        goto restart;
                }
                slot = vm_radix_slot(index, rnode->rn_clev);
-               m = vm_radix_node_page(rnode->rn_child[slot]);
-               if (m != NULL && m->pindex <= index)
-                       return (m);
-               if (rnode->rn_child[slot] != NULL && m == NULL) {
-                       rnode = rnode->rn_child[slot];
-                       continue;
-               }
+               child = rnode->rn_child[slot];
+               if (vm_radix_isleaf(child)) {
+                       m = vm_radix_topage(child);
+                       if (m->pindex <= index)
+                               return (m);
+               } else if (child != NULL)
+                       goto descend;
 
                /*
                 * Look for an available edge or page within the current
@@ -665,29 +664,31 @@ restart:
                        inc = VM_RADIX_UNITLEVEL(rnode->rn_clev);
                        index = vm_radix_trimkey(index, rnode->rn_clev);
                        index |= inc - 1;
-                       index -= inc;
-                       slot--;
-                       for (;; index -= inc, slot--) {
-                               m = vm_radix_node_page(rnode->rn_child[slot]);
-                               if (m != NULL && m->pindex <= index)
-                                       return (m);
-                               if ((rnode->rn_child[slot] != NULL &&
-                                   m == NULL) || slot == 0)
-                                       break;
-                       }
+                       do {
+                               index -= inc;
+                               slot--;
+                               child = rnode->rn_child[slot];
+                               if (vm_radix_isleaf(child)) {
+                                       m = vm_radix_topage(child);
+                                       if (m->pindex <= index)
+                                               return (m);
+                               } else if (child != NULL)
+                                       goto descend;
+                       } while (slot > 0);
                }
+               KASSERT(child == NULL || vm_radix_isleaf(child),
+                   ("vm_radix_lookup_le: child is radix node"));
 
                /*
                 * If a valid page or edge smaller than the search slot is
                 * found in the traversal, skip to the next higher-level key.
                 */
-               if (slot == 0 && (rnode->rn_child[slot] == NULL || m != NULL)) {
-                       if (rnode->rn_clev == 0 || vm_radix_declev(&index,
-                           maplevels, rnode->rn_clev - 1) > 0)
-                               break;
-                       goto restart;
-               }
-               rnode = rnode->rn_child[slot];
+               if (rnode->rn_clev == 0 || vm_radix_declev(&index, maplevels,
+                   rnode->rn_clev - 1) > 0)
+                       break;
+               goto restart;
+descend:
+               rnode = child;
        }
        return (NULL);
 }
@@ -709,8 +710,10 @@ vm_radix_remove(struct vm_radix *rtree, 
                if (rnode == NULL)
                        panic("vm_radix_remove: impossible to locate the key");
                slot = vm_radix_slot(index, rnode->rn_clev);
-               m = vm_radix_node_page(rnode->rn_child[slot]);
-               if (m != NULL && m->pindex == index) {
+               if (vm_radix_isleaf(rnode->rn_child[slot])) {
+                       m = vm_radix_topage(rnode->rn_child[slot]);
+                       if (m->pindex != index)
+                               panic("%s: invalid key found", __func__);
                        rnode->rn_child[slot] = NULL;
                        rnode->rn_count--;
                        if (rnode->rn_count > 1)
@@ -736,8 +739,6 @@ vm_radix_remove(struct vm_radix *rtree, 
                        vm_radix_node_put(rnode);
                        break;
                }
-               if (m != NULL && m->pindex != index)
-                       panic("%s: invalid key found", __func__);
                parent = rnode;
                rnode = rnode->rn_child[slot];
        }
@@ -779,7 +780,8 @@ DB_SHOW_COMMAND(radixnode, db_show_radix
                if (rnode->rn_child[i] != NULL)
                        db_printf("slot: %d, val: %p, page: %p, clev: %d\n",
                            i, (void *)rnode->rn_child[i],
-                           (void *)vm_radix_node_page(rnode->rn_child[i]),
+                           vm_radix_isleaf(rnode->rn_child[i]) ?
+                           vm_radix_topage(rnode->rn_child[i]) : NULL,
                            rnode->rn_clev);
 }
 #endif /* DDB */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to