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_TAGGED_ARRAY_H 17 #define ECMASCRIPT_TAGGED_ARRAY_H 18 19 #include "ecmascript/js_hclass.h" 20 #include "ecmascript/js_tagged_value.h" 21 22 namespace panda::ecmascript { 23 class ObjectFactory; 24 class JSThread; 25 26 class TaggedArray : public TaggedObject { 27 public: 28 static constexpr uint32_t MAX_ARRAY_INDEX = std::numeric_limits<uint32_t>::max(); 29 static constexpr uint32_t MAX_END_UNUSED = 4; 30 31 CAST_CHECK(TaggedArray, IsTaggedArray); 32 33 JSTaggedValue Get(uint32_t idx) const; 34 35 uint32_t GetIdx(const JSTaggedValue &value) const; 36 37 template<typename T> 38 void Set(const JSThread *thread, uint32_t idx, const JSHandle<T> &value); 39 40 JSTaggedValue Get(const JSThread *thread, uint32_t idx) const; 41 42 template <bool needBarrier = true> 43 void Set(const JSThread *thread, uint32_t idx, const JSTaggedValue &value); 44 45 static inline JSHandle<TaggedArray> Append(const JSThread *thread, const JSHandle<TaggedArray> &first, 46 const JSHandle<TaggedArray> &second); 47 static inline JSHandle<TaggedArray> AppendSkipHole(const JSThread *thread, const JSHandle<TaggedArray> &first, 48 const JSHandle<TaggedArray> &second, uint32_t copyLength); 49 ComputeSize(size_t elemSize,uint32_t length)50 static inline size_t ComputeSize(size_t elemSize, uint32_t length) 51 { 52 ASSERT(elemSize != 0); 53 size_t size = DATA_OFFSET + elemSize * length; 54 return size; 55 } 56 GetData()57 inline JSTaggedType *GetData() const 58 { 59 return reinterpret_cast<JSTaggedType *>(ToUintPtr(this) + DATA_OFFSET); 60 } 61 62 inline bool IsDictionaryMode() const; 63 64 bool HasDuplicateEntry() const; 65 66 static JSHandle<TaggedArray> SetCapacity(const JSThread *thread, const JSHandle<TaggedArray> &array, 67 uint32_t capa); 68 69 static JSHandle<TaggedArray> SetCapacityInOldSpace(const JSThread *thread, const JSHandle<TaggedArray> &array, 70 uint32_t capa); 71 72 static inline void RemoveElementByIndex(const JSThread *thread, JSHandle<TaggedArray> &srcArray, 73 uint32_t index, uint32_t effectiveLength); 74 static inline void InsertElementByIndex(const JSThread *thread, JSHandle<TaggedArray> &srcArray, 75 const JSHandle<JSTaggedValue> &value, uint32_t index, uint32_t effectiveLength); 76 static inline void CopyTaggedArrayElement(const JSThread *thread, JSHandle<TaggedArray> &srcElements, 77 JSHandle<TaggedArray> &dstElements, uint32_t effectiveLength); 78 79 inline void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t length, uint32_t extraLength = 0); 80 ShouldTrim(uint32_t oldLength,uint32_t newLength)81 static inline bool ShouldTrim(uint32_t oldLength, uint32_t newLength) 82 { 83 return (oldLength - newLength > MAX_END_UNUSED); 84 } 85 inline void Trim(const JSThread *thread, uint32_t newLength); 86 87 static constexpr size_t LENGTH_OFFSET = TaggedObjectSize(); 88 ACCESSORS_PRIMITIVE_FIELD(Length, uint32_t, LENGTH_OFFSET, EXTRACT_LENGTH_OFFSET) 89 ACCESSORS_PRIMITIVE_FIELD(ExtraLength, uint32_t, EXTRACT_LENGTH_OFFSET, LAST_OFFSET) 90 DEFINE_ALIGN_SIZE(LAST_OFFSET); 91 static constexpr size_t DATA_OFFSET = SIZE; // DATA_OFFSET equal to Empty Array size 92 93 DECL_VISIT_ARRAY(DATA_OFFSET, GetLength()); 94 DECL_DUMP() 95 96 private: 97 friend class ObjectFactory; 98 }; 99 100 static_assert(TaggedArray::LENGTH_OFFSET == sizeof(TaggedObject)); 101 static_assert((TaggedArray::DATA_OFFSET % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT)) == 0); 102 103 // Copy On Write TaggedArray is shared in the nonmovable space. 104 class COWTaggedArray : public TaggedArray { 105 public: 106 CAST_CHECK(COWTaggedArray, IsCOWArray) 107 DECL_DUMP() 108 private: 109 friend class ObjectFactory; 110 }; 111 112 } // namespace panda::ecmascript 113 #endif // ECMASCRIPT_TAGGED_ARRAY_H 114