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