Source code

Revision control

Copy as Markdown

Other Tools

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 nsGkAtoms_h___
#define nsGkAtoms_h___
#include "nsAtom.h"
// Static atoms are structured carefully to satisfy a lot of constraints.
//
// - We have ~2300 static atoms.
//
// - We want them to be constexpr so they end up in .rodata, and thus shared
// between processes, minimizing memory usage.
//
// - We need them to be in an array, so we can iterate over them (for
// registration and lookups).
//
// - Each static atom has a string literal associated with it. We can't use a
// pointer to the string literal because then the atoms won't end up in
// .rodata. Therefore the string literals and the atoms must be arranged in a
// way such that a numeric index can be used instead. This numeric index
// (nsStaticAtom::mStringOffset) must be computable at compile-time to keep
// the static atom constexpr. It should also not be too large (a uint32_t is
// reasonable).
//
// - Each static atom stores the hash value of its associated string literal;
// it's used in various ways. The hash value must be specified at
// compile-time, to keep the static atom constexpr.
//
// - As well as accessing each static atom via array indexing, we need an
// individual pointer, e.g. nsGkAtoms::foo. We want this to be constexpr so
// it doesn't take up any space in memory.
//
// - The array of static atoms can't be in a .h file, because it's a huge
// constexpr expression, which would blow out compile times. But the
// individual pointers for the static atoms must be in a .h file so they are
// public.
//
// nsGkAtoms below defines static atoms in a way that satisfies these
// constraints. It uses nsGkAtomList.h, which defines the names and values of
// the atoms. nsGkAtomList.h is generated by StaticAtoms.py and has entries
// that look like this:
//
// GK_ATOM(a, "a", 0x01234567, nsStaticAtom, Atom)
// GK_ATOM(bb, "bb", 0x12345678, nsCSSPseudoElementStaticAtom,
// PseudoElementAtom)
// GK_ATOM(Ccc, "Ccc", 0x23456789, nsCSSAnonBoxPseudoStaticAtom,
// InheritingAnonBoxAtom)
//
// Comments throughout this file and nsGkAtoms.cpp show how these entries get
// expanded by macros.
// Trivial subclasses of nsStaticAtom so that function signatures can require
// an atom from a specific atom list.
#define DEFINE_STATIC_ATOM_SUBCLASS(name_) \
class name_ : public nsStaticAtom { \
public: \
constexpr name_(uint32_t aLength, uint32_t aHash, uint32_t aOffset, \
bool aIsAsciiLowercase) \
: nsStaticAtom(aLength, aHash, aOffset, aIsAsciiLowercase) {} \
};
DEFINE_STATIC_ATOM_SUBCLASS(nsCSSAnonBoxPseudoStaticAtom)
DEFINE_STATIC_ATOM_SUBCLASS(nsCSSPseudoElementStaticAtom)
#undef DEFINE_STATIC_ATOM_SUBCLASS