Home | History | Annotate | Download | only in lambda
      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>
     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>
     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