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_FREE_OBJECT_LIST_H 17 #define ECMASCRIPT_MEM_FREE_OBJECT_LIST_H 18 19 #include <cstddef> 20 21 #include "ecmascript/mem/free_object_set.h" 22 #include "ecmascript/mem/mem_common.h" 23 24 #include "libpandabase/utils/span.h" 25 26 namespace panda::ecmascript { 27 class JitFort; 28 template <typename T> 29 class FreeObjectList { 30 public: 31 FreeObjectList(); 32 FreeObjectList(JitFort *fort); 33 ~FreeObjectList(); 34 35 T *Allocate(size_t size); 36 37 T *LookupSuitableFreeObject(size_t size); 38 39 void Free(uintptr_t start, size_t size, bool isAdd = true); 40 41 void Rebuild(); 42 43 bool MatchFreeObjectInSet(FreeObjectSet<T> *set, size_t size); 44 45 bool AddSet(FreeObjectSet<T> *set); 46 47 void RemoveSet(FreeObjectSet<T> *set); 48 void Merge(FreeObjectList *list); 49 50 template<class Callback> 51 void EnumerateSets(const Callback &cb) const; 52 53 template<class Callback> 54 void EnumerateSets(SetType type, const Callback &cb) const; 55 56 template<class Callback> 57 void EnumerateTopAndLastSets(const Callback &cb) const; 58 59 NO_COPY_SEMANTIC(FreeObjectList); 60 NO_MOVE_SEMANTIC(FreeObjectList); 61 GetFreeObjectSize()62 size_t GetFreeObjectSize() const 63 { 64 return available_; 65 } GetWastedSize()66 size_t GetWastedSize() const 67 { 68 return wasted_; 69 } DecreaseWastedSize(size_t size)70 void DecreaseWastedSize(size_t size) 71 { 72 wasted_ -= size; 73 } IncreaseWastedSize(size_t size)74 void IncreaseWastedSize(size_t size) 75 { 76 wasted_ += size; 77 } 78 NumberOfSets()79 static int NumberOfSets() 80 { 81 return NUMBER_OF_SETS; 82 } 83 84 private: 85 static constexpr int NUMBER_OF_SETS = 39; 86 static constexpr size_t MIN_SIZE = 16; 87 static constexpr size_t SMALL_SET_MAX_SIZE = 256; 88 static constexpr size_t LARGE_SET_MAX_SIZE = 65536; 89 static constexpr size_t HUGE_SET_MAX_SIZE = 255_KB; 90 static constexpr int SMALL_SET_MAX_INDEX = 29; 91 static constexpr int NUMBER_OF_LAST_LARGE = NUMBER_OF_SETS - 2; 92 static constexpr int NUMBER_OF_LAST_HUGE = NUMBER_OF_SETS - 1; 93 static constexpr size_t INTERVAL_OFFSET = 3; 94 static constexpr size_t LOG2_OFFSET = 21; 95 static constexpr size_t MAX_BIT_OF_SIZET = sizeof(size_t) << INTERVAL_OFFSET; 96 const int smallSetOffsetIndex = 2; 97 SelectSetType(size_t size)98 inline SetType SelectSetType(size_t size) const 99 { 100 if (size < SMALL_SET_MAX_SIZE) { 101 if (UNLIKELY(size < MIN_SIZE)) { 102 return FreeObjectSet<T>::INVALID_SET_TYPE; 103 } 104 return (size >> INTERVAL_OFFSET) - smallSetOffsetIndex; 105 } 106 if (size < LARGE_SET_MAX_SIZE) { 107 #ifdef PANDA_TARGET_64 108 return MAX_BIT_OF_SIZET - __builtin_clzll(size) + LOG2_OFFSET; 109 #else 110 return MAX_BIT_OF_SIZET - __builtin_clzl(size) + LOG2_OFFSET; 111 #endif 112 } 113 if (size >= HUGE_SET_MAX_SIZE) { 114 return NUMBER_OF_LAST_HUGE; 115 } 116 117 return NUMBER_OF_LAST_LARGE; 118 } SetNoneEmptyBit(SetType type)119 inline void SetNoneEmptyBit(SetType type) 120 { 121 noneEmptySetBitMap_ |= 1ULL << static_cast<uint32_t>(type); 122 } ClearNoneEmptyBit(SetType type)123 inline void ClearNoneEmptyBit(SetType type) 124 { 125 noneEmptySetBitMap_ &= ~(1ULL << static_cast<uint32_t>(type)); 126 } CalcNextNoneEmptyIndex(SetType start)127 inline size_t CalcNextNoneEmptyIndex(SetType start) 128 { 129 return __builtin_ffsll(noneEmptySetBitMap_ >> static_cast<uint32_t>(start)) + start - 1; 130 } 131 132 size_t available_ = 0; 133 size_t wasted_ = 0; 134 uint64_t noneEmptySetBitMap_ = 0; 135 Span<FreeObjectSet<T> *> sets_ {}; 136 Span<FreeObjectSet<T> *> lastSets_ {}; 137 JitFort *jitFort_ {nullptr}; 138 }; 139 } // namespace panda::ecmascript 140 #endif // ECMASCRIPT_MEM_FREE_OBJECT_LIST_H 141