commit 440843335085c732d7f8f1fca6f27f90ba76a20a
Author: Moshe Weitzman <weitzman@tejasa.com>
Date:   Thu Oct 24 16:31:24 2013 -0400

    Issue #2094241 by moshe weitzman: Cache tag the page cache.

diff --git a/core/includes/common.inc b/core/includes/common.inc
index 54d4212..b202103 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -3168,7 +3168,7 @@ function drupal_page_set_cache(Response $response, Request $request) {
         // because by the time it is read, the configuration might change.
         'page_compressed' => $page_compressed,
       ),
-      'tags' => array('content' => TRUE),
+      'tags' => array('content' => TRUE) + drupal_cache_tags_page_get(),
       'expire' => CacheBackendInterface::CACHE_PERMANENT,
       'created' => REQUEST_TIME,
     );
@@ -4205,6 +4205,35 @@ function drupal_render_collect_cache_tags($element, $tags = array()) {
   return $tags;
 }
 
+/*
+ * A #post_render callback at the top level of the $page array. Collects the
+ * tags for use in page cache.
+ *
+ * @param string $children
+ *   An HTML string of rendered output.
+ * @param array $elements
+ *   A render array.
+ * @return string
+ *   The same $children that was passed in - no modifications.
+ */
+function drupal_post_render_cache_tags_page_set($children = array(), array $elements) {
+  if (drupal_page_is_cacheable()) {
+    $tags = &drupal_static('system_cache_tags_page', FALSE);
+    $tags = drupal_render_collect_cache_tags($elements);
+  }
+  return $children;
+}
+
+/*
+ * Return the cache tags that were stored during drupal_render_page().
+ *
+ * @return array
+ *   The same $children that was passed in - no modifications.
+ */
+function drupal_cache_tags_page_get() {
+  return drupal_static('system_cache_tags_page', array());
+}
+
 /**
  * Prepares an element for caching based on a query.
  *
diff --git a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
index 42abf7c..653f740 100644
--- a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
+++ b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
@@ -273,6 +273,8 @@ public function flush($path = NULL) {
     if ($module_handler->moduleExists('block')) {
       \Drupal::cache('block')->deleteAll();
     }
+    // @todo Add [#cache][tags][image_style] => TRUE to renderables and
+    //   then invalidate by tag.
     \Drupal::cache('page')->deleteAll();
     return $this;
   }
diff --git a/core/modules/node/lib/Drupal/node/NodeRenderController.php b/core/modules/node/lib/Drupal/node/NodeRenderController.php
index 433adb3..62981e7 100644
--- a/core/modules/node/lib/Drupal/node/NodeRenderController.php
+++ b/core/modules/node/lib/Drupal/node/NodeRenderController.php
@@ -88,7 +88,7 @@ protected function alterBuild(array &$build, EntityInterface $entity, EntityDisp
 
     // The node 'submitted' info is not rendered in a standard way (renderable
     // array) so we have to add a cache tag manually.
-    $build['#cache']['tags']['user'][] = $entity->uid;
+    $build['#cache']['tags']['user'][] = $entity->uid->value;
   }
 
 }
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 80b02f8..5153c81 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -261,6 +261,7 @@ function system_element_info() {
     '#theme_wrappers' => array('form'),
   );
   $types['page'] = array(
+    '#post_render' => array('drupal_post_render_cache_tags_page_set'),
     '#show_messages' => TRUE,
     '#theme' => 'page',
     '#theme_wrappers' => array('html'),
