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 } 51 } 52 53 static const int NOT_FOUND = -1; 54 55 private: PropertiesCache()56 PropertiesCache() 57 { 58 for (uint32_t i = 0; i < CACHE_LENGTH; ++i) { 59 keys_[i].hclass_ = nullptr; 60 keys_[i].key_ = JSTaggedValue::Hole(); 61 keys_[i].results_ = NOT_FOUND; 62 } 63 } 64 ~PropertiesCache() = default; 65 66 struct PropertyKey { 67 JSHClass *hclass_{nullptr}; 68 JSTaggedValue key_{JSTaggedValue::Hole()}; 69 int results_{NOT_FOUND}; 70 }; 71 Hash(JSHClass * cls,JSTaggedValue key)72 static inline int Hash(JSHClass *cls, JSTaggedValue key) 73 { 74 uint32_t clsHash = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(cls)) >> 3U; // skip 8bytes 75 uint32_t keyHash = key.GetKeyHashCode(); 76 return static_cast<int>((clsHash ^ keyHash) & CACHE_LENGTH_MASK); 77 } 78 79 static const uint32_t CACHE_LENGTH_BIT = 10; 80 static const uint32_t CACHE_LENGTH = (1U << CACHE_LENGTH_BIT); 81 static const uint32_t CACHE_LENGTH_MASK = CACHE_LENGTH - 1; 82 83 std::array<PropertyKey, CACHE_LENGTH> keys_{}; 84 85 friend class EcmaContext; 86 }; 87 } // namespace panda::ecmascript 88 #endif // ECMASCRIPT_IC_PROPERTIES_CACHE_H 89