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_ECMA_PARAM_CONFIGURATION_H
17#define ECMASCRIPT_ECMA_PARAM_CONFIGURATION_H
18
19#include "ecmascript/mem/mem_common.h"
20
21#include "ecmascript/log_wrapper.h"
22
23#include "libpandabase/macros.h"
24
25namespace panda::ecmascript {
26static constexpr size_t DEFAULT_HEAP_SIZE = 448_MB;                 // Recommended range: 128-448MB
27static constexpr size_t DEFAULT_WORKER_HEAP_SIZE = 768_MB;          // Recommended range: 128_MB, LargeHeap: 768_MB
28static constexpr size_t DEFAULT_SHARED_HEAP_SIZE = 778_MB;
29static constexpr size_t MAX_HEAP_SIZE = 1024_MB;
30
31class EcmaParamConfiguration {
32public:
33    enum class HeapType : uint8_t {
34        DEFAULT_HEAP,
35        WORKER_HEAP,
36        SHARED_HEAP
37    };
38
39    EcmaParamConfiguration() = default;
40    EcmaParamConfiguration(HeapType heapType, size_t poolSize, size_t heapSize = 1_MB)
41    {
42        switch (heapType) {
43            case HeapType::WORKER_HEAP:
44                if (heapSize > LOW_MEMORY && heapSize < DEFAULT_WORKER_HEAP_SIZE) {
45                    maxHeapSize_ = heapSize;
46                } else {
47                    maxHeapSize_ = DEFAULT_WORKER_HEAP_SIZE;
48                }
49                break;
50            case HeapType::SHARED_HEAP:
51                 if (heapSize > LOW_MEMORY && heapSize < DEFAULT_SHARED_HEAP_SIZE) {
52                    maxHeapSize_ = heapSize;
53                } else {
54                    maxHeapSize_ = DEFAULT_SHARED_HEAP_SIZE;
55                };
56                break;
57            default:
58                if (poolSize >= DEFAULT_HEAP_SIZE) {
59                    maxHeapSize_ = DEFAULT_HEAP_SIZE;
60                } else {
61                    maxHeapSize_ = poolSize; // pool is too small, no memory left for worker
62                }
63                if (heapSize > LOW_MEMORY && heapSize < DEFAULT_HEAP_SIZE) {
64                    maxHeapSize_ = heapSize;
65                }
66                if (heapSize >= DEFAULT_HEAP_SIZE && heapSize <= MAX_HEAP_SIZE) {
67                    maxHeapSize_ = heapSize;
68                }
69        }
70        Initialize();
71    }
72
73    void Initialize()
74    {
75        if (maxHeapSize_ < LOW_MEMORY) {
76            LOG_ECMA(FATAL) << "this branch is unreachable";
77            UNREACHABLE();
78        }
79        if (maxHeapSize_ < MEDIUM_MEMORY) { // 64_MB ~ 128_MB
80            minSemiSpaceSize_ = 2_MB;
81            maxSemiSpaceSize_ = 4_MB;
82            defaultReadOnlySpaceSize_ = 256_KB;
83            defaultNonMovableSpaceSize_ = 2_MB;
84            defaultSnapshotSpaceSize_ = 512_KB;
85            defaultMachineCodeSpaceSize_ = 2_MB;
86            defaultGlobalAllocLimit_ = 20_MB;
87            edenSpaceTriggerConcurrentMark_ = 1_MB;
88            semiSpaceTriggerConcurrentMark_ = 1_MB;
89            semiSpaceStepOvershootSize_ = 2_MB;
90            oldSpaceStepOvershootSize_ = 4_MB;
91            oldSpaceMaxOvershootSize_ = 8_MB;
92            outOfMemoryOvershootSize_ = 2_MB;
93            minAllocLimitGrowingStep_ = 2_MB;
94            minGrowingStep_ = 4_MB;
95            maxStackSize_ = 128_KB;
96            maxJSSerializerSize_ = 8_MB;
97            sharedHeapLimitGrowingFactor_ = 2; // 2: growing factor
98            sharedHeapLimitGrowingStep_ = 20_MB;
99            incObjSizeThresholdInSensitive_ = 40_MB;
100            stepNativeSizeInc_ = 256_MB;
101            nativeSizeOvershoot_ = 80_MB;
102            maxNativeSizeInc_ = 768_MB;
103        } else if (maxHeapSize_ < HIGH_MEMORY) { // 128_MB ~ 256_MB
104            minSemiSpaceSize_ = 2_MB;
105            maxSemiSpaceSize_ = 8_MB;
106            defaultReadOnlySpaceSize_ = 256_KB;
107            defaultNonMovableSpaceSize_ = 6_MB;
108            defaultSnapshotSpaceSize_ = 512_KB;
109            defaultMachineCodeSpaceSize_ = 2_MB;
110            defaultGlobalAllocLimit_ = 20_MB;
111            edenSpaceTriggerConcurrentMark_ = 1.5_MB;
112            semiSpaceTriggerConcurrentMark_ = 1.5_MB;
113            semiSpaceStepOvershootSize_ = 2_MB;
114            oldSpaceStepOvershootSize_ = 8_MB;
115            oldSpaceMaxOvershootSize_ = 16_MB;
116            outOfMemoryOvershootSize_ = 2_MB;
117            minAllocLimitGrowingStep_ = 4_MB;
118            minGrowingStep_ = 8_MB;
119            maxStackSize_ = 128_KB;
120            maxJSSerializerSize_ = 16_MB;
121            sharedHeapLimitGrowingFactor_ = 2; // 2: growing factor
122            sharedHeapLimitGrowingStep_ = 40_MB;
123            incObjSizeThresholdInSensitive_ = 40_MB;
124            stepNativeSizeInc_ = 256_MB;
125            nativeSizeOvershoot_ = 80_MB;
126            maxNativeSizeInc_ = 768_MB;
127        }  else { // 256_MB ~ 384_MB
128            minSemiSpaceSize_ = 2_MB;
129            maxSemiSpaceSize_ = 16_MB;
130            defaultReadOnlySpaceSize_ = 256_KB;
131            defaultNonMovableSpaceSize_ = 64_MB;
132            defaultSnapshotSpaceSize_ = 4_MB;
133            defaultMachineCodeSpaceSize_ = 8_MB;
134            defaultGlobalAllocLimit_ = 20_MB;
135            edenSpaceTriggerConcurrentMark_ = 1.5_MB;
136            semiSpaceTriggerConcurrentMark_ = 1.5_MB;
137            semiSpaceStepOvershootSize_ = 2_MB;
138            oldSpaceStepOvershootSize_ = 8_MB;
139            oldSpaceMaxOvershootSize_ = 16_MB;
140            outOfMemoryOvershootSize_ = 2_MB;
141            minAllocLimitGrowingStep_ = 8_MB;
142            minGrowingStep_ = 16_MB;
143            maxStackSize_ = 128_KB;
144            maxJSSerializerSize_ = 16_MB;
145            sharedHeapLimitGrowingFactor_ = 4; // 4: growing factor
146            sharedHeapLimitGrowingStep_ = 80_MB;
147            incObjSizeThresholdInSensitive_ = 80_MB;
148            stepNativeSizeInc_ = 300_MB;
149            nativeSizeOvershoot_ = 100_MB;
150            asyncClearNativePointerThreshold_ = 500_MB;
151            maxNativeSizeInc_ = 1_GB;
152        }
153    }
154
155    size_t GetMaxHeapSize() const
156    {
157        return maxHeapSize_;
158    }
159
160    size_t GetMinSemiSpaceSize() const
161    {
162        return minSemiSpaceSize_;
163    }
164
165    size_t GetMaxSemiSpaceSize() const
166    {
167        return maxSemiSpaceSize_;
168    }
169
170    size_t GetDefaultReadOnlySpaceSize() const
171    {
172        return defaultReadOnlySpaceSize_;
173    }
174
175    size_t GetDefaultNonMovableSpaceSize() const
176    {
177        return defaultNonMovableSpaceSize_;
178    }
179
180    size_t GetDefaultSnapshotSpaceSize() const
181    {
182        return defaultSnapshotSpaceSize_;
183    }
184
185    size_t GetDefaultMachineCodeSpaceSize() const
186    {
187        return defaultMachineCodeSpaceSize_;
188    }
189
190    size_t GetDefaultGlobalAllocLimit() const
191    {
192        return defaultGlobalAllocLimit_;
193    }
194
195    size_t GetEdenSpaceTriggerConcurrentMark() const
196    {
197        return edenSpaceTriggerConcurrentMark_;
198    }
199
200    size_t GetSemiSpaceTriggerConcurrentMark() const
201    {
202        return semiSpaceTriggerConcurrentMark_;
203    }
204
205    size_t GetSemiSpaceStepOvershootSize() const
206    {
207        return semiSpaceStepOvershootSize_;
208    }
209
210    size_t GetOldSpaceStepOvershootSize() const
211    {
212        return oldSpaceStepOvershootSize_;
213    }
214
215    size_t GetOldSpaceMaxOvershootSize() const
216    {
217        return oldSpaceMaxOvershootSize_;
218    }
219
220    size_t GetOutOfMemoryOvershootSize() const
221    {
222        return outOfMemoryOvershootSize_;
223    }
224
225    size_t GetMinAllocLimitGrowingStep() const
226    {
227        return minAllocLimitGrowingStep_;
228    }
229
230    size_t GetMinGrowingStep() const
231    {
232        return minGrowingStep_;
233    }
234
235    size_t GetSharedHeapLimitGrowingFactor() const
236    {
237        return sharedHeapLimitGrowingFactor_;
238    }
239
240    size_t GetSharedHeapLimitGrowingStep() const
241    {
242        return sharedHeapLimitGrowingStep_;
243    }
244
245    size_t GetIncObjSizeThresholdInSensitive() const
246    {
247        return incObjSizeThresholdInSensitive_;
248    }
249
250    size_t GetStepNativeSizeInc() const
251    {
252        return stepNativeSizeInc_;
253    }
254
255    size_t GetNativeSizeOvershoot() const
256    {
257        return nativeSizeOvershoot_;
258    }
259
260    size_t GetAsyncClearNativePointerThreshold() const
261    {
262        return asyncClearNativePointerThreshold_;
263    }
264
265    size_t GetMaxNativeSizeInc() const
266    {
267        return maxNativeSizeInc_;
268    }
269
270    uint32_t GetMaxStackSize() const
271    {
272        return maxStackSize_;
273    }
274
275    static size_t GetDefalutStackSize()
276    {
277        return DEFAULT_STACK_SIZE;
278    }
279
280    static size_t GetDefaultReservedStackSize()
281    {
282        return DEFAULT_RESERVED_STACK_SIZE;
283    }
284
285    static size_t GetAllowedUpperStackDiff()
286    {
287        return ALLOWED_UPPER_STACK_DIFF;
288    }
289
290    size_t GetMaxJSSerializerSize() const
291    {
292        return maxJSSerializerSize_;
293    }
294
295private:
296    static constexpr size_t LOW_MEMORY = 64_MB;
297    static constexpr size_t MEDIUM_MEMORY = 128_MB;
298    static constexpr size_t HIGH_MEMORY = 256_MB;
299    static constexpr size_t DEFAULT_STACK_SIZE = 992_KB;
300    static constexpr size_t ALLOWED_UPPER_STACK_DIFF = 4_KB;
301    static constexpr size_t DEFAULT_RESERVED_STACK_SIZE = 16_KB;
302
303    size_t maxHeapSize_ {0};
304    size_t minSemiSpaceSize_ {0};
305    size_t maxSemiSpaceSize_ {0};
306    size_t defaultReadOnlySpaceSize_ {0};
307    size_t defaultNonMovableSpaceSize_ {0};
308    size_t defaultSnapshotSpaceSize_ {0};
309    size_t defaultMachineCodeSpaceSize_ {0};
310    size_t defaultGlobalAllocLimit_ {0};
311    size_t edenSpaceTriggerConcurrentMark_ {0};
312    size_t semiSpaceTriggerConcurrentMark_ {0};
313    size_t semiSpaceStepOvershootSize_ {0};
314    size_t oldSpaceStepOvershootSize_ {0};
315    size_t oldSpaceMaxOvershootSize_ {0};
316    size_t outOfMemoryOvershootSize_ {0};
317    size_t minAllocLimitGrowingStep_ {0};
318    size_t minGrowingStep_ {0};
319    size_t sharedHeapLimitGrowingFactor_ {0};
320    size_t sharedHeapLimitGrowingStep_ {0};
321    size_t incObjSizeThresholdInSensitive_ {0};
322    size_t stepNativeSizeInc_ {0};
323    size_t nativeSizeOvershoot_ {0};
324    size_t asyncClearNativePointerThreshold_ {0};
325    size_t maxNativeSizeInc_ {0};
326    size_t maxJSSerializerSize_ {0};
327    uint32_t maxStackSize_ {0};
328};
329} // namespace panda::ecmascript
330
331#endif // ECMASCRIPT_ECMA_PARAM_CONFIGURATION_H
332