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