1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef ART_RUNTIME_LAMBDA_LEAKING_ALLOCATOR_H_ 17 #define ART_RUNTIME_LAMBDA_LEAKING_ALLOCATOR_H_ 18 19 #include <utility> // std::forward 20 #include <type_traits> // std::aligned_storage 21 22 namespace art { 23 class Thread; // forward declaration 24 25 namespace lambda { 26 27 // Temporary class to centralize all the leaking allocations. 28 // Allocations made through this class are never freed, but it is a placeholder 29 // that means that the calling code needs to be rewritten to properly: 30 // 31 // (a) Have a lifetime scoped to some other entity. 32 // (b) Not be allocated over and over again if it was already allocated once (immutable data). 33 // 34 // TODO: do all of the above a/b for each callsite, and delete this class. 35 class LeakingAllocator { 36 public: 37 // An opaque type which is guaranteed for: 38 // * a) be large enough to hold T (e.g. for in-place new) 39 // * b) be well-aligned (so that reads/writes are well-defined) to T 40 // * c) strict-aliasing compatible with T* 41 // 42 // Nominally used to allocate memory for yet unconstructed instances of T. 43 template <typename T> 44 using AlignedMemoryStorage = typename std::aligned_storage<sizeof(T), alignof(T)>::type; 45 46 // Allocate byte_size bytes worth of memory. Never freed. 47 template <typename T> 48 static AlignedMemoryStorage<T>* AllocateMemory(Thread* self, size_t byte_size = sizeof(T)) { 49 return reinterpret_cast<AlignedMemoryStorage<T>*>( 50 AllocateMemoryImpl(self, byte_size, alignof(T))); 51 } 52 53 // Make a new instance of T, flexibly sized, in-place at newly allocated memory. Never freed. 54 template <typename T, typename... Args> MakeFlexibleInstance(Thread * self,size_t byte_size,Args &&...args)55 static T* MakeFlexibleInstance(Thread* self, size_t byte_size, Args&&... args) { 56 return new (AllocateMemory<T>(self, byte_size)) T(std::forward<Args>(args)...); 57 } 58 59 // Make a new instance of T in-place at newly allocated memory. Never freed. 60 template <typename T, typename... Args> MakeInstance(Thread * self,Args &&...args)61 static T* MakeInstance(Thread* self, Args&&... args) { 62 return new (AllocateMemory<T>(self, sizeof(T))) T(std::forward<Args>(args)...); 63 } 64 65 private: 66 static void* AllocateMemoryImpl(Thread* self, size_t byte_size, size_t align_size); 67 }; 68 69 } // namespace lambda 70 } // namespace art 71 72 #endif // ART_RUNTIME_LAMBDA_LEAKING_ALLOCATOR_H_ 73