1 /** 2 * Copyright (c) 2024 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 PANDA_PLUGINS_ETS_RUNTIME_TO_STRING_CACHE 17 #define PANDA_PLUGINS_ETS_RUNTIME_TO_STRING_CACHE 18 19 #include "plugins/ets/runtime/types/ets_array.h" 20 #include "plugins/ets/runtime/types/ets_string.h" 21 namespace ark::ets { 22 23 namespace test { 24 class EtsToStringCacheTest; 25 class EtsToStringCacheElementTest; 26 } // namespace test 27 28 enum class ToStringResult : size_t { 29 LOAD_CACHED = 0, 30 LOAD_FAIL_LOCKED, 31 LOAD_FAIL_UPDATED, 32 STORE_NEW, 33 STORE_UPDATE, 34 STORE_FAIL 35 }; 36 37 inline std::ostream &operator<<(std::ostream &out, ToStringResult res) 38 { 39 static constexpr auto NAMES = 40 std::array {"LOAD_CACHED", "LOAD_FAIL_LOCKED", "LOAD_FAIL_UPDATED", "STORE_NEW", "STORE_UPDATE", "STORE_FAIL"}; 41 ASSERT(static_cast<size_t>(res) < NAMES.size()); 42 return out << NAMES[static_cast<size_t>(res)]; 43 } 44 45 namespace detail { 46 47 template <typename T> 48 class EtsToStringCacheElement; 49 50 template <typename T> 51 struct SimpleHash; 52 53 template <typename T, typename Derived, typename Hash> 54 class EtsToStringCache; 55 56 template <typename T, typename Derived, typename Hash = SimpleHash<T>> 57 class EtsToStringCache : public EtsTypedObjectArray<EtsToStringCacheElement<T>> { 58 public: 59 static Derived *Create(EtsCoroutine *coro); FromCoreType(ObjectHeader * objectHeader)60 static Derived *FromCoreType(ObjectHeader *objectHeader) 61 { 62 return reinterpret_cast<Derived *>(objectHeader); 63 } 64 65 /** 66 * @brief Compute representation of number and store to cache if possible 67 * @param coro Pointer to current coroutine 68 * @param number Number (double, float or int64) to get representation for 69 * @param elem Pointer to `EtsToStringCacheElement` loaded from cache 70 * @param cached Cached `Data` (string and flag) which was read from \p elem 71 * @pre `flag` in `Data` \p cached must be even (unlocked) 72 * @pre `number` stored in `elem` is supposed to differ from \p number (because we force store) 73 */ 74 EtsString *CacheAndGetNoCheck(EtsCoroutine *coro, T number, ObjectHeader *elem, uint64_t cached); 75 76 /** 77 * @brief Load string representation of number from cache, or compute it and store to cache if possible 78 * @param coro Pointer to current coroutine 79 * @param number Number (double, float or int64) to get representation for 80 */ GetOrCache(EtsCoroutine * coro,T number)81 EtsString *GetOrCache(EtsCoroutine *coro, T number) 82 { 83 return GetOrCacheImpl(coro, number).first; 84 } 85 86 /** 87 * @brief Get string representation of number ignoring the cache 88 * @param number Number (double, float or int64) to get representation for 89 */ 90 static EtsString *GetNoCache(T number); 91 92 private: 93 static constexpr uint32_t CACHE_SIZE_SHIFT = 8U; 94 static constexpr size_t SIZE = 1U << CACHE_SIZE_SHIFT; 95 96 using Elem = EtsToStringCacheElement<T>; 97 using Base = EtsTypedObjectArray<Elem>; 98 99 static uint32_t GetIndex(T number); 100 void StoreToCache(EtsCoroutine *coro, EtsHandle<EtsString> &stringHandle, T number, uint32_t index); 101 std::pair<EtsString *, ToStringResult> FinishUpdate(EtsCoroutine *coro, T number, EtsToStringCacheElement<T> *elem, 102 uint64_t cached); 103 std::pair<EtsString *, ToStringResult> GetOrCacheImpl(EtsCoroutine *coro, T number); 104 105 friend class ark::ets::test::EtsToStringCacheTest; 106 }; 107 108 } // namespace detail 109 110 class DoubleToStringCache : public detail::EtsToStringCache<EtsDouble, DoubleToStringCache> {}; 111 class FloatToStringCache : public detail::EtsToStringCache<EtsFloat, FloatToStringCache> {}; 112 class LongToStringCache : public detail::EtsToStringCache<EtsLong, LongToStringCache> {}; 113 114 } // namespace ark::ets 115 116 #endif // PANDA_PLUGINS_ETS_RUNTIME_TO_STRING_CACHE 117