1 /*
2 * Copyright (c) 2021-2022 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_SPACE_H
17 #define ECMASCRIPT_MEM_SPACE_H
18
19 #include "ecmascript/mem/allocator.h"
20 #include "ecmascript/mem/c_containers.h"
21 #include "ecmascript/mem/ecma_list.h"
22 #include "ecmascript/mem/heap_region_allocator.h"
23 #include "ecmascript/mem/mem.h"
24 #include "ecmascript/mem/region.h"
25 #include "libpandabase/utils/type_helpers.h"
26
27 namespace panda::ecmascript {
28 class EcmaVM;
29 class Heap;
30
31 enum MemSpaceType {
32 OLD_SPACE = 0,
33 NON_MOVABLE,
34 MACHINE_CODE_SPACE,
35 HUGE_OBJECT_SPACE,
36 SEMI_SPACE,
37 SNAPSHOT_SPACE,
38 COMPRESS_SPACE,
39 LOCAL_SPACE,
40 SPACE_TYPE_LAST, // Count of different types
41
42 FREE_LIST_NUM = MACHINE_CODE_SPACE - OLD_SPACE + 1,
43 };
44
45 enum TriggerGCType {
46 SEMI_GC,
47 OLD_GC,
48 FULL_GC,
49 GC_TYPE_LAST // Count of different types
50 };
51
ToSpaceTypeName(MemSpaceType type)52 static inline std::string ToSpaceTypeName(MemSpaceType type)
53 {
54 switch (type) {
55 case OLD_SPACE:
56 return "old space";
57 case NON_MOVABLE:
58 return "non movable space";
59 case MACHINE_CODE_SPACE:
60 return "machine code space";
61 case HUGE_OBJECT_SPACE:
62 return "huge object space";
63 case SEMI_SPACE:
64 return "semi space";
65 case SNAPSHOT_SPACE:
66 return "snapshot space";
67 case COMPRESS_SPACE:
68 return "compress space";
69 default:
70 return "unknow space";
71 }
72 }
73
74 class Space {
75 public:
76 Space(Heap *heap, MemSpaceType spaceType, size_t initialCapacity, size_t maximumCapacity);
77 virtual ~Space() = default;
78 NO_COPY_SEMANTIC(Space);
79 NO_MOVE_SEMANTIC(Space);
80
GetHeap()81 Heap *GetHeap() const
82 {
83 return heap_;
84 }
85
GetMaximumCapacity()86 size_t GetMaximumCapacity() const
87 {
88 return maximumCapacity_;
89 }
90
SetMaximumCapacity(size_t maximumCapacity)91 void SetMaximumCapacity(size_t maximumCapacity)
92 {
93 maximumCapacity_ = maximumCapacity;
94 }
95
GetInitialCapacity()96 size_t GetInitialCapacity() const
97 {
98 return initialCapacity_;
99 }
100
SetInitialCapacity(size_t initialCapacity)101 void SetInitialCapacity(size_t initialCapacity)
102 {
103 initialCapacity_ = initialCapacity;
104 }
105
GetCommittedSize()106 size_t GetCommittedSize() const
107 {
108 return committedSize_;
109 }
110
IncrementCommitted(size_t bytes)111 void IncrementCommitted(size_t bytes)
112 {
113 committedSize_ += bytes;
114 }
115
DecrementCommitted(size_t bytes)116 void DecrementCommitted(size_t bytes)
117 {
118 committedSize_ -= bytes;
119 }
120
IncrementObjectSize(size_t bytes)121 void IncrementObjectSize(size_t bytes)
122 {
123 objectSize_ += bytes;
124 }
125
DecrementObjectSize(size_t bytes)126 void DecrementObjectSize(size_t bytes)
127 {
128 objectSize_ -= bytes;
129 }
130
GetSpaceType()131 MemSpaceType GetSpaceType() const
132 {
133 return spaceType_;
134 }
135
136 inline RegionFlags GetRegionFlag() const;
137
GetAllocateAreaBegin()138 uintptr_t GetAllocateAreaBegin() const
139 {
140 return regionList_.GetLast()->GetBegin();
141 }
142
GetAllocateAreaEnd()143 uintptr_t GetAllocateAreaEnd() const
144 {
145 return regionList_.GetLast()->GetEnd();
146 }
147
GetCurrentRegion()148 Region *GetCurrentRegion() const
149 {
150 return regionList_.GetLast();
151 }
152
GetRegionCount()153 uint32_t GetRegionCount()
154 {
155 return regionList_.GetLength();
156 }
157
GetRegionList()158 EcmaList<Region> &GetRegionList()
159 {
160 return regionList_;
161 }
162
GetRegionList()163 const EcmaList<Region> &GetRegionList() const
164 {
165 return regionList_;
166 }
167
168 template <class Callback>
169 inline void EnumerateRegions(const Callback &cb, Region *region = nullptr) const;
170
171 inline void AddRegion(Region *region);
172 inline void RemoveRegion(Region *region);
173
Initialize()174 virtual void Initialize() {};
175 void Destroy();
176
177 void ReclaimRegions();
178
179 bool ContainObject(TaggedObject *object) const;
180
181 protected:
182 void ClearAndFreeRegion(Region *region);
183
184 Heap *heap_ {nullptr};
185 EcmaVM *vm_ {nullptr};
186 JSThread *thread_ {nullptr};
187 HeapRegionAllocator *heapRegionAllocator_ {nullptr};
188 EcmaList<Region> regionList_ {};
189 MemSpaceType spaceType_ {};
190 size_t initialCapacity_ {0};
191 size_t maximumCapacity_ {0};
192 size_t committedSize_ {0};
193 size_t objectSize_ {0};
194 };
195
196 class HugeObjectSpace : public Space {
197 public:
198 explicit HugeObjectSpace(Heap *heap, size_t initialCapacity = MAX_HUGE_OBJECT_SPACE_SIZE,
199 size_t maximumCapacity = MAX_HUGE_OBJECT_SPACE_SIZE);
200 ~HugeObjectSpace() override = default;
201 NO_COPY_SEMANTIC(HugeObjectSpace);
202 NO_MOVE_SEMANTIC(HugeObjectSpace);
203 uintptr_t Allocate(size_t objectSize);
204 void Sweeping();
205 size_t GetHeapObjectSize() const;
206 void IterateOverObjects(const std::function<void(TaggedObject *object)> &objectVisitor) const;
207 };
208 } // namespace panda::ecmascript
209 #endif // ECMASCRIPT_MEM_SPACE_H
210