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