* Copyright (c) 2025 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 COMMON_COMPONENTS_HEAP_HEAP_H
#define COMMON_COMPONENTS_HEAP_HEAP_H
#include <cstdlib>
#include <functional>
#include "common_components/base/immortal_wrapper.h"
#include "common_components/common/base_object.h"
#include "common_components/common/type_def.h"
#include "common_components/heap/barrier/barrier.h"
#include "common_components/heap/collector/collector.h"
#include "common_components/heap/collector/heuristic_gc_policy.h"
#include "base/runtime_param.h"
#include "base_runtime.h"
#include "profiler/heap_profiler_listener.h"
namespace common {
class Allocator;
class AllocationBuffer;
class FinalizerProcessor;
class CollectorResources;
class HeuristicGCPolicy;
using MemoryReduceDegree = common::MemoryReduceDegree;
using AppSensitiveStatus = common::AppSensitiveStatus;
using StartupStatus = common::StartupStatus;
class Heap {
public:
static constexpr size_t NORMAL_UNIT_SIZE = 256 * 1024;
static constexpr size_t NORMAL_UNIT_HEADER_SIZE = AlignUp<size_t>(2 * sizeof(void *) + sizeof(uint8_t), 8);
static constexpr size_t NORMAL_UNIT_AVAILABLE_SIZE = NORMAL_UNIT_SIZE - NORMAL_UNIT_HEADER_SIZE;
static constexpr size_t GetNormalRegionSize()
{
return NORMAL_UNIT_SIZE;
}
static constexpr size_t GetNormalRegionHeaderSize()
{
return NORMAL_UNIT_HEADER_SIZE;
}
static constexpr size_t GetNormalRegionAvailableSize()
{
return NORMAL_UNIT_AVAILABLE_SIZE;
}
static void throwOOM()
{
HeapProfilerListener::GetInstance().OnOutOfMemoryEventCb();
LOG_COMMON(FATAL) << "Out of Memory, abort.";
UNREACHABLE_CC();
}
static Heap& GetHeap();
static Barrier& GetBarrier() { return *currentBarrierPtr_->load(std::memory_order_relaxed); }
static bool UseBarrier() { return currentBarrierPtr_->load(std::memory_order_relaxed) != stwBarrierPtr_; }
virtual void Init(const RuntimeParam& param) = 0;
virtual void Fini() = 0;
virtual void StartRuntimeThreads() = 0;
virtual void StopRuntimeThreads() = 0;
virtual bool IsSurvivedObject(const BaseObject*) const = 0;
bool IsGarbage(const BaseObject* obj) const { return !IsSurvivedObject(obj); }
virtual bool IsGcStarted() const = 0;
virtual void WaitForGCFinish() = 0;
virtual void MarkGCStart() = 0;
virtual void MarkGCFinish() = 0;
virtual bool IsGCEnabled() const = 0;
virtual void EnableGC(bool val) = 0;
virtual HeapAddress Allocate(size_t size, AllocType allocType, bool allowGC) = 0;
virtual Collector& GetCollector() = 0;
virtual Allocator& GetAllocator() = 0;
virtual HeuristicGCPolicy& GetHeuristicGCPolicy() = 0;
virtual void TryHeuristicGC() = 0;
virtual void TryIdleGC() = 0;
virtual void NotifyNativeAllocation(size_t bytes) = 0;
virtual void NotifyNativeFree(size_t bytes) = 0;
virtual void NotifyNativeReset(size_t oldBytes, size_t newBytes) = 0;
virtual size_t GetNotifiedNativeSize() const = 0;
virtual void SetNativeHeapThreshold(size_t newThreshold) = 0;
virtual size_t GetNativeHeapThreshold() const = 0;
virtual void ChangeGCParams(bool isBackground) = 0;
virtual void RecordAliveSizeAfterLastGC(size_t aliveBytes) = 0;
virtual bool CheckAndTriggerHintGC(MemoryReduceDegree degree) = 0;
virtual void NotifyHighSensitive(bool isStart) = 0;
virtual void SetRecordHeapObjectSizeBeforeSensitive(size_t objSize) = 0;
virtual AppSensitiveStatus GetSensitiveStatus() = 0;
virtual StartupStatus GetStartupStatus() = 0;
virtual bool OnStartupEvent() const = 0;
* |------------------------------ max capacity ---------------------------------|
* |------------------------------ current capacity ------------------------|
* |------------------------------ committed size -----------------------|
* |------------------------------ used size -------------------------|
* |------------------------------ allocated size -------------|
* |------------------------------ net size ------------|
* so that inequality size <= capacity <= max capacity always holds.
*/
virtual size_t GetMaxCapacity() const = 0;
virtual size_t GetCurrentCapacity() const = 0;
virtual size_t GetUsedPageSize() const = 0;
virtual size_t GetAllocatedSize() const = 0;
virtual size_t GetSurvivedSize() const = 0;
virtual size_t GetRemainHeapSize() const = 0;
virtual size_t GetAccumulatedAllocateSize() const = 0;
virtual size_t GetAccumulatedFreeSize() const = 0;
virtual HeapAddress GetStartAddress() const = 0;
virtual HeapAddress GetSpaceEndAddress() const = 0;
static bool IsHeapAddress(HeapAddress addr) { return (addr >= heapStartAddr_) && (addr < heapCurrentEnd_); }
static bool IsTaggedObject(HeapAddress addr)
{
static constexpr uint64_t TAG_BITS_SHIFT = 48;
static constexpr uint64_t TAG_MARK = 0xFFFFULL << TAG_BITS_SHIFT;
static constexpr uint64_t TAG_SPECIAL = 0x02ULL;
static constexpr uint64_t TAG_BOOLEAN = 0x04ULL;
static constexpr uint64_t TAG_HEAP_OBJECT_MASK = TAG_MARK | TAG_SPECIAL | TAG_BOOLEAN;
if ((addr & TAG_HEAP_OBJECT_MASK) == 0) {
return true;
}
return false;
}
static void MarkJitFortMemInstalled(void *thread, void *obj);
static bool IsHeapAddress(const void* addr) { return IsHeapAddress(reinterpret_cast<HeapAddress>(addr)); }
virtual void InstallBarrier(const GCPhase) = 0;
virtual GCPhase GetGCPhase() const = 0;
virtual void SetGCPhase(const GCPhase phase) = 0;
virtual bool ForEachObject(const std::function<void(BaseObject*)>&, bool safe) = 0;
virtual void VisitStaticRoots(const RefFieldVisitor& visitor) = 0;
virtual FinalizerProcessor& GetFinalizerProcessor() = 0;
virtual CollectorResources& GetCollectorResources() = 0;
virtual void RegisterAllocBuffer(AllocationBuffer& buffer) = 0;
virtual void UnregisterAllocBuffer(AllocationBuffer& buffer) = 0;
virtual void StopGCWork() = 0;
virtual GCReason GetGCReason() = 0;
virtual void SetGCReason(GCReason reason) = 0;
virtual bool InRecentSpace(const void *addr) = 0;
virtual bool GetForceThrowOOM() const = 0;
virtual void SetForceThrowOOM(bool val) = 0;
static void OnHeapCreated(HeapAddress startAddr)
{
heapStartAddr_ = startAddr;
heapCurrentEnd_ = 0;
}
static void OnHeapExtended(HeapAddress newEnd) { heapCurrentEnd_ = newEnd; }
virtual ~Heap() {}
static std::atomic<Barrier*>* currentBarrierPtr_;
static Barrier* stwBarrierPtr_;
static HeapAddress heapStartAddr_;
static HeapAddress heapCurrentEnd_;
};
}
#endif