1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef ECMASCRIPT_MEM_ALLOCATOR_H
17#define ECMASCRIPT_MEM_ALLOCATOR_H
18
19#include <memory>
20
21#include "ecmascript/mem/free_object_list.h"
22#include "ecmascript/mem/mem.h"
23
24namespace panda::ecmascript {
25class Region;
26class BaseHeap;
27class JitFort;
28
29class Allocator {
30public:
31    Allocator() = default;
32    virtual ~Allocator() = default;
33    NO_COPY_SEMANTIC(Allocator);
34    NO_MOVE_SEMANTIC(Allocator);
35};
36
37class BumpPointerAllocator : public Allocator {
38public:
39    BumpPointerAllocator() = default;
40    ~BumpPointerAllocator() override = default;
41    NO_COPY_SEMANTIC(BumpPointerAllocator);
42    NO_MOVE_SEMANTIC(BumpPointerAllocator);
43
44    inline BumpPointerAllocator(uintptr_t begin, uintptr_t end);
45
46    inline void Reset();
47    inline void Reset(uintptr_t begin, uintptr_t end);
48    inline void Reset(uintptr_t begin, uintptr_t end, uintptr_t top);
49    inline void ResetTopPointer(uintptr_t top);
50    inline uintptr_t Allocate(size_t size);
51
52    uintptr_t GetTop() const
53    {
54        return top_;
55    }
56
57    uintptr_t GetEnd() const
58    {
59        return end_;
60    }
61
62    const uintptr_t *GetTopAddress()
63    {
64        return &top_;
65    }
66
67    const uintptr_t *GetEndAddress()
68    {
69        return &end_;
70    }
71
72    size_t Available() const
73    {
74        return (end_ - top_);
75    }
76
77private:
78    uintptr_t begin_ {0};
79    uintptr_t top_ {0};
80    uintptr_t end_ {0};
81};
82
83template <typename T>
84class FreeListAllocator : public Allocator {
85public:
86    FreeListAllocator() = delete;
87    ~FreeListAllocator() override = default;
88
89    NO_COPY_SEMANTIC(FreeListAllocator);
90    NO_MOVE_SEMANTIC(FreeListAllocator);
91
92    inline explicit FreeListAllocator(BaseHeap *heap);
93    inline explicit FreeListAllocator(BaseHeap *heap, MemDescPool *pool, JitFort *fort);
94    inline void Initialize(Region *region);
95
96    inline void Reset(BaseHeap *heap);
97
98    inline uintptr_t Allocate(size_t size);
99    inline void AddFree(Region *region);
100    inline uintptr_t LookupSuitableFreeObject(size_t size);
101
102    inline void RebuildFreeList();
103
104    inline bool MatchFreeObjectSet(Region *region, size_t size);
105    inline void CollectFreeObjectSet(Region *region);
106    inline void DetachFreeObjectSet(Region *region);
107
108    inline void FreeBumpPoint();
109    // Only fill free object
110    inline void FillBumpPointer();
111
112    inline void ResetBumpPointer(uintptr_t begin, uintptr_t end, uintptr_t top);
113    inline void ResetTopPointer(uintptr_t top);
114
115    inline void Free(uintptr_t begin, size_t size, bool isAdd = true);
116
117    inline size_t GetAvailableSize() const;
118    inline size_t GetWastedSize() const;
119
120    uintptr_t GetTop() const
121    {
122        return bpAllocator_.GetTop();
123    }
124
125    size_t GetAllocatedSize() const
126    {
127        return allocationSizeAccumulator_;
128    }
129
130    void IncreaseAllocatedSize(size_t allocatedSize)
131    {
132        allocationSizeAccumulator_ += allocatedSize;
133    }
134
135private:
136    inline uintptr_t Allocate(T *object, size_t size);
137    std::unique_ptr<FreeObjectList<T>> freeList_ {nullptr};
138    MemDescPool *memDescPool_ {nullptr};
139    BumpPointerAllocator bpAllocator_;
140    BaseHeap *heap_{nullptr};
141    size_t allocationSizeAccumulator_ {0};
142};
143}  // namespace panda::ecmascript
144
145#endif  // ECMASCRIPT_MEM_ALLOCATOR_H
146