1 /*
2  * Copyright (c) 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 #include <fcntl.h>
16 #include <unistd.h>
17 #include <chrono>
18 #include "ecmascript/dfx/hprof/heap_snapshot.h"
19 #include "ecmascript/dfx/hprof/heap_profiler.h"
20 #include "ecmascript/dfx/hprof/heap_root_visitor.h"
21 #include "ecmascript/global_env.h"
22 #include "ecmascript/jspandafile/js_pandafile_manager.h"
23 #include "ecmascript/js_api/js_api_arraylist.h"
24 #include "ecmascript/js_api/js_api_arraylist_iterator.h"
25 #include "ecmascript/js_api/js_api_deque.h"
26 #include "ecmascript/js_api/js_api_hashmap.h"
27 #include "ecmascript/js_api/js_api_hashset.h"
28 #include "ecmascript/js_api/js_api_lightweightmap.h"
29 #include "ecmascript/js_api/js_api_lightweightset.h"
30 #include "ecmascript/js_api/js_api_linked_list.h"
31 #include "ecmascript/js_api/js_api_list.h"
32 #include "ecmascript/js_api/js_api_plain_array.h"
33 #include "ecmascript/js_api/js_api_queue.h"
34 #include "ecmascript/js_api/js_api_stack.h"
35 #include "ecmascript/js_api/js_api_tree_map.h"
36 #include "ecmascript/js_api/js_api_tree_set.h"
37 #include "ecmascript/js_api/js_api_vector.h"
38 #include "ecmascript/js_date.h"
39 #include "ecmascript/js_iterator.h"
40 #include "ecmascript/js_map.h"
41 #include "ecmascript/js_primitive_ref.h"
42 #include "ecmascript/js_promise.h"
43 #include "ecmascript/js_regexp.h"
44 #include "ecmascript/js_set.h"
45 #include "ecmascript/js_string_iterator.h"
46 #include "ecmascript/js_typed_array.h"
47 #include "ecmascript/js_weak_container.h"
48 #include "ecmascript/linked_hash_table.h"
49 #include "ecmascript/napi/include/jsnapi.h"
50 #include "ecmascript/shared_objects/js_shared_array.h"
51 #include "ecmascript/shared_objects/js_shared_map.h"
52 #include "ecmascript/shared_objects/js_shared_set.h"
53 #include "ecmascript/tagged_hash_array.h"
54 #include "ecmascript/tagged_tree.h"
55 #include "ecmascript/tests/test_helper.h"
56 
57 namespace panda::test {
58 using namespace panda::ecmascript;
59 using ErrorType = base::ErrorType;
60 
61 class HeapDumpTest : public testing::Test {
62 public:
63     void SetUp() override
64     {
65         TestHelper::CreateEcmaVMWithScope(ecmaVm_, thread_, scope_);
66         ecmaVm_->SetEnableForceGC(false);
67     }
68 
69     void TearDown() override
70     {
71         TestHelper::DestroyEcmaVMWithScope(ecmaVm_, scope_);
72     }
73 
74     EcmaVM *ecmaVm_ {nullptr};
75     EcmaHandleScope *scope_ {nullptr};
76     JSThread *thread_ {nullptr};
77 };
78 
79 class HeapDumpTestHelper {
80 public:
HeapDumpTestHelper(EcmaVM *vm)81     explicit HeapDumpTestHelper(EcmaVM *vm) : instance(vm) {}
82 
~HeapDumpTestHelper()83     ~HeapDumpTestHelper()
84     {
85         HeapProfilerInterface::Destroy(instance);
86     }
87 
GenerateSnapShot(const std::string &filePath)88     size_t GenerateSnapShot(const std::string &filePath)
89     {
90         // first generate this file of filePath if not exist,
91         // so the function `realpath` of FileStream can not failed on arm/arm64.
92         fstream outputString(filePath, std::ios::out);
93         outputString.close();
94         outputString.clear();
95         FileStream stream(filePath.c_str());
96         HeapProfilerInterface *heapProfile = HeapProfilerInterface::GetInstance(instance);
97         DumpSnapShotOption dumpOption;
98         dumpOption.dumpFormat = DumpFormat::JSON;
99         heapProfile->DumpHeapSnapshot(&stream, dumpOption);
100         return heapProfile->GetIdCount();
101     }
102 
GenerateRawHeapSnashot(const std::string &filePath)103     bool GenerateRawHeapSnashot(const std::string &filePath)
104     {
105         HeapProfilerInterface *heapProfile = HeapProfilerInterface::GetInstance(instance);
106         DumpSnapShotOption dumpOption;
107         dumpOption.dumpFormat = DumpFormat::BINARY;
108         dumpOption.isDumpOOM = true;
109         fstream outputString(filePath, std::ios::out);
110         outputString.close();
111         outputString.clear();
112         int fd = open(filePath.c_str(), O_RDWR | O_CREAT);
113         FileDescriptorStream stream(fd);
114         auto ret = heapProfile->DumpHeapSnapshot(&stream, dumpOption);
115         stream.EndOfStream();
116         return ret;
117     }
118 
DecodeRawHeapSnashot(std::string &inputPath, std::string &outputPath)119     bool DecodeRawHeapSnashot(std::string &inputPath, std::string &outputPath)
120     {
121         HeapProfilerInterface *heapProfile = HeapProfilerInterface::GetInstance(instance);
122         fstream outputString(outputPath, std::ios::out);
123         outputString.close();
124         outputString.clear();
125         auto ret = heapProfile->GenerateHeapSnapshot(inputPath, outputPath);
126         return ret;
127     }
128 
MatchHeapDumpString(const std::string &filePath, std::string targetStr)129     bool MatchHeapDumpString(const std::string &filePath, std::string targetStr)
130     {
131         std::string line;
132         std::ifstream inputStream(filePath);
133         std::size_t lineNum = 0;
134         while (getline(inputStream, line)) {
135             lineNum = line.find(targetStr);
136             if (lineNum != line.npos) {
137                 return true;
138             }
139         }
140         GTEST_LOG_(INFO) << "_______________" << targetStr << std::to_string(lineNum) <<"_______________ not found";
141         return false;  // Lost the Line
142     }
143 
CreateNumberTypedArray(JSType jsType)144     JSHandle<JSTypedArray> CreateNumberTypedArray(JSType jsType)
145     {
146         JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
147         ObjectFactory *factory = instance->GetFactory();
148         JSHandle<JSTaggedValue> handleTagValFunc = env->GetInt8ArrayFunction();
149         switch (jsType) {
150             case JSType::JS_INT8_ARRAY:
151                 break;
152             case JSType::JS_UINT8_ARRAY:
153                 handleTagValFunc = env->GetUint8ArrayFunction();
154                 break;
155             case JSType::JS_UINT8_CLAMPED_ARRAY:
156                 handleTagValFunc = env->GetUint8ClampedArrayFunction();
157                 break;
158             case JSType::JS_INT16_ARRAY:
159                 handleTagValFunc = env->GetInt16ArrayFunction();
160                 break;
161             case JSType::JS_UINT16_ARRAY:
162                 handleTagValFunc = env->GetUint16ArrayFunction();
163                 break;
164             case JSType::JS_INT32_ARRAY:
165                 handleTagValFunc = env->GetInt32ArrayFunction();
166                 break;
167             case JSType::JS_UINT32_ARRAY:
168                 handleTagValFunc = env->GetUint32ArrayFunction();
169                 break;
170             case JSType::JS_FLOAT32_ARRAY:
171                 handleTagValFunc = env->GetFloat32ArrayFunction();
172                 break;
173             case JSType::JS_FLOAT64_ARRAY:
174                 handleTagValFunc = env->GetFloat64ArrayFunction();
175                 break;
176             case JSType::JS_BIGINT64_ARRAY:
177                 handleTagValFunc = env->GetBigInt64ArrayFunction();
178                 break;
179             case JSType::JS_BIGUINT64_ARRAY:
180                 handleTagValFunc = env->GetBigUint64ArrayFunction();
181                 break;
182             default:
183                 ASSERT_PRINT(false, "wrong jsType used in CreateNumberTypedArray function");
184                 break;
185         }
186         return JSHandle<JSTypedArray>::Cast(
187             factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(handleTagValFunc), handleTagValFunc));
188     }
189 
NewObject(uint32_t size, JSType type, JSHandle<JSTaggedValue> proto)190     JSHandle<JSObject> NewObject(uint32_t size, JSType type, JSHandle<JSTaggedValue> proto)
191     {
192         ObjectFactory *factory = instance->GetFactory();
193         JSHandle<JSHClass> hclass = factory->NewEcmaHClass(size, type, proto);
194         return factory->NewJSObjectWithInit(hclass);
195     }
196 
NewSObject(uint32_t size, JSType type, JSHandle<JSTaggedValue> proto)197     JSHandle<JSObject> NewSObject(uint32_t size, JSType type, JSHandle<JSTaggedValue> proto)
198     {
199         ObjectFactory *factory = instance->GetFactory();
200         auto emptySLayout = instance->GetJSThread()->GlobalConstants()->GetHandledEmptySLayoutInfo();
201         JSHandle<JSHClass> hclass = factory->NewSEcmaHClass(size, 0, type, proto, emptySLayout);
202         return factory->NewJSObjectWithInit(hclass);
203     }
204 
205     // JS_SET
NewJSSet()206     JSHandle<JSSet> NewJSSet()
207     {
208         JSThread *thread = instance->GetJSThread();
209         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
210         JSHandle<JSObject> jsSetObject = NewObject(JSSet::SIZE, JSType::JS_SET, proto);
211         JSHandle<JSSet> jsSet = JSHandle<JSSet>::Cast(jsSetObject);
212         JSHandle<LinkedHashSet> linkedSet(LinkedHashSet::Create(thread));
213         jsSet->SetLinkedSet(thread, linkedSet);
214         return jsSet;
215     }
216 
217     // JS_SHARED_SET
NewJSSharedSet()218     JSHandle<JSSharedSet> NewJSSharedSet()
219     {
220         JSThread *thread = instance->GetJSThread();
221         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetSFunctionPrototype();
222         JSHandle<JSObject> jsSSetObject = NewSObject(JSSharedSet::SIZE, JSType::JS_SHARED_SET, proto);
223         JSHandle<JSSharedSet> jsSSet = JSHandle<JSSharedSet>::Cast(jsSSetObject);
224         JSHandle<LinkedHashSet> linkedSet(
225             LinkedHashSet::Create(thread, LinkedHashSet::MIN_CAPACITY, MemSpaceKind::SHARED));
226         jsSSet->SetLinkedSet(thread, linkedSet);
227         jsSSet->SetModRecord(0);
228         return jsSSet;
229     }
230 
231     // JS_MAP
NewJSMap()232     JSHandle<JSMap> NewJSMap()
233     {
234         JSThread *thread = instance->GetJSThread();
235         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
236         JSHandle<JSObject> jsMapObject = NewObject(JSMap::SIZE, JSType::JS_MAP, proto);
237         JSHandle<JSMap> jsMap = JSHandle<JSMap>::Cast(jsMapObject);
238         JSHandle<LinkedHashMap> linkedMap(LinkedHashMap::Create(thread));
239         jsMap->SetLinkedMap(thread, linkedMap);
240         return jsMap;
241     }
242 
243     // JS_SHARED_MAP
NewJSSharedMap()244     JSHandle<JSSharedMap> NewJSSharedMap()
245     {
246         JSThread *thread = instance->GetJSThread();
247         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetSFunctionPrototype();
248         JSHandle<JSObject> jsSMapObject = NewSObject(JSSharedMap::SIZE, JSType::JS_SHARED_MAP, proto);
249         JSHandle<JSSharedMap> jsSMap = JSHandle<JSSharedMap>::Cast(jsSMapObject);
250         JSHandle<LinkedHashMap> linkedMap(
251             LinkedHashMap::Create(thread, LinkedHashMap::MIN_CAPACITY, MemSpaceKind::SHARED));
252         jsSMap->SetLinkedMap(thread, linkedMap);
253         jsSMap->SetModRecord(0);
254         return jsSMap;
255     }
256 
257     //JS_WEAK_SET
NewJSWeakSet()258     JSHandle<JSWeakSet> NewJSWeakSet()
259     {
260         JSThread *thread = instance->GetJSThread();
261         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
262         JSHandle<JSObject> jsWeakSetObject = NewObject(JSWeakSet::SIZE, JSType::JS_WEAK_SET, proto);
263         JSHandle<JSWeakSet> jsWeakSet = JSHandle<JSWeakSet>::Cast(jsWeakSetObject);
264         JSHandle<LinkedHashSet> weakLinkedSet(LinkedHashSet::Create(thread));
265         jsWeakSet->SetLinkedSet(thread, weakLinkedSet);
266         return jsWeakSet;
267     }
268 
269     //JS_WEAK_MAP
NewJSWeakMap()270     JSHandle<JSWeakMap> NewJSWeakMap()
271     {
272         JSThread *thread = instance->GetJSThread();
273         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
274         JSHandle<JSObject> jsWeakMapObject = NewObject(JSWeakMap::SIZE, JSType::JS_WEAK_MAP, proto);
275         JSHandle<JSWeakMap> jsWeakMap = JSHandle<JSWeakMap>::Cast(jsWeakMapObject);
276         JSHandle<LinkedHashMap> weakLinkedMap(LinkedHashMap::Create(thread));
277         jsWeakMap->SetLinkedMap(thread, weakLinkedMap);
278         return jsWeakMap;
279     }
280 
281     // JS_PROXY
NewJSProxy()282     JSHandle<JSProxy> NewJSProxy()
283     {
284         JSThread *thread = instance->GetJSThread();
285         ObjectFactory *factory = instance->GetFactory();
286         JSFunction *newTarget = instance->GetGlobalEnv()->GetObjectFunction().GetObject<JSFunction>();
287         JSHandle<JSTaggedValue> newTargetHandle(thread, newTarget);
288         JSHandle<JSObject> jsObject =
289             factory->NewJSObjectByConstructor(JSHandle<JSFunction>(newTargetHandle), newTargetHandle);
290         JSHandle<JSTaggedValue> emptyObj(thread, jsObject.GetTaggedValue());
291         return factory->NewJSProxy(emptyObj, emptyObj);
292     }
293 
294     // JS_FORIN_ITERATOR
NewJSForInIterator()295     JSHandle<JSForInIterator> NewJSForInIterator()
296     {
297         JSThread *thread = instance->GetJSThread();
298         ObjectFactory *factory = instance->GetFactory();
299         JSHandle<JSTaggedValue> arrayEmpty(thread, factory->NewJSArray().GetTaggedValue());
300         JSHandle<JSTaggedValue> keys(thread, factory->EmptyArray().GetTaggedValue());
301         JSHandle<JSTaggedValue> hclass(thread, JSTaggedValue::Undefined());
302         return factory->NewJSForinIterator(arrayEmpty, keys, hclass);
303     }
304 
305     // JS_REG_EXP_ITERATOR
NewJSRegExpIterator()306     JSHandle<JSRegExpIterator> NewJSRegExpIterator()
307     {
308         ObjectFactory *factory = instance->GetFactory();
309         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
310         JSHandle<EcmaString> emptyString = factory->GetEmptyString();
311         JSHandle<JSTaggedValue> jsRegExp(NewObject(JSRegExp::SIZE, JSType::JS_REG_EXP, proto));
312         return factory->NewJSRegExpIterator(jsRegExp, emptyString, false, false);
313     }
314 
315     // PROMISE_ITERATOR_RECORD
NewPromiseIteratorRecord()316     JSHandle<PromiseIteratorRecord> NewPromiseIteratorRecord()
317     {
318         JSThread *thread = instance->GetJSThread();
319         ObjectFactory *factory = instance->GetFactory();
320         JSFunction *newTarget = instance->GetGlobalEnv()->GetObjectFunction().GetObject<JSFunction>();
321         JSHandle<JSTaggedValue> newTargetHandle(thread, newTarget);
322         JSHandle<JSObject> jsObject =
323             factory->NewJSObjectByConstructor(JSHandle<JSFunction>(newTargetHandle), newTargetHandle);
324         JSHandle<JSTaggedValue> emptyObj(thread, jsObject.GetTaggedValue());
325         return factory->NewPromiseIteratorRecord(emptyObj, false);
326     }
327 
328     // JS_API_ARRAY_LIST
NewJSAPIArrayList()329     JSHandle<JSAPIArrayList> NewJSAPIArrayList()
330     {
331         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
332         JSHandle<JSObject> jsAPIArrayListObject = NewObject(JSAPIArrayList::SIZE, JSType::JS_API_ARRAY_LIST, proto);
333         JSHandle<JSAPIArrayList> jsAPIArrayList = JSHandle<JSAPIArrayList>::Cast(jsAPIArrayListObject);
334         jsAPIArrayList->SetLength(instance->GetJSThread(), JSTaggedValue(0));
335         return jsAPIArrayList;
336     }
337 
338     // JS_API_HASH_MAP
NewJSAPIHashMap()339     JSHandle<JSAPIHashMap> NewJSAPIHashMap()
340     {
341         JSThread *thread = instance->GetJSThread();
342         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
343         JSHandle<JSObject> jsAPIHashMapObject = NewObject(JSAPIHashMap::SIZE, JSType::JS_API_HASH_MAP, proto);
344         JSHandle<JSAPIHashMap> jsAPIHashMap = JSHandle<JSAPIHashMap>::Cast(jsAPIHashMapObject);
345         jsAPIHashMap->SetTable(thread, TaggedHashArray::Create(thread));
346         jsAPIHashMap->SetSize(0);
347         return jsAPIHashMap;
348     }
349 
350     // JS_API_HASH_SET
NewJSAPIHashSet()351     JSHandle<JSAPIHashSet> NewJSAPIHashSet()
352     {
353         JSThread *thread = instance->GetJSThread();
354         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
355         JSHandle<JSObject> jsAPIHashSetObject = NewObject(JSAPIHashSet::SIZE, JSType::JS_API_HASH_SET, proto);
356         JSHandle<JSAPIHashSet> jsAPIHashSet = JSHandle<JSAPIHashSet>::Cast(jsAPIHashSetObject);
357         jsAPIHashSet->SetTable(thread, TaggedHashArray::Create(thread));
358         jsAPIHashSet->SetSize(0);
359         return jsAPIHashSet;
360     }
361 
362     // JS_API_LIGHT_WEIGHT_MAP
NewJSAPILightWeightMap()363     JSHandle<JSAPILightWeightMap> NewJSAPILightWeightMap()
364     {
365         JSThread *thread = instance->GetJSThread();
366         ObjectFactory *factory = instance->GetFactory();
367         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
368         JSHandle<JSObject> jsAPILightWeightMapObject =
369             NewObject(JSAPILightWeightMap::SIZE, JSType::JS_API_LIGHT_WEIGHT_MAP, proto);
370         JSHandle<JSAPILightWeightMap> jsAPILightWeightMap =
371             JSHandle<JSAPILightWeightMap>::Cast(jsAPILightWeightMapObject);
372         JSHandle<JSTaggedValue> hashArray =
373             JSHandle<JSTaggedValue>(factory->NewTaggedArray(JSAPILightWeightMap::DEFAULT_CAPACITY_LENGTH));
374         JSHandle<JSTaggedValue> keyArray =
375             JSHandle<JSTaggedValue>(factory->NewTaggedArray(JSAPILightWeightMap::DEFAULT_CAPACITY_LENGTH));
376         JSHandle<JSTaggedValue> valueArray =
377             JSHandle<JSTaggedValue>(factory->NewTaggedArray(JSAPILightWeightMap::DEFAULT_CAPACITY_LENGTH));
378         jsAPILightWeightMap->SetHashes(thread, hashArray);
379         jsAPILightWeightMap->SetKeys(thread, keyArray);
380         jsAPILightWeightMap->SetValues(thread, valueArray);
381         jsAPILightWeightMap->SetLength(0);
382         return jsAPILightWeightMap;
383     }
384 
385     // JS_API_LIGHT_WEIGHT_SET
NewJSAPILightWeightSet()386     JSHandle<JSAPILightWeightSet> NewJSAPILightWeightSet()
387     {
388         JSThread *thread = instance->GetJSThread();
389         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
390         JSHandle<JSObject> jsAPILightWeightSetObject =
391             NewObject(JSAPILightWeightSet::SIZE, JSType::JS_API_LIGHT_WEIGHT_SET, proto);
392         JSHandle<JSAPILightWeightSet> jsAPILightWeightSet =
393             JSHandle<JSAPILightWeightSet>::Cast(jsAPILightWeightSetObject);
394         JSHandle<TaggedArray> hashes =
395             JSAPILightWeightSet::CreateSlot(thread, JSAPILightWeightSet::DEFAULT_CAPACITY_LENGTH);
396         JSHandle<TaggedArray> values =
397             JSAPILightWeightSet::CreateSlot(thread, JSAPILightWeightSet::DEFAULT_CAPACITY_LENGTH);
398         jsAPILightWeightSet->SetHashes(thread, hashes);
399         jsAPILightWeightSet->SetValues(thread, values);
400         jsAPILightWeightSet->SetLength(0);
401         return jsAPILightWeightSet;
402     }
403 
404     // JS_API_TREE_MAP
NewJSAPITreeMap()405     JSHandle<JSAPITreeMap> NewJSAPITreeMap()
406     {
407         JSThread *thread = instance->GetJSThread();
408         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
409         JSHandle<JSObject> jsAPITreeMapObject = NewObject(JSAPITreeMap::SIZE, JSType::JS_API_TREE_MAP, proto);
410         JSHandle<JSAPITreeMap> jsAPITreeMap = JSHandle<JSAPITreeMap>::Cast(jsAPITreeMapObject);
411         JSHandle<TaggedTreeMap> treeMap(thread, TaggedTreeMap::Create(thread));
412         jsAPITreeMap->SetTreeMap(thread, treeMap);
413         return jsAPITreeMap;
414     }
415 
416     // JS_API_TREE_SET
NewJSAPITreeSet()417     JSHandle<JSAPITreeSet> NewJSAPITreeSet()
418     {
419         JSThread *thread = instance->GetJSThread();
420         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
421         JSHandle<JSObject> jsAPITreeSetObject = NewObject(JSAPITreeSet::SIZE, JSType::JS_API_TREE_SET, proto);
422         JSHandle<JSAPITreeSet> jsAPITreeSet = JSHandle<JSAPITreeSet>::Cast(jsAPITreeSetObject);
423         JSHandle<TaggedTreeSet> treeSet(thread, TaggedTreeSet::Create(thread));
424         jsAPITreeSet->SetTreeSet(thread, treeSet);
425         return jsAPITreeSet;
426     }
427 
428     // JS_API_QUEUE
NewJSAPIQueue()429     JSHandle<JSAPIQueue> NewJSAPIQueue()
430     {
431         JSThread *thread = instance->GetJSThread();
432         ObjectFactory *factory = instance->GetFactory();
433         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
434         JSHandle<JSObject> jsAPIQueueObject = NewObject(JSAPIQueue::SIZE, JSType::JS_API_QUEUE, proto);
435         JSHandle<JSAPIQueue> jsAPIQueue = JSHandle<JSAPIQueue>::Cast(jsAPIQueueObject);
436         JSHandle<TaggedArray> newElements = factory->NewTaggedArray(JSAPIQueue::DEFAULT_CAPACITY_LENGTH);
437         jsAPIQueue->SetLength(thread, JSTaggedValue(0));
438         jsAPIQueue->SetFront(0);
439         jsAPIQueue->SetTail(0);
440         jsAPIQueue->SetElements(thread, newElements);
441         return jsAPIQueue;
442     }
443     // JS_API_DEQUE
NewJSAPIDeque()444     JSHandle<JSAPIDeque> NewJSAPIDeque()
445     {
446         ObjectFactory *factory = instance->GetFactory();
447         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
448         JSHandle<JSObject> jsAPIDequeObject = NewObject(JSAPIDeque::SIZE, JSType::JS_API_DEQUE, proto);
449         JSHandle<JSAPIDeque> jsAPIDeque = JSHandle<JSAPIDeque>::Cast(jsAPIDequeObject);
450         JSHandle<TaggedArray> newElements = factory->NewTaggedArray(JSAPIDeque::DEFAULT_CAPACITY_LENGTH);
451         jsAPIDeque->SetFirst(0);
452         jsAPIDeque->SetLast(0);
453         jsAPIDeque->SetElements(instance->GetJSThread(), newElements);
454         return jsAPIDeque;
455     }
456     // JS_API_STACK
NewJSAPIStack()457     JSHandle<JSAPIStack> NewJSAPIStack()
458     {
459         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
460         JSHandle<JSObject> jsAPIStackObject = NewObject(JSAPIStack::SIZE, JSType::JS_API_STACK, proto);
461         JSHandle<JSAPIStack> jsAPIStack = JSHandle<JSAPIStack>::Cast(jsAPIStackObject);
462         jsAPIStack->SetTop(0);
463         return jsAPIStack;
464     }
465 
466     // JS_API_PLAIN_ARRAY
NewJSAPIPlainArray()467     JSHandle<JSAPIPlainArray> NewJSAPIPlainArray()
468     {
469         JSThread *thread = instance->GetJSThread();
470         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
471         JSHandle<JSObject> jsAPIPlainArrayObject = NewObject(JSAPIPlainArray::SIZE, JSType::JS_API_PLAIN_ARRAY, proto);
472         JSHandle<JSAPIPlainArray> jsAPIPlainArray = JSHandle<JSAPIPlainArray>::Cast(jsAPIPlainArrayObject);
473         JSHandle<TaggedArray> keys =
474                 JSAPIPlainArray::CreateSlot(thread, JSAPIPlainArray::DEFAULT_CAPACITY_LENGTH);
475         JSHandle<TaggedArray> values =
476                 JSAPIPlainArray::CreateSlot(thread, JSAPIPlainArray::DEFAULT_CAPACITY_LENGTH);
477         jsAPIPlainArray->SetKeys(thread, keys);
478         jsAPIPlainArray->SetValues(thread, values);
479         jsAPIPlainArray->SetLength(0);
480         return jsAPIPlainArray;
481     }
482 
483     // JS_API_LIST
NewJSAPIList()484     JSHandle<JSAPIList> NewJSAPIList()
485     {
486         JSThread *thread = instance->GetJSThread();
487         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
488         JSHandle<JSObject> jsAPIListObject = NewObject(JSAPIList::SIZE, JSType::JS_API_LIST, proto);
489         JSHandle<JSAPIList> jsAPIList = JSHandle<JSAPIList>::Cast(jsAPIListObject);
490         JSHandle<JSTaggedValue> taggedSingleList(thread, TaggedSingleList::Create(thread));
491         jsAPIList->SetSingleList(thread, taggedSingleList);
492         return jsAPIList;
493     }
494 
495     // JS_API_LINKED_LIST
NewJSAPILinkedList()496     JSHandle<JSAPILinkedList> NewJSAPILinkedList()
497     {
498         JSThread *thread = instance->GetJSThread();
499         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
500         JSHandle<JSObject> jsAPILinkedListObject = NewObject(JSAPILinkedList::SIZE, JSType::JS_API_LINKED_LIST, proto);
501         JSHandle<JSAPILinkedList> jsAPILinkedList = JSHandle<JSAPILinkedList>::Cast(jsAPILinkedListObject);
502         JSHandle<JSTaggedValue> linkedlist(thread, TaggedDoubleList::Create(thread));
503         jsAPILinkedList->SetDoubleList(thread, linkedlist);
504         return jsAPILinkedList;
505     }
506 
507     // JS_API_VECTOR
NewJSAPIVector()508     JSHandle<JSAPIVector> NewJSAPIVector()
509     {
510         JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
511         JSHandle<JSObject> jsAPIVectorObject = NewObject(JSAPIVector::SIZE, JSType::JS_API_VECTOR, proto);
512         JSHandle<JSAPIVector> jsAPIVector = JSHandle<JSAPIVector>::Cast(jsAPIVectorObject);
513         jsAPIVector->SetLength(0);
514         return jsAPIVector;
515     }
516 
517 private:
518     EcmaVM *instance {nullptr};
519 };
520 
521 class MockHeapProfiler : public HeapProfilerInterface {
522 public:
523     NO_MOVE_SEMANTIC(MockHeapProfiler);
524     NO_COPY_SEMANTIC(MockHeapProfiler);
MockHeapProfiler(HeapProfilerInterface *profiler)525     explicit MockHeapProfiler(HeapProfilerInterface *profiler) : profiler_(profiler) {}
526     ~MockHeapProfiler() override
527     {
528         allocEvtObj_.clear();
529     };
530 
531     void AllocationEvent(TaggedObject *address, size_t size) override
532     {
533         allocEvtObj_.emplace(address, true);
534         profiler_->AllocationEvent(address, size);
535     }
536 
537     void MoveEvent(uintptr_t address, TaggedObject *forwardAddress, size_t size) override
538     {
539         return profiler_->MoveEvent(address, forwardAddress, size);
540     }
541 
542     bool DumpHeapSnapshot(Stream *stream, const DumpSnapShotOption &dumpOption, Progress *progress = nullptr) override
543     {
544         return profiler_->DumpHeapSnapshot(stream, dumpOption, progress);
545     }
546 
547     void DumpHeapSnapshot(const DumpSnapShotOption &dumpOption) override
548     {
549         profiler_->DumpHeapSnapshot(dumpOption);
550     }
551 
552     bool GenerateHeapSnapshot(std::string &inputFilePath, std::string &outputPath) override
553     {
554         return profiler_->GenerateHeapSnapshot(inputFilePath, outputPath);
555     }
556 
557     bool StartHeapTracking(double timeInterval, bool isVmMode = true, Stream *stream = nullptr,
558                            bool traceAllocation = false, bool newThread = true) override
559     {
560         return profiler_->StartHeapTracking(timeInterval, isVmMode, stream, traceAllocation, newThread);
561     }
562 
563     bool StopHeapTracking(Stream *stream, Progress *progress = nullptr, bool newThread = true) override
564     {
565         return profiler_->StopHeapTracking(stream, progress, newThread);
566     }
567 
568     bool UpdateHeapTracking(Stream *stream) override
569     {
570         return profiler_->UpdateHeapTracking(stream);
571     }
572 
573     bool StartHeapSampling(uint64_t samplingInterval, int stackDepth = 128) override
574     {
575         return profiler_->StartHeapSampling(samplingInterval, stackDepth);
576     }
577 
578     void StopHeapSampling() override
579     {
580         profiler_->StopHeapSampling();
581     }
582 
583     const struct SamplingInfo *GetAllocationProfile() override
584     {
585         return profiler_->GetAllocationProfile();
586     }
587 
588     size_t GetIdCount() override
589     {
590         return profiler_->GetIdCount();
591     }
592 
593     std::unordered_map<TaggedObject *, bool> allocEvtObj_;
594     HeapProfilerInterface *profiler_ {nullptr};
595 };
596 
HWTEST_F_L0(HeapDumpTest, TestAllocationEvent)597 HWTEST_F_L0(HeapDumpTest, TestAllocationEvent)
598 {
599     const std::string abcFileName = HPROF_TEST_ABC_FILES_DIR"heapdump.abc";
600     const std::string jsFileName = HPROF_TEST_JS_FILES_DIR"heapdump.js";
601     MockHeapProfiler mockHeapProfiler(ecmaVm_->GetOrNewHeapProfile());
602     ecmaVm_->SetHeapProfile(&mockHeapProfiler);
603 
604     std::unordered_map<TaggedObject *, bool> ObjBeforeExecute;
605     std::unordered_map<TaggedObject *, bool> *ObjMap = &ObjBeforeExecute;
606     auto heap = ecmaVm_->GetHeap();
607     ASSERT_NE(heap, nullptr);
608     auto countCb = [&ObjMap](TaggedObject *obj) {
609         ObjMap->emplace(obj, true);
610     };
611     heap->IterateOverObjects(countCb);
612     RootVisitor rootVisitor = [&countCb]([[maybe_unused]] Root type, ObjectSlot slot) {
613         JSTaggedValue value((slot).GetTaggedType());
614         if (!value.IsHeapObject()) {
615             return;
616         }
617         TaggedObject *root = value.GetTaggedObject();
618         countCb(root);
619     };
620     RootRangeVisitor rangeVisitor = [&rootVisitor]([[maybe_unused]] Root type,
621                                     ObjectSlot start, ObjectSlot end) {
622         for (ObjectSlot slot = start; slot < end; slot++) {
623             rootVisitor(type, slot);
624         }
625     };
626     RootBaseAndDerivedVisitor derivedVisitor = []
627         ([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot base, [[maybe_unused]] ObjectSlot derived,
628          [[maybe_unused]] uintptr_t baseOldObject) {};
629     ecmaVm_->Iterate(rootVisitor, rangeVisitor, VMRootVisitType::HEAP_SNAPSHOT);
630     thread_->Iterate(rootVisitor, rangeVisitor, derivedVisitor);
631 
632     bool result = JSNApi::Execute(ecmaVm_, abcFileName, "heapdump");
633     EXPECT_TRUE(result);
634 
635     std::unordered_map<TaggedObject *, bool> ObjAfterExecute;
636     ObjMap = &ObjAfterExecute;
637     heap->IterateOverObjects(countCb);
638     ecmaVm_->Iterate(rootVisitor, rangeVisitor, VMRootVisitType::HEAP_SNAPSHOT);
639     thread_->Iterate(rootVisitor, rangeVisitor, derivedVisitor);
640     ecmaVm_->SetHeapProfile(mockHeapProfiler.profiler_);
641 
642     std::unordered_map<std::string, int> noTraceObjCheck =
643        {{"TaggedArray", 1}, {"AsyncFunction", 2}, {"LexicalEnv", 2}, {"Array", 3}, {"Function", 7}, {"Map", 1},
644        {"Object", 1}, {"Uint8 Clamped Array", 1}, {"Uint32 Array", 1}, {"Float32 Array", 1}, {"Int32 Array", 1},
645        {"Int16 Array", 1}, {"BigUint64 Array", 1}, {"Uint8 Array", 1}, {"Float64 Array", 1}, {"ByteArray", 11},
646        {"Int8 Array", 1}, {"BigInt64 Array", 1}, {"Uint16 Array", 1}};
647     bool pass = true;
648     std::unordered_map<std::string, int> noTraceObj;
649     for (auto o = ObjAfterExecute.begin(); o != ObjAfterExecute.end(); o++) {
650         if (ObjBeforeExecute.find(o->first) != ObjBeforeExecute.end()) {
651             continue;
652         }
653         if (mockHeapProfiler.allocEvtObj_.find(o->first) != mockHeapProfiler.allocEvtObj_.end()) {
654             continue;
655         }
656         auto objType = o->first->GetClass()->GetObjectType();
657         std::string typeName = ConvertToStdString(JSHClass::DumpJSType(objType));
658         if (noTraceObjCheck.size() == 0) {
659             LOG_ECMA(ERROR) << "Object not traced, Addr=" << o->first << ", TypeName=" << typeName;
660             pass = false;
661         }
662         if (noTraceObj.find(typeName) == noTraceObj.end()) {
663             noTraceObj.emplace(typeName, 0);
664         }
665         noTraceObj[typeName] += 1;
666     }
667     for (auto o = noTraceObj.begin(); o != noTraceObj.end(); o++) {
668         if (noTraceObjCheck.find(o->first) == noTraceObjCheck.end()) {
669             LOG_ECMA(ERROR) << "Object not traced, TypeName=" << o->first << ", count=" << o->second;
670             pass = false;
671         }
672     }
673     ASSERT_TRUE(pass);
674 }
675 
HWTEST_F_L0(HeapDumpTest, TestHeapDumpFunctionUrl)676 HWTEST_F_L0(HeapDumpTest, TestHeapDumpFunctionUrl)
677 {
678     const std::string abcFileName = HPROF_TEST_ABC_FILES_DIR"heapdump.abc";
679 
680     bool result = JSNApi::Execute(ecmaVm_, abcFileName, "heapdump");
681     EXPECT_TRUE(result);
682 
683     HeapDumpTestHelper tester(ecmaVm_);
684     tester.GenerateSnapShot("testFunctionUrl.heapsnapshot");
685 
686     // match function url
687     std::string line;
688     std::ifstream inputStream("testFunctionUrl.heapsnapshot");
689     bool strMatched = false;
690     bool funcTempMatched = false;
691     while (getline(inputStream, line)) {
692         if (strMatched && funcTempMatched) {
693             break;
694         }
695         if (line == "\"heapdump greet(line:98)\",") {
696             strMatched = true;
697             continue;
698         }
699         if (line == "\"ArkInternalFunctionTemplate\",") {
700             funcTempMatched = true;
701             continue;
702         }
703     }
704     ASSERT_TRUE(strMatched);
705     ASSERT_TRUE(funcTempMatched);
706 }
707 
HWTEST_F_L0(HeapDumpTest, DISABLED_TestAllocationMassiveMoveNode)708 HWTEST_F_L0(HeapDumpTest, DISABLED_TestAllocationMassiveMoveNode)
709 {
710     const std::string abcFileName = HPROF_TEST_ABC_FILES_DIR"allocation.abc";
711     HeapProfilerInterface *heapProfile = HeapProfilerInterface::GetInstance(ecmaVm_);
712 
713     // start allocation
714     bool start = heapProfile->StartHeapTracking(50);
715     EXPECT_TRUE(start);
716 
717     auto currentTime = std::chrono::system_clock::now();
718     auto currentTimeBeforeMs =
719         std::chrono::time_point_cast<std::chrono::milliseconds>(currentTime).time_since_epoch().count();
720 
721     bool result = JSNApi::Execute(ecmaVm_, abcFileName, "allocation");
722 
723     currentTime = std::chrono::system_clock::now();
724     auto currentTimeAfterMs =
725         std::chrono::time_point_cast<std::chrono::milliseconds>(currentTime).time_since_epoch().count();
726     EXPECT_TRUE(result);
727 
728     std::string fileName = "test.allocationtime";
729     fstream outputString(fileName, std::ios::out);
730     outputString.close();
731     outputString.clear();
732 
733     // stop allocation
734     FileStream stream(fileName.c_str());
735     bool stop = heapProfile->StopHeapTracking(&stream, nullptr);
736     EXPECT_TRUE(stop);
737     HeapProfilerInterface::Destroy(ecmaVm_);
738 
739     auto timeSpent = currentTimeAfterMs - currentTimeBeforeMs;
740     long long int limitedTimeMs = 30000;
741     ASSERT_TRUE(timeSpent < limitedTimeMs);
742 }
743 
744 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName1)
745 {
746     JSHandle<GlobalEnv> env = thread_->GetEcmaVM()->GetGlobalEnv();
747     ObjectFactory *factory = ecmaVm_->GetFactory();
748     HeapDumpTestHelper tester(ecmaVm_);
749 
750     // TAGGED_ARRAY
751     factory->NewTaggedArray(10);
752     // LEXICAL_ENV
753     factory->NewLexicalEnv(10);
754     // CONSTANT_POOL
755     factory->NewConstantPool(10);
756     // PROFILE_TYPE_INFO
757     factory->NewProfileTypeInfo(10);
758     // TAGGED_DICTIONARY
759     factory->NewDictionaryArray(10);
760     // AOT_LITERAL_INFO
761     factory->NewAOTLiteralInfo(10);
762     // VTABLE
763     factory->NewVTable(10);
764     // COW_TAGGED_ARRAY
765     factory->NewCOWTaggedArray(10);
766     // HCLASS
767     JSHandle<JSTaggedValue> proto = env->GetFunctionPrototype();
768     factory->NewEcmaHClass(JSHClass::SIZE, JSType::HCLASS, proto);
769     // LINKED_NODE
770     JSHandle<LinkedNode> linkedNode(thread_, JSTaggedValue::Hole());
771     factory->NewLinkedNode(1, JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Hole()),
772         JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Hole()), linkedNode);
773     // JS_NATIVE_POINTER
774     auto newData = ecmaVm_->GetNativeAreaAllocator()->AllocateBuffer(8);
775     factory->NewJSNativePointer(newData);
776 
777     tester.GenerateSnapShot("testGenerateNodeName_1.heapsnapshot");
778     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalArray["));
779     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"LexicalEnv["));
780     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalConstantPool["));
781     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalProfileTypeInfo["));
782     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalDict["));
783     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalAOTLiteralInfo["));
784     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalVTable["));
785     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalCOWArray["));
786     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"HiddenClass(NonMovable)"));
787     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"LinkedNode\""));
788     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"JSNativePointer\""));
789     // Test Not Found
790     ASSERT_TRUE(!tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "*#@failed case"));
791 }
792 
HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName2)793 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName2)
794 {
795     ObjectFactory *factory = ecmaVm_->GetFactory();
796     HeapDumpTestHelper tester(ecmaVm_);
797 
798     // JS_ERROR
799     JSHandle<EcmaString> handleMessage(thread_, EcmaStringAccessor::CreateEmptyString(ecmaVm_));
800     factory->NewJSError(ErrorType::ERROR, handleMessage);
801     // JS_EVAL_ERROR
802     factory->NewJSError(ErrorType::EVAL_ERROR, handleMessage);
803     // JS_RANGE_ERROR
804     factory->NewJSError(ErrorType::RANGE_ERROR, handleMessage);
805     // JS_TYPE_ERROR
806     factory->NewJSError(ErrorType::TYPE_ERROR, handleMessage);
807     // JS_AGGREGATE_ERROR
808     factory->NewJSAggregateError();
809     // JS_REFERENCE_ERROR
810     factory->NewJSError(ErrorType::REFERENCE_ERROR, handleMessage);
811     // JS_URI_ERROR
812     factory->NewJSError(ErrorType::URI_ERROR, handleMessage);
813     // JS_SYNTAX_ERROR
814     factory->NewJSError(ErrorType::SYNTAX_ERROR, handleMessage);
815     // JS_OOM_ERROR
816     factory->NewJSError(ErrorType::OOM_ERROR, handleMessage);
817     // JS_TERMINATION_ERROR
818     factory->NewJSError(ErrorType::TERMINATION_ERROR, handleMessage);
819 
820     tester.GenerateSnapShot("testGenerateNodeName_2.heapsnapshot");
821     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Error\""));
822     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Eval Error\""));
823     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Range Error\""));
824     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Type Error\""));
825     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Aggregate Error\""));
826     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Reference Error\""));
827     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Uri Error\""));
828     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Syntax Error\""));
829     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"OutOfMemory Error\""));
830     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Termination Error\""));
831 }
832 
HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName3)833 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName3)
834 {
835     HeapDumpTestHelper tester(ecmaVm_);
836 
837     // JS_INT8_ARRAY
838     tester.CreateNumberTypedArray(JSType::JS_INT8_ARRAY);
839     // JS_UINT8_ARRAY
840     tester.CreateNumberTypedArray(JSType::JS_UINT8_ARRAY);
841     // JS_UINT8_CLAMPED_ARRAY
842     tester.CreateNumberTypedArray(JSType::JS_UINT8_CLAMPED_ARRAY);
843     // JS_INT16_ARRAY
844     tester.CreateNumberTypedArray(JSType::JS_INT16_ARRAY);
845     // JS_UINT16_ARRAY
846     tester.CreateNumberTypedArray(JSType::JS_UINT16_ARRAY);
847     // JS_INT32_ARRAY
848     tester.CreateNumberTypedArray(JSType::JS_INT32_ARRAY);
849     // JS_UINT32_ARRAY
850     tester.CreateNumberTypedArray(JSType::JS_UINT32_ARRAY);
851     // JS_FLOAT32_ARRAY
852     tester.CreateNumberTypedArray(JSType::JS_FLOAT32_ARRAY);
853     // JS_FLOAT64_ARRAY
854     tester.CreateNumberTypedArray(JSType::JS_FLOAT64_ARRAY);
855     // JS_BIGINT64_ARRAY
856     tester.CreateNumberTypedArray(JSType::JS_BIGINT64_ARRAY);
857     // JS_BIGUINT64_ARRAY
858     tester.CreateNumberTypedArray(JSType::JS_BIGUINT64_ARRAY);
859 
860     tester.GenerateSnapShot("testGenerateNodeName_3.heapsnapshot");
861     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Int8 Array\""));
862     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Uint8 Array\""));
863     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Uint8 Clamped Array\""));
864     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Int16 Array\""));
865     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Uint16 Array\""));
866     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Int32 Array\""));
867     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Uint32 Array\""));
868     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Float32 Array\""));
869     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Float64 Array\""));
870     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"BigInt64 Array\""));
871     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"BigUint64 Array\""));
872 }
873 
HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName4)874 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName4)
875 {
876     ObjectFactory *factory = ecmaVm_->GetFactory();
877     HeapDumpTestHelper tester(ecmaVm_);
878 
879     JSHandle<JSTaggedValue> proto = ecmaVm_->GetGlobalEnv()->GetFunctionPrototype();
880     // JS_SET
881     tester.NewJSSet();
882     // JS_SHARED_SET
883     tester.NewJSSharedSet();
884     // JS_MAP
885     tester.NewJSMap();
886     // JS_SHARED_MAP
887     tester.NewJSSharedMap();
888     // JS_WEAK_SET
889     tester.NewJSWeakSet();
890     // JS_WEAK_MAP
891     tester.NewJSWeakMap();
892     // JS_ARRAY
893     factory->NewJSArray();
894     // JS_TYPED_ARRAY
895     tester.NewObject(JSTypedArray::SIZE, JSType::JS_TYPED_ARRAY, proto);
896     tester.GenerateSnapShot("testGenerateNodeName_4.heapsnapshot");
897 
898     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Set\""));
899     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"SharedSet\""));
900     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Map\""));
901     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"SharedMap\""));
902     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"WeakSet\""));
903     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"WeakMap\""));
904     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"JSArray\""));
905     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Typed Array\""));
906 }
907 
HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName5)908 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName5)
909 {
910     ObjectFactory *factory = ecmaVm_->GetFactory();
911     HeapDumpTestHelper tester(ecmaVm_);
912 
913     JSHandle<JSTaggedValue> proto = ecmaVm_->GetGlobalEnv()->GetFunctionPrototype();
914     // JS_REG_EXP
915     tester.NewObject(JSRegExp::SIZE, JSType::JS_REG_EXP, proto);
916     // JS_DATE
917     tester.NewObject(JSDate::SIZE, JSType::JS_DATE, proto);
918     // JS_ARGUMENTS
919     factory->NewJSArguments();
920     // JS_PROXY
921     tester.NewJSProxy();
922     // JS_PRIMITIVE_REF
923     tester.NewObject(JSPrimitiveRef::SIZE, JSType::JS_PRIMITIVE_REF, proto);
924     // JS_DATA_VIEW
925     factory->NewJSDataView(factory->NewJSArrayBuffer(10), 5, 5);
926 
927     tester.GenerateSnapShot("testGenerateNodeName_5.heapsnapshot");
928     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_5.heapsnapshot", "\"Regexp\""));
929     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_5.heapsnapshot", "\"Date\""));
930     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_5.heapsnapshot", "\"Arguments\""));
931     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_5.heapsnapshot", "\"Proxy\""));
932     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_5.heapsnapshot", "\"Primitive\""));
933     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_5.heapsnapshot", "\"DataView\""));
934 }
935 
HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName6)936 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName6)
937 {
938     ObjectFactory *factory = ecmaVm_->GetFactory();
939     HeapDumpTestHelper tester(ecmaVm_);
940 
941     // JS_FORIN_ITERATOR
942     tester.NewJSForInIterator();
943     // JS_MAP_ITERATOR
944     factory->NewJSMapIterator(tester.NewJSMap(), IterationKind::KEY);
945     // JS_SHARED_MAP_ITERATOR
946     factory->NewJSMapIterator(tester.NewJSSharedMap(), IterationKind::KEY);
947     // JS_SET_ITERATOR
948     factory->NewJSSetIterator(tester.NewJSSet(), IterationKind::KEY);
949     // JS_SHARED_SET_ITERATOR
950     factory->NewJSSetIterator(tester.NewJSSharedSet(), IterationKind::KEY);
951     // JS_REG_EXP_ITERATOR
952     tester.NewJSRegExpIterator();
953     // JS_ARRAY_ITERATOR
954     factory->NewJSArrayIterator(JSHandle<JSObject>::Cast(factory->NewJSArray()), IterationKind::KEY);
955     // JS_STRING_ITERATOR
956     JSStringIterator::CreateStringIterator(thread_, factory->GetEmptyString());
957 
958     tester.GenerateSnapShot("testGenerateNodeName_6.heapsnapshot");
959     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"ForinInterator\""));
960     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"MapIterator\""));
961     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"SharedMapIterator\""));
962     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"SetIterator\""));
963     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"SharedSetIterator\""));
964     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"RegExpIterator\""));
965     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"ArrayIterator\""));
966     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"StringIterator\""));
967 }
968 
HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName7)969 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName7)
970 {
971     ObjectFactory *factory = ecmaVm_->GetFactory();
972     HeapDumpTestHelper tester(ecmaVm_);
973     // JS_ARRAY_BUFFER
974     factory->NewJSArrayBuffer(10);
975     // JS_SHARED_ARRAY_BUFFER
976     factory->NewJSSharedArrayBuffer(10);
977     // PROMISE_REACTIONS
978     factory->NewPromiseReaction();
979     // PROMISE_CAPABILITY
980     factory->NewPromiseCapability();
981     // PROMISE_ITERATOR_RECORD
982     tester.NewPromiseIteratorRecord();
983     // PROMISE_RECORD
984     factory->NewPromiseRecord();
985     // RESOLVING_FUNCTIONS_RECORD
986     factory->NewResolvingFunctionsRecord();
987     // JS_PROMISE
988     JSHandle<JSTaggedValue> proto = ecmaVm_->GetGlobalEnv()->GetFunctionPrototype();
989     tester.NewObject(JSPromise::SIZE, JSType::JS_PROMISE, proto);
990     // ASYNC_GENERATOR_REQUEST
991     factory->NewAsyncGeneratorRequest();
992 
993     tester.GenerateSnapShot("testGenerateNodeName_7.heapsnapshot");
994     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"ArrayBuffer\""));
995     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"SharedArrayBuffer\""));
996     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"PromiseReaction\""));
997     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"PromiseCapability\""));
998     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"PromiseIteratorRecord\""));
999     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"PromiseRecord\""));
1000     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"ResolvingFunctionsRecord\""));
1001     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"Promise\""));
1002     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"AsyncGeneratorRequest\""));
1003 }
1004 
HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName8)1005 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName8)
1006 {
1007     auto factory = ecmaVm_->GetFactory();
1008     HeapDumpTestHelper tester(ecmaVm_);
1009     // JS_API_ARRAY_LIST
1010     auto jsAPIArrayList = tester.NewJSAPIArrayList();
1011     // JS_API_ARRAYLIST_ITERATOR
1012     factory->NewJSAPIArrayListIterator(jsAPIArrayList);
1013     // JS_API_HASH_MAP
1014     auto jsAPIHashMap = tester.NewJSAPIHashMap();
1015     // JS_API_HASHMAP_ITERATOR
1016     factory->NewJSAPIHashMapIterator(jsAPIHashMap, IterationKind::KEY);
1017     // JS_API_HASH_SET
1018     auto jsAPIHashSet = tester.NewJSAPIHashSet();
1019     // JS_API_HASHSET_ITERATOR
1020     factory->NewJSAPIHashSetIterator(jsAPIHashSet, IterationKind::KEY);
1021     // JS_API_LIGHT_WEIGHT_MAP
1022     auto jsAPILightWeightMap = tester.NewJSAPILightWeightMap();
1023     // JS_API_LIGHT_WEIGHT_MAP_ITERATOR
1024     factory->NewJSAPILightWeightMapIterator(jsAPILightWeightMap, IterationKind::KEY);
1025     // JS_API_LIGHT_WEIGHT_SET
1026     auto jsAPILightWeightSet = tester.NewJSAPILightWeightSet();
1027     // JS_API_LIGHT_WEIGHT_SET_ITERATOR
1028     factory->NewJSAPILightWeightSetIterator(jsAPILightWeightSet, IterationKind::KEY);
1029 
1030     tester.GenerateSnapShot("testGenerateNodeName_8.heapsnapshot");
1031     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"ArrayList\""));
1032     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"ArrayListIterator\""));
1033     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"HashMap\""));
1034     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"HashSet\""));
1035     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"HashMapIterator\""));
1036     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"HashSetIterator\""));
1037     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"LightWeightMap\""));
1038     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"LightWeightMapIterator\""));
1039     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"LightWeightSet\""));
1040     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"LightWeightSetIterator\""));
1041 }
1042 
HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName9)1043 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName9)
1044 {
1045     auto factory = ecmaVm_->GetFactory();
1046     HeapDumpTestHelper tester(ecmaVm_);
1047     // JS_API_TREE_MAP
1048     auto jsAPITreeMap = tester.NewJSAPITreeMap();
1049     // JS_API_TREEMAP_ITERATOR
1050     factory->NewJSAPITreeMapIterator(jsAPITreeMap, IterationKind::KEY);
1051     // JS_API_TREE_SET
1052     auto jsAPITreeSet = tester.NewJSAPITreeSet();
1053     // JS_API_TREESET_ITERATOR
1054     factory->NewJSAPITreeSetIterator(jsAPITreeSet, IterationKind::KEY);
1055     // JS_API_VECTOR
1056     auto jsAPIVector = tester.NewJSAPIVector();
1057     // JS_API_VECTOR_ITERATOR
1058     factory->NewJSAPIVectorIterator(jsAPIVector);
1059     // JS_API_QUEUE
1060     auto jsAPIQueue = tester.NewJSAPIQueue();
1061     // JS_API_QUEUE_ITERATOR
1062     factory->NewJSAPIQueueIterator(jsAPIQueue);
1063     // JS_API_DEQUE
1064     auto jsAPIDeque = tester.NewJSAPIDeque();
1065     // JS_API_DEQUE_ITERATOR
1066     factory->NewJSAPIDequeIterator(jsAPIDeque);
1067     // JS_API_STACK
1068     auto jsAPIStack = tester.NewJSAPIStack();
1069     // JS_API_STACK_ITERATOR
1070     factory->NewJSAPIStackIterator(jsAPIStack);
1071     // JS_API_LIST
1072     tester.NewJSAPIList();
1073     // JS_API_LINKED_LIST
1074     tester.NewJSAPILinkedList();
1075     // JS_API_PLAIN_ARRAY
1076     auto jsAPIPlainArray = tester.NewJSAPIPlainArray();
1077     // JS_API_PLAIN_ARRAY_ITERATOR
1078     factory->NewJSAPIPlainArrayIterator(jsAPIPlainArray, IterationKind::KEY);
1079 
1080     tester.GenerateSnapShot("testGenerateNodeName_9.heapsnapshot");
1081     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"TreeMap\""));
1082     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"TreeMapIterator\""));
1083     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"TreeSet\""));
1084     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"TreeSetIterator\""));
1085     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"Vector\""));
1086     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"VectorIterator\""));
1087     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"Queue\""));
1088     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"QueueIterator\""));
1089     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"Deque\""));
1090     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"DequeIterator\""));
1091     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"Stack\""));
1092     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"StackIterator\""));
1093     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"List\""));
1094     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"LinkedList\""));
1095     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"PlainArray\""));
1096     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"PlainArrayIterator\""));
1097 }
1098 
HWTEST_F_L0(HeapDumpTest, TestHeapDumpBinaryDump)1099 HWTEST_F_L0(HeapDumpTest, TestHeapDumpBinaryDump)
1100 {
1101     ObjectFactory *factory = ecmaVm_->GetFactory();
1102     HeapDumpTestHelper tester(ecmaVm_);
1103     // PROMISE_ITERATOR_RECORD
1104     tester.NewPromiseIteratorRecord();
1105     // PROMISE_RECORD
1106     factory->NewPromiseRecord();
1107     // JS_ARRAY_BUFFER
1108     factory->NewJSArrayBuffer(10);
1109     // JS_SHARED_ARRAY_BUFFER
1110     factory->NewJSSharedArrayBuffer(10);
1111     // PROMISE_REACTIONS
1112     factory->NewPromiseReaction();
1113     // PROMISE_CAPABILITY
1114     factory->NewPromiseCapability();
1115     // RESOLVING_FUNCTIONS_RECORD
1116     factory->NewResolvingFunctionsRecord();
1117     // JS_PROMISE
1118     JSHandle<JSTaggedValue> proto = ecmaVm_->GetGlobalEnv()->GetFunctionPrototype();
1119     tester.NewObject(JSPromise::SIZE, JSType::JS_PROMISE, proto);
1120     // ASYNC_GENERATOR_REQUEST
1121     factory->NewAsyncGeneratorRequest();
1122     // JS_WEAK_SET
1123     tester.NewJSWeakSet();
1124     // JS_WEAK_MAP
1125     tester.NewJSWeakMap();
1126     std::string rawHeapPath("test_binary_dump.raw");
1127     bool ret = tester.GenerateRawHeapSnashot(rawHeapPath);
1128     ASSERT_TRUE(ret);
1129     std::ifstream file(rawHeapPath, std::ios::binary);
1130     std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
1131     ASSERT_TRUE(content.size() > 0);
1132     auto u64Ptr = reinterpret_cast<const uint64_t *>(content.c_str());
1133     ASSERT_TRUE(*u64Ptr > 0);
1134     std::string snapshotPath("test_binary_dump.heapsnapshot");
1135     ret = tester.DecodeRawHeapSnashot(rawHeapPath, snapshotPath);
1136     ASSERT_TRUE(ret);
1137     ASSERT_TRUE(tester.MatchHeapDumpString(snapshotPath, "\"SharedArrayBuffer\""));
1138     ASSERT_TRUE(tester.MatchHeapDumpString(snapshotPath, "\"WeakSet\""));
1139     ASSERT_TRUE(tester.MatchHeapDumpString(snapshotPath, "\"WeakMap\""));
1140 }
1141 
HWTEST_F_L0(HeapDumpTest, TestSharedFullGCInHeapDump)1142 HWTEST_F_L0(HeapDumpTest, TestSharedFullGCInHeapDump)
1143 {
1144     ObjectFactory *factory = ecmaVm_->GetFactory();
1145     HeapDumpTestHelper tester(ecmaVm_);
1146 
1147     JSHandle<JSTaggedValue> proto = ecmaVm_->GetGlobalEnv()->GetFunctionPrototype();
1148     // JS_SET
1149     tester.NewJSSet();
1150     // JS_SHARED_SET
1151     tester.NewJSSharedSet();
1152     // JS_MAP
1153     tester.NewJSMap();
1154     // JS_SHARED_MAP
1155     tester.NewJSSharedMap();
1156     // JS_WEAK_SET
1157     tester.NewJSWeakSet();
1158     // JS_WEAK_MAP
1159     tester.NewJSWeakMap();
1160     // JS_ARRAY
1161     factory->NewJSArray();
1162     // JS_TYPED_ARRAY
1163     tester.NewObject(JSTypedArray::SIZE, JSType::JS_TYPED_ARRAY, proto);
1164     tester.GenerateSnapShot("testGenerateNodeName_4.heapsnapshot");
1165 
1166     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Set\""));
1167     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"SharedSet\""));
1168     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Map\""));
1169     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"SharedMap\""));
1170     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"WeakSet\""));
1171     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"WeakMap\""));
1172     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"JSArray\""));
1173     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Typed Array\""));
1174 
1175     auto sHeap = SharedHeap::GetInstance();
1176     sHeap->CollectGarbage<TriggerGCType::SHARED_FULL_GC, GCReason::OTHER>(thread_);
1177 
1178     tester.GenerateSnapShot("testGenerateNodeName_4.heapsnapshot");
1179 
1180     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Set\""));
1181     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"SharedSet\""));
1182     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Map\""));
1183     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"SharedMap\""));
1184     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"WeakSet\""));
1185     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"WeakMap\""));
1186     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"JSArray\""));
1187     ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Typed Array\""));
1188 }
1189 }
1190