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_TS_TYPES_TS_OBJ_LAYOUT_INFO_H 17 #define ECMASCRIPT_TS_TYPES_TS_OBJ_LAYOUT_INFO_H 18 19 #include "ecmascript/tagged_array-inl.h" 20 21 namespace panda::ecmascript { 22 /* 23 * The TSObjLayoutInfo is organized as follows: 24 * The first position is used to store the number of properties. 25 * Store the key and gt of properties alternately starting from the second position. 26 * +---+-------+------+-------+------+-----+-------+------+ 27 * | N | key_1 | gt_1 | key_2 | gt_2 | ... | key_N | gt_N | 28 * +---+-------+------+-------+------+-----+-------+------+ 29 */ 30 class TSObjLayoutInfo : private TaggedArray { 31 public: 32 static constexpr int MIN_PROPERTIES_LENGTH = JSObject::MIN_PROPERTIES_LENGTH; 33 static constexpr int MAX_PROPERTIES_LENGTH = PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES; 34 static constexpr int ELEMENTS_COUNT_INDEX = 0; 35 static constexpr int ELEMENTS_START_INDEX = 1; 36 static constexpr int ENTRY_SIZE = 2; 37 static constexpr int ENTRY_KEY_OFFSET = 0; 38 static constexpr int ENTRY_TYPE_OFFSET = 1; 39 Cast(TaggedObject * obj)40 inline static TSObjLayoutInfo *Cast(TaggedObject *obj) 41 { 42 ASSERT(JSTaggedValue(obj).IsTaggedArray()); 43 return reinterpret_cast<TSObjLayoutInfo*>(obj); 44 } 45 GetPropertiesCapacity()46 inline uint32_t GetPropertiesCapacity() const 47 { 48 return static_cast<uint32_t>((GetLength() - ELEMENTS_START_INDEX) / ENTRY_SIZE); 49 } 50 SetNumOfProperties(const JSThread * thread,int propertiesNum)51 inline void SetNumOfProperties(const JSThread *thread, int propertiesNum) 52 { 53 return TaggedArray::Set(thread, ELEMENTS_COUNT_INDEX, JSTaggedValue(propertiesNum)); 54 } 55 GetNumOfProperties()56 inline uint32_t GetNumOfProperties() const 57 { 58 return TaggedArray::Get(ELEMENTS_COUNT_INDEX).GetInt(); 59 } 60 GetKey(int index)61 inline JSTaggedValue GetKey(int index) const 62 { 63 uint32_t idxInArray = GetKeyIndex(index); 64 return TaggedArray::Get(idxInArray); 65 } 66 GetTypeId(int index)67 inline JSTaggedValue GetTypeId(int index) const 68 { 69 uint32_t idxInArray = GetTypeIdIndex(index); 70 return TaggedArray::Get(idxInArray); 71 } 72 73 void AddKeyAndType(const JSThread *thread, const JSTaggedValue &key, const JSTaggedValue &typeIdVal); 74 GetLength()75 inline uint32_t GetLength() const 76 { 77 return TaggedArray::GetLength(); 78 } 79 ComputeArrayLength(uint32_t properties_number)80 static inline uint32_t ComputeArrayLength(uint32_t properties_number) 81 { 82 return (properties_number * ENTRY_SIZE) + ELEMENTS_START_INDEX; 83 } 84 85 private: SetKey(const JSThread * thread,int index,const JSTaggedValue & key)86 inline void SetKey(const JSThread *thread, int index, const JSTaggedValue &key) 87 { 88 uint32_t idxInArray = GetKeyIndex(index); 89 TaggedArray::Set(thread, idxInArray, key); 90 } 91 SetTypeId(const JSThread * thread,int index,const JSTaggedValue & tsTypeId)92 inline void SetTypeId(const JSThread *thread, int index, const JSTaggedValue &tsTypeId) 93 { 94 uint32_t idxInArray = GetTypeIdIndex(index); 95 TaggedArray::Set(thread, idxInArray, tsTypeId); 96 } 97 GetKeyIndex(int index)98 inline uint32_t GetKeyIndex(int index) const 99 { 100 return ELEMENTS_START_INDEX + (static_cast<uint32_t>(index) * ENTRY_SIZE) + ENTRY_KEY_OFFSET; 101 } 102 GetTypeIdIndex(int index)103 inline uint32_t GetTypeIdIndex(int index) const 104 { 105 return ELEMENTS_START_INDEX + (static_cast<uint32_t>(index) * ENTRY_SIZE) + ENTRY_TYPE_OFFSET; 106 } 107 ComputeGrowCapacity(uint32_t old_capacity)108 static inline uint32_t ComputeGrowCapacity(uint32_t old_capacity) 109 { 110 uint32_t new_capacity = old_capacity * ENTRY_SIZE + ELEMENTS_START_INDEX; 111 return new_capacity > MAX_PROPERTIES_LENGTH ? MAX_PROPERTIES_LENGTH : new_capacity; 112 } 113 }; 114 } // namespace panda::ecmascript 115 116 #endif // ECMASCRIPT_TS_TYPES_TS_OBJ_LAYOUT_INFO_H 117