1 /*
2  * Copyright (C) 2011 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 
17 #include "arena_bit_vector.h"
18 
19 #include "allocator.h"
20 #include "arena_allocator.h"
21 
22 namespace art {
23 
24 template <bool kCount>
25 class ArenaBitVectorAllocatorKindImpl;
26 
27 template <>
28 class ArenaBitVectorAllocatorKindImpl<false> {
29  public:
30   // Not tracking allocations, ignore the supplied kind and arbitrarily provide kArenaAllocSTL.
31   explicit ArenaBitVectorAllocatorKindImpl(ArenaAllocKind kind ATTRIBUTE_UNUSED) {}
32   ArenaBitVectorAllocatorKindImpl(const ArenaBitVectorAllocatorKindImpl&) = default;
33   ArenaBitVectorAllocatorKindImpl& operator=(const ArenaBitVectorAllocatorKindImpl&) = default;
34   ArenaAllocKind Kind() { return kArenaAllocGrowableBitMap; }
35 };
36 
37 template <bool kCount>
38 class ArenaBitVectorAllocatorKindImpl {
39  public:
40   explicit ArenaBitVectorAllocatorKindImpl(ArenaAllocKind kind) : kind_(kind) { }
41   ArenaBitVectorAllocatorKindImpl(const ArenaBitVectorAllocatorKindImpl&) = default;
42   ArenaBitVectorAllocatorKindImpl& operator=(const ArenaBitVectorAllocatorKindImpl&) = default;
43   ArenaAllocKind Kind() { return kind_; }
44 
45  private:
46   ArenaAllocKind kind_;
47 };
48 
49 using ArenaBitVectorAllocatorKind =
50     ArenaBitVectorAllocatorKindImpl<kArenaAllocatorCountAllocations>;
51 
52 template <typename ArenaAlloc>
53 class ArenaBitVectorAllocator final : public Allocator, private ArenaBitVectorAllocatorKind {
54  public:
55   static ArenaBitVectorAllocator* Create(ArenaAlloc* allocator, ArenaAllocKind kind) {
56     void* storage = allocator->template Alloc<ArenaBitVectorAllocator>(kind);
57     return new (storage) ArenaBitVectorAllocator(allocator, kind);
58   }
59 
60   ~ArenaBitVectorAllocator() {
61     LOG(FATAL) << "UNREACHABLE";
62     UNREACHABLE();
63   }
64 
65   void* Alloc(size_t size) override {
66     return allocator_->Alloc(size, this->Kind());
67   }
68 
69   void Free(void*) override {}  // Nop.
70 
71  private:
72   ArenaBitVectorAllocator(ArenaAlloc* allocator, ArenaAllocKind kind)
73       : ArenaBitVectorAllocatorKind(kind), allocator_(allocator) { }
74 
75   ArenaAlloc* const allocator_;
76 
77   DISALLOW_COPY_AND_ASSIGN(ArenaBitVectorAllocator);
78 };
79 
80 ArenaBitVector::ArenaBitVector(ArenaAllocator* allocator,
81                                unsigned int start_bits,
82                                bool expandable,
83                                ArenaAllocKind kind)
84   :  BitVector(start_bits,
85                expandable,
86                ArenaBitVectorAllocator<ArenaAllocator>::Create(allocator, kind)) {
87 }
88 
89 ArenaBitVector::ArenaBitVector(ScopedArenaAllocator* allocator,
90                                unsigned int start_bits,
91                                bool expandable,
92                                ArenaAllocKind kind)
93   :  BitVector(start_bits,
94                expandable,
95                ArenaBitVectorAllocator<ScopedArenaAllocator>::Create(allocator, kind)) {
96 }
97 
98 }  // namespace art
99