blob: 2eb51b647bda0c5fb28a9c2b0c4ca97404ec4ea4 [file] [log] [blame]
// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_MEMORY_INDEX_POINTER_H_
#define BASE_MEMORY_INDEX_POINTER_H_
namespace base::subtle {
// An IndexPointer stores a pointer in the form of an index from a base object.
// This is intended only for use in generated code for now.
//
// See StringSlice for a similar type that is specifically for strings
// represented as slices (which needs a few more bytes than a C-style string but
// could be faster to access in some contexts).
//
// This should only be used for pointers which are:
//
// - constant
// - stored in statically-allocated objects
// - accessed rarely
//
// Storing pointers in this form avoids relocations, which saves disk space and
// allows storing data structures containing them in .rodata (which is truly a
// straight read-only mapping of clean file pages that the OS can discard
// anytime) instead of in .data.rel.ro (which has copy-on-write contents because
// the runtime linker writes into it).
//
// This is inspired by how the Linux kernel stores its kallsyms symbol table to
// avoid processing lots of relocations on boot and bloating the kernel image,
// though Linux implements it with a code generator that emits a data-only
// assembly file:
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/kallsyms.c
// (See in particular write_src(), which emits some values as subtractions
// between two labels.)
template <typename T, const T base[]>
class IndexPointer {
public:
explicit constexpr IndexPointer(unsigned int offset) : offset_(offset) {}
// NOLINTNEXTLINE(google-explicit-constructor)
inline operator const T*() const {
// SAFETY: offset_ is always an in-bounds compile-time constant.
return UNSAFE_BUFFERS(&base[offset_]);
}
private:
unsigned int offset_;
};
} // namespace base::subtle
#endif // BASE_MEMORY_INDEX_POINTER_H_