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