Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.245
diff -u -p -r1.245 bootstrap.inc
--- includes/bootstrap.inc	2 Nov 2008 10:56:35 -0000	1.245
+++ includes/bootstrap.inc	6 Nov 2008 04:28:46 -0000
@@ -207,6 +207,16 @@ define('CHECK_PLAIN', 0);
 define('PASS_THROUGH', -1);
 
 /**
+ * Signals that the registry lookup cache should be reset. 
+ */
+define('RESET_REGISTRY_LOOKUP_CACHE', 1);
+
+/**
+ * Signals that the registry lookup cache should be written to storage. 
+ */
+define('WRITE_REGISTRY_LOOKUP_CACHE', 2);
+
+/**
  * @} End of "Title text filtering flags".
  */
 
@@ -1415,7 +1425,6 @@ function drupal_function_exists($functio
   $checked[$function] = FALSE;
 
   if (function_exists($function)) {
-    registry_mark_code('function', $function);
     $checked[$function] = TRUE;
     return TRUE;
   }
@@ -1460,7 +1469,37 @@ function drupal_autoload_class($class) {
 /**
  * Helper to check for a resource in the registry.
  */
-function _registry_check_code($type, $name) {
+function _registry_check_code($type, $name = NULL) {
+  static $lookup_cache, $cache_update_needed;
+
+  if ($lookup_cache === NULL) {
+    $lookup_cache = array();
+    if ($cache = cache_get('lookup_cache', 'cache_registry')) {
+      $lookup_cache = $cache->data;
+    }
+  }
+  
+  // When we rebuild the registry, we need to reset this cache so that it
+  // only contains resources that we know haven't changed during the rebuild.
+  if ($type === RESET_REGISTRY_LOOKUP_CACHE) {
+    $cache_update_needed = TRUE;
+    $lookup_cache = $name;
+    return;
+  }
+
+  if ($type === WRITE_REGISTRY_LOOKUP_CACHE && $cache_update_needed) {
+    cache_set('lookup_cache', $lookup_cache, 'cache_registry');
+    return;
+  }
+  
+  $cache_key = $type{0} . $name;
+  if (isset($lookup_cache[$cache_key])) {
+    if ($lookup_cache[$cache_key]) {
+      require_once DRUPAL_ROOT . '/' . $lookup_cache[$cache_key];
+    }
+    return $lookup_cache[$cache_key];
+  }
+  
   // This function may get called when the default database is not active, but
   // there is no reason we'd ever want to not use the default database for
   // this query.
@@ -1469,38 +1508,20 @@ function _registry_check_code($type, $na
       ':type' => $type,
     ))
     ->fetchField();
+
+  // Flag that we've run a lookup query and need to update the cache.
+  $cache_update_needed = TRUE;
+
+  // Misses are valuable information worth caching, so cache even if
+  // $file is FALSE.
+  $lookup_cache[$cache_key] = $file;
+
   if ($file) {
     require_once DRUPAL_ROOT . '/' . $file;
-    registry_mark_code($type, $name);
     return TRUE;
   }
-  return FALSE;
-}
-
-/**
- * Collect the resources used for this request.
- *
- * @param $type
- *   The type of resource.
- * @param $name
- *   The name of the resource.
- * @param $return
- *   Boolean flag to indicate whether to return the resources.
- */
-function registry_mark_code($type, $name, $return = FALSE) {
-  static $resources = array();
-
-  if ($type && $name) {
-    if (!isset($resources[$type])) {
-      $resources[$type] = array();
-    }
-    if (!in_array($name, $resources[$type])) {
-      $resources[$type][] = $name;
-    }
-  }
-
-  if ($return) {
-    return $resources;
+  else {
+    return FALSE;
   }
 }
 
@@ -1516,62 +1537,5 @@ function registry_rebuild() {
 }
 
 /**
- * Save the files required by the registry for this path.
- */
-function registry_cache_path_files() {
-  if ($used_code = registry_mark_code(NULL, NULL, TRUE)) {
-    $files = array();
-    $type_sql = array();
-    $params = array();
-
-    // This function may get called when the default database is not active, but
-    // there is no reason we'd ever want to not use the default database for
-    // this query.
-    $select = Database::getConnection('default')->select('registry')->distinct();
-    $select->addField('registry', 'filename');
-
-    // This creates a series of 2-clause AND conditions that are then ORed together.
-    $ors = db_or();
-    foreach ($used_code as $type => $names) {
-      $and = db_and()
-        ->condition('name', $names, 'IN')
-        ->condition('type', $type);
-      $ors->condition($and);
-    }
-    $select->condition($ors);
-    $files = $select->execute()->fetchCol();
-
-    if ($files) {
-      sort($files);
-      // Only write this to cache if the file list we are going to cache
-      // is different to what we loaded earlier in the request.
-      if ($files != registry_load_path_files(TRUE)) {
-        $menu = menu_get_item();
-        cache_set('registry:' . $menu['path'], implode(';', $files), 'cache_registry');
-      }
-    }
-  }
-}
-
-/**
- * registry_load_path_files
- */
-function registry_load_path_files($return = FALSE) {
-  static $file_cache_data = array();
-  if ($return) {
-    sort($file_cache_data);
-    return $file_cache_data;
-  }
-  $menu = menu_get_item();
-  $cache = cache_get('registry:' . $menu['path'], 'cache_registry');
-  if (!empty($cache->data)) {
-    foreach(explode(';', $cache->data) as $file) {
-      require_once DRUPAL_ROOT . '/' . $file;
-      $file_cache_data[] = $file;
-    }
-  }
-}
-
-/**
  * @} End of "ingroup registry".
  */
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.816
diff -u -p -r1.816 common.inc
--- includes/common.inc	5 Nov 2008 17:06:18 -0000	1.816
+++ includes/common.inc	6 Nov 2008 04:28:47 -0000
@@ -1625,7 +1625,7 @@ function drupal_page_footer() {
   module_invoke_all('exit');
 
   module_implements(MODULE_IMPLEMENTS_WRITE_CACHE);
-  registry_cache_path_files();
+  _registry_check_code(WRITE_REGISTRY_LOOKUP_CACHE);
 }
 
 /**
Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.299
diff -u -p -r1.299 menu.inc
--- includes/menu.inc	31 Oct 2008 02:18:22 -0000	1.299
+++ includes/menu.inc	6 Nov 2008 04:28:48 -0000
@@ -393,7 +393,6 @@ function menu_execute_active_handler($pa
     menu_rebuild();
   }
   if ($router_item = menu_get_item($path)) {
-    registry_load_path_files();
     if ($router_item['access']) {
       if (drupal_function_exists($router_item['page_callback'])) {
         return call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
Index: includes/registry.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/registry.inc,v
retrieving revision 1.7
diff -u -p -r1.7 registry.inc
--- includes/registry.inc	31 Oct 2008 02:18:22 -0000	1.7
+++ includes/registry.inc	6 Nov 2008 04:28:48 -0000
@@ -69,10 +69,23 @@ function _registry_rebuild() {
         ->execute();
     }
   }
-  _registry_parse_files($files);
+  $parsed_files = _registry_parse_files($files);
 
+  $unchanged_resources = array();
+  if ($lookup_cache = cache_get('lookup_cache', 'cache_registry')) {
+    foreach ($lookup_cache->data as $key => $file) {
+      // If the file for this cached resource is carried over unchanged from 
+      // the last registry build, then we can safely re-cache it.
+      if ($file && in_array($file, array_keys($files)) && !in_array($file, $parsed_files)) {
+        $unchanged_resources[$key] = $file;
+      }
+    }
+  }
   module_implements(MODULE_IMPLEMENTS_CLEAR_CACHE);
   cache_clear_all('*', 'cache_registry', TRUE);
+  if (count($unchanged_resources) > 0) {
+    _registry_check_code(RESET_REGISTRY_LOOKUP_CACHE, $unchanged_resources);
+  }
 }
 
 /**
@@ -92,12 +105,13 @@ function registry_get_parsed_files() {
  *  The list of files to check and parse.
  */
 function _registry_parse_files($files) {
-  $changed_files = array();
+  $parsed_files = array();
   foreach ($files as $filename => $file) {
     $contents = file_get_contents($filename);
     $md5 = md5($contents);
     $new_file = !isset($file['md5']);
     if ($new_file || $md5 != $file['md5']) {
+      $parsed_files[] = $filename;
       // We update the md5 after we've saved the files resources rather than here, so if we
       // don't make it through this rebuild, the next run will reparse the file.
       _registry_parse_file($filename, $contents, $file['module'], $file['weight']);
@@ -108,6 +122,7 @@ function _registry_parse_files($files) {
         ->execute();
     }
   }
+  return $parsed_files;
 }
 
 /**
