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