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 void Set(const JSThread *thread, uint32_t idx, const JSTaggedValue &value); 43 44 static inline JSHandle<TaggedArray> Append(const JSThread *thread, const JSHandle<TaggedArray> &first, 45 const JSHandle<TaggedArray> &second); 46 static inline JSHandle<TaggedArray> AppendSkipHole(const JSThread *thread, const JSHandle<TaggedArray> &first, 47 const JSHandle<TaggedArray> &second, uint32_t copyLength); 48 ComputeSize(size_t elemSize,uint32_t length)49 static inline size_t ComputeSize(size_t elemSize, uint32_t length) 50 { 51 ASSERT(elemSize != 0); 52 size_t size = DATA_OFFSET + elemSize * length; 53 return size; 54 } 55 GetData()56 inline JSTaggedType *GetData() const 57 { 58 return reinterpret_cast<JSTaggedType *>(ToUintPtr(this) + DATA_OFFSET); 59 } 60 61 inline bool IsDictionaryMode() const; 62 63 bool HasDuplicateEntry() const; 64 65 static JSHandle<TaggedArray> SetCapacity(const JSThread *thread, const JSHandle<TaggedArray> &array, 66 uint32_t capa); 67 68 static JSHandle<TaggedArray> SetCapacityInOldSpace(const JSThread *thread, const JSHandle<TaggedArray> &array, 69 uint32_t capa); 70 71 inline void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t length, uint32_t extraLength = 0); 72 ShouldTrim(uint32_t oldLength,uint32_t newLength)73 static inline bool ShouldTrim(uint32_t oldLength, uint32_t newLength) 74 { 75 return (oldLength - newLength > MAX_END_UNUSED); 76 } 77 inline void Trim(JSThread *thread, uint32_t newLength); 78 79 static constexpr size_t LENGTH_OFFSET = TaggedObjectSize(); 80 ACCESSORS_PRIMITIVE_FIELD(Length, uint32_t, LENGTH_OFFSET, EXTRACT_LENGTH_OFFSET) 81 ACCESSORS_PRIMITIVE_FIELD(ExtraLength, uint32_t, EXTRACT_LENGTH_OFFSET, LAST_OFFSET) 82 DEFINE_ALIGN_SIZE(LAST_OFFSET); 83 static constexpr size_t DATA_OFFSET = SIZE; // DATA_OFFSET equal to Empty Array size 84 85 DECL_VISIT_ARRAY(DATA_OFFSET, GetLength()); 86 DECL_DUMP() 87 88 private: 89 friend class ObjectFactory; 90 }; 91 92 static_assert(TaggedArray::LENGTH_OFFSET == sizeof(TaggedObject)); 93 static_assert((TaggedArray::DATA_OFFSET % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT)) == 0); 94 95 // Copy On Write TaggedArray is shared in the nonmovable space. 96 class COWTaggedArray : public TaggedArray { 97 public: 98 CAST_CHECK(COWTaggedArray, IsCOWArray) 99 DECL_DUMP() 100 private: 101 friend class ObjectFactory; 102 }; 103 104 } // namespace panda::ecmascript 105 #endif // ECMASCRIPT_TAGGED_ARRAY_H 106