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