1 /*
2  * Copyright (c) 2023 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 #ifndef ECMASCRIPT_COMPILER_AOT_SNAPSHOT_SNAPSHOT_GLOBAL_DATA_H
16 #define ECMASCRIPT_COMPILER_AOT_SNAPSHOT_SNAPSHOT_GLOBAL_DATA_H
17 
18 #include "ecmascript/ecma_vm.h"
19 #include "ecmascript/object_factory.h"
20 
21 namespace panda::ecmascript::kungfu {
22 class SnapshotGlobalData;
23 /*
24  * The information that needs to be revised before saving the 'ai' file is recorded in SnapshotReviseData.
25  * Currently, the revised information includes the entry index of each method in the 'an' file.
26  */
27 class ReviseData {
28 public:
29     struct ItemData {
30         uint32_t dataIdx_;
31         uint32_t cpArrayIdx_;
32         int32_t constpoolIdx_;
33     };
34 
35     ReviseData() = default;
36     virtual ~ReviseData() = default;
37 
Record(ItemData data)38     void Record(ItemData data)
39     {
40         data_.emplace_back(data);
41     }
42 
43     void PUBLIC_API Resolve(JSThread *thread, const SnapshotGlobalData *globalData,
44                             const CMap<std::pair<std::string, uint32_t>, uint32_t> &methodToEntryIndexMap);
45 
46 protected:
47     JSHandle<ConstantPool> GetConstantPoolFromSnapshotData(JSThread *thread, const SnapshotGlobalData *globalData,
48                                                            uint32_t dataIdx, uint32_t cpArrayIdx);
49     std::vector<ItemData> data_;
50 };
51 
52 class SnapshotReviseInfo {
53 public:
54     SnapshotReviseInfo() = default;
55     ~SnapshotReviseInfo() = default;
56 
Record(ReviseData::ItemData data)57     void Record(ReviseData::ItemData data)
58     {
59         reviseData_.Record(data);
60     }
61 
ResolveData(JSThread *thread, const SnapshotGlobalData *globalData, const CMap<std::pair<std::string, uint32_t>, uint32_t> &methodToEntryIndexMap)62     void ResolveData(JSThread *thread, const SnapshotGlobalData *globalData,
63                      const CMap<std::pair<std::string, uint32_t>, uint32_t> &methodToEntryIndexMap)
64     {
65         reviseData_.Resolve(thread, globalData, methodToEntryIndexMap);
66     }
67 
68 private:
69     ReviseData reviseData_ {};
70 };
71 
72 class SnapshotGlobalData {
73 public:
74     // top level specified field
75     enum class CP_TOP_ITEM : int8_t {
76         PANDA_INFO_ID = 0,
77         CP_ARRAY_ID,
78         COUNT
79     };
80 
81     // file specified field
82     enum class CP_PANDA_INFO_ITEM : int8_t {
83         NAME_ID = 0,
84         INDEX_ID,
85         COUNT
86     };
87 
Cast(CP_TOP_ITEM value)88     static int8_t Cast(CP_TOP_ITEM value)
89     {
90         return static_cast<int8_t>(value);
91     }
92 
Cast(CP_PANDA_INFO_ITEM value)93     static int8_t Cast(CP_PANDA_INFO_ITEM value)
94     {
95         return static_cast<int8_t>(value);
96     }
97 
98     SnapshotGlobalData() = default;
99     ~SnapshotGlobalData() = default;
100 
Iterate(const RootVisitor &v)101     void Iterate(const RootVisitor &v)
102     {
103         v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&data_)));
104         v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&curSnapshotCpArray_)));
105         v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&symbolInfo_)));
106         v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&hclassInfo_)));
107         v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&arrayInfo_)));
108         v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&constantIndexInfo_)));
109         v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&protoTransTableInfo_)));
110     }
111 
SetData(JSTaggedValue data)112     void SetData(JSTaggedValue data)
113     {
114         data_ = data;
115     }
116 
GetData() const117     JSTaggedValue GetData() const
118     {
119         return data_;
120     }
121 
GetCurDataIdx() const122     uint32_t GetCurDataIdx() const
123     {
124         return curDataIdx_;
125     }
126 
GetCurSnapshotCpArray() const127     JSTaggedValue GetCurSnapshotCpArray() const
128     {
129         return curSnapshotCpArray_;
130     }
131 
132     void AddSnapshotCpArrayToData(JSThread *thread, CString fileName, uint32_t fileIndex,
133                                   JSHandle<TaggedArray> snapshotCpArray);
134 
135     CString GetFileNameByDataIdx(uint32_t dataIdx) const;
136 
RecordReviseData(ReviseData::ItemData data)137     void RecordReviseData(ReviseData::ItemData data)
138     {
139         reviseInfo_.Record(data);
140     }
141 
ResolveSnapshotData(JSThread *thread, const CMap<std::pair<std::string, uint32_t>, uint32_t> &methodToEntryIndexMap)142     void ResolveSnapshotData(JSThread *thread,
143                              const CMap<std::pair<std::string, uint32_t>, uint32_t> &methodToEntryIndexMap)
144     {
145         reviseInfo_.ResolveData(thread, this, methodToEntryIndexMap);
146     }
147 
RecordCpArrIdx(int32_t constantPoolId, uint32_t cpArrIdx)148     void RecordCpArrIdx(int32_t constantPoolId, uint32_t cpArrIdx)
149     {
150         dataIdxToCpArrIdxMap_[curDataIdx_][constantPoolId] = cpArrIdx;
151     }
152 
GetCpArrIdxByConstanPoolId(int32_t constantPoolId)153     uint32_t GetCpArrIdxByConstanPoolId(int32_t constantPoolId)
154     {
155         return GetCpIdToCpArrIdxMap().at(constantPoolId);
156     }
157 
GetCpIdToCpArrIdxMap()158     const CUnorderedMap<int32_t, uint32_t>& GetCpIdToCpArrIdxMap()
159     {
160         return dataIdxToCpArrIdxMap_.at(curDataIdx_);
161     }
162 
GetHClassInfo()163     JSTaggedValue GetHClassInfo()
164     {
165         return hclassInfo_;
166     }
167 
GetArrayInfo()168     JSTaggedValue GetArrayInfo()
169     {
170         return arrayInfo_;
171     }
172 
GetSymbolInfo() const173     JSTaggedValue GetSymbolInfo() const
174     {
175         return symbolInfo_;
176     }
177 
GetConstantIndexInfo()178     JSTaggedValue GetConstantIndexInfo()
179     {
180         return constantIndexInfo_;
181     }
182 
GetProtoTransTableInfo() const183     JSTaggedValue GetProtoTransTableInfo() const
184     {
185         return protoTransTableInfo_;
186     }
187 
GetObjectLiteralHClassCache() const188     JSTaggedValue GetObjectLiteralHClassCache() const
189     {
190         if (hclassInfo_.IsTaggedArray()) {
191             auto hclassInfoArr = TaggedArray::Cast(hclassInfo_);
192             ASSERT(hclassInfoArr->GetLength() > 0);
193             return hclassInfoArr->Get(hclassInfoArr->GetLength() - 1);
194         }
195         return JSTaggedValue::Undefined();
196     }
197 
StoreHClassInfo(JSHandle<TaggedArray> info)198     void StoreHClassInfo(JSHandle<TaggedArray> info)
199     {
200         hclassInfo_ = info.GetTaggedValue();
201     }
202 
StoreArrayInfo(JSHandle<TaggedArray> info)203     void StoreArrayInfo(JSHandle<TaggedArray> info)
204     {
205         arrayInfo_ = info.GetTaggedValue();
206     }
207 
StoreSymbolInfo(JSHandle<TaggedArray> info)208     void StoreSymbolInfo(JSHandle<TaggedArray> info)
209     {
210         symbolInfo_ = info.GetTaggedValue();
211     }
212 
StoreConstantIndexInfo(JSHandle<TaggedArray> info)213     void StoreConstantIndexInfo(JSHandle<TaggedArray> info)
214     {
215         constantIndexInfo_ = info.GetTaggedValue();
216     }
217 
StoreProtoTransTableInfo(JSHandle<JSTaggedValue> info)218     void StoreProtoTransTableInfo(JSHandle<JSTaggedValue> info)
219     {
220         protoTransTableInfo_ = info.GetTaggedValue();
221     }
222 
223 private:
224     using CpIdToCpArrIdxMap = CUnorderedMap<int32_t, uint32_t>;
225 
226     bool isFirstData_ {true};
227     uint32_t curDataIdx_ {0};
228     JSTaggedValue data_ {JSTaggedValue::Hole()};
229     JSTaggedValue curSnapshotCpArray_ {JSTaggedValue::Hole()};
230     CUnorderedMap<uint32_t, CpIdToCpArrIdxMap> dataIdxToCpArrIdxMap_;
231     CUnorderedMap<uint32_t, CString> dataIdxToFileNameMap_ {};
232 
233     SnapshotReviseInfo reviseInfo_;
234     JSTaggedValue hclassInfo_ {JSTaggedValue::Hole()};
235     JSTaggedValue arrayInfo_ {JSTaggedValue::Hole()};
236     JSTaggedValue symbolInfo_ {JSTaggedValue::Hole()};
237     JSTaggedValue constantIndexInfo_ {JSTaggedValue::Hole()};
238     JSTaggedValue protoTransTableInfo_ {JSTaggedValue::Hole()};
239 };
240 }  // panda::ecmascript::kungfu
241 #endif // ECMASCRIPT_COMPILER_AOT_SNAPSHOT_SNAPSHOT_GLOBAL_DATA_H
242