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