[go: nahoru, domu]

blob: b12adee69fbce9b54524642b7d218b38f5131c9c [file] [log] [blame]
Stefan Zagerce1b8672023-03-13 17:08:071// Copyright 2023 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_MEMORY_STACK_ALLOCATED_H_
6#define BASE_MEMORY_STACK_ALLOCATED_H_
7
Avi Drissman5e5f3fb02023-09-14 14:47:078#include <stddef.h>
9
Stefan Zagerce1b8672023-03-13 17:08:0710#if defined(__clang__)
11#define STACK_ALLOCATED_IGNORE(reason) \
12 __attribute__((annotate("stack_allocated_ignore")))
13#else // !defined(__clang__)
14#define STACK_ALLOCATED_IGNORE(reason)
15#endif // !defined(__clang__)
16
17// If a class or one of its ancestor classes is annotated with STACK_ALLOCATED()
18// in its class definition, then instances of the class may not be allocated on
19// the heap or as a member variable of a non-stack-allocated class.
20#define STACK_ALLOCATED() \
21 public: \
22 using IsStackAllocatedTypeMarker [[maybe_unused]] = int; \
23 \
24 private: \
25 void* operator new(size_t) = delete; \
26 void* operator new(size_t, ::base::NotNullTag, void*) = delete; \
27 void* operator new(size_t, void*) = delete
28
29namespace base {
30
31// NotNullTag was originally added to WebKit here:
32// https://trac.webkit.org/changeset/103243/webkit
33// ...with the stated goal of improving the performance of the placement new
34// operator and potentially enabling the -fomit-frame-pointer compiler flag.
35//
36// TODO(szager): The placement new operator which uses this tag is currently
37// defined in third_party/blink/renderer/platform/wtf/allocator/allocator.h,
38// in the global namespace. It should probably move to /base.
39//
40// It's unknown at the time of writing whether it still provides any benefit
41// (or if it ever did). It is used by placing the kNotNull tag before the
42// address of the object when calling placement new.
43//
44// If the kNotNull tag is specified to placement new for a null pointer,
45// Undefined Behaviour can result.
46//
47// Example:
48//
49// union { int i; } u;
50//
51// // Typically placement new looks like this.
52// new (&u.i) int(3);
53// // But we can promise `&u.i` is not null like this.
54// new (base::NotNullTag::kNotNull, &u.i) int(3);
55enum class NotNullTag { kNotNull };
56
57} // namespace base
58
59#endif // BASE_MEMORY_STACK_ALLOCATED_H_