DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (2f44d750d784)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef nsXULPrototypeCache_h__
#define nsXULPrototypeCache_h__

#include "nsCOMPtr.h"
#include "nsIObserver.h"
#include "nsXBLDocumentInfo.h"
#include "nsJSThingHashtable.h"
#include "nsInterfaceHashtable.h"
#include "nsRefPtrHashtable.h"
#include "nsURIHashKey.h"
#include "nsXULPrototypeDocument.h"
#include "nsIInputStream.h"
#include "nsIStorageStream.h"

#include "mozilla/scache/StartupCache.h"

class nsIHandleReportCallback;
namespace mozilla {
class StyleSheet;
}  // namespace mozilla

/**
 * The XUL prototype cache can be used to store and retrieve shared data for
 * XUL documents, style sheets, XBL, and scripts.
 *
 * The cache has two levels:
 *  1. In-memory hashtables
 *  2. The on-disk cache file.
 */
class nsXULPrototypeCache : public nsIObserver {
 public:
  // nsISupports
  NS_DECL_THREADSAFE_ISUPPORTS
  NS_DECL_NSIOBSERVER

  bool IsCached(nsIURI* aURI) { return GetPrototype(aURI) != nullptr; }
  void AbortCaching();

  /**
   * Whether the prototype cache is enabled.
   */
  bool IsEnabled();

  /**
   * Flush the cache; remove all XUL prototype documents, style
   * sheets, and scripts.
   */
  void Flush();

  // The following methods are used to put and retrive various items into and
  // from the cache.

  nsXULPrototypeDocument* GetPrototype(nsIURI* aURI);
  nsresult PutPrototype(nsXULPrototypeDocument* aDocument);

  JSScript* GetScript(nsIURI* aURI);
  nsresult PutScript(nsIURI* aURI, JS::Handle<JSScript*> aScriptObject);

  nsXBLDocumentInfo* GetXBLDocumentInfo(nsIURI* aURL);

  nsresult PutXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo);

  /**
   * Get a style sheet by URI. If the style sheet is not in the cache,
   * returns nullptr.
   */
  mozilla::StyleSheet* GetStyleSheet(nsIURI* aURI);

  /**
   * Store a style sheet in the cache. The key, style sheet's URI is obtained
   * from the style sheet itself.
   */
  nsresult PutStyleSheet(mozilla::StyleSheet* aStyleSheet);

  /**
   * Write the XUL prototype document to a cache file. The proto must be
   * fully loaded.
   */
  nsresult WritePrototype(nsXULPrototypeDocument* aPrototypeDocument);

  /**
   * This interface allows partial reads and writes from the buffers in the
   * startupCache.
   */
  nsresult GetInputStream(nsIURI* aURI, nsIObjectInputStream** objectInput);
  nsresult FinishInputStream(nsIURI* aURI);
  nsresult GetOutputStream(nsIURI* aURI, nsIObjectOutputStream** objectOutput);
  nsresult FinishOutputStream(nsIURI* aURI);
  nsresult HasData(nsIURI* aURI, bool* exists);

  static nsXULPrototypeCache* GetInstance();
  static nsXULPrototypeCache* MaybeGetInstance() { return sInstance; }

  static void ReleaseGlobals() { NS_IF_RELEASE(sInstance); }

  void MarkInCCGeneration(uint32_t aGeneration);
  void MarkInGC(JSTracer* aTrc);
  void FlushScripts();

  static void CollectMemoryReports(nsIHandleReportCallback* aHandleReport,
                                   nsISupports* aData);

 protected:
  friend nsresult NS_NewXULPrototypeCache(nsISupports* aOuter, REFNSIID aIID,
                                          void** aResult);

  nsXULPrototypeCache();
  virtual ~nsXULPrototypeCache();

  static nsXULPrototypeCache* sInstance;

  using StyleSheetTable = nsRefPtrHashtable<nsURIHashKey, mozilla::StyleSheet>;
  using XBLDocTable = nsRefPtrHashtable<nsURIHashKey, nsXBLDocumentInfo>;

  nsRefPtrHashtable<nsURIHashKey, nsXULPrototypeDocument>
      mPrototypeTable;  // owns the prototypes
  StyleSheetTable mStyleSheetTable;
  nsJSThingHashtable<nsURIHashKey, JSScript*> mScriptTable;
  XBLDocTable mXBLDocTable;

  // URIs already written to the startup cache, to prevent double-caching.
  nsTHashtable<nsURIHashKey> mStartupCacheURITable;

  nsInterfaceHashtable<nsURIHashKey, nsIStorageStream> mOutputStreamTable;
  nsInterfaceHashtable<nsURIHashKey, nsIObjectInputStream> mInputStreamTable;

  // Bootstrap caching service
  nsresult BeginCaching(nsIURI* aDocumentURI);
};

#endif  // nsXULPrototypeCache_h__