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/base/number_helper.h"
19 #include "ecmascript/dfx/hprof/heap_snapshot.h"
20 #include "ecmascript/dfx/hprof/heap_profiler.h"
21 #include "ecmascript/dfx/hprof/heap_root_visitor.h"
22 #include "ecmascript/dfx/hprof/rawheap_translate/rawheap_translate.h"
23 #include "ecmascript/dfx/hprof/heap_marker.h"
24 #include "ecmascript/global_env.h"
25 #include "ecmascript/jspandafile/js_pandafile_manager.h"
26 #include "ecmascript/js_api/js_api_arraylist.h"
27 #include "ecmascript/js_api/js_api_arraylist_iterator.h"
28 #include "ecmascript/js_api/js_api_deque.h"
29 #include "ecmascript/js_api/js_api_hashmap.h"
30 #include "ecmascript/js_api/js_api_hashset.h"
31 #include "ecmascript/js_api/js_api_lightweightmap.h"
32 #include "ecmascript/js_api/js_api_lightweightset.h"
33 #include "ecmascript/js_api/js_api_linked_list.h"
34 #include "ecmascript/js_api/js_api_list.h"
35 #include "ecmascript/js_api/js_api_plain_array.h"
36 #include "ecmascript/js_api/js_api_queue.h"
37 #include "ecmascript/js_api/js_api_stack.h"
38 #include "ecmascript/js_api/js_api_tree_map.h"
39 #include "ecmascript/js_api/js_api_tree_set.h"
40 #include "ecmascript/js_api/js_api_vector.h"
41 #include "ecmascript/js_date.h"
42 #include "ecmascript/js_iterator.h"
43 #include "ecmascript/js_map.h"
44 #include "ecmascript/js_primitive_ref.h"
45 #include "ecmascript/js_promise.h"
46 #include "ecmascript/js_regexp.h"
47 #include "ecmascript/js_set.h"
48 #include "ecmascript/js_string_iterator.h"
49 #include "ecmascript/js_typed_array.h"
50 #include "ecmascript/js_weak_container.h"
51 #include "ecmascript/linked_hash_table.h"
52 #include "ecmascript/napi/include/jsnapi.h"
53 #include "ecmascript/shared_objects/js_shared_array.h"
54 #include "ecmascript/shared_objects/js_shared_map.h"
55 #include "ecmascript/shared_objects/js_shared_set.h"
56 #include "ecmascript/tagged_hash_array.h"
57 #include "ecmascript/tagged_tree.h"
58 #include "ecmascript/tests/test_helper.h"
59
60 namespace panda::test {
61 using namespace panda::ecmascript;
62 using ErrorType = base::ErrorType;
63
64 class HeapDumpTest : public testing::Test {
65 public:
SetUp()66 void SetUp() override
67 {
68 TestHelper::CreateEcmaVMWithScope(ecmaVm_, thread_, scope_);
69 ecmaVm_->SetEnableForceGC(false);
70 }
71
TearDown()72 void TearDown() override
73 {
74 TestHelper::DestroyEcmaVMWithScope(ecmaVm_, scope_);
75 }
76
77 EcmaVM *ecmaVm_ {nullptr};
78 EcmaHandleScope *scope_ {nullptr};
79 JSThread *thread_ {nullptr};
80 };
81
82 class HeapDumpTestHelper {
83 public:
HeapDumpTestHelper(EcmaVM * vm)84 explicit HeapDumpTestHelper(EcmaVM *vm) : instance(vm) {}
85
~HeapDumpTestHelper()86 ~HeapDumpTestHelper()
87 {
88 HeapProfilerInterface::Destroy(instance);
89 }
90
GenerateSnapShot(const std::string & filePath)91 size_t GenerateSnapShot(const std::string &filePath)
92 {
93 // first generate this file of filePath if not exist,
94 // so the function `realpath` of FileStream can not failed on arm/arm64.
95 fstream outputString(filePath, std::ios::out);
96 outputString.close();
97 outputString.clear();
98 FileStream stream(filePath.c_str());
99 HeapProfilerInterface *heapProfile = HeapProfilerInterface::GetInstance(instance);
100 DumpSnapShotOption dumpOption;
101 dumpOption.dumpFormat = DumpFormat::JSON;
102 heapProfile->DumpHeapSnapshot(&stream, dumpOption);
103 return heapProfile->GetIdCount();
104 }
105
GenerateRawHeapSnashot(const std::string & filePath,DumpSnapShotOption & dumpOption,Progress * progress=nullptr,std::function<void (uint8_t)> callback=[](uint8_t){})106 bool GenerateRawHeapSnashot(const std::string &filePath, DumpSnapShotOption &dumpOption,
107 Progress *progress = nullptr, std::function<void(uint8_t)> callback = [] (uint8_t) {})
108 {
109 HeapProfilerInterface *heapProfile = HeapProfilerInterface::GetInstance(instance);
110 dumpOption.dumpFormat = DumpFormat::BINARY;
111 dumpOption.isDumpOOM = true;
112 dumpOption.isFullGC = false;
113 fstream outputString(filePath, std::ios::out);
114 outputString.close();
115 outputString.clear();
116 int fd = open(filePath.c_str(), O_RDWR | O_CREAT);
117 FileDescriptorStream stream(fd);
118 auto ret = heapProfile->DumpHeapSnapshot(&stream, dumpOption, progress, callback);
119 stream.EndOfStream();
120 return ret;
121 }
122
DecodeRawHeapObjectTableV1(std::string & filePath,CSet<JSTaggedType> & result)123 bool DecodeRawHeapObjectTableV1(std::string &filePath, CSet<JSTaggedType> &result)
124 {
125 uint64_t fileSize = rawheap_translate::FileReader::GetFileSize(filePath);
126 rawheap_translate::FileReader file;
127 rawheap_translate::RawHeapTranslateV1 translate(nullptr);
128
129 if (!file.Initialize(filePath) || !translate.Parse(file, fileSize)) {
130 return false;
131 }
132
133 for (auto &it : translate.nodesMap_) {
134 result.insert(it.first);
135 }
136 GTEST_LOG_(INFO) << "DecodeRawHeapObjectTable count " << translate.nodesMap_.size();
137 return true;
138 }
139
CheckHashInNodeId(JSThread * thread,const std::vector<Reference> & refs,const std::string & filePath)140 bool CheckHashInNodeId(JSThread *thread, const std::vector<Reference> &refs, const std::string &filePath)
141 {
142 uint64_t fileSize = rawheap_translate::FileReader::GetFileSize(filePath);
143 rawheap_translate::FileReader file;
144 rawheap_translate::RawHeapTranslateV1 translate(nullptr);
145 if (!file.Initialize(filePath) || !translate.Parse(file, fileSize)) {
146 return false;
147 }
148
149 int checkCnt = 0;
150 for (auto const &ref : refs) {
151 if (!ref.value_.IsJSObject()) {
152 continue;
153 }
154
155 auto it = translate.nodesMap_.find(ref.value_.GetRawData());
156 if (it == translate.nodesMap_.end()) {
157 std::cout << "CheckHashInNodeId, missed object in rawheap." << std::endl;
158 return false;
159 }
160
161 ++checkCnt;
162 // 32: 32-bits means a half of uint64_t
163 if (JSObject::Cast(ref.value_)->GetHash(thread) != static_cast<int32_t>(it->second->nodeId >> 32)) {
164 std::cout << "CheckHashInNodeId, hash value verification failed!" << std::endl;
165 return false;
166 }
167 }
168
169 if (checkCnt == 0) {
170 std::cout << "CheckHashInNodeId, no JSObject." << std::endl;
171 return false;
172 }
173 return true;
174 }
175
DecodeRawHeapObjectTableV2(std::string & filePath,CSet<uint32_t> & result)176 bool DecodeRawHeapObjectTableV2(std::string &filePath, CSet<uint32_t> &result)
177 {
178 uint64_t fileSize = rawheap_translate::FileReader::GetFileSize(filePath);
179 rawheap_translate::FileReader file;
180 rawheap_translate::RawHeapTranslateV2 translate(nullptr);
181
182 if (!file.Initialize(filePath) || !translate.Parse(file, fileSize)) {
183 return false;
184 }
185
186 for (auto &it : translate.nodesMap_) {
187 result.insert(it.first);
188 }
189 GTEST_LOG_(INFO) << "DecodeRawHeapObjectTable count " << translate.nodesMap_.size();
190 return true;
191 }
192
AddMetaDataJsonToRawheap(const std::string & rawFilePath)193 bool AddMetaDataJsonToRawheap(const std::string &rawFilePath)
194 {
195 uint32_t rawheapSize = rawheap_translate::FileReader::GetFileSize(rawFilePath);
196 uint32_t metadataSize = rawheap_translate::FileReader::GetFileSize(HPROF_TEST_METADATA_JSON_DIR"metadata.json");
197 if (rawheapSize == 0 || metadataSize == 0) {
198 std::cout << "rawheapSize=" << rawheapSize << ", metadataSize=" << metadataSize << std::endl;
199 return false;
200 }
201
202 std::ofstream rawheapFile(rawFilePath, std::ios::app | std::ios::binary);
203 std::ifstream metadataFile(HPROF_TEST_METADATA_JSON_DIR"metadata.json", std::ios::binary);
204 if (!rawheapFile.is_open() || !metadataFile.is_open()) {
205 return false;
206 }
207
208 uint32_t bufSize = metadataSize + sizeof(uint64_t);
209 char *buf = new char[bufSize];
210 if (!metadataFile.read(buf, metadataSize)) {
211 delete[] buf;
212 return false;
213 }
214
215 *reinterpret_cast<uint32_t *>(buf + bufSize - sizeof(uint64_t)) = rawheapSize;
216 *reinterpret_cast<uint32_t *>(buf + bufSize - sizeof(uint32_t)) = metadataSize;
217 rawheapFile.write(buf, bufSize);
218
219 rawheapFile.close();
220 metadataFile.close();
221 delete[] buf;
222 return true;
223 }
224
DecodeRawheap(const std::string & rawFilePath,const std::string & outputPath)225 bool DecodeRawheap(const std::string &rawFilePath, const std::string &outputPath)
226 {
227 return rawheap_translate::RawHeap::TranslateRawheap(rawFilePath, outputPath);
228 }
229
MatchHeapObjectReferencesV1(const std::vector<Reference> & refs,const CSet<JSTaggedType> & dumpObjects)230 bool MatchHeapObjectReferencesV1(const std::vector<Reference> &refs, const CSet<JSTaggedType> &dumpObjects)
231 {
232 for (auto &ref : refs) {
233 if (ref.value_.IsHeapObject() && dumpObjects.find(ref.value_.GetRawData()) == dumpObjects.end()) {
234 return false;
235 }
236 }
237 return true;
238 }
239
MatchHeapObjectReferencesV2(const std::vector<Reference> & refs,const CSet<uint32_t> & dumpObjects)240 bool MatchHeapObjectReferencesV2(const std::vector<Reference> &refs, const CSet<uint32_t> &dumpObjects)
241 {
242 for (auto &ref : refs) {
243 if (ref.value_.IsHeapObject() &&
244 dumpObjects.find(static_cast<uint32_t>(ref.value_.GetRawData())) == dumpObjects.end()) {
245 return false;
246 }
247 }
248 return true;
249 }
250
MatchHeapDumpString(const std::string & filePath,std::string targetStr)251 bool MatchHeapDumpString(const std::string &filePath, std::string targetStr)
252 {
253 std::string line;
254 std::ifstream inputStream(filePath);
255 std::size_t lineNum = 0;
256 while (getline(inputStream, line)) {
257 lineNum = line.find(targetStr);
258 if (lineNum != line.npos) {
259 return true;
260 }
261 }
262 GTEST_LOG_(ERROR) << "file: " << filePath.c_str() << ", target:" << targetStr.c_str()
263 << ", line:" << std::to_string(lineNum) <<"not found";
264 return false; // Lost the Line
265 }
266
CreateNumberTypedArray(JSType jsType)267 JSHandle<JSTypedArray> CreateNumberTypedArray(JSType jsType)
268 {
269 JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
270 ObjectFactory *factory = instance->GetFactory();
271 JSHandle<JSTaggedValue> handleTagValFunc = env->GetInt8ArrayFunction();
272 switch (jsType) {
273 case JSType::JS_INT8_ARRAY:
274 break;
275 case JSType::JS_UINT8_ARRAY:
276 handleTagValFunc = env->GetUint8ArrayFunction();
277 break;
278 case JSType::JS_UINT8_CLAMPED_ARRAY:
279 handleTagValFunc = env->GetUint8ClampedArrayFunction();
280 break;
281 case JSType::JS_INT16_ARRAY:
282 handleTagValFunc = env->GetInt16ArrayFunction();
283 break;
284 case JSType::JS_UINT16_ARRAY:
285 handleTagValFunc = env->GetUint16ArrayFunction();
286 break;
287 case JSType::JS_INT32_ARRAY:
288 handleTagValFunc = env->GetInt32ArrayFunction();
289 break;
290 case JSType::JS_UINT32_ARRAY:
291 handleTagValFunc = env->GetUint32ArrayFunction();
292 break;
293 case JSType::JS_FLOAT32_ARRAY:
294 handleTagValFunc = env->GetFloat32ArrayFunction();
295 break;
296 case JSType::JS_FLOAT64_ARRAY:
297 handleTagValFunc = env->GetFloat64ArrayFunction();
298 break;
299 case JSType::JS_BIGINT64_ARRAY:
300 handleTagValFunc = env->GetBigInt64ArrayFunction();
301 break;
302 case JSType::JS_BIGUINT64_ARRAY:
303 handleTagValFunc = env->GetBigUint64ArrayFunction();
304 break;
305 default:
306 ASSERT_PRINT(false, "wrong jsType used in CreateNumberTypedArray function");
307 break;
308 }
309 return JSHandle<JSTypedArray>::Cast(
310 factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(handleTagValFunc), handleTagValFunc));
311 }
312
CreateNumberSharedTypedArray(JSType jsType)313 JSHandle<JSSharedTypedArray> CreateNumberSharedTypedArray(JSType jsType)
314 {
315 JSHandle<GlobalEnv> env = instance->GetGlobalEnv();
316 ObjectFactory *factory = instance->GetFactory();
317 JSHandle<JSTaggedValue> handleTagValFunc = env->GetSharedInt8ArrayFunction();
318 switch (jsType) {
319 case JSType::JS_SHARED_INT8_ARRAY:
320 break;
321 case JSType::JS_SHARED_UINT8_ARRAY:
322 handleTagValFunc = env->GetSharedUint8ArrayFunction();
323 break;
324 case JSType::JS_SHARED_UINT8_CLAMPED_ARRAY:
325 handleTagValFunc = env->GetSharedUint8ClampedArrayFunction();
326 break;
327 case JSType::JS_SHARED_INT16_ARRAY:
328 handleTagValFunc = env->GetSharedInt16ArrayFunction();
329 break;
330 case JSType::JS_SHARED_UINT16_ARRAY:
331 handleTagValFunc = env->GetSharedUint16ArrayFunction();
332 break;
333 case JSType::JS_SHARED_INT32_ARRAY:
334 handleTagValFunc = env->GetSharedInt32ArrayFunction();
335 break;
336 case JSType::JS_SHARED_UINT32_ARRAY:
337 handleTagValFunc = env->GetSharedUint32ArrayFunction();
338 break;
339 case JSType::JS_SHARED_FLOAT32_ARRAY:
340 handleTagValFunc = env->GetSharedFloat32ArrayFunction();
341 break;
342 case JSType::JS_SHARED_FLOAT64_ARRAY:
343 handleTagValFunc = env->GetSharedFloat64ArrayFunction();
344 break;
345 case JSType::JS_SHARED_BIGINT64_ARRAY:
346 handleTagValFunc = env->GetSharedBigInt64ArrayFunction();
347 break;
348 case JSType::JS_SHARED_BIGUINT64_ARRAY:
349 handleTagValFunc = env->GetSharedBigUint64ArrayFunction();
350 break;
351 default:
352 ASSERT_PRINT(false, "wrong jsType used in CreateNumberTypedArray function");
353 break;
354 }
355 return JSHandle<JSSharedTypedArray>::Cast(
356 factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(handleTagValFunc), handleTagValFunc));
357 }
358
NewSharedTypedArray()359 JSHandle<TaggedArray> NewSharedTypedArray()
360 {
361 ObjectFactory *factory = instance->GetFactory();
362 JSThread *thread = instance->GetJSThread();
363 JSHandle<TaggedArray> array(factory->NewTaggedArray(11)); // 11: elements
364 // 0: JS_SHARED_INT8_ARRAY
365 array->Set(thread, 0, CreateNumberSharedTypedArray(JSType::JS_SHARED_INT8_ARRAY));
366 // 1: JS_SHARED_UINT8_ARRAY
367 array->Set(thread, 1, CreateNumberSharedTypedArray(JSType::JS_SHARED_UINT8_ARRAY));
368 // 2: JS_SHARED_UINT8_CLAMPED_ARRAY
369 array->Set(thread, 2, CreateNumberSharedTypedArray(JSType::JS_SHARED_UINT8_CLAMPED_ARRAY));
370 // 3: JS_SHARED_INT16_ARRAY
371 array->Set(thread, 3, CreateNumberSharedTypedArray(JSType::JS_SHARED_INT16_ARRAY));
372 // 4: JS_SHARED_UINT16_ARRAY
373 array->Set(thread, 4, CreateNumberSharedTypedArray(JSType::JS_SHARED_UINT16_ARRAY));
374 // 5: JS_SHARED_INT32_ARRAY
375 array->Set(thread, 5, CreateNumberSharedTypedArray(JSType::JS_SHARED_INT32_ARRAY));
376 // 6: JS_SHARED_UINT32_ARRAY
377 array->Set(thread, 6, CreateNumberSharedTypedArray(JSType::JS_SHARED_UINT32_ARRAY));
378 // 7: JS_SHARED_FLOAT32_ARRAY
379 array->Set(thread, 7, CreateNumberSharedTypedArray(JSType::JS_SHARED_FLOAT32_ARRAY));
380 // 8: JS_SHARED_FLOAT64_ARRAY
381 array->Set(thread, 8, CreateNumberSharedTypedArray(JSType::JS_SHARED_FLOAT64_ARRAY));
382 // 9: JS_SHARED_BIGINT64_ARRAY
383 array->Set(thread, 9, CreateNumberSharedTypedArray(JSType::JS_SHARED_BIGINT64_ARRAY));
384 // 10: JS_SHARED_BIGUINT64_ARRAY
385 array->Set(thread, 10, CreateNumberSharedTypedArray(JSType::JS_SHARED_BIGUINT64_ARRAY));
386 return array;
387 }
388
NewObject(uint32_t size,JSType type,JSHandle<JSTaggedValue> proto)389 JSHandle<JSObject> NewObject(uint32_t size, JSType type, JSHandle<JSTaggedValue> proto)
390 {
391 ObjectFactory *factory = instance->GetFactory();
392 JSHandle<JSHClass> hclass = factory->NewEcmaHClass(size, type, proto);
393 return factory->NewJSObjectWithInit(hclass);
394 }
395
NewSObject(uint32_t size,JSType type,JSHandle<JSTaggedValue> proto)396 JSHandle<JSObject> NewSObject(uint32_t size, JSType type, JSHandle<JSTaggedValue> proto)
397 {
398 ObjectFactory *factory = instance->GetFactory();
399 auto emptySLayout = instance->GetJSThread()->GlobalConstants()->GetHandledEmptySLayoutInfo();
400 JSHandle<JSHClass> hclass = factory->NewSEcmaHClass(size, 0, type, proto, emptySLayout);
401 return factory->NewJSObjectWithInit(hclass);
402 }
403
404 // JS_SET
NewJSSet()405 JSHandle<JSSet> NewJSSet()
406 {
407 JSThread *thread = instance->GetJSThread();
408 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
409 JSHandle<JSObject> jsSetObject = NewObject(JSSet::SIZE, JSType::JS_SET, proto);
410 JSHandle<JSSet> jsSet = JSHandle<JSSet>::Cast(jsSetObject);
411 JSHandle<LinkedHashSet> linkedSet(LinkedHashSet::Create(thread));
412 jsSet->SetLinkedSet(thread, linkedSet);
413 return jsSet;
414 }
415
416 // JS_SHARED_SET
NewJSSharedSet()417 JSHandle<JSSharedSet> NewJSSharedSet()
418 {
419 JSThread *thread = instance->GetJSThread();
420 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetSFunctionPrototype();
421 JSHandle<JSObject> jsSSetObject = NewSObject(JSSharedSet::SIZE, JSType::JS_SHARED_SET, proto);
422 JSHandle<JSSharedSet> jsSSet = JSHandle<JSSharedSet>::Cast(jsSSetObject);
423 JSHandle<LinkedHashSet> linkedSet(
424 LinkedHashSet::Create(thread, LinkedHashSet::MIN_CAPACITY, MemSpaceKind::SHARED));
425 jsSSet->SetLinkedSet(thread, linkedSet);
426 jsSSet->SetModRecord(0);
427 return jsSSet;
428 }
429
430 // JS_MAP
NewJSMap()431 JSHandle<JSMap> NewJSMap()
432 {
433 JSThread *thread = instance->GetJSThread();
434 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
435 JSHandle<JSObject> jsMapObject = NewObject(JSMap::SIZE, JSType::JS_MAP, proto);
436 JSHandle<JSMap> jsMap = JSHandle<JSMap>::Cast(jsMapObject);
437 JSHandle<LinkedHashMap> linkedMap(LinkedHashMap::Create(thread));
438 jsMap->SetLinkedMap(thread, linkedMap);
439 return jsMap;
440 }
441
442 // JS_SHARED_MAP
NewJSSharedMap()443 JSHandle<JSSharedMap> NewJSSharedMap()
444 {
445 JSThread *thread = instance->GetJSThread();
446 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetSFunctionPrototype();
447 JSHandle<JSObject> jsSMapObject = NewSObject(JSSharedMap::SIZE, JSType::JS_SHARED_MAP, proto);
448 JSHandle<JSSharedMap> jsSMap = JSHandle<JSSharedMap>::Cast(jsSMapObject);
449 JSHandle<LinkedHashMap> linkedMap(
450 LinkedHashMap::Create(thread, LinkedHashMap::MIN_CAPACITY, MemSpaceKind::SHARED));
451 jsSMap->SetLinkedMap(thread, linkedMap);
452 jsSMap->SetModRecord(0);
453 return jsSMap;
454 }
455
456 //JS_WEAK_SET
NewJSWeakSet()457 JSHandle<JSWeakSet> NewJSWeakSet()
458 {
459 JSThread *thread = instance->GetJSThread();
460 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
461 JSHandle<JSObject> jsWeakSetObject = NewObject(JSWeakSet::SIZE, JSType::JS_WEAK_SET, proto);
462 JSHandle<JSWeakSet> jsWeakSet = JSHandle<JSWeakSet>::Cast(jsWeakSetObject);
463 JSHandle<LinkedHashSet> weakLinkedSet(LinkedHashSet::Create(thread));
464 jsWeakSet->SetLinkedSet(thread, weakLinkedSet);
465 return jsWeakSet;
466 }
467
468 //JS_WEAK_MAP
NewJSWeakMap()469 JSHandle<JSWeakMap> NewJSWeakMap()
470 {
471 JSThread *thread = instance->GetJSThread();
472 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
473 JSHandle<JSObject> jsWeakMapObject = NewObject(JSWeakMap::SIZE, JSType::JS_WEAK_MAP, proto);
474 JSHandle<JSWeakMap> jsWeakMap = JSHandle<JSWeakMap>::Cast(jsWeakMapObject);
475 JSHandle<LinkedHashMap> weakLinkedMap(LinkedHashMap::Create(thread));
476 jsWeakMap->SetLinkedMap(thread, weakLinkedMap);
477 return jsWeakMap;
478 }
479
480 // JS_PROXY
NewJSProxy()481 JSHandle<JSProxy> NewJSProxy()
482 {
483 JSThread *thread = instance->GetJSThread();
484 ObjectFactory *factory = instance->GetFactory();
485 JSFunction *newTarget = instance->GetGlobalEnv()->GetObjectFunction().GetObject<JSFunction>();
486 JSHandle<JSTaggedValue> newTargetHandle(thread, newTarget);
487 JSHandle<JSObject> jsObject =
488 factory->NewJSObjectByConstructor(JSHandle<JSFunction>(newTargetHandle), newTargetHandle);
489 JSHandle<JSTaggedValue> emptyObj(thread, jsObject.GetTaggedValue());
490 return factory->NewJSProxy(emptyObj, emptyObj);
491 }
492
493 // JS_FORIN_ITERATOR
NewJSForInIterator()494 JSHandle<JSForInIterator> NewJSForInIterator()
495 {
496 JSThread *thread = instance->GetJSThread();
497 ObjectFactory *factory = instance->GetFactory();
498 JSHandle<JSTaggedValue> arrayEmpty(thread, factory->NewJSArray().GetTaggedValue());
499 JSHandle<JSTaggedValue> keys(thread, factory->EmptyArray().GetTaggedValue());
500 JSHandle<JSTaggedValue> hclass(thread, JSTaggedValue::Undefined());
501 return factory->NewJSForinIterator(arrayEmpty, keys, hclass, static_cast<uint32_t>(EnumCacheKind::NONE));
502 }
503
504 // JS_REG_EXP_ITERATOR
NewJSRegExpIterator()505 JSHandle<JSRegExpIterator> NewJSRegExpIterator()
506 {
507 ObjectFactory *factory = instance->GetFactory();
508 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
509 JSHandle<EcmaString> emptyString = factory->GetEmptyString();
510 JSHandle<JSTaggedValue> jsRegExp(NewObject(JSRegExp::SIZE, JSType::JS_REG_EXP, proto));
511 return factory->NewJSRegExpIterator(jsRegExp, emptyString, false, false);
512 }
513
514 // PROMISE_ITERATOR_RECORD
NewPromiseIteratorRecord()515 JSHandle<PromiseIteratorRecord> NewPromiseIteratorRecord()
516 {
517 JSThread *thread = instance->GetJSThread();
518 ObjectFactory *factory = instance->GetFactory();
519 JSFunction *newTarget = instance->GetGlobalEnv()->GetObjectFunction().GetObject<JSFunction>();
520 JSHandle<JSTaggedValue> newTargetHandle(thread, newTarget);
521 JSHandle<JSObject> jsObject =
522 factory->NewJSObjectByConstructor(JSHandle<JSFunction>(newTargetHandle), newTargetHandle);
523 JSHandle<JSTaggedValue> emptyObj(thread, jsObject.GetTaggedValue());
524 return factory->NewPromiseIteratorRecord(emptyObj, false);
525 }
526
527 // JS_API_ARRAY_LIST
NewJSAPIArrayList()528 JSHandle<JSAPIArrayList> NewJSAPIArrayList()
529 {
530 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
531 JSHandle<JSObject> jsAPIArrayListObject = NewObject(JSAPIArrayList::SIZE, JSType::JS_API_ARRAY_LIST, proto);
532 JSHandle<JSAPIArrayList> jsAPIArrayList = JSHandle<JSAPIArrayList>::Cast(jsAPIArrayListObject);
533 JSThread *thread = instance->GetJSThread();
534 jsAPIArrayList->SetLength(thread, JSTaggedValue(0));
535 return jsAPIArrayList;
536 }
537
538 // JS_API_HASH_MAP
NewJSAPIHashMap()539 JSHandle<JSAPIHashMap> NewJSAPIHashMap()
540 {
541 JSThread *thread = instance->GetJSThread();
542 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
543 JSHandle<JSObject> jsAPIHashMapObject = NewObject(JSAPIHashMap::SIZE, JSType::JS_API_HASH_MAP, proto);
544 JSHandle<JSAPIHashMap> jsAPIHashMap = JSHandle<JSAPIHashMap>::Cast(jsAPIHashMapObject);
545 jsAPIHashMap->SetTable(thread, TaggedHashArray::Create(thread));
546 jsAPIHashMap->SetSize(0);
547 return jsAPIHashMap;
548 }
549
550 // JS_API_HASH_SET
NewJSAPIHashSet()551 JSHandle<JSAPIHashSet> NewJSAPIHashSet()
552 {
553 JSThread *thread = instance->GetJSThread();
554 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
555 JSHandle<JSObject> jsAPIHashSetObject = NewObject(JSAPIHashSet::SIZE, JSType::JS_API_HASH_SET, proto);
556 JSHandle<JSAPIHashSet> jsAPIHashSet = JSHandle<JSAPIHashSet>::Cast(jsAPIHashSetObject);
557 jsAPIHashSet->SetTable(thread, TaggedHashArray::Create(thread));
558 jsAPIHashSet->SetSize(0);
559 return jsAPIHashSet;
560 }
561
562 // JS_API_LIGHT_WEIGHT_MAP
NewJSAPILightWeightMap()563 JSHandle<JSAPILightWeightMap> NewJSAPILightWeightMap()
564 {
565 JSThread *thread = instance->GetJSThread();
566 ObjectFactory *factory = instance->GetFactory();
567 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
568 JSHandle<JSObject> jsAPILightWeightMapObject =
569 NewObject(JSAPILightWeightMap::SIZE, JSType::JS_API_LIGHT_WEIGHT_MAP, proto);
570 JSHandle<JSAPILightWeightMap> jsAPILightWeightMap =
571 JSHandle<JSAPILightWeightMap>::Cast(jsAPILightWeightMapObject);
572 JSHandle<JSTaggedValue> hashArray =
573 JSHandle<JSTaggedValue>(factory->NewTaggedArray(JSAPILightWeightMap::DEFAULT_CAPACITY_LENGTH));
574 JSHandle<JSTaggedValue> keyArray =
575 JSHandle<JSTaggedValue>(factory->NewTaggedArray(JSAPILightWeightMap::DEFAULT_CAPACITY_LENGTH));
576 JSHandle<JSTaggedValue> valueArray =
577 JSHandle<JSTaggedValue>(factory->NewTaggedArray(JSAPILightWeightMap::DEFAULT_CAPACITY_LENGTH));
578 jsAPILightWeightMap->SetHashes(thread, hashArray);
579 jsAPILightWeightMap->SetKeys(thread, keyArray);
580 jsAPILightWeightMap->SetValues(thread, valueArray);
581 jsAPILightWeightMap->SetLength(0);
582 return jsAPILightWeightMap;
583 }
584
585 // JS_API_LIGHT_WEIGHT_SET
NewJSAPILightWeightSet()586 JSHandle<JSAPILightWeightSet> NewJSAPILightWeightSet()
587 {
588 JSThread *thread = instance->GetJSThread();
589 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
590 JSHandle<JSObject> jsAPILightWeightSetObject =
591 NewObject(JSAPILightWeightSet::SIZE, JSType::JS_API_LIGHT_WEIGHT_SET, proto);
592 JSHandle<JSAPILightWeightSet> jsAPILightWeightSet =
593 JSHandle<JSAPILightWeightSet>::Cast(jsAPILightWeightSetObject);
594 JSHandle<TaggedArray> hashes =
595 JSAPILightWeightSet::CreateSlot(thread, JSAPILightWeightSet::DEFAULT_CAPACITY_LENGTH);
596 JSHandle<TaggedArray> values =
597 JSAPILightWeightSet::CreateSlot(thread, JSAPILightWeightSet::DEFAULT_CAPACITY_LENGTH);
598 jsAPILightWeightSet->SetHashes(thread, hashes);
599 jsAPILightWeightSet->SetValues(thread, values);
600 jsAPILightWeightSet->SetLength(0);
601 return jsAPILightWeightSet;
602 }
603
604 // JS_API_TREE_MAP
NewJSAPITreeMap()605 JSHandle<JSAPITreeMap> NewJSAPITreeMap()
606 {
607 JSThread *thread = instance->GetJSThread();
608 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
609 JSHandle<JSObject> jsAPITreeMapObject = NewObject(JSAPITreeMap::SIZE, JSType::JS_API_TREE_MAP, proto);
610 JSHandle<JSAPITreeMap> jsAPITreeMap = JSHandle<JSAPITreeMap>::Cast(jsAPITreeMapObject);
611 JSHandle<TaggedTreeMap> treeMap(thread, TaggedTreeMap::Create(thread));
612 jsAPITreeMap->SetTreeMap(thread, treeMap);
613 return jsAPITreeMap;
614 }
615
616 // JS_API_TREE_SET
NewJSAPITreeSet()617 JSHandle<JSAPITreeSet> NewJSAPITreeSet()
618 {
619 JSThread *thread = instance->GetJSThread();
620 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
621 JSHandle<JSObject> jsAPITreeSetObject = NewObject(JSAPITreeSet::SIZE, JSType::JS_API_TREE_SET, proto);
622 JSHandle<JSAPITreeSet> jsAPITreeSet = JSHandle<JSAPITreeSet>::Cast(jsAPITreeSetObject);
623 JSHandle<TaggedTreeSet> treeSet(thread, TaggedTreeSet::Create(thread));
624 jsAPITreeSet->SetTreeSet(thread, treeSet);
625 return jsAPITreeSet;
626 }
627
628 // JS_API_QUEUE
NewJSAPIQueue()629 JSHandle<JSAPIQueue> NewJSAPIQueue()
630 {
631 JSThread *thread = instance->GetJSThread();
632 ObjectFactory *factory = instance->GetFactory();
633 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
634 JSHandle<JSObject> jsAPIQueueObject = NewObject(JSAPIQueue::SIZE, JSType::JS_API_QUEUE, proto);
635 JSHandle<JSAPIQueue> jsAPIQueue = JSHandle<JSAPIQueue>::Cast(jsAPIQueueObject);
636 JSHandle<TaggedArray> newElements = factory->NewTaggedArray(JSAPIQueue::DEFAULT_CAPACITY_LENGTH);
637 jsAPIQueue->SetLength(thread, JSTaggedValue(0));
638 jsAPIQueue->SetFront(0);
639 jsAPIQueue->SetTail(0);
640 jsAPIQueue->SetElements(thread, newElements);
641 return jsAPIQueue;
642 }
643 // JS_API_DEQUE
NewJSAPIDeque()644 JSHandle<JSAPIDeque> NewJSAPIDeque()
645 {
646 ObjectFactory *factory = instance->GetFactory();
647 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
648 JSHandle<JSObject> jsAPIDequeObject = NewObject(JSAPIDeque::SIZE, JSType::JS_API_DEQUE, proto);
649 JSHandle<JSAPIDeque> jsAPIDeque = JSHandle<JSAPIDeque>::Cast(jsAPIDequeObject);
650 JSHandle<TaggedArray> newElements = factory->NewTaggedArray(JSAPIDeque::DEFAULT_CAPACITY_LENGTH);
651 jsAPIDeque->SetFirst(0);
652 jsAPIDeque->SetLast(0);
653 jsAPIDeque->SetElements(instance->GetJSThread(), newElements);
654 return jsAPIDeque;
655 }
656 // JS_API_STACK
NewJSAPIStack()657 JSHandle<JSAPIStack> NewJSAPIStack()
658 {
659 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
660 JSHandle<JSObject> jsAPIStackObject = NewObject(JSAPIStack::SIZE, JSType::JS_API_STACK, proto);
661 JSHandle<JSAPIStack> jsAPIStack = JSHandle<JSAPIStack>::Cast(jsAPIStackObject);
662 jsAPIStack->SetTop(0);
663 return jsAPIStack;
664 }
665
666 // JS_API_PLAIN_ARRAY
NewJSAPIPlainArray()667 JSHandle<JSAPIPlainArray> NewJSAPIPlainArray()
668 {
669 JSThread *thread = instance->GetJSThread();
670 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
671 JSHandle<JSObject> jsAPIPlainArrayObject = NewObject(JSAPIPlainArray::SIZE, JSType::JS_API_PLAIN_ARRAY, proto);
672 JSHandle<JSAPIPlainArray> jsAPIPlainArray = JSHandle<JSAPIPlainArray>::Cast(jsAPIPlainArrayObject);
673 JSHandle<TaggedArray> keys =
674 JSAPIPlainArray::CreateSlot(thread, JSAPIPlainArray::DEFAULT_CAPACITY_LENGTH);
675 JSHandle<TaggedArray> values =
676 JSAPIPlainArray::CreateSlot(thread, JSAPIPlainArray::DEFAULT_CAPACITY_LENGTH);
677 jsAPIPlainArray->SetKeys(thread, keys);
678 jsAPIPlainArray->SetValues(thread, values);
679 jsAPIPlainArray->SetLength(0);
680 return jsAPIPlainArray;
681 }
682
683 // JS_API_LIST
NewJSAPIList()684 JSHandle<JSAPIList> NewJSAPIList()
685 {
686 JSThread *thread = instance->GetJSThread();
687 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
688 JSHandle<JSObject> jsAPIListObject = NewObject(JSAPIList::SIZE, JSType::JS_API_LIST, proto);
689 JSHandle<JSAPIList> jsAPIList = JSHandle<JSAPIList>::Cast(jsAPIListObject);
690 JSHandle<JSTaggedValue> taggedSingleList(thread, TaggedSingleList::Create(thread));
691 jsAPIList->SetSingleList(thread, taggedSingleList);
692 return jsAPIList;
693 }
694
695 // JS_API_LINKED_LIST
NewJSAPILinkedList()696 JSHandle<JSAPILinkedList> NewJSAPILinkedList()
697 {
698 JSThread *thread = instance->GetJSThread();
699 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetObjectFunctionPrototype();
700 JSHandle<JSObject> jsAPILinkedListObject = NewObject(JSAPILinkedList::SIZE, JSType::JS_API_LINKED_LIST, proto);
701 JSHandle<JSAPILinkedList> jsAPILinkedList = JSHandle<JSAPILinkedList>::Cast(jsAPILinkedListObject);
702 JSHandle<JSTaggedValue> linkedlist(thread, TaggedDoubleList::Create(thread));
703 jsAPILinkedList->SetDoubleList(thread, linkedlist);
704 return jsAPILinkedList;
705 }
706
707 // JS_API_VECTOR
NewJSAPIVector()708 JSHandle<JSAPIVector> NewJSAPIVector()
709 {
710 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
711 JSHandle<JSObject> jsAPIVectorObject = NewObject(JSAPIVector::SIZE, JSType::JS_API_VECTOR, proto);
712 JSHandle<JSAPIVector> jsAPIVector = JSHandle<JSAPIVector>::Cast(jsAPIVectorObject);
713 jsAPIVector->SetLength(0);
714 return jsAPIVector;
715 }
716
717 // JS_WEAK_REF
NewJSWeakRef()718 JSHandle<JSWeakRef> NewJSWeakRef()
719 {
720 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
721 JSHandle<JSObject> jsWeakRefObject = NewObject(JSWeakRef::SIZE, JSType::JS_WEAK_REF, proto);
722 JSHandle<JSWeakRef> jsWeakRef = JSHandle<JSWeakRef>::Cast(jsWeakRefObject);
723 return jsWeakRef;
724 }
725
726 // JS_FINALIZATION_REGISTRY
NewJSFinalizationRegistry()727 JSHandle<JSFinalizationRegistry> NewJSFinalizationRegistry()
728 {
729 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
730 JSHandle<JSObject> jsFinalizationRegistryObject =
731 NewObject(JSFinalizationRegistry::SIZE, JSType::JS_FINALIZATION_REGISTRY, proto);
732 JSHandle<JSFinalizationRegistry> jsFinalizationRegistry =
733 JSHandle<JSFinalizationRegistry>::Cast(jsFinalizationRegistryObject);
734 return jsFinalizationRegistry;
735 }
736
737 // JS_ASYNC_FROM_SYNC_ITERATOR
NewJSAsyncFromSyncIterator()738 JSHandle<JSAsyncFromSyncIterator> NewJSAsyncFromSyncIterator()
739 {
740 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
741 JSHandle<JSObject> jsAsyncFromSyncIteratorObject =
742 NewObject(JSAsyncFromSyncIterator::SIZE, JSType::JS_ASYNC_FROM_SYNC_ITERATOR, proto);
743 JSHandle<JSAsyncFromSyncIterator> jsAsyncFromSyncIterator =
744 JSHandle<JSAsyncFromSyncIterator>::Cast(jsAsyncFromSyncIteratorObject);
745 return jsAsyncFromSyncIterator;
746 }
747
748 // JS_API_LINKED_LIST_ITERATOR
NewJSAPILinkedListIterator()749 JSHandle<JSAPILinkedListIterator> NewJSAPILinkedListIterator()
750 {
751 ObjectFactory *factory = instance->GetFactory();
752 JSHandle<JSAPILinkedList> jsAPILinkedList = NewJSAPILinkedList();
753 JSHandle<JSAPILinkedListIterator> jsAPILinkedListIter =
754 factory->NewJSAPILinkedListIterator(jsAPILinkedList);
755 return jsAPILinkedListIter;
756 }
757
758 // JS_API_LIST_ITERATOR
NewJSAPIListIterator()759 JSHandle<JSAPIListIterator> NewJSAPIListIterator()
760 {
761 ObjectFactory *factory = instance->GetFactory();
762 JSHandle<JSAPIList> jsAPIList = NewJSAPIList();
763 JSHandle<JSAPIListIterator> jsAPIListIter = factory->NewJSAPIListIterator(jsAPIList);
764 return jsAPIListIter;
765 }
766
767 // JS_SHARED_ARRAY_ITERATOR
NewJSSharedArrayIterator()768 JSHandle<JSSharedArrayIterator> NewJSSharedArrayIterator()
769 {
770 ObjectFactory *factory = instance->GetFactory();
771 JSHandle<JSSharedArrayIterator> sharedArrayIter = factory->NewJSSharedArrayIterator(
772 JSHandle<JSObject>::Cast(factory->NewJSSArray()), IterationKind::KEY);
773 return sharedArrayIter;
774 }
775
776 // BYTE_ARRAY
NewByteArray()777 JSHandle<ByteArray> NewByteArray()
778 {
779 uint8_t value = 255; // 255 : test case
780 int byteArrayLength = 10; // 10: arrayLength
781 ObjectFactory *factory = instance->GetFactory();
782 JSHandle<ByteArray> byteArray = factory->NewByteArray(byteArrayLength, sizeof(value));
783 return byteArray;
784 }
785
786 // RB_TREENODE
NewRBTreeNode()787 JSHandle<RBTreeNode> NewRBTreeNode()
788 {
789 ObjectFactory *factory = instance->GetFactory();
790 JSThread *thread = instance->GetJSThread();
791 std::string k("testKey");
792 std::string v("testValue");
793 JSHandle<JSTaggedValue> key(thread, factory->NewFromStdString(k).GetTaggedValue());
794 JSHandle<JSTaggedValue> value(thread, factory->NewFromStdString(v).GetTaggedValue());
795 int hash = TaggedNode::Hash(thread, factory->NewFromStdString(k).GetTaggedValue());
796 JSHandle<RBTreeNode> newNode = factory->NewTreeNode(hash, key, value);
797 return newNode;
798 }
799
800 // CLASS_LITERAL
NewClassLiteral()801 JSHandle<ClassLiteral> NewClassLiteral()
802 {
803 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
804 JSHandle<JSObject> classLiteralObject = NewObject(ClassLiteral::SIZE, JSType::CLASS_LITERAL, proto);
805 JSHandle<ClassLiteral> classLiteral = JSHandle<ClassLiteral>::Cast(classLiteralObject);
806 ObjectFactory *factory = instance->GetFactory();
807 JSHandle<TaggedArray> emptyArray = factory->EmptyArray();
808
809 classLiteral->SetArray(instance->GetJSThread(), emptyArray);
810 classLiteral->SetIsAOTUsed(false);
811 return classLiteral;
812 }
813
814 // ASYNC_ITERATOR_RECORD
NewAsyncIteratorRecord()815 JSHandle<AsyncIteratorRecord> NewAsyncIteratorRecord()
816 {
817 ObjectFactory *factory = instance->GetFactory();
818 JSHandle<JSTaggedValue> proto = instance->GetGlobalEnv()->GetFunctionPrototype();
819 JSHandle<JSObject> jsObject = NewObject(JSObject::SIZE, JSType::JS_OBJECT, proto);
820 JSHandle<JSTaggedValue> emptyObj(jsObject);
821 JSHandle<JSTaggedValue> emptyMethod(jsObject);
822 JSHandle<AsyncIteratorRecord> asyncIteratorRecord =
823 factory->NewAsyncIteratorRecord(emptyObj, emptyMethod, false);
824 return asyncIteratorRecord;
825 }
826
827 // PROFILE_TYPE_INFO_CELL
NewProfileTypeInfoCell()828 JSHandle<ProfileTypeInfoCell> NewProfileTypeInfoCell()
829 {
830 JSThread *thread = instance->GetJSThread();
831 JSHandle<JSTaggedValue> handleUndefined(thread, JSTaggedValue::Undefined());
832 JSHandle<ProfileTypeInfoCell> newProfileTypeInfoCell =
833 instance->GetFactory()->NewProfileTypeInfoCell(handleUndefined);
834 return newProfileTypeInfoCell;
835 }
836 private:
837 EcmaVM *instance {nullptr};
838 };
839
840 class MockHeapProfiler : public HeapProfilerInterface {
841 public:
842 NO_MOVE_SEMANTIC(MockHeapProfiler);
843 NO_COPY_SEMANTIC(MockHeapProfiler);
MockHeapProfiler(HeapProfilerInterface * profiler)844 explicit MockHeapProfiler(HeapProfilerInterface *profiler) : profiler_(profiler) {}
~MockHeapProfiler()845 ~MockHeapProfiler() override
846 {
847 allocEvtObj_.clear();
848 };
849
AllocationEvent(TaggedObject * address,size_t size)850 void AllocationEvent(TaggedObject *address, size_t size) override
851 {
852 allocEvtObj_.emplace(address, true);
853 profiler_->AllocationEvent(address, size);
854 }
855
MoveEvent(uintptr_t address,TaggedObject * forwardAddress,size_t size)856 void MoveEvent(uintptr_t address, TaggedObject *forwardAddress, size_t size) override
857 {
858 return profiler_->MoveEvent(address, forwardAddress, size);
859 }
860
DumpHeapSnapshot(Stream * stream,const DumpSnapShotOption & dumpOption,Progress * progress=nullptr,std::function<void (uint8_t)> callback=[](uint8_t){})861 bool DumpHeapSnapshot(Stream *stream, const DumpSnapShotOption &dumpOption, Progress *progress = nullptr,
862 std::function<void(uint8_t)> callback = [] (uint8_t) {}) override
863 {
864 return profiler_->DumpHeapSnapshot(stream, dumpOption, progress, callback);
865 }
866
DumpHeapSnapshotForOOM(const DumpSnapShotOption & dumpOption,bool fromSharedGC=false)867 void DumpHeapSnapshotForOOM(const DumpSnapShotOption &dumpOption, bool fromSharedGC = false) override
868 {
869 profiler_->DumpHeapSnapshotForOOM(dumpOption, fromSharedGC);
870 }
871
StartHeapTracking(double timeInterval,bool isVmMode=true,Stream * stream=nullptr,bool traceAllocation=false,bool newThread=true)872 bool StartHeapTracking(double timeInterval, bool isVmMode = true, Stream *stream = nullptr,
873 bool traceAllocation = false, bool newThread = true) override
874 {
875 return profiler_->StartHeapTracking(timeInterval, isVmMode, stream, traceAllocation, newThread);
876 }
877
StopHeapTracking(Stream * stream,Progress * progress=nullptr,bool newThread=true)878 bool StopHeapTracking(Stream *stream, Progress *progress = nullptr, bool newThread = true) override
879 {
880 return profiler_->StopHeapTracking(stream, progress, newThread);
881 }
882
UpdateHeapTracking(Stream * stream)883 bool UpdateHeapTracking(Stream *stream) override
884 {
885 return profiler_->UpdateHeapTracking(stream);
886 }
887
StartHeapSampling(uint64_t samplingInterval,int stackDepth=128)888 bool StartHeapSampling(uint64_t samplingInterval, int stackDepth = 128) override
889 {
890 return profiler_->StartHeapSampling(samplingInterval, stackDepth);
891 }
892
StopHeapSampling()893 void StopHeapSampling() override
894 {
895 profiler_->StopHeapSampling();
896 }
897
GetAllocationProfile()898 const struct SamplingInfo *GetAllocationProfile() override
899 {
900 return profiler_->GetAllocationProfile();
901 }
902
GetIdCount()903 size_t GetIdCount() override
904 {
905 return profiler_->GetIdCount();
906 }
907
908 std::unordered_map<TaggedObject *, bool> allocEvtObj_;
909 HeapProfilerInterface *profiler_ {nullptr};
910 };
911
912 template <class Callback>
913 class TestAllocationEventRootVisitor final : public RootVisitor {
914 public:
TestAllocationEventRootVisitor(Callback & cb)915 explicit TestAllocationEventRootVisitor(Callback &cb) : cb_(cb) {}
916 ~TestAllocationEventRootVisitor() = default;
VisitRoot(Root type,ObjectSlot slot)917 void VisitRoot([[maybe_unused]] Root type, ObjectSlot slot) override
918 {
919 JSTaggedValue value((slot).GetTaggedType());
920 if (!value.IsHeapObject()) {
921 return;
922 }
923 TaggedObject *root = value.GetTaggedObject();
924 cb_(root);
925 }
VisitRangeRoot(Root type,ObjectSlot start,ObjectSlot end)926 void VisitRangeRoot([[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) override
927 {
928 for (ObjectSlot slot = start; slot < end; slot++) {
929 VisitRoot(type, slot);
930 }
931 }
VisitBaseAndDerivedRoot(Root type,ObjectSlot base,ObjectSlot derived,uintptr_t baseOldObject)932 void VisitBaseAndDerivedRoot([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot base,
933 [[maybe_unused]] ObjectSlot derived, [[maybe_unused]] uintptr_t baseOldObject) override {}
934 private:
935 Callback &cb_;
936 };
937
HWTEST_F_L0(HeapDumpTest,TestAllocationEvent)938 HWTEST_F_L0(HeapDumpTest, TestAllocationEvent)
939 {
940 const std::string abcFileName = HPROF_TEST_ABC_FILES_DIR"heapdump.abc";
941 const std::string jsFileName = HPROF_TEST_JS_FILES_DIR"heapdump.js";
942 MockHeapProfiler mockHeapProfiler(ecmaVm_->GetOrNewHeapProfile());
943 ecmaVm_->SetHeapProfile(&mockHeapProfiler);
944
945 std::unordered_map<TaggedObject *, bool> ObjBeforeExecute;
946 std::unordered_map<TaggedObject *, bool> *ObjMap = &ObjBeforeExecute;
947 auto heap = ecmaVm_->GetHeap();
948 ASSERT_NE(heap, nullptr);
949 auto countCb = [&ObjMap](TaggedObject *obj) {
950 ObjMap->emplace(obj, true);
951 };
952 heap->IterateOverObjects(countCb);
953
954 TestAllocationEventRootVisitor testAllocationEventRootVisitor(countCb);
955 ecmaVm_->Iterate(testAllocationEventRootVisitor);
956 thread_->Iterate(testAllocationEventRootVisitor);
957
958 bool result = JSNApi::Execute(ecmaVm_, abcFileName, "heapdump");
959 EXPECT_TRUE(result);
960
961 std::unordered_map<TaggedObject *, bool> ObjAfterExecute;
962 ObjMap = &ObjAfterExecute;
963 heap->IterateOverObjects(countCb);
964 ecmaVm_->Iterate(testAllocationEventRootVisitor);
965 thread_->Iterate(testAllocationEventRootVisitor);
966 ecmaVm_->SetHeapProfile(mockHeapProfiler.profiler_);
967
968 std::unordered_map<std::string, int> noTraceObjCheck =
969 {{"TaggedArray", 1}, {"AsyncFunction", 2}, {"LexicalEnv", 2}, {"Array", 3}, {"Function", 7}, {"Map", 1},
970 {"Object", 1}, {"Uint8 Clamped Array", 1}, {"Uint32 Array", 1}, {"Float32 Array", 1}, {"Int32 Array", 1},
971 {"Int16 Array", 1}, {"BigUint64 Array", 1}, {"Uint8 Array", 1}, {"Float64 Array", 1}, {"ByteArray", 11},
972 {"Int8 Array", 1}, {"BigInt64 Array", 1}, {"Uint16 Array", 1}, {"ArrayIterator", 1}};
973 bool pass = true;
974 std::unordered_map<std::string, int> noTraceObj;
975 for (auto o = ObjAfterExecute.begin(); o != ObjAfterExecute.end(); o++) {
976 if (ObjBeforeExecute.find(o->first) != ObjBeforeExecute.end()) {
977 continue;
978 }
979 if (mockHeapProfiler.allocEvtObj_.find(o->first) != mockHeapProfiler.allocEvtObj_.end()) {
980 continue;
981 }
982 auto objType = o->first->GetClass()->GetObjectType();
983 std::string typeName = ConvertToStdString(JSHClass::DumpJSType(objType));
984 if (noTraceObjCheck.size() == 0) {
985 LOG_ECMA(ERROR) << "Object not traced, Addr=" << o->first << ", TypeName=" << typeName;
986 pass = false;
987 }
988 if (noTraceObj.find(typeName) == noTraceObj.end()) {
989 noTraceObj.emplace(typeName, 0);
990 }
991 noTraceObj[typeName] += 1;
992 }
993 for (auto o = noTraceObj.begin(); o != noTraceObj.end(); o++) {
994 if (noTraceObjCheck.find(o->first) == noTraceObjCheck.end()) {
995 LOG_ECMA(ERROR) << "Object not traced, TypeName=" << o->first << ", count=" << o->second;
996 pass = false;
997 }
998 }
999 ASSERT_TRUE(pass);
1000 }
1001
HWTEST_F_L0(HeapDumpTest,TestHeapDumpFunctionUrl)1002 HWTEST_F_L0(HeapDumpTest, TestHeapDumpFunctionUrl)
1003 {
1004 const std::string abcFileName = HPROF_TEST_ABC_FILES_DIR"heapdump.abc";
1005
1006 bool result = JSNApi::Execute(ecmaVm_, abcFileName, "heapdump");
1007 EXPECT_TRUE(result);
1008
1009 HeapDumpTestHelper tester(ecmaVm_);
1010 tester.GenerateSnapShot("testFunctionUrl.heapsnapshot");
1011
1012 // match function url
1013 std::string line;
1014 std::ifstream inputStream("testFunctionUrl.heapsnapshot");
1015 bool strMatched = false;
1016 bool funcTempMatched = false;
1017 while (getline(inputStream, line)) {
1018 if (strMatched && funcTempMatched) {
1019 break;
1020 }
1021 if (line.find("heapdump.js#greet(line:98)") != std::string::npos) {
1022 strMatched = true;
1023 continue;
1024 }
1025 if (line == "\"ArkInternalFunctionTemplate\",") {
1026 funcTempMatched = true;
1027 continue;
1028 }
1029 }
1030 ASSERT_TRUE(strMatched);
1031 ASSERT_TRUE(funcTempMatched);
1032 }
1033
HWTEST_F_L0(HeapDumpTest,TestHeapDumpFunctionAndObject)1034 HWTEST_F_L0(HeapDumpTest, TestHeapDumpFunctionAndObject)
1035 {
1036 const std::string abcFileName = HPROF_TEST_ABC_FILES_DIR"heapdump1.abc";
1037
1038 bool result = JSNApi::Execute(ecmaVm_, abcFileName, "heapdump1");
1039 EXPECT_TRUE(result);
1040 ecmaVm_->SetBundleName("com.example.testFunctionAndObject");
1041 HeapDumpTestHelper tester(ecmaVm_);
1042 tester.GenerateSnapShot("testFunctionAndObject.heapsnapshot");
1043
1044 // match function url
1045 std::string line;
1046 std::ifstream inputStream("testFunctionAndObject.heapsnapshot");
1047 bool strMatched = false;
1048 bool strMatched1 = false;
1049 bool strMatched2 = false;
1050 bool strMatched3 = false;
1051 bool strMatched4 = false;
1052 bool strMatched5 = false;
1053 bool strMatched6 = false;
1054 bool strMatched7 = false;
1055 while (getline(inputStream, line)) {
1056 if (strMatched && strMatched1 && strMatched2 && strMatched3 &&
1057 strMatched4 && strMatched5 && strMatched6 && strMatched7) {
1058 break;
1059 }
1060 if (line.find("heapdump1.js#anonymous(line:19)") != std::string::npos) {
1061 strMatched = true;
1062 continue;
1063 }
1064 if (line.find("heapdump1.js#test(line:25)") != std::string::npos) {
1065 strMatched1 = true;
1066 continue;
1067 }
1068 if (line.find("heapdump1.js#ObjectFun(line:30)") != std::string::npos) {
1069 strMatched2 = true;
1070 continue;
1071 }
1072 if (line.find("heapdump1.js#Person(line:35)") != std::string::npos) {
1073 strMatched3 = true;
1074 continue;
1075 }
1076 if (line.find("heapdump1.js#greet(line:40)") != std::string::npos) {
1077 strMatched4 = true;
1078 continue;
1079 }
1080 if (line.find("heapdump1.js#testObject(line:51)") != std::string::npos) {
1081 strMatched5 = true;
1082 continue;
1083 }
1084 if (line.find("heapdump1.js#Student(line:62)") != std::string::npos) {
1085 strMatched6 = true;
1086 continue;
1087 }
1088 if (line.find("heapdump1.js#getMessage(line:67)") != std::string::npos) {
1089 strMatched7 = true;
1090 continue;
1091 }
1092 }
1093 ASSERT_TRUE(strMatched);
1094 ASSERT_TRUE(strMatched1);
1095 ASSERT_TRUE(strMatched2);
1096 ASSERT_TRUE(strMatched3);
1097 ASSERT_TRUE(strMatched4);
1098 ASSERT_TRUE(strMatched5);
1099 ASSERT_TRUE(strMatched6);
1100 ASSERT_TRUE(strMatched7);
1101 }
1102
HWTEST_F_L0(HeapDumpTest,TestHeapDumpGenerateNodeName1)1103 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName1)
1104 {
1105 JSHandle<GlobalEnv> env = thread_->GetEcmaVM()->GetGlobalEnv();
1106 ObjectFactory *factory = ecmaVm_->GetFactory();
1107 HeapDumpTestHelper tester(ecmaVm_);
1108
1109 // TAGGED_ARRAY
1110 factory->NewTaggedArray(10);
1111 // LEXICAL_ENV
1112 factory->NewLexicalEnv(10);
1113 // CONSTANT_POOL
1114 factory->NewConstantPool(10);
1115 // PROFILE_TYPE_INFO
1116 factory->NewProfileTypeInfo(10);
1117 // TAGGED_DICTIONARY
1118 factory->NewDictionaryArray(10);
1119 // AOT_LITERAL_INFO
1120 factory->NewAOTLiteralInfo(10);
1121 // VTABLE
1122 factory->NewVTable(10);
1123 // COW_TAGGED_ARRAY
1124 factory->NewCOWTaggedArray(10);
1125 // HCLASS
1126 JSHandle<JSTaggedValue> proto = env->GetFunctionPrototype();
1127 factory->NewEcmaHClass(JSHClass::SIZE, JSType::HCLASS, proto);
1128 // LINKED_NODE
1129 JSHandle<LinkedNode> linkedNode(thread_, JSTaggedValue::Hole());
1130 factory->NewLinkedNode(1, JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Hole()),
1131 JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Hole()), linkedNode);
1132 // JS_NATIVE_POINTER
1133 auto newData = ecmaVm_->GetNativeAreaAllocator()->AllocateBuffer(8);
1134 factory->NewJSNativePointer(newData);
1135
1136 tester.GenerateSnapShot("testGenerateNodeName_1.heapsnapshot");
1137 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalArray["));
1138 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"LexicalEnv["));
1139 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalConstantPool["));
1140 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalProfileTypeInfo["));
1141 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalDict["));
1142 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalAOTLiteralInfo["));
1143 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalVTable["));
1144 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalCOWArray["));
1145 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"HiddenClass(NonMovable)"));
1146 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"LinkedNode\""));
1147 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"JSNativePointer\""));
1148 // Test Not Found
1149 ASSERT_TRUE(!tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "*#@failed case"));
1150 }
1151
HWTEST_F_L0(HeapDumpTest,TestHeapDumpGenerateNodeName2)1152 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName2)
1153 {
1154 ObjectFactory *factory = ecmaVm_->GetFactory();
1155 HeapDumpTestHelper tester(ecmaVm_);
1156
1157 // JS_ERROR
1158 JSHandle<EcmaString> handleMessage(thread_, EcmaStringAccessor::CreateEmptyString(ecmaVm_));
1159 factory->NewJSError(ErrorType::ERROR, handleMessage);
1160 // JS_EVAL_ERROR
1161 factory->NewJSError(ErrorType::EVAL_ERROR, handleMessage);
1162 // JS_RANGE_ERROR
1163 factory->NewJSError(ErrorType::RANGE_ERROR, handleMessage);
1164 // JS_TYPE_ERROR
1165 factory->NewJSError(ErrorType::TYPE_ERROR, handleMessage);
1166 // JS_AGGREGATE_ERROR
1167 factory->NewJSAggregateError();
1168 // JS_REFERENCE_ERROR
1169 factory->NewJSError(ErrorType::REFERENCE_ERROR, handleMessage);
1170 // JS_URI_ERROR
1171 factory->NewJSError(ErrorType::URI_ERROR, handleMessage);
1172 // JS_SYNTAX_ERROR
1173 factory->NewJSError(ErrorType::SYNTAX_ERROR, handleMessage);
1174 // JS_OOM_ERROR
1175 factory->NewJSError(ErrorType::OOM_ERROR, handleMessage);
1176 // JS_TERMINATION_ERROR
1177 factory->NewJSError(ErrorType::TERMINATION_ERROR, handleMessage);
1178
1179 tester.GenerateSnapShot("testGenerateNodeName_2.heapsnapshot");
1180 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Error\""));
1181 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Eval Error\""));
1182 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Range Error\""));
1183 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Type Error\""));
1184 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Aggregate Error\""));
1185 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Reference Error\""));
1186 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Uri Error\""));
1187 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Syntax Error\""));
1188 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"OutOfMemory Error\""));
1189 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Termination Error\""));
1190 }
1191
HWTEST_F_L0(HeapDumpTest,TestHeapDumpGenerateNodeName3)1192 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName3)
1193 {
1194 HeapDumpTestHelper tester(ecmaVm_);
1195
1196 // JS_INT8_ARRAY
1197 tester.CreateNumberTypedArray(JSType::JS_INT8_ARRAY);
1198 // JS_UINT8_ARRAY
1199 tester.CreateNumberTypedArray(JSType::JS_UINT8_ARRAY);
1200 // JS_UINT8_CLAMPED_ARRAY
1201 tester.CreateNumberTypedArray(JSType::JS_UINT8_CLAMPED_ARRAY);
1202 // JS_INT16_ARRAY
1203 tester.CreateNumberTypedArray(JSType::JS_INT16_ARRAY);
1204 // JS_UINT16_ARRAY
1205 tester.CreateNumberTypedArray(JSType::JS_UINT16_ARRAY);
1206 // JS_INT32_ARRAY
1207 tester.CreateNumberTypedArray(JSType::JS_INT32_ARRAY);
1208 // JS_UINT32_ARRAY
1209 tester.CreateNumberTypedArray(JSType::JS_UINT32_ARRAY);
1210 // JS_FLOAT32_ARRAY
1211 tester.CreateNumberTypedArray(JSType::JS_FLOAT32_ARRAY);
1212 // JS_FLOAT64_ARRAY
1213 tester.CreateNumberTypedArray(JSType::JS_FLOAT64_ARRAY);
1214 // JS_BIGINT64_ARRAY
1215 tester.CreateNumberTypedArray(JSType::JS_BIGINT64_ARRAY);
1216 // JS_BIGUINT64_ARRAY
1217 tester.CreateNumberTypedArray(JSType::JS_BIGUINT64_ARRAY);
1218
1219 tester.GenerateSnapShot("testGenerateNodeName_3.heapsnapshot");
1220 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Int8 Array\""));
1221 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Uint8 Array\""));
1222 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Uint8 Clamped Array\""));
1223 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Int16 Array\""));
1224 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Uint16 Array\""));
1225 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Int32 Array\""));
1226 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Uint32 Array\""));
1227 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Float32 Array\""));
1228 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"Float64 Array\""));
1229 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"BigInt64 Array\""));
1230 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_3.heapsnapshot", "\"BigUint64 Array\""));
1231 }
1232
HWTEST_F_L0(HeapDumpTest,TestHeapDumpGenerateNodeName4)1233 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName4)
1234 {
1235 ObjectFactory *factory = ecmaVm_->GetFactory();
1236 HeapDumpTestHelper tester(ecmaVm_);
1237
1238 JSHandle<JSTaggedValue> proto = ecmaVm_->GetGlobalEnv()->GetFunctionPrototype();
1239 // JS_SET
1240 tester.NewJSSet();
1241 // JS_SHARED_SET
1242 tester.NewJSSharedSet();
1243 // JS_MAP
1244 tester.NewJSMap();
1245 // JS_SHARED_MAP
1246 tester.NewJSSharedMap();
1247 // JS_WEAK_SET
1248 tester.NewJSWeakSet();
1249 // JS_WEAK_MAP
1250 tester.NewJSWeakMap();
1251 // JS_ARRAY
1252 factory->NewJSArray();
1253 // JS_TYPED_ARRAY
1254 tester.NewObject(JSTypedArray::SIZE, JSType::JS_TYPED_ARRAY, proto);
1255 tester.GenerateSnapShot("testGenerateNodeName_4.heapsnapshot");
1256
1257 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Set\""));
1258 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"SharedSet\""));
1259 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Map\""));
1260 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"SharedMap\""));
1261 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"WeakSet\""));
1262 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"WeakMap\""));
1263 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"JSArray\""));
1264 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Typed Array\""));
1265 }
1266
HWTEST_F_L0(HeapDumpTest,TestHeapDumpGenerateNodeName5)1267 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName5)
1268 {
1269 ObjectFactory *factory = ecmaVm_->GetFactory();
1270 HeapDumpTestHelper tester(ecmaVm_);
1271
1272 JSHandle<JSTaggedValue> proto = ecmaVm_->GetGlobalEnv()->GetFunctionPrototype();
1273 // JS_REG_EXP
1274 tester.NewObject(JSRegExp::SIZE, JSType::JS_REG_EXP, proto);
1275 // JS_DATE
1276 tester.NewObject(JSDate::SIZE, JSType::JS_DATE, proto);
1277 // JS_ARGUMENTS
1278 factory->NewJSArguments();
1279 // JS_PROXY
1280 tester.NewJSProxy();
1281 // JS_PRIMITIVE_REF
1282 tester.NewObject(JSPrimitiveRef::SIZE, JSType::JS_PRIMITIVE_REF, proto);
1283 // JS_DATA_VIEW
1284 factory->NewJSDataView(factory->NewJSArrayBuffer(10), 5, 5);
1285
1286 tester.GenerateSnapShot("testGenerateNodeName_5.heapsnapshot");
1287 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_5.heapsnapshot", "\"Regexp\""));
1288 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_5.heapsnapshot", "\"Date\""));
1289 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_5.heapsnapshot", "\"Arguments\""));
1290 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_5.heapsnapshot", "\"Proxy\""));
1291 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_5.heapsnapshot", "\"Primitive\""));
1292 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_5.heapsnapshot", "\"DataView\""));
1293 }
1294
HWTEST_F_L0(HeapDumpTest,TestHeapDumpGenerateNodeName6)1295 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName6)
1296 {
1297 ObjectFactory *factory = ecmaVm_->GetFactory();
1298 HeapDumpTestHelper tester(ecmaVm_);
1299
1300 // JS_FORIN_ITERATOR
1301 tester.NewJSForInIterator();
1302 // JS_MAP_ITERATOR
1303 factory->NewJSMapIterator(tester.NewJSMap(), IterationKind::KEY);
1304 // JS_SHARED_MAP_ITERATOR
1305 factory->NewJSMapIterator(tester.NewJSSharedMap(), IterationKind::KEY);
1306 // JS_SET_ITERATOR
1307 factory->NewJSSetIterator(tester.NewJSSet(), IterationKind::KEY);
1308 // JS_SHARED_SET_ITERATOR
1309 factory->NewJSSetIterator(tester.NewJSSharedSet(), IterationKind::KEY);
1310 // JS_REG_EXP_ITERATOR
1311 tester.NewJSRegExpIterator();
1312 // JS_ARRAY_ITERATOR
1313 factory->NewJSArrayIterator(JSHandle<JSObject>::Cast(factory->NewJSArray()), IterationKind::KEY);
1314 // JS_STRING_ITERATOR
1315 JSStringIterator::CreateStringIterator(thread_, factory->GetEmptyString());
1316
1317 tester.GenerateSnapShot("testGenerateNodeName_6.heapsnapshot");
1318 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"ForinInterator\""));
1319 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"MapIterator\""));
1320 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"SharedMapIterator\""));
1321 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"SetIterator\""));
1322 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"SharedSetIterator\""));
1323 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"RegExpIterator\""));
1324 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"ArrayIterator\""));
1325 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_6.heapsnapshot", "\"StringIterator\""));
1326 }
1327
HWTEST_F_L0(HeapDumpTest,TestHeapDumpGenerateNodeName7)1328 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName7)
1329 {
1330 ObjectFactory *factory = ecmaVm_->GetFactory();
1331 HeapDumpTestHelper tester(ecmaVm_);
1332 // JS_ARRAY_BUFFER
1333 factory->NewJSArrayBuffer(10);
1334 // JS_SHARED_ARRAY_BUFFER
1335 factory->NewJSSharedArrayBuffer(10);
1336 // PROMISE_REACTIONS
1337 factory->NewPromiseReaction();
1338 // PROMISE_CAPABILITY
1339 factory->NewPromiseCapability();
1340 // PROMISE_ITERATOR_RECORD
1341 tester.NewPromiseIteratorRecord();
1342 // PROMISE_RECORD
1343 factory->NewPromiseRecord();
1344 // RESOLVING_FUNCTIONS_RECORD
1345 factory->NewResolvingFunctionsRecord();
1346 // JS_PROMISE
1347 JSHandle<JSTaggedValue> proto = ecmaVm_->GetGlobalEnv()->GetFunctionPrototype();
1348 tester.NewObject(JSPromise::SIZE, JSType::JS_PROMISE, proto);
1349 // ASYNC_GENERATOR_REQUEST
1350 factory->NewAsyncGeneratorRequest();
1351
1352 tester.GenerateSnapShot("testGenerateNodeName_7.heapsnapshot");
1353 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"ArrayBuffer\""));
1354 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"SharedArrayBuffer\""));
1355 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"PromiseReaction\""));
1356 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"PromiseCapability\""));
1357 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"PromiseIteratorRecord\""));
1358 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"PromiseRecord\""));
1359 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"ResolvingFunctionsRecord\""));
1360 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"Promise\""));
1361 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_7.heapsnapshot", "\"AsyncGeneratorRequest\""));
1362 }
1363
HWTEST_F_L0(HeapDumpTest,TestHeapDumpGenerateNodeName8)1364 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName8)
1365 {
1366 auto factory = ecmaVm_->GetFactory();
1367 HeapDumpTestHelper tester(ecmaVm_);
1368 // JS_API_ARRAY_LIST
1369 auto jsAPIArrayList = tester.NewJSAPIArrayList();
1370 // JS_API_ARRAYLIST_ITERATOR
1371 factory->NewJSAPIArrayListIterator(jsAPIArrayList);
1372 // JS_API_HASH_MAP
1373 auto jsAPIHashMap = tester.NewJSAPIHashMap();
1374 // JS_API_HASHMAP_ITERATOR
1375 factory->NewJSAPIHashMapIterator(jsAPIHashMap, IterationKind::KEY);
1376 // JS_API_HASH_SET
1377 auto jsAPIHashSet = tester.NewJSAPIHashSet();
1378 // JS_API_HASHSET_ITERATOR
1379 factory->NewJSAPIHashSetIterator(jsAPIHashSet, IterationKind::KEY);
1380 // JS_API_LIGHT_WEIGHT_MAP
1381 auto jsAPILightWeightMap = tester.NewJSAPILightWeightMap();
1382 // JS_API_LIGHT_WEIGHT_MAP_ITERATOR
1383 factory->NewJSAPILightWeightMapIterator(jsAPILightWeightMap, IterationKind::KEY);
1384 // JS_API_LIGHT_WEIGHT_SET
1385 auto jsAPILightWeightSet = tester.NewJSAPILightWeightSet();
1386 // JS_API_LIGHT_WEIGHT_SET_ITERATOR
1387 factory->NewJSAPILightWeightSetIterator(jsAPILightWeightSet, IterationKind::KEY);
1388
1389 tester.GenerateSnapShot("testGenerateNodeName_8.heapsnapshot");
1390 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"ArrayList\""));
1391 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"ArrayListIterator\""));
1392 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"HashMap\""));
1393 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"HashSet\""));
1394 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"HashMapIterator\""));
1395 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"HashSetIterator\""));
1396 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"LightWeightMap\""));
1397 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"LightWeightMapIterator\""));
1398 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"LightWeightSet\""));
1399 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_8.heapsnapshot", "\"LightWeightSetIterator\""));
1400 }
1401
HWTEST_F_L0(HeapDumpTest,TestHeapDumpGenerateNodeName9)1402 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName9)
1403 {
1404 auto factory = ecmaVm_->GetFactory();
1405 HeapDumpTestHelper tester(ecmaVm_);
1406 // JS_API_TREE_MAP
1407 auto jsAPITreeMap = tester.NewJSAPITreeMap();
1408 // JS_API_TREEMAP_ITERATOR
1409 factory->NewJSAPITreeMapIterator(jsAPITreeMap, IterationKind::KEY);
1410 // JS_API_TREE_SET
1411 auto jsAPITreeSet = tester.NewJSAPITreeSet();
1412 // JS_API_TREESET_ITERATOR
1413 factory->NewJSAPITreeSetIterator(jsAPITreeSet, IterationKind::KEY);
1414 // JS_API_VECTOR
1415 auto jsAPIVector = tester.NewJSAPIVector();
1416 // JS_API_VECTOR_ITERATOR
1417 factory->NewJSAPIVectorIterator(jsAPIVector);
1418 // JS_API_QUEUE
1419 auto jsAPIQueue = tester.NewJSAPIQueue();
1420 // JS_API_QUEUE_ITERATOR
1421 factory->NewJSAPIQueueIterator(jsAPIQueue);
1422 // JS_API_DEQUE
1423 auto jsAPIDeque = tester.NewJSAPIDeque();
1424 // JS_API_DEQUE_ITERATOR
1425 factory->NewJSAPIDequeIterator(jsAPIDeque);
1426 // JS_API_STACK
1427 auto jsAPIStack = tester.NewJSAPIStack();
1428 // JS_API_STACK_ITERATOR
1429 factory->NewJSAPIStackIterator(jsAPIStack);
1430 // JS_API_LIST
1431 tester.NewJSAPIList();
1432 // JS_API_LINKED_LIST
1433 tester.NewJSAPILinkedList();
1434 // JS_API_PLAIN_ARRAY
1435 auto jsAPIPlainArray = tester.NewJSAPIPlainArray();
1436 // JS_API_PLAIN_ARRAY_ITERATOR
1437 factory->NewJSAPIPlainArrayIterator(jsAPIPlainArray, IterationKind::KEY);
1438
1439 tester.GenerateSnapShot("testGenerateNodeName_9.heapsnapshot");
1440 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"TreeMap\""));
1441 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"TreeMapIterator\""));
1442 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"TreeSet\""));
1443 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"TreeSetIterator\""));
1444 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"Vector\""));
1445 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"VectorIterator\""));
1446 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"Queue\""));
1447 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"QueueIterator\""));
1448 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"Deque\""));
1449 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"DequeIterator\""));
1450 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"Stack\""));
1451 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"StackIterator\""));
1452 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"List\""));
1453 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"LinkedList\""));
1454 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"PlainArray\""));
1455 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_9.heapsnapshot", "\"PlainArrayIterator\""));
1456 }
1457
HWTEST_F_L0(HeapDumpTest,TestHeapDumpGenerateNodeName10)1458 HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName10)
1459 {
1460 auto factory = ecmaVm_->GetFactory();
1461 HeapDumpTestHelper tester(ecmaVm_);
1462 // JS_WEAK_REF
1463 tester.NewJSWeakRef();
1464 // JS_FINALIZATION_REGISTRY
1465 tester.NewJSFinalizationRegistry();
1466 // JS_ASYNC_FROM_SYNC_ITERATOR
1467 tester.NewJSAsyncFromSyncIterator();
1468 // JS_API_LINKED_LIST_ITERATOR
1469 tester.NewJSAPILinkedListIterator();
1470 // JS_API_LIST_ITERATOR
1471 tester.NewJSAPIListIterator();
1472 // JS_SHARED_ARRAY_ITERATOR
1473 tester.NewJSSharedArrayIterator();
1474 // JS_SHARED_INT8_ARRAY
1475 // JS_SHARED_UINT8_ARRAY
1476 // JS_SHARED_UINT8_CLAMPED_ARRAY
1477 // JS_SHARED_INT16_ARRAY
1478 // JS_SHARED_UINT16_ARRAY
1479 // JS_SHARED_INT32_ARRAY
1480 // JS_SHARED_UINT32_ARRAY
1481 // JS_SHARED_FLOAT32_ARRAY
1482 // JS_SHARED_FLOAT64_ARRAY
1483 // JS_SHARED_BIGINT64_ARRAY
1484 // JS_SHARED_BIGUINT64_ARRAY
1485 tester.NewSharedTypedArray();
1486 // BYTE_ARRAY
1487 tester.NewByteArray();
1488 // RB_TREENODE
1489 tester.NewRBTreeNode();
1490 // ENUM_CACHE
1491 factory->NewEnumCache();
1492 // CLASS_LITERAL
1493 factory->NewClassLiteral();
1494 // ASYNC_ITERATOR_RECORD
1495 tester.NewAsyncIteratorRecord();
1496 // PROFILE_TYPE_INFO_CELL
1497 tester.NewProfileTypeInfoCell();
1498 // CELL_RECORD
1499 factory->NewCellRecord();
1500 // NATIVE_MODULE_FAILURE_INFO
1501 factory->NewNativeModuleFailureInfo();
1502 // MUTANT_TAGGED_ARRAY
1503 factory->NewMutantTaggedArray(10); // 10: arrayLength
1504 // COW_MUTANT_TAGGED_ARRAY
1505 factory->NewCOWMutantTaggedArray(10); // 10: arrayLength
1506 // EXTRA_PROFILE_TYPE_INFO
1507 factory->NewExtraProfileTypeInfo();
1508
1509 tester.GenerateSnapShot("testGenerateNodeName_10.heapsnapshot");
1510 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"WeakRef\""));
1511 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"JSFinalizationRegistry\""));
1512 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"AsyncFromSyncIterator\""));
1513 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"LinkedListIterator\""));
1514 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"ListIterator\""));
1515 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"SharedArrayIterator\""));
1516 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"ByteArray\""));
1517 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"RBTreeNode\""));
1518 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"EnumCache\""));
1519 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"ClassLiteral\""));
1520 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"AsyncIteratorRecord\""));
1521 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"ProfileTypeInfoCell\""));
1522 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"CellRecord\""));
1523 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"NativeModuleFailureInfo\""));
1524 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"MutantTaggedArray\""));
1525 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"COWMutantTaggedArray\""));
1526 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"ExtraProfileTypeInfo\""));
1527 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"Shared Int8 Array\""));
1528 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"Shared Uint8 Array\""));
1529 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"Shared Uint8 Clamped Array\""));
1530 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"Shared Int16 Array\""));
1531 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"Shared Uint16 Array\""));
1532 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"Shared Int32 Array\""));
1533 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"Shared Uint32 Array\""));
1534 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"Shared Float32 Array\""));
1535 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"Shared Float64 Array\""));
1536 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"Shared BigInt64 Array\""));
1537 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_10.heapsnapshot", "\"Shared BigUint64 Array\""));
1538 }
1539
1540 #ifndef PANDA_TARGET_ARM32
1541 #define CREATE_OBJECT_AND_ADD_REFS(generator, typeName, refs) \
1542 { \
1543 auto obj = generator->New##typeName(); \
1544 refs.emplace_back(#typeName, obj.GetTaggedValue()); \
1545 obj.GetTaggedValue().DumpForSnapshot(thread, refs); \
1546 }
1547
1548 #define CREATE_ARRAY_AND_ADD_REFS(generator, typeName, length, refs) \
1549 { \
1550 auto obj = generator->New##typeName(length); \
1551 refs.emplace_back(#typeName, obj.GetTaggedValue()); \
1552 obj.GetTaggedValue().DumpForSnapshot(thread, refs); \
1553 }
1554
CreateObjectsForBinaryDump(JSThread * thread,ObjectFactory * factory,HeapDumpTestHelper * tester,std::vector<Reference> & refs)1555 void CreateObjectsForBinaryDump(JSThread *thread, ObjectFactory *factory, HeapDumpTestHelper *tester,
1556 std::vector<Reference> &refs)
1557 {
1558 CREATE_OBJECT_AND_ADD_REFS(factory, PromiseRecord, refs)
1559 CREATE_OBJECT_AND_ADD_REFS(factory, PromiseReaction, refs)
1560 CREATE_OBJECT_AND_ADD_REFS(factory, PromiseCapability, refs)
1561 CREATE_OBJECT_AND_ADD_REFS(factory, ResolvingFunctionsRecord, refs)
1562 CREATE_OBJECT_AND_ADD_REFS(factory, AsyncGeneratorRequest, refs)
1563 CREATE_OBJECT_AND_ADD_REFS(tester, PromiseIteratorRecord, refs)
1564 CREATE_OBJECT_AND_ADD_REFS(tester, JSWeakSet, refs)
1565 CREATE_OBJECT_AND_ADD_REFS(tester, JSWeakMap, refs)
1566 CREATE_ARRAY_AND_ADD_REFS(factory, JSArrayBuffer, 10, refs)
1567 CREATE_ARRAY_AND_ADD_REFS(factory, JSSharedArrayBuffer, 10, refs)
1568 }
1569
HWTEST_F_L0(HeapDumpTest,TestHeapDumpBinaryDumpV0)1570 HWTEST_F_L0(HeapDumpTest, TestHeapDumpBinaryDumpV0)
1571 {
1572 ObjectFactory *factory = ecmaVm_->GetFactory();
1573 HeapDumpTestHelper tester(ecmaVm_);
1574 std::vector<Reference> vec;
1575 CreateObjectsForBinaryDump(thread_, factory, &tester, vec);
1576
1577 std::string rawHeapPath("test_binary_dump_v0.rawheap");
1578 DumpSnapShotOption dumpOption;
1579 ASSERT_TRUE(tester.GenerateRawHeapSnashot(rawHeapPath, dumpOption));
1580
1581 FILE* file = std::fopen(rawHeapPath.c_str(), "rb+");
1582 ASSERT_TRUE(file != nullptr);
1583
1584 char version[sizeof(uint64_t)];
1585 *reinterpret_cast<uint64_t *>(version) = 0;
1586 std::fseek(file, 0, SEEK_SET);
1587 std::fwrite(version, sizeof(char), sizeof(version), file);
1588 std::fclose(file);
1589
1590 std::string heapsnapshotPath("test_binary_dump_v0.heapsnapshot");
1591 ASSERT_TRUE(tester.AddMetaDataJsonToRawheap(rawHeapPath));
1592 ASSERT_TRUE(tester.DecodeRawheap(rawHeapPath, heapsnapshotPath));
1593 }
1594
HWTEST_F_L0(HeapDumpTest,TestHeapDumpBinaryDumpV1)1595 HWTEST_F_L0(HeapDumpTest, TestHeapDumpBinaryDumpV1)
1596 {
1597 ObjectFactory *factory = ecmaVm_->GetFactory();
1598 HeapDumpTestHelper tester(ecmaVm_);
1599 std::vector<Reference> vec;
1600 CreateObjectsForBinaryDump(thread_, factory, &tester, vec);
1601
1602 std::string rawHeapPath("test_binary_dump_v1.rawheap");
1603 DumpSnapShotOption dumpOption;
1604 ASSERT_TRUE(tester.GenerateRawHeapSnashot(rawHeapPath, dumpOption));
1605
1606 CSet<JSTaggedType> dumpObjects;
1607 ASSERT_TRUE(tester.DecodeRawHeapObjectTableV1(rawHeapPath, dumpObjects));
1608
1609 ASSERT_TRUE(tester.MatchHeapObjectReferencesV1(vec, dumpObjects));
1610
1611 std::string heapsnapshotPath("test_binary_dump_v1.heapsnapshot");
1612 ASSERT_TRUE(tester.AddMetaDataJsonToRawheap(rawHeapPath));
1613 ASSERT_TRUE(tester.DecodeRawheap(rawHeapPath, heapsnapshotPath));
1614 }
1615
HWTEST_F_L0(HeapDumpTest,TestHeapDumpBinaryDumpV2)1616 HWTEST_F_L0(HeapDumpTest, TestHeapDumpBinaryDumpV2)
1617 {
1618 ObjectFactory *factory = ecmaVm_->GetFactory();
1619 HeapDumpTestHelper tester(ecmaVm_);
1620 std::vector<Reference> vec;
1621 CreateObjectsForBinaryDump(thread_, factory, &tester, vec);
1622
1623 std::string rawHeapPath("test_binary_dump_v2.rawheap");
1624 Runtime::GetInstance()->SetRawHeapDumpCropLevel(RawHeapDumpCropLevel::LEVEL_V2);
1625 DumpSnapShotOption dumpOption;
1626 ASSERT_TRUE(tester.GenerateRawHeapSnashot(rawHeapPath, dumpOption));
1627
1628 CSet<uint32_t> dumpObjects;
1629 ASSERT_TRUE(tester.DecodeRawHeapObjectTableV2(rawHeapPath, dumpObjects));
1630
1631 ASSERT_TRUE(tester.MatchHeapObjectReferencesV2(vec, dumpObjects));
1632 Runtime::GetInstance()->SetRawHeapDumpCropLevel(RawHeapDumpCropLevel::DEFAULT);
1633
1634 std::string heapsnapshotPath("test_binary_dump_v2.heapsnapshot");
1635 ASSERT_TRUE(tester.AddMetaDataJsonToRawheap(rawHeapPath));
1636 ASSERT_TRUE(tester.DecodeRawheap(rawHeapPath, heapsnapshotPath));
1637 }
1638
HWTEST_F_L0(HeapDumpTest,TestHeapDumpBinaryDumpByForkWithCallback)1639 HWTEST_F_L0(HeapDumpTest, TestHeapDumpBinaryDumpByForkWithCallback)
1640 {
1641 ObjectFactory *factory = ecmaVm_->GetFactory();
1642 HeapDumpTestHelper tester(ecmaVm_);
1643 std::vector<Reference> vec;
1644 CreateObjectsForBinaryDump(thread_, factory, &tester, vec);
1645
1646 bool status = true;
1647 std::string rawHeapPath("test_binary_dump_by_fork_with_callback.raw");
1648 auto cb = [&status](uint8_t retCode) {
1649 if (retCode != static_cast<uint8_t>(DumpHeapSnapshotStatus::SUCCESS)) {
1650 status = false;
1651 }
1652 };
1653 DumpSnapShotOption dumpOption;
1654 dumpOption.isSync = false;
1655 ASSERT_TRUE(tester.GenerateRawHeapSnashot(rawHeapPath, dumpOption, nullptr, cb));
1656 ASSERT_TRUE(status);
1657 }
1658
HWTEST_F_L0(HeapDumpTest,TestGenerateMixedNodeId)1659 HWTEST_F_L0(HeapDumpTest, TestGenerateMixedNodeId)
1660 {
1661 ObjectFactory *factory = ecmaVm_->GetFactory();
1662 HeapDumpTestHelper tester(ecmaVm_);
1663 std::vector<Reference> vec;
1664 CreateObjectsForBinaryDump(thread_, factory, &tester, vec);
1665
1666 for (auto ref : vec) {
1667 if (ref.value_.IsJSObject()) {
1668 int32_t hash = base::RandomGenerator::GenerateIdentityHash();
1669 JSHandle<ECMAObject> ecmaObj(thread_, ref.value_);
1670 ECMAObject::SetHash(thread_, hash, ecmaObj);
1671 }
1672 }
1673
1674 std::string rawHeapPath("test_binary_dump_for_mixed_node_id.rawheap");
1675 DumpSnapShotOption dumpOption;
1676 dumpOption.isSync = false;
1677 dumpOption.isJSLeakWatcher = true;
1678 ASSERT_TRUE(tester.GenerateRawHeapSnashot(rawHeapPath, dumpOption));
1679 ASSERT_TRUE(tester.CheckHashInNodeId(thread_, vec, rawHeapPath));
1680 }
1681 #endif
1682
HWTEST_F_L0(HeapDumpTest,TestSharedFullGCInHeapDump)1683 HWTEST_F_L0(HeapDumpTest, TestSharedFullGCInHeapDump)
1684 {
1685 ObjectFactory *factory = ecmaVm_->GetFactory();
1686 HeapDumpTestHelper tester(ecmaVm_);
1687
1688 JSHandle<JSTaggedValue> proto = ecmaVm_->GetGlobalEnv()->GetFunctionPrototype();
1689 // JS_SET
1690 tester.NewJSSet();
1691 // JS_SHARED_SET
1692 tester.NewJSSharedSet();
1693 // JS_MAP
1694 tester.NewJSMap();
1695 // JS_SHARED_MAP
1696 tester.NewJSSharedMap();
1697 // JS_WEAK_SET
1698 tester.NewJSWeakSet();
1699 // JS_WEAK_MAP
1700 tester.NewJSWeakMap();
1701 // JS_ARRAY
1702 factory->NewJSArray();
1703 // JS_TYPED_ARRAY
1704 tester.NewObject(JSTypedArray::SIZE, JSType::JS_TYPED_ARRAY, proto);
1705 tester.GenerateSnapShot("testGenerateNodeName_4.heapsnapshot");
1706
1707 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Set\""));
1708 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"SharedSet\""));
1709 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Map\""));
1710 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"SharedMap\""));
1711 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"WeakSet\""));
1712 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"WeakMap\""));
1713 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"JSArray\""));
1714 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Typed Array\""));
1715
1716 auto sHeap = SharedHeap::GetInstance();
1717 sHeap->CollectGarbage<TriggerGCType::SHARED_FULL_GC, GCReason::OTHER>(thread_);
1718
1719 tester.GenerateSnapShot("testGenerateNodeName_4.heapsnapshot");
1720
1721 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Set\""));
1722 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"SharedSet\""));
1723 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Map\""));
1724 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"SharedMap\""));
1725 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"WeakSet\""));
1726 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"WeakMap\""));
1727 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"JSArray\""));
1728 ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_4.heapsnapshot", "\"Typed Array\""));
1729 }
1730
HWTEST_F_L0(HeapDumpTest,TestMarkObjects)1731 HWTEST_F_L0(HeapDumpTest, TestMarkObjects)
1732 {
1733 HeapDumpTestHelper tester(ecmaVm_);
1734 JSHandle<JSMap> jsMap = tester.NewJSMap();
1735 JSHandle<JSSet> jsSet = tester.NewJSSet();
1736 JSHandle<JSAPIArrayList> jsAPIArrayList = tester.NewJSAPIArrayList();
1737 [[maybe_unused]] JSHandle<JSAPIDeque> jsAPIDeque = tester.NewJSAPIDeque();
1738 [[maybe_unused]] JSHandle<JSSharedMap> jsSharedMap = tester.NewJSSharedMap();
1739 [[maybe_unused]] JSHandle<JSWeakMap> jsWeakMap = tester.NewJSWeakMap();
1740
1741 HeapMarker marker {};
1742 marker.Mark(jsMap.GetTaggedType());
1743 marker.Mark(jsSet.GetTaggedType());
1744 marker.Mark(jsAPIArrayList.GetTaggedType());
1745
1746 ASSERT_TRUE(marker.IsMarked(jsMap.GetTaggedType()));
1747 ASSERT_FALSE(marker.IsMarked(jsSharedMap.GetTaggedType()));
1748 }
1749
HWTEST_F_L0(HeapDumpTest,TestIterateMarkedObjects)1750 HWTEST_F_L0(HeapDumpTest, TestIterateMarkedObjects)
1751 {
1752 HeapDumpTestHelper tester(ecmaVm_);
1753 JSHandle<JSMap> jsMap = tester.NewJSMap();
1754 JSHandle<JSSet> jsSet = tester.NewJSSet();
1755 JSHandle<JSAPIArrayList> jsAPIArrayList = tester.NewJSAPIArrayList();
1756 [[maybe_unused]] JSHandle<JSAPIDeque> jsAPIDeque = tester.NewJSAPIDeque();
1757 [[maybe_unused]] JSHandle<JSSharedMap> jsSharedMap = tester.NewJSSharedMap();
1758 [[maybe_unused]] JSHandle<JSWeakMap> jsWeakMap = tester.NewJSWeakMap();
1759
1760 HeapMarker marker {};
1761 marker.Mark(jsMap.GetTaggedType());
1762 marker.Mark(jsSet.GetTaggedType());
1763 marker.Mark(jsAPIArrayList.GetTaggedType());
1764
1765 std::unordered_set<uintptr_t> markedObjects;
1766 markedObjects.emplace(jsMap.GetTaggedType());
1767 markedObjects.emplace(jsSet.GetTaggedType());
1768 markedObjects.emplace(jsAPIArrayList.GetTaggedType());
1769 std::function<void(JSTaggedType addr)> callback = [markedObjects](JSTaggedType addr) {
1770 ASSERT_TRUE(markedObjects.find(addr) != markedObjects.end());
1771 };
1772 marker.IterateMarked(callback);
1773 }
1774
HWTEST_F_L0(HeapDumpTest,TestRemoveUnmarkedObjects)1775 HWTEST_F_L0(HeapDumpTest, TestRemoveUnmarkedObjects)
1776 {
1777 HeapDumpTestHelper tester(ecmaVm_);
1778 JSHandle<JSMap> jsMap = tester.NewJSMap();
1779 JSHandle<JSSet> jsSet = tester.NewJSSet();
1780 JSHandle<JSAPIArrayList> jsAPIArrayList = tester.NewJSAPIArrayList();
1781 JSHandle<JSAPIDeque> jsAPIDeque = tester.NewJSAPIDeque();
1782 JSHandle<JSSharedMap> jsSharedMap = tester.NewJSSharedMap();
1783 JSHandle<JSWeakMap> jsWeakMap = tester.NewJSWeakMap();
1784
1785 EntryIdMap entryIdMap {};
1786 entryIdMap.InsertId(jsMap.GetTaggedType(), entryIdMap.GetNextId());
1787 entryIdMap.InsertId(jsSet.GetTaggedType(), entryIdMap.GetNextId());
1788 entryIdMap.InsertId(jsAPIArrayList.GetTaggedType(), entryIdMap.GetNextId());
1789 entryIdMap.InsertId(jsAPIDeque.GetTaggedType(), entryIdMap.GetNextId());
1790 entryIdMap.InsertId(jsSharedMap.GetTaggedType(), entryIdMap.GetNextId());
1791 entryIdMap.InsertId(jsWeakMap.GetTaggedType(), entryIdMap.GetNextId());
1792 ASSERT_EQ(entryIdMap.GetIdMap()->size(), 6);
1793
1794 HeapMarker marker {};
1795 marker.Mark(jsMap.GetTaggedType());
1796 marker.Mark(jsSet.GetTaggedType());
1797 marker.Mark(jsAPIArrayList.GetTaggedType());
1798 marker.Mark(jsAPIDeque.GetTaggedType());
1799
1800 entryIdMap.RemoveUnmarkedObjects(marker);
1801 ASSERT_EQ(entryIdMap.GetIdMap()->size(), 4);
1802 }
1803 }
1804