• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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