1 /*
2 * Copyright (c) 2022-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
16 #include "ecmascript/dfx/hprof/heap_profiler_interface.h"
17 #include "ecmascript/dfx/stackinfo/js_stackinfo.h"
18 #include "ecmascript/dfx/vmstat/runtime_stat.h"
19 #include "ecmascript/ecma_context.h"
20 #include "ecmascript/mem/heap-inl.h"
21 #include "ecmascript/mem/concurrent_marker.h"
22 #include "ecmascript/mem/concurrent_sweeper.h"
23 #include "ecmascript/napi/include/dfx_jsnapi.h"
24 #include "ecmascript/tests/test_helper.h"
25 #include "ecmascript/dfx/cpu_profiler/samples_record.h"
26 #include "ecmascript/dfx/tracing/tracing.h"
27
28 using namespace panda;
29 using namespace panda::ecmascript;
30
31 namespace panda::test {
32 using FunctionForRef = Local<JSValueRef> (*)(JsiRuntimeCallInfo *);
33 class DFXJSNApiTests : public testing::Test {
34 public:
SetUpTestCase()35 static void SetUpTestCase()
36 {
37 GTEST_LOG_(INFO) << "SetUpTestCase";
38 }
39
TearDownTestCase()40 static void TearDownTestCase()
41 {
42 GTEST_LOG_(INFO) << "TearDownCase";
43 }
44
SetUp()45 void SetUp() override
46 {
47 TestHelper::CreateEcmaVMWithScope(vm_, thread_, scope_);
48 vm_->GetJSThread()->GetEcmaVM()->SetRuntimeStatEnable(true);
49 vm_->SetEnableForceGC(false);
50 }
51
TearDown()52 void TearDown() override
53 {
54 TestHelper::DestroyEcmaVMWithScope(vm_, scope_);
55 }
56
57 protected:
58 EcmaVM *vm_ {nullptr};
59 JSThread *thread_ = {nullptr};
60 EcmaHandleScope *scope_ {nullptr};
61 };
62
MatchJSONLineHeader(std::fstream & fs,const std::string filePath,int lineNum,CString lineContent)63 bool MatchJSONLineHeader(std::fstream &fs, const std::string filePath, int lineNum, CString lineContent)
64 {
65 CString tempLineContent = "";
66 int lineCount = 1;
67 fs.open(filePath.c_str(), std::ios::in);
68 while (getline(fs, tempLineContent)) {
69 if (lineNum == lineCount && tempLineContent.find(lineContent) != CString::npos) {
70 fs.close();
71 fs.clear();
72 return true;
73 }
74 lineCount++;
75 }
76 fs.close();
77 fs.clear();
78 return false;
79 }
80
HWTEST_F_L0(DFXJSNApiTests,DumpHeapSnapshot_001)81 HWTEST_F_L0(DFXJSNApiTests, DumpHeapSnapshot_001)
82 {
83 const std::string filePath = "DFXJSNApiTests_json_001.heapsnapshot";
84 std::fstream outputString(filePath, std::ios::out);
85 outputString.close();
86 outputString.clear();
87
88 std::fstream inputFile {};
89 EXPECT_TRUE(inputFile.good());
90
91 DumpSnapShotOption dumpOption;
92 dumpOption.dumpFormat = ecmascript::DumpFormat::JSON;
93 dumpOption.isVmMode = true;
94 dumpOption.isPrivate = false;
95 dumpOption.captureNumericValue = false;
96 DFXJSNApi::DumpHeapSnapshot(vm_, filePath, dumpOption);
97 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 1, "{\"snapshot\":"));
98 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 2, "{\"meta\":"));
99 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 3, "{\"node_fields\":"));
100 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 4, "\"node_types\":"));
101 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 5, "\"edge_fields\":"));
102 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 6, "\"edge_types\":"));
103 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 7, "\"trace_function_info_fields\":"));
104 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 8, "\"trace_node_fields\":"));
105 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 9, "\"sample_fields\":"));
106 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 10, "\"location_fields\":"));
107 std::remove(filePath.c_str());
108 }
109
HWTEST_F_L0(DFXJSNApiTests,DumpHeapSnapshot_002)110 HWTEST_F_L0(DFXJSNApiTests, DumpHeapSnapshot_002)
111 {
112 const std::string filePath = "DFXJSNApiTests_json_002.heapsnapshot";
113 std::fstream outputString(filePath, std::ios::out);
114 outputString.close();
115 outputString.clear();
116
117 ecmascript::FileStream stream(filePath);
118 EXPECT_TRUE(stream.Good());
119
120 ecmascript::Progress *progress = nullptr;
121 std::fstream fStream {};
122 EXPECT_TRUE(fStream.good());
123
124 DumpSnapShotOption dumpOption;
125 dumpOption.dumpFormat = ecmascript::DumpFormat::JSON;
126 dumpOption.isVmMode = true;
127 dumpOption.isPrivate = false;
128 dumpOption.captureNumericValue = false;
129 DFXJSNApi::DumpHeapSnapshot(vm_, &stream, dumpOption, progress);
130 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 1, "{\"snapshot\":"));
131 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 2, "{\"meta\":"));
132 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 3, "{\"node_fields\":"));
133 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 4, "\"node_types\":"));
134 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 5, "\"edge_fields\":"));
135 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 6, "\"edge_types\":"));
136 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 7, "\"trace_function_info_fields\":"));
137 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 8, "\"trace_node_fields\":"));
138 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 9, "\"sample_fields\":"));
139 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 10, "\"location_fields\":"));
140 std::remove(filePath.c_str());
141 }
142
HWTEST_F_L0(DFXJSNApiTests,BuildNativeAndJsStackTrace)143 HWTEST_F_L0(DFXJSNApiTests, BuildNativeAndJsStackTrace)
144 {
145 bool result = false;
146 std::string stackTraceStr = "stack_trace_str";
147 result = DFXJSNApi::BuildNativeAndJsStackTrace(vm_, stackTraceStr);
148 #if defined(ENABLE_EXCEPTION_BACKTRACE)
149 EXPECT_FALSE(stackTraceStr.empty());
150 EXPECT_TRUE(result);
151 #else
152 EXPECT_TRUE(stackTraceStr.empty());
153 EXPECT_FALSE(result);
154 #endif
155 }
156
HWTEST_F_L0(DFXJSNApiTests,BuildJsStackTrace)157 HWTEST_F_L0(DFXJSNApiTests, BuildJsStackTrace)
158 {
159 std::string stackTraceStr = "stack_trace_str";
160 bool result = DFXJSNApi::BuildJsStackTrace(vm_, stackTraceStr);
161 #if defined(ENABLE_EXCEPTION_BACKTRACE)
162 EXPECT_FALSE(stackTraceStr.empty());
163 EXPECT_TRUE(result);
164 #else
165 EXPECT_TRUE(stackTraceStr.empty());
166 EXPECT_FALSE(result);
167 #endif
168 }
169
HWTEST_F_L0(DFXJSNApiTests,Start_Stop_HeapTracking_001)170 HWTEST_F_L0(DFXJSNApiTests, Start_Stop_HeapTracking_001)
171 {
172 [[maybe_unused]] EcmaHandleScope handleScope(thread_);
173 vm_->SetEnableForceGC(false);
174
175 auto factory = vm_->GetFactory();
176 bool isVmMode = true;
177 bool traceAllocation = false;
178 double timeInterval = 50; // 50 : time interval 50 ms
179 ecmascript::FileStream *stream = nullptr;
180 bool startResult = false;
181 startResult = DFXJSNApi::StartHeapTracking(vm_, timeInterval, isVmMode, stream, traceAllocation);
182 EXPECT_TRUE(startResult);
183
184 sleep(1);
185 int count = 300;
186 while (count-- > 0) {
187 JSHandle<JSTaggedValue> undefined = thread_->GlobalConstants()->GetHandledUndefined();
188 JSHandle<EcmaString> string = factory->NewFromASCII("Start_Stop_HeapTracking_001_TestString");
189 factory->NewJSString(JSHandle<JSTaggedValue>(string), undefined);
190 }
191 const std::string filePath = "Start_Stop_HeapTracking_001.heaptimeline";
192 std::fstream outputString(filePath, std::ios::out);
193 outputString.close();
194 outputString.clear();
195
196 bool stopResult = DFXJSNApi::StopHeapTracking(vm_, filePath);
197 EXPECT_TRUE(stopResult);
198
199 std::fstream inputStream(filePath, std::ios::in);
200 std::string line;
201 std::string emptySample = "\"samples\":";
202 std::string firstSample = "\"samples\":[0, ";
203 bool isFind = false;
204 while (getline(inputStream, line)) {
205 if (line.substr(0U, emptySample.size()) == emptySample) {
206 EXPECT_TRUE(line.substr(0, firstSample.size()) == firstSample);
207 isFind = true;
208 }
209 }
210 EXPECT_TRUE(isFind);
211
212 inputStream.close();
213 inputStream.clear();
214 std::remove(filePath.c_str());
215 vm_->SetEnableForceGC(true);
216 }
217
HWTEST_F_L0(DFXJSNApiTests,Start_Stop_HeapTracking_002)218 HWTEST_F_L0(DFXJSNApiTests, Start_Stop_HeapTracking_002)
219 {
220 [[maybe_unused]] EcmaHandleScope handleScope(thread_);
221 vm_->SetEnableForceGC(false);
222
223 auto factory = vm_->GetFactory();
224 bool isVmMode = true;
225 bool traceAllocation = false;
226 double timeInterval = 50; // 50 : time interval 50 ms
227 ecmascript::FileStream *stream = nullptr;
228 bool startResult = false;
229 startResult = DFXJSNApi::StartHeapTracking(vm_, timeInterval, isVmMode, stream, traceAllocation);
230 EXPECT_TRUE(startResult);
231
232 sleep(1);
233 int count = 300;
234 while (count-- > 0) {
235 factory->NewJSAsyncFuncObject();
236 factory->NewJSSymbol();
237 }
238 const std::string filePath = "Start_Stop_HeapTracking_002.heaptimeline";
239 std::fstream outputString(filePath, std::ios::out);
240 outputString.close();
241 outputString.clear();
242
243 ecmascript::FileStream fileStream(filePath);
244 bool stopResult = DFXJSNApi::StopHeapTracking(vm_, &fileStream);
245 EXPECT_TRUE(stopResult);
246
247 std::fstream inputStream(filePath, std::ios::in);
248 std::string line;
249 std::string emptySample = "\"samples\":";
250 std::string firstSample = "\"samples\":[0, ";
251 bool isFind = false;
252 while (getline(inputStream, line)) {
253 if (line.substr(0U, emptySample.size()) == emptySample) {
254 EXPECT_TRUE(line.substr(0, firstSample.size()) == firstSample);
255 isFind = true;
256 }
257 }
258 EXPECT_TRUE(isFind);
259
260 inputStream.close();
261 inputStream.clear();
262 std::remove(filePath.c_str());
263 vm_->SetEnableForceGC(true);
264 }
265
HWTEST_F_L0(DFXJSNApiTests,Start_Stop_RuntimeStat)266 HWTEST_F_L0(DFXJSNApiTests, Start_Stop_RuntimeStat)
267 {
268 EcmaRuntimeStat *ecmaRuntimeStat = vm_->GetRuntimeStat();
269 EXPECT_TRUE(ecmaRuntimeStat != nullptr);
270
271 ecmaRuntimeStat->SetRuntimeStatEnabled(false);
272 EXPECT_TRUE(!ecmaRuntimeStat->IsRuntimeStatEnabled());
273
274 DFXJSNApi::StartRuntimeStat(vm_);
275 EXPECT_TRUE(ecmaRuntimeStat->IsRuntimeStatEnabled());
276
277 DFXJSNApi::StopRuntimeStat(vm_);
278 EXPECT_TRUE(!ecmaRuntimeStat->IsRuntimeStatEnabled());
279 }
280
HWTEST_F_L0(DFXJSNApiTests,GetArrayBufferSize_GetHeapTotalSize_GetHeapUsedSize)281 HWTEST_F_L0(DFXJSNApiTests, GetArrayBufferSize_GetHeapTotalSize_GetHeapUsedSize)
282 {
283 auto heap = vm_->GetHeap();
284 size_t arrayBufferSize = DFXJSNApi::GetArrayBufferSize(vm_);
285 size_t expectArrayBufferSize = heap->GetArrayBufferSize();
286 EXPECT_EQ(arrayBufferSize, expectArrayBufferSize);
287
288 size_t heapTotalSize = DFXJSNApi::GetHeapTotalSize(vm_);
289 size_t expectHeapTotalSize = heap->GetCommittedSize();
290 EXPECT_EQ(heapTotalSize, expectHeapTotalSize);
291
292 size_t heapUsedSize = DFXJSNApi::GetHeapUsedSize(vm_);
293 size_t expectHeapUsedSize = heap->GetLiveObjectSize();
294 EXPECT_EQ(heapUsedSize, expectHeapUsedSize);
295
296 size_t heapObjectSize = DFXJSNApi::GetHeapObjectSize(vm_);
297 size_t expectHeapObjectSize = heap->GetHeapObjectSize();
298 EXPECT_EQ(heapObjectSize, expectHeapObjectSize);
299
300 size_t processHeapLimitSize = DFXJSNApi::GetProcessHeapLimitSize();
301 EXPECT_GE(processHeapLimitSize, heap->GetEcmaParamConfiguration().GetMaxHeapSize());
302 EXPECT_LE(processHeapLimitSize, MAX_MEM_POOL_CAPACITY);
303 }
304
HWTEST_F_L0(DFXJSNApiTests,DFXJSNApiForGCInfo)305 HWTEST_F_L0(DFXJSNApiTests, DFXJSNApiForGCInfo)
306 {
307 size_t oldGCCount = DFXJSNApi::GetGCCount(vm_);
308 size_t expectGCCount = vm_->GetEcmaGCStats()->GetGCCount() +
309 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCCount();
310 EXPECT_EQ(oldGCCount, expectGCCount);
311
312 size_t oldGCDuration = DFXJSNApi::GetGCDuration(vm_);
313 size_t expectGCDuration = vm_->GetEcmaGCStats()->GetGCDuration() +
314 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCDuration();
315 EXPECT_EQ(oldGCDuration, expectGCDuration);
316
317 size_t oldAllocateSize = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
318 size_t expectAllocateSize = vm_->GetEcmaGCStats()->GetAccumulatedAllocateSize() +
319 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedAllocateSize();
320 EXPECT_EQ(oldAllocateSize, expectAllocateSize);
321
322 size_t oldFreeSize = DFXJSNApi::GetAccumulatedFreeSize(vm_);
323 size_t expectFreeSize = vm_->GetEcmaGCStats()->GetAccumulatedFreeSize() +
324 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedFreeSize();
325 EXPECT_EQ(oldFreeSize, expectFreeSize);
326
327 size_t oldLongTimeCount = DFXJSNApi::GetFullGCLongTimeCount(vm_);
328 size_t expectLongTimeCount = vm_->GetEcmaGCStats()->GetFullGCLongTimeCount() +
329 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetFullGCLongTimeCount();
330 EXPECT_EQ(oldLongTimeCount, expectLongTimeCount);
331
332 ObjectFactory *factory = vm_->GetFactory();
333 auto heap = const_cast<Heap *>(vm_->GetHeap());
334 heap->CollectGarbage(TriggerGCType::FULL_GC);
335 {
336 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread_);
337 for (int i = 0; i < 10240; i++) {
338 factory->NewTaggedArray(512, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE);
339 }
340 size_t newAllocateSize = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
341 EXPECT_TRUE(oldAllocateSize < newAllocateSize);
342 }
343 ecmascript::SharedHeap::GetInstance()->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::OTHER>(thread_);
344 heap->CollectGarbage(TriggerGCType::FULL_GC);
345 size_t newFreeSize = DFXJSNApi::GetAccumulatedFreeSize(vm_);
346 EXPECT_TRUE(oldFreeSize < newFreeSize);
347 size_t newGCCount = DFXJSNApi::GetGCCount(vm_);
348 EXPECT_TRUE(oldGCCount < newGCCount);
349 size_t newGCDuration = DFXJSNApi::GetGCDuration(vm_);
350 EXPECT_TRUE(oldGCDuration < newGCDuration);
351 }
352
HWTEST_F_L0(DFXJSNApiTests,NotifyApplicationState)353 HWTEST_F_L0(DFXJSNApiTests, NotifyApplicationState)
354 {
355 auto heap = vm_->GetHeap();
356 [[maybe_unused]] auto concurrentMarker = heap->GetConcurrentMarker();
357 auto sweeper = heap->GetSweeper();
358
359 DFXJSNApi::NotifyApplicationState(vm_, false);
360 #if !ECMASCRIPT_DISABLE_CONCURRENT_MARKING
361 EXPECT_TRUE(!concurrentMarker->IsDisabled());
362 #endif
363 EXPECT_TRUE(!sweeper->IsDisabled());
364
365 const_cast<ecmascript::Heap *>(heap)->CollectGarbage(TriggerGCType::OLD_GC, GCReason::OTHER);
366 DFXJSNApi::NotifyApplicationState(vm_, true);
367 #if !ECMASCRIPT_DISABLE_CONCURRENT_MARKING
368 EXPECT_TRUE(!concurrentMarker->IsDisabled());
369 #endif
370 EXPECT_TRUE(!sweeper->IsDisabled());
371 }
372
HWTEST_F_L0(DFXJSNApiTests,NotifyMemoryPressure)373 HWTEST_F_L0(DFXJSNApiTests, NotifyMemoryPressure)
374 {
375 auto heap = vm_->GetHeap();
376 bool inHighMemoryPressure = true;
377 DFXJSNApi::NotifyMemoryPressure(vm_, inHighMemoryPressure);
378 EXPECT_EQ(heap->GetMemGrowingType(), MemGrowingType::PRESSURE);
379
380 inHighMemoryPressure = false;
381 DFXJSNApi::NotifyMemoryPressure(vm_, inHighMemoryPressure);
382 EXPECT_EQ(heap->GetMemGrowingType(), MemGrowingType::CONSERVATIVE);
383 }
384
HWTEST_F_L0(DFXJSNApiTests,BuildJsStackInfoList)385 HWTEST_F_L0(DFXJSNApiTests, BuildJsStackInfoList)
386 {
387 uint32_t hostTid = vm_->GetJSThread()->GetThreadId();
388 std::vector<ecmascript::JsFrameInfo> jsFrameInfo;
389 bool result = DFXJSNApi::BuildJsStackInfoList(vm_, hostTid, jsFrameInfo);
390 EXPECT_FALSE(result);
391 }
392
HWTEST_F_L0(DFXJSNApiTests,StartSampling)393 HWTEST_F_L0(DFXJSNApiTests, StartSampling)
394 {
395 uint64_t samplingInterval = 32768;
396 bool result = DFXJSNApi::StartSampling(vm_, samplingInterval);
397 EXPECT_TRUE(result);
398 result = DFXJSNApi::StartSampling(vm_, samplingInterval);
399 EXPECT_FALSE(result);
400 }
401
HWTEST_F_L0(DFXJSNApiTests,StopSampling)402 HWTEST_F_L0(DFXJSNApiTests, StopSampling)
403 {
404 uint64_t samplingInterval = 32768;
405 bool result = DFXJSNApi::StartSampling(vm_, samplingInterval);
406 EXPECT_TRUE(result);
407 DFXJSNApi::StopSampling(vm_);
408 result = DFXJSNApi::StartSampling(vm_, samplingInterval);
409 EXPECT_TRUE(result);
410 }
411
HWTEST_F_L0(DFXJSNApiTests,GetAllocationProfile)412 HWTEST_F_L0(DFXJSNApiTests, GetAllocationProfile)
413 {
414 const SamplingInfo *result = DFXJSNApi::GetAllocationProfile(vm_);
415 EXPECT_TRUE(result == nullptr);
416 uint64_t samplingInterval = 32768;
417 DFXJSNApi::StartSampling(vm_, samplingInterval);
418 result = DFXJSNApi::GetAllocationProfile(vm_);
419 EXPECT_TRUE(result != nullptr);
420 }
421
HWTEST_F_L0(DFXJSNApiTests,NotifyIdleStatusControl)422 HWTEST_F_L0(DFXJSNApiTests, NotifyIdleStatusControl)
423 {
424 bool receivedValue = false;
425 std::function<void(bool)> cb = [&](bool value) {
426 receivedValue = value;
427 };
428 DFXJSNApi::NotifyIdleStatusControl(vm_, cb);
429 const_cast<ecmascript::Heap *>(vm_->GetHeap())->DisableNotifyIdle();
430 EXPECT_TRUE(receivedValue);
431 }
432
HWTEST_F_L0(DFXJSNApiTests,NotifyIdleTime)433 HWTEST_F_L0(DFXJSNApiTests, NotifyIdleTime)
434 {
435 auto heap = const_cast<ecmascript::Heap *>(vm_->GetHeap());
436 heap->SetIdleTask(IdleTaskType::YOUNG_GC);
437 DFXJSNApi::NotifyIdleTime(vm_, 10);
438 EXPECT_EQ(vm_->GetEcmaGCStats()->GetGCReason(), GCReason::IDLE);
439 }
440
HWTEST_F_L0(DFXJSNApiTests,NotifyHighSensitive)441 HWTEST_F_L0(DFXJSNApiTests, NotifyHighSensitive)
442 {
443 auto heap = const_cast<ecmascript::Heap *>(vm_->GetHeap());
444 DFXJSNApi::NotifyHighSensitive(vm_, true);
445 EXPECT_TRUE(heap->GetSensitiveStatus() == AppSensitiveStatus::ENTER_HIGH_SENSITIVE);
446 DFXJSNApi::NotifyHighSensitive(vm_, false);
447 EXPECT_TRUE(heap->GetSensitiveStatus() == AppSensitiveStatus::EXIT_HIGH_SENSITIVE);
448 }
449
HWTEST_F_L0(DFXJSNApiTests,GetGCCount)450 HWTEST_F_L0(DFXJSNApiTests, GetGCCount)
451 {
452 vm_->GetJSOptions().SetIsWorker(true);
453 size_t count = DFXJSNApi::GetGCCount(vm_);
454 ASSERT_EQ(count, vm_->GetEcmaGCStats()->GetGCCount());
455
456 vm_->GetJSOptions().SetIsWorker(false);
457 count = DFXJSNApi::GetGCCount(vm_);
458 ASSERT_EQ(count, vm_->GetEcmaGCStats()->GetGCCount() +
459 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCCount());
460 }
461
HWTEST_F_L0(DFXJSNApiTests,GetGCDuration)462 HWTEST_F_L0(DFXJSNApiTests, GetGCDuration)
463 {
464 vm_->GetJSOptions().SetIsWorker(true);
465 size_t duration = DFXJSNApi::GetGCDuration(vm_);
466 ASSERT_EQ(duration, vm_->GetEcmaGCStats()->GetGCDuration());
467
468 vm_->GetJSOptions().SetIsWorker(false);
469 duration = DFXJSNApi::GetGCDuration(vm_);
470 ASSERT_EQ(duration, vm_->GetEcmaGCStats()->GetGCDuration() +
471 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCDuration());
472 }
473
HWTEST_F_L0(DFXJSNApiTests,GetAccumulatedAllocateSize)474 HWTEST_F_L0(DFXJSNApiTests, GetAccumulatedAllocateSize)
475 {
476 vm_->GetJSOptions().SetIsWorker(true);
477 size_t size = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
478 ASSERT_EQ(size, vm_->GetEcmaGCStats()->GetAccumulatedAllocateSize());
479
480 vm_->GetJSOptions().SetIsWorker(false);
481 size = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
482 ASSERT_EQ(size, vm_->GetEcmaGCStats()->GetAccumulatedAllocateSize() +
483 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedAllocateSize());
484 }
485
HWTEST_F_L0(DFXJSNApiTests,GetAccumulatedFreeSize)486 HWTEST_F_L0(DFXJSNApiTests, GetAccumulatedFreeSize)
487 {
488 vm_->GetJSOptions().SetIsWorker(true);
489 size_t size = DFXJSNApi::GetAccumulatedFreeSize(vm_);
490 ASSERT_EQ(size, vm_->GetEcmaGCStats()->GetAccumulatedFreeSize());
491
492 vm_->GetJSOptions().SetIsWorker(false);
493 size = DFXJSNApi::GetAccumulatedFreeSize(vm_);
494 ASSERT_EQ(size, vm_->GetEcmaGCStats()->GetAccumulatedFreeSize() +
495 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedFreeSize());
496 }
497
HWTEST_F_L0(DFXJSNApiTests,StopCpuProfilerForColdStart)498 HWTEST_F_L0(DFXJSNApiTests, StopCpuProfilerForColdStart)
499 {
500 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
501 ASSERT_FALSE(DFXJSNApi::StopCpuProfilerForColdStart(vm_));
502
503 vm_->GetJSOptions().SetArkProperties(ArkProperties::CPU_PROFILER_COLD_START_MAIN_THREAD);
504 ASSERT_TRUE(DFXJSNApi::StopCpuProfilerForColdStart(vm_));
505
506 vm_->GetJSOptions().SetArkProperties(ArkProperties::CPU_PROFILER_COLD_START_WORKER_THREAD);
507 ASSERT_TRUE(DFXJSNApi::StopCpuProfilerForColdStart(vm_));
508 #else
509 ASSERT_FALSE(DFXJSNApi::StopCpuProfilerForColdStart(vm_));
510 #endif
511 }
512
HWTEST_F_L0(DFXJSNApiTests,CpuProfilerSamplingAnyTime)513 HWTEST_F_L0(DFXJSNApiTests, CpuProfilerSamplingAnyTime)
514 {
515 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
516 ASSERT_FALSE(DFXJSNApi::CpuProfilerSamplingAnyTime(vm_));
517 #else
518 ASSERT_FALSE(DFXJSNApi::CpuProfilerSamplingAnyTime(vm_));
519 #endif
520 }
521
HWTEST_F_L0(DFXJSNApiTests,StartCpuProfilerForFile)522 HWTEST_F_L0(DFXJSNApiTests, StartCpuProfilerForFile)
523 {
524 int interval = 32768;
525 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
526 int illegalInterval = 0;
527 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForFile(vm_, "StartCpuProfilerForFile", illegalInterval));
528
529 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForFile(nullptr, "StartCpuProfilerForFile", interval));
530
531 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForFile(vm_, "StartCpuProfilerForFile", interval));
532 #else
533 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForFile(vm_, "StartCpuProfilerForFile", interval));
534 #endif
535 }
536
HWTEST_F_L0(DFXJSNApiTests,StartCpuProfilerForInfo)537 HWTEST_F_L0(DFXJSNApiTests, StartCpuProfilerForInfo)
538 {
539 int interval = 32768;
540 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
541 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForInfo(nullptr, interval));
542
543 int illegalInterval = 0;
544 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForInfo(vm_, illegalInterval));
545
546 ASSERT_TRUE(DFXJSNApi::StartCpuProfilerForInfo(vm_, interval));
547 ASSERT_NE(DFXJSNApi::StopCpuProfilerForInfo(vm_), nullptr);
548 #else
549 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForInfo(vm_, interval));
550 #endif
551 }
552
HWTEST_F_L0(DFXJSNApiTests,StopCpuProfilerForInfo)553 HWTEST_F_L0(DFXJSNApiTests, StopCpuProfilerForInfo)
554 {
555 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
556 ASSERT_EQ(DFXJSNApi::StopCpuProfilerForInfo(nullptr), nullptr);
557
558 vm_->SetProfiler(nullptr);
559 ASSERT_EQ(DFXJSNApi::StopCpuProfilerForInfo(vm_), nullptr);
560 #else
561 ASSERT_EQ(DFXJSNApi::StopCpuProfilerForInfo(vm_), nullptr);
562 #endif
563 }
564
HWTEST_F_L0(DFXJSNApiTests,SuspendVM)565 HWTEST_F_L0(DFXJSNApiTests, SuspendVM)
566 {
567 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
568 ASSERT_FALSE(DFXJSNApi::SuspendVM(vm_));
569 #else
570 ASSERT_FALSE(DFXJSNApi::SuspendVM(vm_));
571 #endif
572 }
573
HWTEST_F_L0(DFXJSNApiTests,IsSuspended)574 HWTEST_F_L0(DFXJSNApiTests, IsSuspended)
575 {
576 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
577 ASSERT_FALSE(DFXJSNApi::IsSuspended(vm_));
578 #else
579 ASSERT_FALSE(DFXJSNApi::IsSuspended(vm_));
580 #endif
581 }
582
HWTEST_F_L0(DFXJSNApiTests,CheckSafepoint)583 HWTEST_F_L0(DFXJSNApiTests, CheckSafepoint)
584 {
585 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
586 ASSERT_FALSE(DFXJSNApi::CheckSafepoint(vm_));
587 #else
588 ASSERT_FALSE(DFXJSNApi::CheckSafepoint(vm_));
589 #endif
590 }
591
HWTEST_F_L0(DFXJSNApiTests,BuildJsStackInfoList_2)592 HWTEST_F_L0(DFXJSNApiTests, BuildJsStackInfoList_2)
593 {
594 std::vector<ecmascript::JsFrameInfo> jsFrames;
595 uint32_t tid = vm_->GetAssociatedJSThread()->GetThreadId();
596 ASSERT_FALSE(DFXJSNApi::BuildJsStackInfoList(vm_, tid + 1, jsFrames));
597
598 ASSERT_FALSE(DFXJSNApi::BuildJsStackInfoList(vm_, tid, jsFrames));
599 }
600
HWTEST_F_L0(DFXJSNApiTests,StartProfiler)601 HWTEST_F_L0(DFXJSNApiTests, StartProfiler)
602 {
603 DFXJSNApi::ProfilerOption option;
604 option.profilerType = DFXJSNApi::ProfilerType::CPU_PROFILER;
605 DebuggerPostTask debuggerPostTask;
606 uint32_t tid = vm_->GetAssociatedJSThread()->GetThreadId();
607 int32_t instanceId = 1;
608 ASSERT_FALSE(DFXJSNApi::StartProfiler(nullptr, option, tid, instanceId, debuggerPostTask, true));
609
610 option.profilerType = DFXJSNApi::ProfilerType::HEAP_PROFILER;
611 ASSERT_FALSE(DFXJSNApi::StartProfiler(nullptr, option, tid, instanceId, debuggerPostTask, false));
612 }
613
HWTEST_F_L0(DFXJSNApiTests,SuspendVMById)614 HWTEST_F_L0(DFXJSNApiTests, SuspendVMById)
615 {
616 uint32_t tid = vm_->GetAssociatedJSThread()->GetThreadId();
617 ASSERT_FALSE(DFXJSNApi::SuspendVMById(vm_, tid + 1));
618
619 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
620 ASSERT_FALSE(DFXJSNApi::SuspendVMById(vm_, tid));
621 #else
622 ASSERT_FALSE(DFXJSNApi::SuspendVMById(vm_, tid));
623 #endif
624 }
625
HWTEST_F_L0(DFXJSNApiTests,StartTracing)626 HWTEST_F_L0(DFXJSNApiTests, StartTracing)
627 {
628 std::string categories = "StartTracing";
629 #if defined(ECMASCRIPT_SUPPORT_TRACING)
630 ASSERT_FALSE(DFXJSNApi::StartTracing(nullptr, categories));
631
632 vm_->SetTracing(nullptr);
633 ASSERT_TRUE(DFXJSNApi::StartTracing(vm_, categories));
634 ASSERT_NE(DFXJSNApi::StopTracing(vm_), nullptr);
635 #else
636 ASSERT_FALSE(DFXJSNApi::StartTracing(vm_, categories));
637 #endif
638 }
639
HWTEST_F_L0(DFXJSNApiTests,StopTracing)640 HWTEST_F_L0(DFXJSNApiTests, StopTracing)
641 {
642 #if defined(ECMASCRIPT_SUPPORT_TRACING)
643 ASSERT_EQ(DFXJSNApi::StopTracing(nullptr), nullptr);
644
645 vm_->SetTracing(nullptr);
646 ASSERT_EQ(DFXJSNApi::StopTracing(vm_), nullptr);
647 #else
648 ASSERT_EQ(DFXJSNApi::StopTracing(vm_), nullptr);
649 #endif
650 }
651
HWTEST_F_L0(DFXJSNApiTests,TranslateJSStackInfo)652 HWTEST_F_L0(DFXJSNApiTests, TranslateJSStackInfo)
653 {
654 std::string resultUrl = "";
655 auto cb = [&resultUrl](std::string& url, int& line, int& column, std::string& packageName) -> bool {
656 line = 0;
657 column = 0;
658 packageName = "name";
659 if (url.find("TranslateJSStackInfo", 0) != std::string::npos) {
660 resultUrl = "true";
661 return true;
662 }
663 resultUrl = "false";
664 return false;
665 };
666
667 vm_->SetSourceMapTranslateCallback(nullptr);
668 std::string url = "TranslateJSStackInfo";
669 int32_t line = 0;
670 int32_t column = 0;
671 std::string packageName = "";
672 DFXJSNApi::TranslateJSStackInfo(vm_, url, line, column, packageName);
673
674 vm_->SetSourceMapTranslateCallback(cb);
675 url = "Translate";
676 DFXJSNApi::TranslateJSStackInfo(vm_, url, line, column, packageName);
677 ASSERT_STREQ(resultUrl.c_str(), "false");
678
679 url = "TranslateJSStackInfo";
680 DFXJSNApi::TranslateJSStackInfo(vm_, url, line, column, packageName);
681 ASSERT_STREQ(resultUrl.c_str(), "true");
682 }
683
HWTEST_F_L0(DFXJSNApiTests,GetCurrentThreadId)684 HWTEST_F_L0(DFXJSNApiTests, GetCurrentThreadId)
685 {
686 ASSERT_EQ(DFXJSNApi::GetCurrentThreadId(), JSThread::GetCurrentThreadId());
687 }
688
FunctionCallback(JsiRuntimeCallInfo * info)689 Local<JSValueRef> FunctionCallback(JsiRuntimeCallInfo *info)
690 {
691 EscapeLocalScope scope(info->GetVM());
692 return scope.Escape(ArrayRef::New(info->GetVM(), info->GetArgsNumber()));
693 }
694
HWTEST_F_L0(DFXJSNApiTests,GetObjectHashCode_1)695 HWTEST_F_L0(DFXJSNApiTests, GetObjectHashCode_1)
696 {
697 LocalScope scope(vm_);
698 Local<FunctionRef> functioncallback = FunctionRef::New(vm_, FunctionCallback);
699 struct Data {
700 int32_t length;
701 };
702 const int32_t length = 15;
703 Data *data = new Data();
704 data->length = length;
705 functioncallback->SetData(vm_, data);
706 auto hash = DFXJSNApi::GetObjectHashCode(vm_, functioncallback);
707 ASSERT_TRUE(hash != 0);
708 }
709
HWTEST_F_L0(DFXJSNApiTests,GetObjectHashCode_2)710 HWTEST_F_L0(DFXJSNApiTests, GetObjectHashCode_2)
711 {
712 Local<ObjectRef> object = ObjectRef::New(vm_);
713 object->SetNativePointerFieldCount(vm_, 10);
714 auto hash = DFXJSNApi::GetObjectHashCode(vm_, object);
715 ASSERT_TRUE(hash != 0);
716 }
717
HWTEST_F_L0(DFXJSNApiTests,GetObjectHash_3)718 HWTEST_F_L0(DFXJSNApiTests, GetObjectHash_3)
719 {
720 Local<ObjectRef> object = ObjectRef::New(vm_);
721 auto hash = DFXJSNApi::GetObjectHash(vm_, object);
722 ASSERT_TRUE(hash != 0);
723 }
724
HWTEST_F_L0(DFXJSNApiTests,GetObjectHashCode_3)725 HWTEST_F_L0(DFXJSNApiTests, GetObjectHashCode_3)
726 {
727 Local<ObjectRef> object = ObjectRef::New(vm_);
728 auto hash = DFXJSNApi::GetObjectHashCode(vm_, object);
729 ASSERT_TRUE(hash != 0);
730 }
731
HWTEST_F_L0(DFXJSNApiTests,GetObjectHash_4)732 HWTEST_F_L0(DFXJSNApiTests, GetObjectHash_4)
733 {
734 Local<ObjectRef> object = ObjectRef::New(vm_);
735 NativePointerCallback callBack = nullptr;
736 void *vp1 = static_cast<void *>(new std::string("test"));
737 void *vp2 = static_cast<void *>(new std::string("test"));
738 object->SetNativePointerField(vm_, 33, vp1, callBack, vp2);
739 auto hash = DFXJSNApi::GetObjectHash(vm_, object);
740 ASSERT_TRUE(hash != 0);
741 }
742
HWTEST_F_L0(DFXJSNApiTests,GetObjectHashCode_4)743 HWTEST_F_L0(DFXJSNApiTests, GetObjectHashCode_4)
744 {
745 Local<ObjectRef> object = ObjectRef::New(vm_);
746 NativePointerCallback callBack = nullptr;
747 void *vp1 = static_cast<void *>(new std::string("test"));
748 void *vp2 = static_cast<void *>(new std::string("test"));
749 object->SetNativePointerField(vm_, 33, vp1, callBack, vp2);
750 auto hash = DFXJSNApi::GetObjectHashCode(vm_, object);
751 ASSERT_TRUE(hash != 0);
752 }
753 } // namespace panda::test
754