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