• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_IC_PROPERTIES_CACHE_H
17 #define ECMASCRIPT_IC_PROPERTIES_CACHE_H
18 
19 #include <array>
20 
21 #include "ecmascript/js_hclass.h"
22 #include "ecmascript/js_tagged_value.h"
23 #include "ecmascript/ecma_macros.h"
24 
25 namespace panda::ecmascript {
26 class EcmaVM;
27 class PropertiesCache {
28 public:
Get(JSHClass * jsHclass,JSTaggedValue key)29     inline int Get(JSHClass *jsHclass, JSTaggedValue key)
30     {
31         int hash = Hash(jsHclass, key);
32         PropertyKey &prop = keys_[hash];
33         if ((prop.hclass_ == jsHclass) && (prop.key_ == key)) {
34             return keys_[hash].results_;
35         }
36         return NOT_FOUND;
37     }
Set(JSHClass * jsHclass,JSTaggedValue key,int index)38     inline void Set(JSHClass *jsHclass, JSTaggedValue key, int index)
39     {
40         int hash = Hash(jsHclass, key);
41         PropertyKey &prop = keys_[hash];
42         prop.hclass_ = jsHclass;
43         prop.key_ = key;
44         keys_[hash].results_ = index;
45     }
Clear()46     inline void Clear()
47     {
48         for (auto &key : keys_) {
49             key.hclass_ = nullptr;
50             key.key_ = JSTaggedValue::Hole();
51         }
52     }
IsCleared()53     inline bool IsCleared() const
54     {
55         for (auto &key : keys_) {
56             if (key.hclass_ != nullptr) {
57                 return false;
58             }
59         }
60         return true;
61     }
62     static const int NOT_FOUND = -1;
63 
64 private:
PropertiesCache()65     PropertiesCache()
66     {
67         for (uint32_t i = 0; i < CACHE_LENGTH; ++i) {
68             keys_[i].hclass_ = nullptr;
69             keys_[i].key_ = JSTaggedValue::Hole();
70             keys_[i].results_ = NOT_FOUND;
71         }
72     }
73     ~PropertiesCache() = default;
74 
75     struct PropertyKey {
76         JSHClass *hclass_{nullptr};
77         JSTaggedValue key_{JSTaggedValue::Hole()};
78         int results_{NOT_FOUND};
79     };
80 
Hash(JSHClass * cls,JSTaggedValue key)81     static inline int Hash(JSHClass *cls, JSTaggedValue key)
82     {
83         uint32_t clsHash = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(cls)) >> 3U;  // skip 8bytes
84         uint32_t keyHash = key.GetKeyHashCode();
85         return static_cast<int>((clsHash ^ keyHash) & CACHE_LENGTH_MASK);
86     }
87 
88     static const uint32_t CACHE_LENGTH_BIT = 10;
89     static const uint32_t CACHE_LENGTH = (1U << CACHE_LENGTH_BIT);
90     static const uint32_t CACHE_LENGTH_MASK = CACHE_LENGTH - 1;
91 
92     std::array<PropertyKey, CACHE_LENGTH> keys_{};
93 
94     friend class EcmaContext;
95 };
96 }  // namespace panda::ecmascript
97 #endif  // ECMASCRIPT_IC_PROPERTIES_CACHE_H
98