arkcompiler_ets_runtime/ecmascript/mem/free_object_set.cpp
fangting cdbfa4340e optimize compiler
Issue:#IALVU8
Signed-off-by: fangting <fangting12@huawei.com>
2024-08-27 11:02:23 +08:00

167 lines
5.3 KiB
C++

/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecmascript/mem/free_object_set.h"
#include "ecmascript/free_object.h"
namespace panda::ecmascript {
template <typename T>
void FreeObjectSet<T>::Free(uintptr_t begin, size_t size)
{
auto freeObject = T::Cast(begin);
ASSERT(freeObject->IsFreeObject());
freeObject->SetNext(freeObject_);
freeObject_ = freeObject;
available_ += size;
}
template void FreeObjectSet<FreeObject>::Free(uintptr_t, size_t);
template <>
void FreeObjectSet<MemDesc>::Free(uintptr_t begin, size_t size)
{
ASSERT(begin >= memDescPool_->JitFortBegin() &&
size <= memDescPool_->JitFortSize());
auto freeObject = memDescPool_->GetDescFromPool();
freeObject->SetMem(begin);
freeObject->SetSize(size);
freeObject->SetNext(freeObject_);
freeObject_ = freeObject;
available_ += size;
}
template <typename T>
void FreeObjectSet<T>::Rebuild()
{
freeObject_ = T::Cast(INVALID_OBJPTR);
available_ = 0;
isAdded_ = false;
next_ = nullptr;
prev_ = nullptr;
}
template void FreeObjectSet<FreeObject>::Rebuild();
template <>
void FreeObjectSet<MemDesc>::Rebuild()
{
MemDesc *current = freeObject_;
while (!MemDescPool::IsEmpty(current)) {
// put desc back to free pool
auto next = current->GetNext();
memDescPool_->ReturnDescToPool(current);
current = next;
}
freeObject_ = MemDesc::Cast(INVALID_OBJPTR);
available_ = 0;
isAdded_ = false;
next_ = nullptr;
prev_ = nullptr;
}
template <typename T>
T *FreeObjectSet<T>::ObtainSmallFreeObject(size_t size)
{
T *curFreeObject = T::Cast(INVALID_OBJPTR);
if (freeObject_ != T::Cast(INVALID_OBJPTR)) {
freeObject_->AsanUnPoisonFreeObject();
if (freeObject_->Available() >= size) {
curFreeObject = freeObject_;
freeObject_ = freeObject_->GetNext();
curFreeObject->SetNext(T::Cast(INVALID_OBJPTR));
available_ -= curFreeObject->Available();
// It need to mark unpoison when object being allocated in freelist.
ASAN_UNPOISON_MEMORY_REGION(curFreeObject, curFreeObject->Available());
} else {
freeObject_->AsanPoisonFreeObject();
}
}
return curFreeObject;
}
template FreeObject *FreeObjectSet<FreeObject>::ObtainSmallFreeObject(size_t);
template MemDesc *FreeObjectSet<MemDesc>::ObtainSmallFreeObject(size_t);
template <typename T>
T *FreeObjectSet<T>::ObtainLargeFreeObject(size_t size)
{
T *prevFreeObject = freeObject_;
T *curFreeObject = freeObject_;
while (curFreeObject != T::Cast(INVALID_OBJPTR)) {
curFreeObject->AsanUnPoisonFreeObject();
if (curFreeObject->Available() >= size) {
if (curFreeObject == freeObject_) {
freeObject_ = curFreeObject->GetNext();
} else {
prevFreeObject->SetNext(curFreeObject->GetNext());
prevFreeObject->AsanPoisonFreeObject();
}
curFreeObject->SetNext(T::Cast(INVALID_OBJPTR));
available_ -= curFreeObject->Available();
ASAN_UNPOISON_MEMORY_REGION(curFreeObject, curFreeObject->Available());
return curFreeObject;
}
if (prevFreeObject != curFreeObject) {
prevFreeObject->AsanPoisonFreeObject();
}
prevFreeObject = curFreeObject;
curFreeObject = curFreeObject->GetNext();
}
return T::Cast(INVALID_OBJPTR);
}
template FreeObject *FreeObjectSet<FreeObject>::ObtainLargeFreeObject(size_t);
template MemDesc *FreeObjectSet<MemDesc>::ObtainLargeFreeObject(size_t);
template <typename T>
T *FreeObjectSet<T>::LookupSmallFreeObject(size_t size)
{
if (freeObject_ != INVALID_OBJECT) {
freeObject_->AsanUnPoisonFreeObject();
if (freeObject_->Available() >= size) {
freeObject_->AsanPoisonFreeObject();
return freeObject_;
}
freeObject_->AsanPoisonFreeObject();
}
return INVALID_OBJECT;
}
template FreeObject *FreeObjectSet<FreeObject>::LookupSmallFreeObject(size_t);
template <typename T>
T *FreeObjectSet<T>::LookupLargeFreeObject(size_t size)
{
if (available_ < size) {
return INVALID_OBJECT;
}
T *curFreeObject = freeObject_;
while (curFreeObject != INVALID_OBJECT) {
curFreeObject->AsanUnPoisonFreeObject();
if (curFreeObject->Available() >= size) {
curFreeObject->AsanPoisonFreeObject();
return curFreeObject;
}
T *preFreeObject = curFreeObject;
curFreeObject = curFreeObject->GetNext();
preFreeObject->AsanPoisonFreeObject();
}
return INVALID_OBJECT;
}
template FreeObject *FreeObjectSet<FreeObject>::LookupLargeFreeObject(size_t);
} // namespace panda::ecmascript