1 // 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 8 #include <stddef.h> 9 10 #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 29 namespace 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); 55 enum class NotNullTag { kNotNull }; 56 57 } // namespace base 58 59 #endif // BASE_MEMORY_STACK_ALLOCATED_H_ 60