gecko-dev/dom/base/nsNodeInfoManager.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

181 строка
5.7 KiB
C
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
2012-05-21 15:12:37 +04:00
/* 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/. */
/*
* A class for handing out nodeinfos and ensuring sharing of them as needed.
*/
#ifndef nsNodeInfoManager_h___
#define nsNodeInfoManager_h___
#include "mozilla/Attributes.h" // for final
#include "mozilla/dom/NodeInfo.h"
#include "mozilla/dom/DOMArena.h"
#include "mozilla/MruCache.h"
#include "nsCOMPtr.h" // for member
#include "nsCycleCollectionParticipant.h" // for NS_DECL_CYCLE_*
#include "nsDataHashtable.h"
#include "nsStringFwd.h"
class nsAtom;
class nsIPrincipal;
class nsWindowSizes;
template <class T>
struct already_AddRefed;
namespace mozilla {
namespace dom {
class Document;
} // namespace dom
} // namespace mozilla
class nsNodeInfoManager final {
private:
~nsNodeInfoManager();
public:
nsNodeInfoManager();
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_NATIVE_CLASS(nsNodeInfoManager)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsNodeInfoManager)
/**
* Initialize the nodeinfo manager with a document.
*/
nsresult Init(mozilla::dom::Document*);
/**
* Release the reference to the document, this will be called when
* the document is going away.
*/
void DropDocumentReference();
/**
* Methods for creating nodeinfo's from atoms and/or strings.
*/
already_AddRefed<mozilla::dom::NodeInfo> GetNodeInfo(
nsAtom* aName, nsAtom* aPrefix, int32_t aNamespaceID, uint16_t aNodeType,
nsAtom* aExtraName = nullptr);
nsresult GetNodeInfo(const nsAString& aName, nsAtom* aPrefix,
int32_t aNamespaceID, uint16_t aNodeType,
mozilla::dom::NodeInfo** aNodeInfo);
nsresult GetNodeInfo(const nsAString& aName, nsAtom* aPrefix,
const nsAString& aNamespaceURI, uint16_t aNodeType,
mozilla::dom::NodeInfo** aNodeInfo);
/**
* Returns the nodeinfo for text nodes. Can return null if OOM.
*/
already_AddRefed<mozilla::dom::NodeInfo> GetTextNodeInfo();
/**
* Returns the nodeinfo for comment nodes. Can return null if OOM.
*/
already_AddRefed<mozilla::dom::NodeInfo> GetCommentNodeInfo();
/**
* Returns the nodeinfo for the document node. Can return null if OOM.
*/
already_AddRefed<mozilla::dom::NodeInfo> GetDocumentNodeInfo();
/**
* Retrieve a pointer to the document that owns this node info
* manager.
*/
mozilla::dom::Document* GetDocument() const { return mDocument; }
/**
* Gets the principal of the document this nodeinfo manager belongs to.
*/
nsIPrincipal* DocumentPrincipal() const {
NS_ASSERTION(mPrincipal, "How'd that happen?");
return mPrincipal;
}
void RemoveNodeInfo(mozilla::dom::NodeInfo* aNodeInfo);
/**
* Returns true if SVG nodes in this document have real SVG semantics.
*/
bool SVGEnabled() { return mSVGEnabled.valueOr(InternalSVGEnabled()); }
/**
* Returns true if MathML nodes in this document have real MathML semantics.
*/
bool MathMLEnabled() {
return mMathMLEnabled.valueOr(InternalMathMLEnabled());
}
mozilla::dom::DOMArena* GetArenaAllocator() { return mArena; }
void SetArenaAllocator(mozilla::dom::DOMArena* aArena);
void* Allocate(size_t aSize);
void Free(void* aPtr) { free(aPtr); }
bool HasAllocated() { return mHasAllocated; }
void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const;
protected:
friend class mozilla::dom::Document;
friend class nsXULPrototypeDocument;
/**
* Sets the principal of the document this nodeinfo manager belongs to.
*/
void SetDocumentPrincipal(nsIPrincipal* aPrincipal);
private:
bool InternalSVGEnabled();
bool InternalMathMLEnabled();
class NodeInfoInnerKey
: public nsPtrHashKey<mozilla::dom::NodeInfo::NodeInfoInner> {
public:
explicit NodeInfoInnerKey(KeyTypePointer aKey) : nsPtrHashKey(aKey) {}
Bug 1415980 - make hash keys movable and not copyable; r=erahm Everything that goes in a PLDHashtable (and its derivatives, like nsTHashtable) needs to inherit from PLDHashEntryHdr. But through a lack of enforcement, copy constructors for these derived classes didn't explicitly invoke the copy constructor for PLDHashEntryHdr (and the compiler didn't invoke the copy constructor for us). Instead, PLDHashTable explicitly copied around the bits that the copy constructor would have. The current setup has two problems: 1) Derived classes should be using move construction, not copy construction, since anything that's shuffling hash table keys/entries around will be using move construction. 2) Derived classes should take responsibility for transferring bits of superclass state around, and not rely on something else to handle that. The second point is not a huge problem for PLDHashTable (PLDHashTable only has to copy PLDHashEntryHdr's bits in a single place), but future hash table implementations that might move entries around more aggressively would have to insert compensation code all over the place. Additionally, if moving entries is implemented via memcpy (which is quite common), PLDHashTable copying around bits *again* is inefficient. Let's fix all these problems in one go, by: 1) Explicitly declaring the set of constructors that PLDHashEntryHdr implements (and does not implement). In particular, the copy constructor is deleted, so any derived classes that attempt to make themselves copyable will be detected at compile time: the compiler will complain that the superclass type is not copyable. This change on its own will result in many compiler errors, so... 2) Change any derived classes to implement move constructors instead of copy constructors. Note that some of these move constructors are, strictly speaking, unnecessary, since the relevant classes are moved via memcpy in nsTHashtable and its derivatives.
2018-09-20 18:20:36 +03:00
NodeInfoInnerKey(NodeInfoInnerKey&&) = default;
~NodeInfoInnerKey() = default;
bool KeyEquals(KeyTypePointer aKey) const { return *mKey == *aKey; }
static PLDHashNumber HashKey(KeyTypePointer aKey) { return aKey->Hash(); }
};
struct NodeInfoCache
: public mozilla::MruCache<mozilla::dom::NodeInfo::NodeInfoInner,
mozilla::dom::NodeInfo*, NodeInfoCache> {
static mozilla::HashNumber Hash(
const mozilla::dom::NodeInfo::NodeInfoInner& aKey) {
return aKey.Hash();
}
static bool Match(const mozilla::dom::NodeInfo::NodeInfoInner& aKey,
const mozilla::dom::NodeInfo* aVal) {
return aKey == aVal->mInner;
}
};
nsDataHashtable<NodeInfoInnerKey, mozilla::dom::NodeInfo*> mNodeInfoHash;
mozilla::dom::Document* MOZ_NON_OWNING_REF mDocument; // WEAK
uint32_t mNonDocumentNodeInfos;
nsCOMPtr<nsIPrincipal> mPrincipal; // Never null after Init() succeeds.
nsCOMPtr<nsIPrincipal> mDefaultPrincipal; // Never null after Init() succeeds
mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF
mTextNodeInfo; // WEAK to avoid circular ownership
mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF
mCommentNodeInfo; // WEAK to avoid circular ownership
mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF
mDocumentNodeInfo; // WEAK to avoid circular ownership
NodeInfoCache mRecentlyUsedNodeInfos;
mozilla::Maybe<bool> mSVGEnabled; // Lazily initialized.
mozilla::Maybe<bool> mMathMLEnabled; // Lazily initialized.
// For dom_arena_allocator_enabled
RefPtr<mozilla::dom::DOMArena> mArena;
bool mHasAllocated = false;
};
#endif /* nsNodeInfoManager_h___ */