* Copyright (c) 2024 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.
*/
#ifndef ECMASCRIPT_MEM_JIT_FORT_MEMDESC_H
#define ECMASCRIPT_MEM_JIT_FORT_MEMDESC_H
#include <deque>
#include "common_components/base/asan_interface.h"
#include "ecmascript/js_tagged_value.h"
#include "ecmascript/platform/mutex.h"
namespace panda::ecmascript {
#define INVALID_OBJPTR ((uintptr_t) JSTaggedValue::NULL_POINTER)
class MemDesc {
public:
MemDesc() = default;
~MemDesc() = default;
static MemDesc *Cast(uintptr_t object)
{
return reinterpret_cast<MemDesc *>(object);
}
inline uintptr_t GetBegin() const
{
return mem_;
}
inline uintptr_t GetEnd() const
{
return mem_ + size_;
}
inline void SetMem(uintptr_t mem)
{
mem_ = mem;
}
inline void SetSize(size_t size)
{
size_ = size;
}
inline void SetNext(MemDesc *desc)
{
next_ = desc;
}
inline MemDesc *GetNext()
{
return next_;
}
inline uint32_t Available() const
{
return size_;
}
inline bool IsFreeObject() const
{
return true;
}
inline void SetAvailable(uint32_t size)
{
size_ = size;
}
inline void AsanPoisonFreeObject() const
{
ASAN_POISON_MEMORY_REGION((const volatile void *)mem_, size_);
}
inline void AsanUnPoisonFreeObject() const
{
ASAN_UNPOISON_MEMORY_REGION((const volatile void *)mem_, size_);
}
private:
uintptr_t mem_ {0};
size_t size_ {0};
MemDesc *next_ {MemDesc::Cast(INVALID_OBJPTR)};
};
class MemDescPool {
public:
MemDescPool(uintptr_t fortBegin, size_t fortSize);
~MemDescPool();
static inline bool IsEmpty(MemDesc* list)
{
return (list == nullptr || list == MemDesc::Cast(INVALID_OBJPTR));
}
inline MemDesc *GetDescFromPool()
{
LockHolder lock(lock_);
return GetDesc();
}
inline void ReturnDescToPool(MemDesc *desc)
{
LockHolder lock(lock_);
Add(desc);
returned_++;
}
inline uintptr_t JitFortBegin()
{
return fortBegin_;
}
inline size_t JitFortSize()
{
return fortSize_;
}
private:
MemDesc *GetDesc();
void Add(MemDesc *);
void Expand();
static constexpr size_t MEMDESCS_PER_BLOCK = 100;
MemDesc *freeList_ {nullptr};
std::deque<void *> memDescBlocks_;
size_t allocated_ {0};
size_t returned_ {0};
size_t highwater_ {0};
Mutex lock_;
uintptr_t fortBegin_;
size_t fortSize_;
};
}
#endif