Skip to content

Commit ec18757

Browse files
committed
Bug 1482782 - Part 7: Expand out nsStaticAtom.h macros now that we only static atom table. r=njn
Summary: Depends On D3285 Reviewers: njn! Tags: #secure-revision Bug #: 1482782 Differential Revision: https://phabricator.services.mozilla.com/D3286
1 parent e816227 commit ec18757

File tree

10 files changed

+229
-273
lines changed

10 files changed

+229
-273
lines changed

layout/style/ComputedStyle.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
#include <algorithm>
1414
#include "mozilla/ArenaObjectID.h"
1515
#include "mozilla/Assertions.h"
16+
#include "mozilla/CachedInheritingStyles.h"
17+
#include "mozilla/Maybe.h"
1618
#include "mozilla/ServoComputedData.h"
1719
#include "mozilla/ServoTypes.h"
1820
#include "mozilla/ServoUtils.h"
1921
#include "mozilla/StyleComplexColor.h"
20-
#include "mozilla/CachedInheritingStyles.h"
2122
#include "nsCSSAnonBoxes.h"
2223
#include "nsCSSPseudoElements.h"
2324

layout/style/nsCSSAnonBoxes.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "nsCSSAnonBoxes.h"
1212
#include "nsGkAtomConsts.h"
13+
#include "nsStaticAtomUtils.h"
1314

1415
using namespace mozilla;
1516

layout/style/nsCSSPseudoElements.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "nsCSSAnonBoxes.h"
1414
#include "nsDOMString.h"
1515
#include "nsGkAtomConsts.h"
16+
#include "nsStaticAtomUtils.h"
1617

1718
using namespace mozilla;
1819

xpcom/ds/moz.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ EXPORTS += [
6464
'nsPointerHashKeys.h',
6565
'nsQuickSort.h',
6666
'nsRefPtrHashtable.h',
67-
'nsStaticAtom.h',
67+
'nsStaticAtomUtils.h',
6868
'nsStaticNameTable.h',
6969
'nsStringEnumerator.h',
7070
'nsSupportsPrimitives.h',

xpcom/ds/nsAtom.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class nsStaticAtom : public nsAtom
155155

156156
private:
157157
// This is an offset to the string chars, which must be at a lower address in
158-
// memory. This should be achieved by using the macros in nsStaticAtom.h.
158+
// memory.
159159
uint32_t mStringOffset;
160160
};
161161

xpcom/ds/nsAtomTable.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "nsGkAtoms.h"
2222
#include "nsHashKeys.h"
2323
#include "nsPrintfCString.h"
24-
#include "nsStaticAtom.h"
2524
#include "nsString.h"
2625
#include "nsThreadUtils.h"
2726
#include "nsUnicharUtils.h"

xpcom/ds/nsGkAtoms.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,32 @@
66

77
#include "nsGkAtoms.h"
88

9+
// Register an array of static atoms with the atom table.
10+
void
11+
NS_RegisterStaticAtoms(const nsStaticAtom* aAtoms, size_t aAtomsLen);
12+
913
namespace mozilla {
1014
namespace detail {
1115

1216
MOZ_PUSH_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING
1317
extern constexpr GkAtoms gGkAtoms = {
14-
#define GK_ATOM(name_, value_, type_, atom_type_) NS_STATIC_ATOM_INIT_STRING(value_)
18+
// The initialization of each atom's string.
19+
#define GK_ATOM(name_, value_, type_, atom_type_) \
20+
u"" value_,
1521
#include "nsGkAtomList.h"
1622
#undef GK_ATOM
1723
{
18-
#define GK_ATOM(name_, value_, type_, atom_type_) \
19-
NS_STATIC_ATOM_INIT_ATOM(nsStaticAtom, GkAtoms, name_, value_)
24+
// The initialization of the atoms themselves.
25+
//
26+
// Note that |value_| is an 8-bit string, and so |sizeof(value_)| is equal
27+
// to the number of chars (including the terminating '\0'). The |u""| prefix
28+
// converts |value_| to a 16-bit string.
29+
#define GK_ATOM(name_, value_, type_, atom_type_) \
30+
nsStaticAtom(u"" value_, \
31+
sizeof(value_) - 1, \
32+
offsetof(GkAtoms, \
33+
mAtoms[static_cast<size_t>(GkAtoms::Atoms::name_)]) - \
34+
offsetof(GkAtoms, name_##_string)),
2035
#include "nsGkAtomList.h"
2136
#undef GK_ATOM
2237
}
@@ -28,10 +43,11 @@ MOZ_POP_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING
2843

2944
const nsStaticAtom* const nsGkAtoms::sAtoms = mozilla::detail::gGkAtoms.mAtoms;
3045

31-
#define GK_ATOM(name_, value_, type_, atom_type_) \
32-
NS_STATIC_ATOM_DEFN_PTR( \
33-
type_, mozilla::detail::GkAtoms, mozilla::detail::gGkAtoms, \
34-
nsGkAtoms, name_)
46+
// Definition of the pointer to the static atom.
47+
#define GK_ATOM(name_, value_, type_, atom_type_) \
48+
type_* nsGkAtoms::name_ = const_cast<type_*>(static_cast<const type_*>( \
49+
&mozilla::detail::gGkAtoms.mAtoms[ \
50+
static_cast<size_t>(mozilla::detail::GkAtoms::Atoms::name_)]));
3551
#include "nsGkAtomList.h"
3652
#undef GK_ATOM
3753

xpcom/ds/nsGkAtoms.h

Lines changed: 163 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,151 @@
88
#define nsGkAtoms_h___
99

1010
#include "nsAtom.h"
11-
#include "nsStaticAtom.h"
11+
12+
// Static atoms are structured carefully to satisfy a lot of constraints.
13+
//
14+
// - We have ~2300 static atoms.
15+
//
16+
// - We want them to be constexpr so they end up in .rodata, and thus shared
17+
// between processes, minimizing memory usage.
18+
//
19+
// - We need them to be in an array, so we can iterate over them (for
20+
// registration and lookups).
21+
//
22+
// - Each static atom has a string literal associated with it. We can't use a
23+
// pointer to the string literal because then the atoms won't end up in
24+
// .rodata. Therefore the string literals and the atoms must be arranged in a
25+
// way such that a numeric index can be used instead. This numeric index
26+
// (nsStaticAtom::mStringOffset) must be computable at compile-time to keep
27+
// the static atom constexpr. It should also not be too large (a uint32_t is
28+
// reasonable).
29+
//
30+
// - Each static atom stores the hash value of its associated string literal;
31+
// it's used in various ways. The hash value must be computed at
32+
// compile-time, to keep the static atom constexpr.
33+
//
34+
// - As well as accessing each static atom via array indexing, we need an
35+
// individual pointer, e.g. nsGkAtoms::foo. Ideally this would be constexpr
36+
// so it doesn't take up any space in memory. Unfortunately MSVC's constexpr
37+
// support is buggy and so this isn't possible yet. See bug 1449787.
38+
//
39+
// - The array of static atoms can't be in a .h file, because it's a huge
40+
// constexpr expression, which would blow out compile times. But the
41+
// individual pointers for the static atoms must be in a .h file so they are
42+
// public.
43+
//
44+
// nsGkAtoms below defines static atoms in a way that satisfies these
45+
// constraints. It uses nsGkAtomList.h, which defines the names and values of
46+
// the atoms.
47+
//
48+
// nsGkAtomList.h is generated by StaticAtoms.py and has entries that look
49+
// like this:
50+
//
51+
// GK_ATOM(one, "one", nsStaticAtom, Atom)
52+
// GK_ATOM(two, "two", nsICSSPseudoElement, PseudoElementAtom)
53+
// GK_ATOM(three, "three", nsICSSAnonBoxPseudo, InheritingAnonBoxAtom)
54+
//
55+
// After macro expansion, the atom definitions look like the following:
56+
//
57+
// ====> nsGkAtoms.h <====
58+
//
59+
// namespace mozilla {
60+
// namespace detail {
61+
//
62+
// struct GkAtoms
63+
// {
64+
// // The declaration of each atom's string.
65+
// const char16_t one_string[sizeof("one")];
66+
// const char16_t two_string[sizeof("two")];
67+
// const char16_t three_string[sizeof("three")];
68+
//
69+
// // The enum value for each atom.
70+
// enum class Atoms {
71+
// one_,
72+
// two_,
73+
// three_,
74+
// AtomsCount
75+
// };
76+
//
77+
// const nsStaticAtom mAtoms[static_cast<size_t>(Atoms::AtomsCount)];
78+
// };
79+
//
80+
// } // namespace detail
81+
// } // namespace mozilla
82+
//
83+
// // This class holds the pointers to the individual atoms.
84+
// class nsGkAtoms
85+
// {
86+
// private:
87+
// // This is a useful handle to the array of atoms, used below and also
88+
// // possibly by Rust code.
89+
// static const nsStaticAtom* const sAtoms;
90+
//
91+
// // The number of atoms, used below.
92+
// static constexpr size_t sAtomsLen =
93+
// static_cast<size_t>(detail::MyAtoms::Atoms::AtomsCount);
94+
//
95+
// public:
96+
// // These types are not `nsStaticAtom* const`, etc. -- even though these
97+
// // atoms are immutable -- because they are often passed to functions with
98+
// // `nsAtom*` parameters, i.e. that can be passed both dynamic and
99+
// // static.
100+
// static nsStaticAtom* one;
101+
// static nsICSSPseudoElement* two;
102+
// static nsICSSAnonBoxPseudo* three;
103+
// };
104+
//
105+
// ====> nsGkAtoms.cpp <====
106+
//
107+
// namespace mozilla {
108+
// namespace detail {
109+
//
110+
// // Need to suppress some MSVC warning weirdness with WrappingMultiply().
111+
// MOZ_PUSH_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING
112+
// // Because this is `constexpr` it ends up in read-only memory where it can
113+
// // be shared between processes.
114+
// static constexpr GkAtoms gGkAtoms = {
115+
// // The initialization of each atom's string.
116+
// u"one",
117+
// u"two",
118+
// u"three",
119+
// {
120+
// // The initialization of the atoms themselves.
121+
// nsStaticAtom(
122+
// u"one", 3,
123+
// offsetof(GkAtoms, mAtoms[static_cast<size_t>(GkAtoms::Atoms::one)]) -
124+
// offsetof(GkAtoms, one_string)),
125+
// nsStaticAtom(
126+
// u"two", 3,
127+
// offsetof(GkAtoms, mAtoms[static_cast<size_t>(GkAtoms::Atoms::two)]) -
128+
// offsetof(GkAtoms, two_string)),
129+
// nsStaticAtom(
130+
// u"three", 3,
131+
// offsetof(GkAtoms, mAtoms[static_cast<size_t>(GkAtoms::Atoms::three)]) -
132+
// offsetof(GkAtoms, three_string)),
133+
// }
134+
// };
135+
// MOZ_POP_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING
136+
//
137+
// } // namespace detail
138+
// } // namespace mozilla
139+
//
140+
// const nsStaticAtom* const nsGkAtoms::sAtoms =
141+
// mozilla::detail::gGkAtoms.mAtoms;
142+
//
143+
// // Definition of the pointer to the static atom.
144+
// nsStaticAtom* nsGkAtoms::one =
145+
// const_cast<nsStaticAtom*>(static_cast<const nsStaticAtom*>(
146+
// &detail::gGkAtoms.mAtoms[
147+
// static_cast<size_t>(detail::GkAtoms::Atoms::one)]);
148+
// nsICSSPseudoElement* nsGkAtoms::two =
149+
// const_cast<nsICSSPseudoElement*>(static_cast<const nsICSSPseudoElement*>(
150+
// &detail::gGkAtoms.mAtoms[
151+
// static_cast<size_t>(detail::GkAtoms::Atoms::two)]);
152+
// nsICSSAnonBoxPseudo* nsGkAtoms::three =
153+
// const_cast<nsICSSAnonBoxPseudo*>(static_cast<const nsICSSAnonBoxPseudo*>(
154+
// &detail::gGkAtoms.mAtoms[
155+
// static_cast<size_t>(detail::GkAtoms::Atoms::three)]);
12156

13157
// Trivial subclasses of nsStaticAtom so that function signatures can require
14158
// an atom from a specific atom list.
@@ -28,14 +172,24 @@ DEFINE_STATIC_ATOM_SUBCLASS(nsICSSPseudoElement)
28172
namespace mozilla {
29173
namespace detail {
30174

175+
// This `detail` class contains the atom strings and the atom objects.
176+
// Because they are together in a class, the mStringOffset field of the
177+
// atoms will be small and can be initialized at compile time.
178+
//
179+
// A `detail` namespace is used because the things within it aren't directly
180+
// referenced by external users of these static atoms.
31181
struct GkAtoms
32182
{
33-
#define GK_ATOM(name_, value_, type_, atom_type_) NS_STATIC_ATOM_DECL_STRING(name_, value_)
183+
// The declaration of each atom's string.
184+
#define GK_ATOM(name_, value_, type_, atom_type_) \
185+
const char16_t name_##_string[sizeof(value_)];
34186
#include "nsGkAtomList.h"
35187
#undef GK_ATOM
36188

189+
// The enum value for each atom.
37190
enum class Atoms {
38-
#define GK_ATOM(name_, value_, type_, atom_type_) NS_STATIC_ATOM_ENUM(name_)
191+
#define GK_ATOM(name_, value_, type_, atom_type_) \
192+
name_,
39193
#include "nsGkAtomList.h"
40194
#undef GK_ATOM
41195
AtomsCount
@@ -63,7 +217,12 @@ class nsGkAtoms
63217
return const_cast<nsStaticAtom*>(&sAtoms[aIndex]);
64218
}
65219

66-
#define GK_ATOM(name_, value_, type_, atom_type_) NS_STATIC_ATOM_DECL_PTR(type_, name_)
220+
// The declaration of the pointer to each static atom.
221+
//
222+
// XXX: Eventually this should be combined with its definition and the
223+
// pointer should be made `constexpr`. See bug 1449787.
224+
#define GK_ATOM(name_, value_, type_, atom_type_) \
225+
static type_* name_;
67226
#include "nsGkAtomList.h"
68227
#undef GK_ATOM
69228
};

0 commit comments

Comments
 (0)