diff --git a/core/lib/Drupal/Core/Cache/CacheBackendInterface.php b/core/lib/Drupal/Core/Cache/CacheBackendInterface.php
index faf2459..3bf9fb4 100644
--- a/core/lib/Drupal/Core/Cache/CacheBackendInterface.php
+++ b/core/lib/Drupal/Core/Cache/CacheBackendInterface.php
@@ -120,6 +120,7 @@ public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = array
    *     ),
    *   );
    *   @endcode
+   *   Backend implementations must keep the order of items.
    */
   public function setMultiple(array $items);
 
diff --git a/core/lib/Drupal/Core/PhpStorage/CacheStorage.php b/core/lib/Drupal/Core/PhpStorage/CacheStorage.php
new file mode 100644
index 0000000..872f9da
--- /dev/null
+++ b/core/lib/Drupal/Core/PhpStorage/CacheStorage.php
@@ -0,0 +1,199 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\PhpStorage\CacheStorage.
+ */
+
+namespace Drupal\Core\PhpStorage;
+
+use Drupal\Component\PhpStorage\PhpStorageInterface;
+use Drupal\Core\Cache\DatabaseBackend;
+use Drupal\Core\Cache\DatabaseCacheTagsChecksum;
+use Drupal\Core\Database\Database;
+use Drupal\Core\StreamWrapper\SpecialInMemoryStream;
+
+/**
+ * This class stores PHP classes in a cache storage keeping it opcacheable.
+ */
+class CacheStorage implements PhpStorageInterface {
+
+  /**
+   * The backend.
+   *
+   * @var \Drupal\Core\Cache\CacheBackendInterface
+   */
+  protected $cacheBackend;
+
+  /**
+   * The configuration array passed to the constructor.
+   *
+   * @var array $configuration
+   */
+  protected $configuration;
+
+  /**
+   * @param array $configuration
+   *   The configuration containing bin, secret and an optional callable
+   *   cache_backend_factory.
+   *
+   * @see \Drupal\Core\PhpStorage\PhpStorageFactory::get()
+   */
+  public function __construct(array $configuration) {
+    $this->configuration = $configuration;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function exists($name) {
+    $key = $this->getKeyFromFilename($name);
+    $cids = [$key, "$key:mtime"];
+    $this->cacheBackend()->getMultiple($cids);
+    return !$cids;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function load($name) {
+    $key = $this->getKeyFromFilename($name);
+    $cached = $this->cacheBackend()->get("$key:mtime");
+    if (!$cached) {
+      return FALSE;
+    }
+    // Load the data from cache.
+    // Hook in the fake phar wrapper. Opcode included in PHP 5.5 hardwires file
+    // and phar as the only two stream wrappers which can be opcode cached.
+    // The file protocol is used to read local files and will be triggered
+    // multiple times by the classloader as the container class is loaded.
+    // So for better performance use the phar protocol.
+    stream_wrapper_unregister('phar');
+    stream_wrapper_register('phar', 'Drupal\Core\StreamWrapper\SpecialInMemoryStream');
+    SpecialInMemoryStream::init($this, $cached->data);
+    $return = (include "phar://$name") !== FALSE;
+    #var_dump(opcache_get_status(TRUE)['scripts']["phar://$name"]);
+    // Restore the system wrapper.
+    stream_wrapper_restore('phar');
+    return $return;
+  }
+
+  /**
+   * @param $name
+   * @return bool|resource
+   */
+  public function open($name) {
+    $key = $this->getKeyFromFilename(substr($name, 7));
+    if (!$cached = $this->cacheBackend()->get($key)) {
+      return FALSE;
+    }
+    // Copy it into a file in memory.
+    if (!$handle = fopen('php://memory', 'rwb')) {
+      return FALSE;
+    }
+    if (fwrite($handle, $cached->data) === FALSE || fseek($handle, 0) === -1) {
+      fclose($handle);
+      return FALSE;
+    }
+    return $handle;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save($name, $code) {
+    $key = $this->getKeyFromFilename($name);
+    // We do not need a real mtime, we just need a timestamp that changes when
+    // the code changes.
+    $hash = hash('sha256', $code);
+    $mtime = hexdec(substr($hash, 0, 7));
+    $this->cacheBackend()->setMultiple([
+      $key => ['data' => $code],
+      "$key:mtime" => ['data' => $mtime],
+    ]);
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function writeable() {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function delete($name) {
+    $return = $this->exists($name);
+    $key = $this->getKeyFromFilename($name);
+    // Delete nonetheless because between exists and delete the entry might've
+    // been written.
+    $this->cacheBackend()->delete($key);
+    return $return;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteAll() {
+    $this->cacheBackend()->deleteAll();
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFullPath($name) {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function listAll() {
+    // Only PhpBackEnd::invalidateAll() uses this method and that's not
+    // compatible anyways since it relies on getFullPath().
+    throw new \BadMethodCallException('CacheStorage::listall() is not implemented.');
+  }
+
+  /**
+   * @return \Drupal\Core\Cache\CacheBackendInterface
+   */
+  protected function cacheBackend() {
+    if (!isset($this->cacheBackend)) {
+      if (isset($this->configuration['cache_backend_factory']) && is_callable($this->configuration['cache_backend_factory'])) {
+        $this->cacheBackend = call_user_func($this->configuration['cache_backend_factory'], $this->configuration);
+      }
+      else {
+        $this->cacheBackend = static::getDatabaseBackend($this->configuration);
+      }
+    }
+    return $this->cacheBackend;
+  }
+
+  /**
+   * Construct a database cache backend.
+   */
+  protected static function getDatabaseBackend($configuration) {
+    $connection = Database::getConnection();
+    return new DatabaseBackend($connection, new DatabaseCacheTagsChecksum($connection), 'php_' . $configuration['bin']);
+  }
+
+  /**
+   * Return a secret key based on the filename.
+   *
+   * By using a secret key, a SQL injection does not lead immediately to
+   * arbitrary PHP inclusion.
+   *
+   * @param string $filename
+   *   The filename.
+   *
+   * @return string
+   *   The secret hash.
+   */
+  protected function getKeyFromFilename($filename) {
+    return hash_hmac('sha256', $filename, $this->configuration['secret']);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/PhpStorage/PhpStorageFactory.php b/core/lib/Drupal/Core/PhpStorage/PhpStorageFactory.php
index 3386bba..5d8b4c5 100644
--- a/core/lib/Drupal/Core/PhpStorage/PhpStorageFactory.php
+++ b/core/lib/Drupal/Core/PhpStorage/PhpStorageFactory.php
@@ -48,6 +48,9 @@ static function get($name) {
       );
     }
     $class = isset($configuration['class']) ? $configuration['class'] : 'Drupal\Component\PhpStorage\MTimeProtectedFileStorage';
+    if ($name == 'service_container') {
+      $class = 'Drupal\Core\PhpStorage\CacheStorage';
+    }
     if (!isset($configuration['bin'])) {
       $configuration['bin'] = $name;
     }
diff --git a/core/lib/Drupal/Core/StreamWrapper/SpecialInMemoryStream.php b/core/lib/Drupal/Core/StreamWrapper/SpecialInMemoryStream.php
new file mode 100644
index 0000000..a69bc10
--- /dev/null
+++ b/core/lib/Drupal/Core/StreamWrapper/SpecialInMemoryStream.php
@@ -0,0 +1,164 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\StreamWrapper\SpecialInMemoryStream.
+ */
+
+namespace Drupal\Core\StreamWrapper;
+use Drupal\Core\PhpStorage\CacheStorage;
+
+/**
+ * The stream wrapper for \Drupal\Core\PhpStorage\CacheStorage .
+ *
+ * This class is not usable as a generic stream wrapper.
+ */
+class SpecialInMemoryStream {
+
+  /**
+   * @var \Drupal\Core\PhpStorage\CacheStorage
+   */
+  protected static $storage;
+
+  /**
+   * @var int
+   */
+  protected static $mtime;
+
+  /**
+   * Stream context resource.
+   *
+   * @var resource
+   */
+  public $context = NULL;
+
+  /**
+   * A generic resource handle.
+   *
+   * @var resource
+   */
+  protected static $handle = NULL;
+
+  /**
+   * Initialize the wrapper
+   *
+   * @param $storage
+   *   The corresponding \Drupal\Core\PhpStorage\CacheStorage instance. This
+   *   wil be used by stream_open().
+   * @param $mtime
+   *   The (fake) modified timestamp of the wrapped file.
+   */
+  public static function init(CacheStorage $storage, $mtime) {
+    static::$storage = $storage;
+    static::$mtime = $mtime;
+  }
+
+  public function dir_closedir() {
+    throw new \BadMethodCallException('Not implemented');
+  }
+
+  public function dir_opendir($path) {
+    throw new \BadMethodCallException('Not implemented');
+  }
+
+  public function dir_readdir() {
+    throw new \BadMethodCallException('Not implemented');
+  }
+
+  public function dir_rewinddir() {
+    throw new \BadMethodCallException('Not implemented');
+  }
+
+  public function mkdir() {
+    throw new \BadMethodCallException('Not implemented');
+  }
+
+  public function rename() {
+    throw new \BadMethodCallException('Not implemented');
+  }
+
+  public function rmdir() {
+    throw new \BadMethodCallException('Not implemented');
+  }
+
+  public function stream_cast() {
+    return static::$handle ? static::$handle : FALSE;
+  }
+
+  public function stream_close () {
+    return fclose(static::$handle);
+  }
+
+  public function stream_eof() {
+    return feof(static::$handle);
+  }
+
+  public function stream_flush() {
+    return fflush(static::$handle);
+  }
+
+  public function stream_lock($operation) {
+    return flock(static::$handle, $operation);
+  }
+
+  public function stream_metadata() {
+    throw new \BadMethodCallException('Not implemented');
+  }
+
+  public function stream_open($path) {
+    static::$handle = static::$storage->open($path);
+    return (bool) static::$handle;
+  }
+
+  public function stream_read($count) {
+    return fread(static::$handle, $count);
+  }
+
+  public function stream_seek($offset, $whence = SEEK_SET) {
+    return fseek(static::$handle, $offset, $whence);
+  }
+
+  public function stream_set_option() {
+    throw new \BadMethodCallException('Not implemented');
+  }
+
+  public function stream_stat() {
+    return fstat(static::$handle);
+  }
+
+  public function stream_tell() {
+    return ftell(static::$handle);
+  }
+
+  public function stream_truncate() {
+    throw new \BadMethodCallException('Not implemented');
+  }
+
+  public function stream_write() {
+    throw new \BadMethodCallException('Not implemented');
+  }
+
+  public function unlink() {
+    throw new \BadMethodCallException('Not implemented');
+  }
+
+  public function url_stat() {
+    $return = [
+      'dev' => 0,
+      'ino' => 0,
+      'mode' => 0,
+      'nlink' => 0,
+      'uid' => 0,
+      'gid' => 0,
+      'rdev' => 0,
+      'size' => 0,
+      'atime' => 0,
+      'mtime' => static::$mtime,
+      'ctime' => 0,
+      'blksize' => -1,
+      'blocks' => -1,
+    ];
+    return $return + array_values($return);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/PhpStorage/CacheStorageTest.php b/core/tests/Drupal/Tests/Core/PhpStorage/CacheStorageTest.php
new file mode 100644
index 0000000..da5a272
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/PhpStorage/CacheStorageTest.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\PhpStorage\CacheStorageTest.
+ */
+
+namespace Drupal\Tests\Core\PhpStorage;
+
+use Drupal\Core\Cache\MemoryBackend;
+use Drupal\Core\PhpStorage\CacheStorage;
+use Drupal\Core\Site\Settings;
+use Drupal\Tests\Component\PhpStorage\PhpStorageTestBase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\PhpStorage\CacheStorage
+ * @group Drupal
+ * @group PhpStorage
+ */
+class CacheStorageTest extends PhpStorageTestBase {
+
+  /**
+   * Tests basic load/save/delete operations.
+   *
+   * @covers ::load
+   * @covers ::save
+   * @covers ::exists
+   * @covers ::delete
+   */
+  public function testCRUD() {
+    $secret = $this->randomMachineName();
+    $storage = new CacheStorage([
+      'secret' => $secret,
+      'cache_backend_factory' => function (array $configuration) { return new MemoryBackend($configuration['bin']);},
+      'bin' => 'test'
+    ]);
+    $this->assertCRUD($storage);
+  }
+
+}
