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