• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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/ecma_macros.h"
20 #include "ecmascript/js_tagged_value.h"
21 #include "ecmascript/mem/barriers.h"
22 #include "ecmascript/mem/visitor.h"
23 
24 namespace panda::ecmascript {
25 class ObjectFactory;
26 class JSThread;
27 
28 class TaggedArray : public TaggedObject {
29 public:
30     static constexpr uint32_t MAX_ARRAY_INDEX = std::numeric_limits<uint32_t>::max();
31     static constexpr uint32_t MAX_END_UNUSED = 4;
32 
33     CAST_CHECK(TaggedArray, IsTaggedArray);
34 
35     JSTaggedValue Get(uint32_t idx) const;
36 
37     JSTaggedValue Get([[maybe_unused]] const JSThread *thread, uint32_t idx) const;
38 
39     uint32_t GetIdx(const JSTaggedValue &value) const;
40     JSTaggedValue GetBit(uint32_t idx, uint32_t bitOffset) const;
41 
42     template<typename T>
43     inline void Set(const JSThread *thread, uint32_t idx, const JSHandle<T> &value);
44 
45     template <bool needBarrier = true>
46     inline void Set(const JSThread *thread, uint32_t idx, const JSTaggedValue &value);
47 
48     void Set(uint32_t idx, const JSTaggedValue &value);
49     void SetBit(const JSThread* thread, uint32_t idx, uint32_t bitOffset, const JSTaggedValue& value);
50 
51     static JSHandle<TaggedArray> Append(const JSThread *thread, const JSHandle<TaggedArray> &first,
52                                                const JSHandle<TaggedArray> &second);
53     static JSHandle<TaggedArray> AppendSkipHole(const JSThread *thread, const JSHandle<TaggedArray> &first,
54                                                        const JSHandle<TaggedArray> &second, uint32_t copyLength);
55 
ComputeSize(size_t elemSize,uint32_t length)56     static size_t ComputeSize(size_t elemSize, uint32_t length)
57     {
58         ASSERT(elemSize != 0);
59         size_t size = DATA_OFFSET + elemSize * length;
60         return size;
61     }
62 
GetData()63     JSTaggedType *GetData() const
64     {
65         return reinterpret_cast<JSTaggedType *>(ToUintPtr(this) + DATA_OFFSET);
66     }
67 
68     bool IsDictionaryMode() const;
69 
70     bool HasDuplicateEntry() const;
71 
72     bool IsGeneralNewAndNotMarking(const JSThread *thread);
73 
74     static JSHandle<TaggedArray> SetCapacity(const JSThread *thread, const JSHandle<TaggedArray> &array,
75                                              uint32_t capa);
76 
77     static JSHandle<TaggedArray> SetCapacityInOldSpace(const JSThread *thread, const JSHandle<TaggedArray> &array,
78                                                        uint32_t capa);
79 
80     static void RemoveElementByIndex(const JSThread *thread, JSHandle<TaggedArray> &srcArray,
81                                             uint32_t index, uint32_t effectiveLength, bool noNeedBarrier = false);
82     static void InsertElementByIndex(const JSThread *thread, JSHandle<TaggedArray> &srcArray,
83         const JSHandle<JSTaggedValue> &value, uint32_t index, uint32_t effectiveLength);
84     static void CopyTaggedArrayElement(const JSThread *thread, JSHandle<TaggedArray> &srcElements,
85                                               JSHandle<TaggedArray> &dstElements, uint32_t effectiveLength);
86 
87     void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t length, uint32_t extraLength = 0);
88     void FillRangeWithSpecialValue(JSTaggedValue initValue, uint32_t start, uint32_t end);
89 
ShouldTrim(uint32_t oldLength,uint32_t newLength)90     static bool ShouldTrim(uint32_t oldLength, uint32_t newLength)
91     {
92         ASSERT(oldLength >= newLength);
93         return (oldLength - newLength > MAX_END_UNUSED);
94     }
95     void Trim(const JSThread *thread, uint32_t newLength);
96 
97     static constexpr size_t LENGTH_OFFSET = TaggedObjectSize();
98     ACCESSORS_PRIMITIVE_FIELD(Length, uint32_t, LENGTH_OFFSET, EXTRA_LENGTH_OFFSET)
99     ACCESSORS_PRIMITIVE_FIELD(ExtraLength, uint32_t, EXTRA_LENGTH_OFFSET, LAST_OFFSET)
100     DEFINE_ALIGN_SIZE(LAST_OFFSET);
101     static constexpr size_t DATA_OFFSET = SIZE;  // DATA_OFFSET equal to Empty Array size
102 
103     DECL_VISIT_ARRAY(DATA_OFFSET, GetLength(), GetLength());
104     DECL_DUMP()
105 
106 private:
107     friend class ObjectFactory;
108 };
109 
110 static_assert(TaggedArray::LENGTH_OFFSET == sizeof(TaggedObject));
111 static_assert((TaggedArray::DATA_OFFSET % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT)) == 0);
112 
113 // Copy On Write TaggedArray is shared in the nonmovable space.
114 class COWTaggedArray : public TaggedArray {
115 public:
116     CAST_CHECK(COWTaggedArray, IsCOWArray)
117     DECL_DUMP()
118 private:
119     friend class ObjectFactory;
120 };
121 
122 // A Mutant of TaggedArray which has numbers directly stored in Data section.
123 // Used by JSArrays with specified elementsKind.
124 class MutantTaggedArray : public TaggedArray {
125 public:
126     void InitializeWithSpecialValue(JSTaggedType initValue, uint32_t length, uint32_t extraLength = 0);
127 
128     DECL_VISIT_ARRAY(DATA_OFFSET, 0, GetLength());
129     CAST_CHECK(MutantTaggedArray, IsMutantTaggedArray)
130     DECL_DUMP()
131 private:
132     friend class ObjectFactory;
133 };
134 
135 // Copy On Write MutantTaggedArray is shared in the nonmovable space.
136 // With raw numbers stored in Data section.
137 class COWMutantTaggedArray : public MutantTaggedArray {
138 public:
139 
140     DECL_VISIT_ARRAY(DATA_OFFSET, 0, GetLength());
141     CAST_CHECK(COWMutantTaggedArray, IsCOWArray)
142     DECL_DUMP()
143 private:
144     friend class ObjectFactory;
145 };
146 
147 }  // namespace panda::ecmascript
148 #endif  // ECMASCRIPT_TAGGED_ARRAY_H
149