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