• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef LIBPANDABASE_MEM_ARENA_INL_H
17 #define LIBPANDABASE_MEM_ARENA_INL_H
18 
19 #include <memory>
20 #include "arena.h"
21 #include "macros.h"
22 #include "utils/logger.h"
23 #include "utils/asan_interface.h"
24 
25 namespace panda {
26 
Arena(size_t buff_size,void * buff)27 inline Arena::Arena(size_t buff_size, void *buff) : Arena(buff_size, buff, ARENA_DEFAULT_ALIGNMENT) {}
28 
Arena(size_t buff_size,void * buff,Alignment start_alignment)29 inline Arena::Arena(size_t buff_size, void *buff, Alignment start_alignment)
30     : buff_(buff),
31       startPos_(ToVoidPtr(AlignUp(ToUintPtr(buff), GetAlignmentInBytes(start_alignment)))),
32       curPos_(startPos_),
33       size_(buff_size)
34 {
35     ASSERT(ToUintPtr(buff) == AlignUp(ToUintPtr(buff), GetAlignmentInBytes(ARENA_DEFAULT_ALIGNMENT)));
36     ASAN_POISON_MEMORY_REGION(buff_, size_);
37     LOG(DEBUG, ALLOC) << "Arena: created with buff addr = " << buff << " size = " << buff_size;
38 }
39 
~Arena()40 inline Arena::~Arena()
41 {
42     ASAN_UNPOISON_MEMORY_REGION(buff_, size_);
43     LOG(DEBUG, ALLOC) << "Destroy Arena buff addr = " << buff_ << " size = " << size_;
44 }
45 
Alloc(size_t size,Alignment alignment)46 inline void *Arena::Alloc(size_t size, Alignment alignment)
47 {
48     void *ret = nullptr;
49     size_t free_size = GetFreeSize();
50     ret = std::align(GetAlignmentInBytes(alignment), size, curPos_, free_size);
51     if (ret != nullptr) {
52         ASAN_UNPOISON_MEMORY_REGION(ret, size);
53         curPos_ = ToVoidPtr(ToUintPtr(ret) + size);
54     }
55     LOG(DEBUG, ALLOC) << "Arena::Alloc size = " << size << " alignment = " << alignment << " at addr = " << ret;
56     return ret;
57 }
58 
AlignedAlloc(size_t size,Alignment alignment)59 inline void *Arena::AlignedAlloc(size_t size, [[maybe_unused]] Alignment alignment)
60 {
61     ASSERT(AlignUp(ToUintPtr(curPos_), GetAlignmentInBytes(alignment)) == ToUintPtr(curPos_));
62     ASSERT(AlignUp(size, GetAlignmentInBytes(alignment)) == size);
63     void *ret = nullptr;
64     uintptr_t new_cur_pos = ToUintPtr(curPos_) + size;
65     if (new_cur_pos <= (ToUintPtr(buff_) + size_)) {
66         ret = curPos_;
67         curPos_ = ToVoidPtr(new_cur_pos);
68         ASAN_UNPOISON_MEMORY_REGION(ret, size);
69     }
70     return ret;
71 }
72 
LinkTo(Arena * arena)73 inline void Arena::LinkTo(Arena *arena)
74 {
75     LOG(DEBUG, ALLOC) << "Link arena " << this << " to " << arena;
76     ASSERT(next_ == nullptr);
77     next_ = arena;
78 }
79 
ClearNextLink()80 inline void Arena::ClearNextLink()
81 {
82     next_ = nullptr;
83 }
84 
GetNextArena()85 inline Arena *Arena::GetNextArena() const
86 {
87     return next_;
88 }
89 
GetFreeSize()90 inline size_t Arena::GetFreeSize() const
91 {
92     ASSERT(ToUintPtr(curPos_) >= ToUintPtr(GetStartPos()));
93     return size_ - (ToUintPtr(curPos_) - ToUintPtr(GetStartPos()));
94 }
95 
GetOccupiedSize()96 inline size_t Arena::GetOccupiedSize() const
97 {
98     ASSERT(ToUintPtr(curPos_) >= ToUintPtr(GetStartPos()));
99     return ToUintPtr(curPos_) - ToUintPtr(GetStartPos());
100 }
101 
GetArenaEnd()102 inline void *Arena::GetArenaEnd() const
103 {
104     return ToVoidPtr(size_ + ToUintPtr(buff_));
105 }
106 
GetAllocatedEnd()107 inline void *Arena::GetAllocatedEnd() const
108 {
109     return ToVoidPtr(ToUintPtr(GetStartPos()) + GetOccupiedSize());
110 }
111 
GetAllocatedStart()112 inline void *Arena::GetAllocatedStart() const
113 {
114     return GetStartPos();
115 }
116 
InArena(const void * mem)117 inline bool Arena::InArena(const void *mem) const
118 {
119     return (ToUintPtr(curPos_) > ToUintPtr(mem)) && (ToUintPtr(GetStartPos()) <= ToUintPtr(mem));
120 }
121 
Free(void * mem)122 inline void Arena::Free(void *mem)
123 {
124     ASSERT(InArena(mem));
125     ASAN_POISON_MEMORY_REGION(mem, ToUintPtr(curPos_) - ToUintPtr(mem));
126     curPos_ = mem;
127 }
128 
Resize(size_t new_size)129 inline void Arena::Resize(size_t new_size)
130 {
131     size_t old_size = GetOccupiedSize();
132     ASSERT(new_size <= old_size);
133     curPos_ = ToVoidPtr(ToUintPtr(GetStartPos()) + new_size);
134     ASAN_POISON_MEMORY_REGION(curPos_, old_size - new_size);
135 }
136 
Reset()137 inline void Arena::Reset()
138 {
139     Resize(0);
140 }
141 
ExpandArena(const void * extra_buff,size_t size)142 inline void Arena::ExpandArena(const void *extra_buff, size_t size)
143 {
144     ASSERT(ToUintPtr(extra_buff) == AlignUp(ToUintPtr(extra_buff), DEFAULT_ALIGNMENT_IN_BYTES));
145     ASSERT(ToUintPtr(extra_buff) == ToUintPtr(GetArenaEnd()));
146     ASAN_POISON_MEMORY_REGION(extra_buff, size);
147     LOG(DEBUG, ALLOC) << "Expand arena: Add " << size << " bytes to the arena " << this;
148     size_ += size;
149 }
150 
151 }  // namespace panda
152 
153 #endif  // LIBPANDABASE_MEM_ARENA_INL_H
154