mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-08 00:24:00 +00:00
56bb730cba
related issue: https://gitee.com/openharmony/ark_js_runtime/issues/I4VDA4 Change-Id: I4560cf0ec4c05ccd855debb51b6d0190b4f1ccfa Signed-off-by: panzhenyu1 <panzhenyu1@huawei.com>
177 lines
5.1 KiB
C++
177 lines
5.1 KiB
C++
/*
|
|
* Copyright (c) 2022 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_SPARSE_SPACE_H
|
|
#define ECMASCRIPT_MEM_SPARSE_SPACE_H
|
|
|
|
#include "ecmascript/mem/space-inl.h"
|
|
|
|
#define CHECK_OBJECT_AND_INC_OBJ_SIZE(size) \
|
|
if (object != 0) { \
|
|
IncrementLiveObjectSize(size); \
|
|
return object; \
|
|
}
|
|
|
|
enum class SweepState : uint8_t {
|
|
NO_SWEEP,
|
|
SWEEPING,
|
|
SWEPT
|
|
};
|
|
|
|
namespace panda::ecmascript {
|
|
class LocalSpace;
|
|
|
|
class SparseSpace : public Space {
|
|
public:
|
|
explicit SparseSpace(Heap *heap, MemSpaceType type, size_t initialCapacity, size_t maximumCapacity);
|
|
~SparseSpace() override = default;
|
|
NO_COPY_SEMANTIC(SparseSpace);
|
|
NO_MOVE_SEMANTIC(SparseSpace);
|
|
|
|
void Initialize() override;
|
|
void Reset();
|
|
|
|
uintptr_t Allocate(size_t size, bool isAllowGC = true);
|
|
bool Expand();
|
|
|
|
// For sweeping
|
|
void PrepareSweeping();
|
|
void AsyncSweeping(bool isMain);
|
|
void Sweeping();
|
|
|
|
bool FillSweptRegion();
|
|
|
|
void AddSweepingRegion(Region *region);
|
|
void SortSweepingRegion();
|
|
Region *GetSweepingRegionSafe();
|
|
void AddSweptRegionSafe(Region *region);
|
|
Region *GetSweptRegionSafe();
|
|
|
|
void FreeRegion(Region *current, bool isMain = true);
|
|
void FreeLiveRange(Region *current, uintptr_t freeStart, uintptr_t freeEnd, bool isMain);
|
|
|
|
void DetachFreeObjectSet(Region *region);
|
|
|
|
void IterateOverObjects(const std::function<void(TaggedObject *object)> &objectVisitor) const;
|
|
|
|
size_t GetHeapObjectSize() const;
|
|
void IncrementLiveObjectSize(size_t size)
|
|
{
|
|
liveObjectSize_ += size;
|
|
}
|
|
|
|
void DecrementLiveObjectSize(size_t size)
|
|
{
|
|
liveObjectSize_ -= size;
|
|
}
|
|
|
|
size_t GetTotalAllocatedSize() const;
|
|
|
|
protected:
|
|
FreeListAllocator *allocator_;
|
|
SweepState sweepState_ = SweepState::NO_SWEEP;
|
|
|
|
private:
|
|
// For sweeping
|
|
uintptr_t AllocateAfterSweepingCompleted(size_t size);
|
|
|
|
os::memory::Mutex lock_;
|
|
std::vector<Region *> sweepingList_;
|
|
std::vector<Region *> sweptList_;
|
|
size_t liveObjectSize_ {0};
|
|
};
|
|
|
|
class OldSpace : public SparseSpace {
|
|
public:
|
|
explicit OldSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity);
|
|
~OldSpace() override = default;
|
|
NO_COPY_SEMANTIC(OldSpace);
|
|
NO_MOVE_SEMANTIC(OldSpace);
|
|
|
|
/* The most extreme situation:
|
|
* All the younger generation were promoted, and there was no free space in the old space.
|
|
*/
|
|
bool CanExpand(size_t promoteSize)
|
|
{
|
|
return initialCapacity_ > committedSize_ + promoteSize;
|
|
}
|
|
Region *TryToGetExclusiveRegion(size_t size);
|
|
|
|
// CSet
|
|
void SelectCSet();
|
|
void CheckRegionSize();
|
|
void RevertCSet();
|
|
void ReclaimCSet();
|
|
bool IsCSetEmpty() const
|
|
{
|
|
return isCSetEmpty_;
|
|
}
|
|
unsigned long GetSelectedRegionNumber() const
|
|
{
|
|
return std::max(committedSize_ / PARTIAL_GC_MAX_COLLECT_REGION_RATE, PARTIAL_GC_INITIAL_COLLECT_REGION_SIZE);
|
|
}
|
|
|
|
template<class Callback>
|
|
void EnumerateCollectRegionSet(const Callback &cb) const
|
|
{
|
|
for (Region *current : collectRegionSet_) {
|
|
if (current != nullptr) {
|
|
cb(current);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Merge(LocalSpace *localSpace);
|
|
private:
|
|
static constexpr unsigned long long PARTIAL_GC_MAX_COLLECT_REGION_RATE = 1024 * 1024 * 2;
|
|
static constexpr unsigned long long PARTIAL_GC_INITIAL_COLLECT_REGION_SIZE = 16;
|
|
static constexpr size_t PARTIAL_GC_MIN_COLLECT_REGION_SIZE = 5;
|
|
|
|
CVector<Region *> collectRegionSet_;
|
|
bool isCSetEmpty_ {true};
|
|
os::memory::Mutex lock_;
|
|
};
|
|
|
|
class NonMovableSpace : public SparseSpace {
|
|
public:
|
|
explicit NonMovableSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity);
|
|
~NonMovableSpace() override = default;
|
|
NO_COPY_SEMANTIC(NonMovableSpace);
|
|
NO_MOVE_SEMANTIC(NonMovableSpace);
|
|
};
|
|
|
|
class LocalSpace : public SparseSpace {
|
|
public:
|
|
LocalSpace() = delete;
|
|
explicit LocalSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity);
|
|
~LocalSpace() override = default;
|
|
NO_COPY_SEMANTIC(LocalSpace);
|
|
NO_MOVE_SEMANTIC(LocalSpace);
|
|
|
|
uintptr_t Allocate(size_t size, bool isExpand = true);
|
|
bool AddRegionToList(Region *region);
|
|
void FreeBumpPoint();
|
|
};
|
|
|
|
class MachineCodeSpace : public SparseSpace {
|
|
public:
|
|
explicit MachineCodeSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity);
|
|
~MachineCodeSpace() override = default;
|
|
NO_COPY_SEMANTIC(MachineCodeSpace);
|
|
NO_MOVE_SEMANTIC(MachineCodeSpace); // Note: Expand() left for define
|
|
};
|
|
} // namespace panda::ecmascript
|
|
#endif // ECMASCRIPT_MEM_SPARSE_SPACE_H
|