1 /*
2 * Copyright (c) 2021-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/builtins/builtins_ark_tools.h"
17
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include "ecmascript/dfx/vmstat/opt_code_profiler.h"
22 #include "ecmascript/mem/verification.h"
23 #include "ecmascript/module/js_module_source_text.h"
24 #include "ecmascript/property_detector-inl.h"
25 #include "ecmascript/js_arraybuffer.h"
26 #include "ecmascript/interpreter/fast_runtime_stub-inl.h"
27 #include "ecmascript/linked_hash_table.h"
28 #include "builtins_typedarray.h"
29 #include "ecmascript/jit/jit.h"
30
31 #if defined(PANDA_TARGET_ARM64)
32 /* Note: If not open ArkTools option(set by `persist.ark.mem_config_property openArkTools`), */
33 /* ArkTools return Empty Implementation */
34 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
35 #define RETURN_IF_DISALLOW_ARKTOOLS(thread) \
36 do { \
37 if (!((thread)->GetEcmaVM()->GetJSOptions().IsOpenArkTools())) { \
38 return JSTaggedValue::Undefined(); \
39 } \
40 } while (0)
41 #else
42 #define RETURN_IF_DISALLOW_ARKTOOLS(thread) static_cast<void>(0) // NOLINT(cppcoreguidelines-macro-usage)
43 #endif
44
45 namespace panda::ecmascript::builtins {
46 using StringHelper = base::StringHelper;
47
48 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
49 constexpr char FILEDIR[] = "/data/storage/el2/base/files/";
50 #endif
51
ObjectDump(EcmaRuntimeCallInfo * info)52 JSTaggedValue BuiltinsArkTools::ObjectDump(EcmaRuntimeCallInfo *info)
53 {
54 ASSERT(info);
55 JSThread *thread = info->GetThread();
56 RETURN_IF_DISALLOW_ARKTOOLS(thread);
57 [[maybe_unused]] EcmaHandleScope handleScope(thread);
58
59 JSHandle<EcmaString> str = JSTaggedValue::ToString(thread, GetCallArg(info, 0));
60 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
61 // The default log level of ace_engine and js_runtime is error
62 LOG_ECMA(ERROR) << ": " << EcmaStringAccessor(str).ToStdString();
63
64 uint32_t numArgs = info->GetArgsNumber();
65 for (uint32_t i = 1; i < numArgs; i++) {
66 JSHandle<JSTaggedValue> obj = GetCallArg(info, i);
67 std::ostringstream oss;
68 obj->Dump(oss);
69
70 // The default log level of ace_engine and js_runtime is error
71 LOG_ECMA(ERROR) << ": " << oss.str();
72 }
73
74 return JSTaggedValue::Undefined();
75 }
76
CompareHClass(EcmaRuntimeCallInfo * info)77 JSTaggedValue BuiltinsArkTools::CompareHClass(EcmaRuntimeCallInfo *info)
78 {
79 ASSERT(info);
80 JSThread *thread = info->GetThread();
81 RETURN_IF_DISALLOW_ARKTOOLS(thread);
82 [[maybe_unused]] EcmaHandleScope handleScope(thread);
83
84 JSHandle<JSTaggedValue> obj1 = GetCallArg(info, 0);
85 JSHandle<JSTaggedValue> obj2 = GetCallArg(info, 1);
86 JSHClass *obj1Hclass = obj1->GetTaggedObject()->GetClass();
87 JSHClass *obj2Hclass = obj2->GetTaggedObject()->GetClass();
88 std::ostringstream oss;
89 obj1Hclass->Dump(oss);
90 obj2Hclass->Dump(oss);
91 bool res = (obj1Hclass == obj2Hclass);
92 if (!res) {
93 LOG_ECMA(ERROR) << "These two object don't share the same hclass:" << oss.str();
94 }
95 return JSTaggedValue(res);
96 }
97
DumpHClass(EcmaRuntimeCallInfo * info)98 JSTaggedValue BuiltinsArkTools::DumpHClass(EcmaRuntimeCallInfo *info)
99 {
100 ASSERT(info);
101 JSThread *thread = info->GetThread();
102 RETURN_IF_DISALLOW_ARKTOOLS(thread);
103 [[maybe_unused]] EcmaHandleScope handleScope(thread);
104
105 JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
106 JSHClass *objHclass = obj->GetTaggedObject()->GetClass();
107 std::ostringstream oss;
108 objHclass->Dump(oss);
109
110 LOG_ECMA(ERROR) << "hclass:" << oss.str();
111 return JSTaggedValue::Undefined();
112 }
113
IsTSHClass(EcmaRuntimeCallInfo * info)114 JSTaggedValue BuiltinsArkTools::IsTSHClass(EcmaRuntimeCallInfo *info)
115 {
116 ASSERT(info);
117 JSThread *thread = info->GetThread();
118 RETURN_IF_DISALLOW_ARKTOOLS(thread);
119 [[maybe_unused]] EcmaHandleScope handleScope(thread);
120
121 ASSERT(info->GetArgsNumber() == 1);
122 JSHandle<JSTaggedValue> object = GetCallArg(info, 0);
123 JSHClass *hclass = object->GetTaggedObject()->GetClass();
124 bool isTSHClass = hclass->IsTS();
125 return GetTaggedBoolean(isTSHClass);
126 }
127
GetHClass(EcmaRuntimeCallInfo * info)128 JSTaggedValue BuiltinsArkTools::GetHClass(EcmaRuntimeCallInfo *info)
129 {
130 ASSERT(info);
131 JSThread *thread = info->GetThread();
132 RETURN_IF_DISALLOW_ARKTOOLS(thread);
133 [[maybe_unused]] EcmaHandleScope handleScope(thread);
134
135 ASSERT(info->GetArgsNumber() == 1);
136 JSHandle<JSTaggedValue> object = GetCallArg(info, 0);
137 JSHClass *hclass = object->GetTaggedObject()->GetClass();
138 return JSTaggedValue(hclass);
139 }
140
IsSlicedString(EcmaRuntimeCallInfo * info)141 JSTaggedValue BuiltinsArkTools::IsSlicedString(EcmaRuntimeCallInfo *info)
142 {
143 ASSERT(info);
144 JSThread *thread = info->GetThread();
145 RETURN_IF_DISALLOW_ARKTOOLS(thread);
146 [[maybe_unused]] EcmaHandleScope handleScope(thread);
147
148 ASSERT(info->GetArgsNumber() == 1);
149 JSHandle<JSTaggedValue> str = GetCallArg(info, 0);
150 return GetTaggedBoolean(str->IsSlicedString());
151 }
152
IsNotHoleProperty(EcmaRuntimeCallInfo * info)153 JSTaggedValue BuiltinsArkTools::IsNotHoleProperty(EcmaRuntimeCallInfo *info)
154 {
155 [[maybe_unused]] DisallowGarbageCollection noGc;
156 ASSERT(info);
157 JSThread *thread = info->GetThread();
158 RETURN_IF_DISALLOW_ARKTOOLS(thread);
159 [[maybe_unused]] EcmaHandleScope handleScope(thread);
160
161 ASSERT(info->GetArgsNumber() == 2); // 2 : object and key
162 JSHandle<JSTaggedValue> object = GetCallArg(info, 0);
163 JSTaggedValue key = GetCallArg(info, 1).GetTaggedValue();
164 JSHClass *hclass = object->GetTaggedObject()->GetClass();
165 int entry = JSHClass::FindPropertyEntry(thread, hclass, key);
166 if (entry == -1) {
167 return GetTaggedBoolean(false);
168 }
169 PropertyAttributes attr = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject())->GetAttr(entry);
170 return GetTaggedBoolean(attr.IsNotHole());
171 }
172
HiddenStackSourceFile(EcmaRuntimeCallInfo * info)173 JSTaggedValue BuiltinsArkTools::HiddenStackSourceFile(EcmaRuntimeCallInfo *info)
174 {
175 [[maybe_unused]] DisallowGarbageCollection noGc;
176 ASSERT(info);
177 JSThread *thread = info->GetThread();
178 RETURN_IF_DISALLOW_ARKTOOLS(thread);
179 thread->SetEnableStackSourceFile(false);
180 return JSTaggedValue::True();
181 }
182
ExcutePendingJob(EcmaRuntimeCallInfo * info)183 JSTaggedValue BuiltinsArkTools::ExcutePendingJob(EcmaRuntimeCallInfo *info)
184 {
185 ASSERT(info);
186 JSThread *thread = info->GetThread();
187 RETURN_IF_DISALLOW_ARKTOOLS(thread);
188 [[maybe_unused]] EcmaHandleScope handleScope(thread);
189
190 thread->GetCurrentEcmaContext()->ExecutePromisePendingJob();
191 return JSTaggedValue::True();
192 }
193
GetLexicalEnv(EcmaRuntimeCallInfo * info)194 JSTaggedValue BuiltinsArkTools::GetLexicalEnv(EcmaRuntimeCallInfo *info)
195 {
196 ASSERT(info);
197 JSThread *thread = info->GetThread();
198 RETURN_IF_DISALLOW_ARKTOOLS(thread);
199 [[maybe_unused]] EcmaHandleScope handleScope(thread);
200
201 ASSERT(info->GetArgsNumber() == 1);
202 JSHandle<JSTaggedValue> object = GetCallArg(info, 0);
203 if (object->IsHeapObject() && object->IsJSFunction()) {
204 JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(object);
205 return function->GetLexicalEnv();
206 }
207 return JSTaggedValue::Null();
208 }
209
ForceFullGC(EcmaRuntimeCallInfo * info)210 JSTaggedValue BuiltinsArkTools::ForceFullGC(EcmaRuntimeCallInfo *info)
211 {
212 ASSERT(info);
213 auto heap = const_cast<Heap *>(info->GetThread()->GetEcmaVM()->GetHeap());
214 heap->CollectGarbage(TriggerGCType::FULL_GC, GCReason::TRIGGER_BY_JS);
215 SharedHeap::GetInstance()->CollectGarbage<TriggerGCType::SHARED_FULL_GC, GCReason::TRIGGER_BY_JS>(
216 info->GetThread());
217 heap->GetHeapPrepare();
218 return JSTaggedValue::True();
219 }
220
HintGC(EcmaRuntimeCallInfo * info)221 JSTaggedValue BuiltinsArkTools::HintGC(EcmaRuntimeCallInfo *info)
222 {
223 ASSERT(info);
224 return JSTaggedValue(const_cast<Heap *>(info->GetThread()->GetEcmaVM()->GetHeap())->
225 CheckAndTriggerHintGC());
226 }
227
RemoveAOTFlag(EcmaRuntimeCallInfo * info)228 JSTaggedValue BuiltinsArkTools::RemoveAOTFlag(EcmaRuntimeCallInfo *info)
229 {
230 ASSERT(info);
231 JSThread *thread = info->GetThread();
232 RETURN_IF_DISALLOW_ARKTOOLS(thread);
233 [[maybe_unused]] EcmaHandleScope handleScope(thread);
234
235 ASSERT(info->GetArgsNumber() == 1);
236 JSHandle<JSTaggedValue> object = GetCallArg(info, 0);
237 if (object->IsHeapObject() && object->IsJSFunction()) {
238 JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(object);
239 JSHandle<Method> method = JSHandle<Method>(thread, func->GetMethod());
240 method->SetAotCodeBit(false);
241 }
242
243 return JSTaggedValue::Undefined();
244 }
245
CheckCircularImport(EcmaRuntimeCallInfo * info)246 JSTaggedValue BuiltinsArkTools::CheckCircularImport(EcmaRuntimeCallInfo *info)
247 {
248 ASSERT(info);
249 JSThread *thread = info->GetThread();
250 RETURN_IF_DISALLOW_ARKTOOLS(thread);
251 [[maybe_unused]] EcmaHandleScope handleScope(thread);
252 JSHandle<EcmaString> str = JSTaggedValue::ToString(thread, GetCallArg(info, 0));
253 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
254 bool printOtherCircular = false;
255 if (info->GetArgsNumber() == 2) { // 2: input number
256 printOtherCircular = GetCallArg(info, 1).GetTaggedValue().ToBoolean();
257 }
258 CList<CString> referenceList;
259 // str: bundleName/moduleName/xxx/xxx
260 CString string = ConvertToString(str.GetTaggedValue());
261 LOG_ECMA(INFO) << "checkCircularImport begin with: "<< string;
262 SourceTextModule::CheckCircularImportTool(thread, string, referenceList, printOtherCircular);
263 return JSTaggedValue::Undefined();
264 }
265
HashCode(EcmaRuntimeCallInfo * info)266 JSTaggedValue BuiltinsArkTools::HashCode(EcmaRuntimeCallInfo *info)
267 {
268 ASSERT(info);
269 JSThread *thread = info->GetThread();
270 RETURN_IF_DISALLOW_ARKTOOLS(thread);
271 [[maybe_unused]] EcmaHandleScope handleScope(thread);
272 JSHandle<JSTaggedValue> key = GetCallArg(info, 0);
273 return JSTaggedValue(LinkedHash::Hash(thread, key.GetTaggedValue()));
274 }
275
276 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
StartCpuProfiler(EcmaRuntimeCallInfo * info)277 JSTaggedValue BuiltinsArkTools::StartCpuProfiler(EcmaRuntimeCallInfo *info)
278 {
279 ASSERT(info);
280 JSThread *thread = info->GetThread();
281 RETURN_IF_DISALLOW_ARKTOOLS(thread);
282 [[maybe_unused]] EcmaHandleScope handleScope(thread);
283
284 auto vm = thread->GetEcmaVM();
285
286 // get file name
287 JSHandle<JSTaggedValue> fileNameValue = GetCallArg(info, 0);
288 std::string fileName = "";
289 if (fileNameValue->IsString()) {
290 JSHandle<EcmaString> str = JSTaggedValue::ToString(thread, fileNameValue);
291 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
292 fileName = EcmaStringAccessor(str).ToStdString() + ".cpuprofile";
293 } else {
294 fileName = GetProfileName();
295 }
296
297 if (!CreateFile(fileName)) {
298 LOG_ECMA(ERROR) << "CreateFile failed " << fileName;
299 }
300
301 // get sampling interval
302 JSHandle<JSTaggedValue> samplingIntervalValue = GetCallArg(info, 1);
303 uint32_t interval = 500; // 500:Default Sampling interval 500 microseconds
304 if (samplingIntervalValue->IsNumber()) {
305 interval = JSTaggedValue::ToUint32(thread, samplingIntervalValue);
306 }
307
308 DFXJSNApi::StartCpuProfilerForFile(vm, fileName, interval);
309 return JSTaggedValue::Undefined();
310 }
311
StopCpuProfiler(EcmaRuntimeCallInfo * info)312 JSTaggedValue BuiltinsArkTools::StopCpuProfiler(EcmaRuntimeCallInfo *info)
313 {
314 JSThread *thread = info->GetThread();
315 RETURN_IF_DISALLOW_ARKTOOLS(thread);
316 [[maybe_unused]] EcmaHandleScope handleScope(thread);
317 auto vm = thread->GetEcmaVM();
318 DFXJSNApi::StopCpuProfilerForFile(vm);
319
320 return JSTaggedValue::Undefined();
321 }
322
GetProfileName()323 std::string BuiltinsArkTools::GetProfileName()
324 {
325 char time1[16] = {0}; // 16:Time format length
326 char time2[16] = {0}; // 16:Time format length
327 time_t timep = std::time(nullptr);
328 struct tm nowTime1;
329 localtime_r(&timep, &nowTime1);
330 size_t result = 0;
331 result = strftime(time1, sizeof(time1), "%Y%m%d", &nowTime1);
332 if (result == 0) {
333 LOG_ECMA(ERROR) << "get time failed";
334 return "";
335 }
336 result = strftime(time2, sizeof(time2), "%H%M%S", &nowTime1);
337 if (result == 0) {
338 LOG_ECMA(ERROR) << "get time failed";
339 return "";
340 }
341 std::string profileName = "cpuprofile-";
342 profileName += time1;
343 profileName += "TO";
344 profileName += time2;
345 profileName += ".cpuprofile";
346 return profileName;
347 }
348
CreateFile(std::string & fileName)349 bool BuiltinsArkTools::CreateFile(std::string &fileName)
350 {
351 std::string path = FILEDIR + fileName;
352 if (access(path.c_str(), F_OK) == 0) {
353 if (access(path.c_str(), W_OK) == 0) {
354 fileName = path;
355 return true;
356 }
357 LOG_ECMA(ERROR) << "file create failed, W_OK false";
358 return false;
359 }
360 const mode_t defaultMode = S_IRUSR | S_IWUSR | S_IRGRP; // -rw-r--
361 int fd = creat(path.c_str(), defaultMode);
362 if (fd == -1) {
363 fd = creat(fileName.c_str(), defaultMode);
364 if (fd == -1) {
365 LOG_ECMA(ERROR) << "file create failed, errno = "<< errno;
366 return false;
367 }
368 close(fd);
369 return true;
370 } else {
371 fileName = path;
372 close(fd);
373 return true;
374 }
375 }
376 #endif
377
378 // It is used to check whether an object is a proto, and this function can be
379 // used to check whether the state machine of IC is faulty.
IsPrototype(EcmaRuntimeCallInfo * info)380 JSTaggedValue BuiltinsArkTools::IsPrototype(EcmaRuntimeCallInfo *info)
381 {
382 ASSERT(info);
383 JSThread *thread = info->GetThread();
384 RETURN_IF_DISALLOW_ARKTOOLS(thread);
385 [[maybe_unused]] EcmaHandleScope handleScope(thread);
386
387 JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
388 JSHClass *objHclass = obj->GetTaggedObject()->GetClass();
389 return JSTaggedValue(objHclass->IsPrototype());
390 }
391
392 // It is used to check whether a function is aot compiled.
IsAOTCompiled(EcmaRuntimeCallInfo * info)393 JSTaggedValue BuiltinsArkTools::IsAOTCompiled(EcmaRuntimeCallInfo *info)
394 {
395 ASSERT(info);
396 JSThread *thread = info->GetThread();
397 RETURN_IF_DISALLOW_ARKTOOLS(thread);
398 [[maybe_unused]] EcmaHandleScope handleScope(thread);
399
400 JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
401 JSHandle<JSFunction> func(thread, obj.GetTaggedValue());
402 return JSTaggedValue(func->IsCompiledCode());
403 }
404
405 // It is used to check whether two functions have same profileTypeInfo
IsSameProfileTypeInfo(EcmaRuntimeCallInfo * info)406 JSTaggedValue BuiltinsArkTools::IsSameProfileTypeInfo(EcmaRuntimeCallInfo *info)
407 {
408 ASSERT(info);
409 JSThread *thread = info->GetThread();
410 RETURN_IF_DISALLOW_ARKTOOLS(thread);
411 [[maybe_unused]] EcmaHandleScope handleScope(thread);
412 JSHandle<JSFunction> func0 = JSHandle<JSFunction>::Cast(GetCallArg(info, 0));
413 JSHandle<JSFunction> func1 = JSHandle<JSFunction>::Cast(GetCallArg(info, 1));
414 return JSTaggedValue(func0->GetProfileTypeInfo() == func1->GetProfileTypeInfo());
415 }
416
417 // It is used to check whether a function has valid profileTypeInfo
IsProfileTypeInfoValid(EcmaRuntimeCallInfo * info)418 JSTaggedValue BuiltinsArkTools::IsProfileTypeInfoValid(EcmaRuntimeCallInfo *info)
419 {
420 ASSERT(info);
421 JSThread *thread = info->GetThread();
422 RETURN_IF_DISALLOW_ARKTOOLS(thread);
423 [[maybe_unused]] EcmaHandleScope handleScope(thread);
424 JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(GetCallArg(info, 0));
425 return JSTaggedValue(func->GetProfileTypeInfo().IsTaggedArray());
426 }
427
IsOnHeap(EcmaRuntimeCallInfo * info)428 JSTaggedValue BuiltinsArkTools::IsOnHeap(EcmaRuntimeCallInfo *info)
429 {
430 ASSERT(info);
431 JSThread *thread = info->GetThread();
432 RETURN_IF_DISALLOW_ARKTOOLS(thread);
433 [[maybe_unused]] EcmaHandleScope handleScope(thread);
434
435 JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
436 return JSTaggedValue(obj.GetTaggedValue().GetTaggedObject()->GetClass()->IsOnHeapFromBitField());
437 }
438
439 // It is used to check whether a function is aot compiled and deopted at runtime.
IsAOTDeoptimized(EcmaRuntimeCallInfo * info)440 JSTaggedValue BuiltinsArkTools::IsAOTDeoptimized(EcmaRuntimeCallInfo *info)
441 {
442 ASSERT(info);
443 JSThread *thread = info->GetThread();
444 RETURN_IF_DISALLOW_ARKTOOLS(thread);
445 [[maybe_unused]] EcmaHandleScope handleScope(thread);
446
447 JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
448 JSHandle<JSFunction> func(thread, obj.GetTaggedValue());
449 bool isAotCompiled = func->IsCompiledCode();
450 if (isAotCompiled) {
451 Method *method = func->GetCallTarget();
452 uint32_t deoptedCount = method->GetDeoptThreshold();
453 uint32_t deoptThreshold = thread->GetEcmaVM()->GetJSOptions().GetDeoptThreshold();
454 return JSTaggedValue(deoptedCount != deoptThreshold);
455 }
456
457 return JSTaggedValue(false);
458 }
459
CheckDeoptStatus(EcmaRuntimeCallInfo * info)460 JSTaggedValue BuiltinsArkTools::CheckDeoptStatus(EcmaRuntimeCallInfo *info)
461 {
462 ASSERT(info);
463 JSThread *thread = info->GetThread();
464 RETURN_IF_DISALLOW_ARKTOOLS(thread);
465 [[maybe_unused]] EcmaHandleScope handleScope(thread);
466
467 JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
468 JSHandle<JSFunction> func(thread, obj.GetTaggedValue());
469 Method *method = func->GetCallTarget();
470 bool isAotCompiled = func->IsCompiledCode();
471 uint16_t threshold = method->GetDeoptThreshold();
472 if (threshold > 0) {
473 return JSTaggedValue(isAotCompiled);
474 }
475 // check status before deopt
476 JSHandle<JSTaggedValue> hasDeopt = GetCallArg(info, 1);
477 if (hasDeopt->IsFalse()) {
478 return JSTaggedValue(!isAotCompiled);
479 }
480 if (!hasDeopt->IsTrue()) {
481 return JSTaggedValue(false);
482 }
483 // check status after deopt
484 if (isAotCompiled ||
485 func->IsCompiledFastCall() ||
486 method->GetDeoptType() != kungfu::DeoptType::NONE ||
487 method->GetCodeEntryOrLiteral() == 0) {
488 return JSTaggedValue(false);
489 }
490 return JSTaggedValue(true);
491 }
492
PrintTypedOpProfiler(EcmaRuntimeCallInfo * info)493 JSTaggedValue BuiltinsArkTools::PrintTypedOpProfiler(EcmaRuntimeCallInfo *info)
494 {
495 ASSERT(info);
496 JSThread *thread = info->GetThread();
497 RETURN_IF_DISALLOW_ARKTOOLS(thread);
498 [[maybe_unused]] EcmaHandleScope handleScope(thread);
499
500 JSHandle<JSTaggedValue> opStrVal = GetCallArg(info, 0);
501 std::string opStr = EcmaStringAccessor(opStrVal.GetTaggedValue()).ToStdString();
502 TypedOpProfiler *profiler = thread->GetCurrentEcmaContext()->GetTypdOpProfiler();
503 if (profiler != nullptr) {
504 profiler->Print(opStr);
505 }
506 return JSTaggedValue::Undefined();
507 }
508
ClearTypedOpProfiler(EcmaRuntimeCallInfo * info)509 JSTaggedValue BuiltinsArkTools::ClearTypedOpProfiler(EcmaRuntimeCallInfo *info)
510 {
511 ASSERT(info);
512 JSThread *thread = info->GetThread();
513 RETURN_IF_DISALLOW_ARKTOOLS(thread);
514 [[maybe_unused]] EcmaHandleScope handleScope(thread);
515
516 TypedOpProfiler *profiler = thread->GetCurrentEcmaContext()->GetTypdOpProfiler();
517 if (profiler != nullptr) {
518 profiler->Clear();
519 }
520 return JSTaggedValue::Undefined();
521 }
522
GetElementsKind(EcmaRuntimeCallInfo * info)523 JSTaggedValue BuiltinsArkTools::GetElementsKind(EcmaRuntimeCallInfo *info)
524 {
525 ASSERT(info);
526 JSThread *thread = info->GetThread();
527 RETURN_IF_DISALLOW_ARKTOOLS(thread);
528 [[maybe_unused]] EcmaHandleScope handleScope(thread);
529
530 JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
531 JSHClass *hclass = obj->GetTaggedObject()->GetClass();
532 ElementsKind kind = hclass->GetElementsKind();
533 return JSTaggedValue(static_cast<uint32_t>(kind));
534 }
535
IsRegExpReplaceDetectorValid(EcmaRuntimeCallInfo * info)536 JSTaggedValue BuiltinsArkTools::IsRegExpReplaceDetectorValid(EcmaRuntimeCallInfo *info)
537 {
538 ASSERT(info);
539 JSThread *thread = info->GetThread();
540 RETURN_IF_DISALLOW_ARKTOOLS(thread);
541 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
542 return JSTaggedValue(PropertyDetector::IsRegExpReplaceDetectorValid(env));
543 }
544
IsRegExpFlagsDetectorValid(EcmaRuntimeCallInfo * info)545 JSTaggedValue BuiltinsArkTools::IsRegExpFlagsDetectorValid(EcmaRuntimeCallInfo *info)
546 {
547 ASSERT(info);
548 JSThread *thread = info->GetThread();
549 RETURN_IF_DISALLOW_ARKTOOLS(thread);
550 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
551 return JSTaggedValue(PropertyDetector::IsRegExpFlagsDetectorValid(env));
552 }
553
IsNumberStringNotRegexpLikeDetectorValid(EcmaRuntimeCallInfo * info)554 JSTaggedValue BuiltinsArkTools::IsNumberStringNotRegexpLikeDetectorValid(EcmaRuntimeCallInfo *info)
555 {
556 ASSERT(info);
557 JSThread *thread = info->GetThread();
558 RETURN_IF_DISALLOW_ARKTOOLS(thread);
559 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
560 return JSTaggedValue(PropertyDetector::IsNumberStringNotRegexpLikeDetectorValid(env));
561 }
562
IsSymbolIteratorDetectorValid(EcmaRuntimeCallInfo * info)563 JSTaggedValue BuiltinsArkTools::IsSymbolIteratorDetectorValid(EcmaRuntimeCallInfo *info)
564 {
565 ASSERT(info);
566 JSThread *thread = info->GetThread();
567 RETURN_IF_DISALLOW_ARKTOOLS(thread);
568 [[maybe_unused]] EcmaHandleScope handleScope(thread);
569
570 JSHandle<JSTaggedValue> kind = GetCallArg(info, 0);
571 if (!kind->IsString()) {
572 return JSTaggedValue::Undefined();
573 }
574 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
575 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
576 JSHandle<EcmaString> mapString = factory->NewFromUtf8ReadOnly("Map");
577 if (JSTaggedValue::Equal(thread, kind, JSHandle<JSTaggedValue>(mapString))) {
578 return JSTaggedValue(PropertyDetector::IsMapIteratorDetectorValid(env));
579 }
580 JSHandle<EcmaString> setString = factory->NewFromUtf8ReadOnly("Set");
581 if (JSTaggedValue::Equal(thread, kind, JSHandle<JSTaggedValue>(setString))) {
582 return JSTaggedValue(PropertyDetector::IsSetIteratorDetectorValid(env));
583 }
584 JSHandle<EcmaString> stringString = factory->NewFromUtf8ReadOnly("String");
585 if (JSTaggedValue::Equal(thread, kind, JSHandle<JSTaggedValue>(stringString))) {
586 return JSTaggedValue(PropertyDetector::IsStringIteratorDetectorValid(env));
587 }
588 JSHandle<EcmaString> arrayString = factory->NewFromUtf8ReadOnly("Array");
589 if (JSTaggedValue::Equal(thread, kind, JSHandle<JSTaggedValue>(arrayString))) {
590 return JSTaggedValue(PropertyDetector::IsArrayIteratorDetectorValid(env));
591 }
592 JSHandle<EcmaString> typedarrayString = factory->NewFromUtf8ReadOnly("TypedArray");
593 if (JSTaggedValue::Equal(thread, kind, JSHandle<JSTaggedValue>(typedarrayString))) {
594 return JSTaggedValue(PropertyDetector::IsTypedArrayIteratorDetectorValid(env));
595 }
596 return JSTaggedValue::Undefined();
597 }
598
TimeInUs(EcmaRuntimeCallInfo * info)599 JSTaggedValue BuiltinsArkTools::TimeInUs([[maybe_unused]] EcmaRuntimeCallInfo *info)
600 {
601 [[maybe_unused]] JSThread *thread = info->GetThread();
602 RETURN_IF_DISALLOW_ARKTOOLS(thread);
603 ClockScope scope;
604 return JSTaggedValue(scope.GetCurTime());
605 }
606
607 #if ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT
StartScopeLockStats(EcmaRuntimeCallInfo * info)608 JSTaggedValue BuiltinsArkTools::StartScopeLockStats(EcmaRuntimeCallInfo *info)
609 {
610 JSThread *thread = info->GetThread();
611 RETURN_IF_DISALLOW_ARKTOOLS(thread);
612 auto vm = thread->GetEcmaVM();
613 vm->StartCollectingScopeLockStats();
614 LOG_FULL(INFO) << "Start Collecting ArkCompiler Scope-Lock Stats";
615 return JSTaggedValue::Undefined();
616 }
617
StopScopeLockStats(EcmaRuntimeCallInfo * info)618 JSTaggedValue BuiltinsArkTools::StopScopeLockStats(EcmaRuntimeCallInfo *info)
619 {
620 JSThread *thread = info->GetThread();
621 RETURN_IF_DISALLOW_ARKTOOLS(thread);
622 auto vm = thread->GetEcmaVM();
623 LOG_FULL(INFO) << "Stop Collecting ArkCompiler Scope-Lock Stats: "
624 << " ThreadStateTransition count: " << vm->GetUpdateThreadStateTransCount()
625 << " , Entered Scope But NO State Transition count: " << (vm->GetEnterJsiNativeScopeCount() +
626 vm->GetEnterFastNativeScopeCount() +
627 vm->GetEnterThreadManagedScopeCount() -
628 vm->GetUpdateThreadStateTransCount())
629 << " , String-Table Lock count: " << vm->GetStringTableLockCount();
630 vm->ResetScopeLockStats();
631 vm->StopCollectingScopeLockStats();
632 return JSTaggedValue::Undefined();
633 }
634 #endif
635
UnimplementedBuiltin(char const * name,EcmaRuntimeCallInfo * info)636 static JSTaggedValue UnimplementedBuiltin(char const *name, [[maybe_unused]] EcmaRuntimeCallInfo *info)
637 {
638 ASSERT(info);
639 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
640 LOG_ECMA(DEBUG) << "Enter unimplemented ArkTools." << name;
641 return JSTaggedValue::Undefined();
642 }
643
BuiltinFail(JSThread * thread,char const * msg)644 static JSTaggedValue BuiltinFail(JSThread *thread, char const *msg)
645 {
646 [[maybe_unused]] EcmaHandleScope handleScope(thread);
647 THROW_NEW_ERROR_WITH_MSG_AND_RETURN_VALUE(thread, ErrorType::ERROR, msg, JSTaggedValue::Exception());
648 }
649
NotSupportedBuiltin(char const * name,EcmaRuntimeCallInfo * info)650 static JSTaggedValue NotSupportedBuiltin(char const *name, [[maybe_unused]] EcmaRuntimeCallInfo *info)
651 {
652 ASSERT(info);
653 JSThread *thread = info->GetThread();
654 RETURN_IF_DISALLOW_ARKTOOLS(thread);
655 std::string msg = std::string(name) + " is not supported";
656 return BuiltinFail(thread, msg.c_str());
657 }
658
659 // empty function for regress-xxx test cases
PrepareFunctionForOptimization(EcmaRuntimeCallInfo * info)660 JSTaggedValue BuiltinsArkTools::PrepareFunctionForOptimization([[maybe_unused]] EcmaRuntimeCallInfo *info)
661 {
662 return UnimplementedBuiltin(__func__, info);
663 }
664
665 // empty function for regress-xxx test cases
OptimizeFunctionOnNextCall(EcmaRuntimeCallInfo * info)666 JSTaggedValue BuiltinsArkTools::OptimizeFunctionOnNextCall([[maybe_unused]] EcmaRuntimeCallInfo *info)
667 {
668 return UnimplementedBuiltin(__func__, info);
669 }
670
671 // empty function for regress-xxx test cases
OptimizeMaglevOnNextCall(EcmaRuntimeCallInfo * info)672 JSTaggedValue BuiltinsArkTools::OptimizeMaglevOnNextCall([[maybe_unused]] EcmaRuntimeCallInfo *info)
673 {
674 return UnimplementedBuiltin(__func__, info);
675 }
676
677 // empty function for regress-xxx test cases
DeoptimizeFunction(EcmaRuntimeCallInfo * info)678 JSTaggedValue BuiltinsArkTools::DeoptimizeFunction([[maybe_unused]] EcmaRuntimeCallInfo *info)
679 {
680 return UnimplementedBuiltin(__func__, info);
681 }
682
683 // empty function for regress-xxx test cases
OptimizeOsr(EcmaRuntimeCallInfo * info)684 JSTaggedValue BuiltinsArkTools::OptimizeOsr([[maybe_unused]] EcmaRuntimeCallInfo *info)
685 {
686 return UnimplementedBuiltin(__func__, info);
687 }
688
689 // empty function for regress-xxx test cases
NeverOptimizeFunction(EcmaRuntimeCallInfo * info)690 JSTaggedValue BuiltinsArkTools::NeverOptimizeFunction([[maybe_unused]] EcmaRuntimeCallInfo *info)
691 {
692 return UnimplementedBuiltin(__func__, info);
693 }
694
HeapObjectVerify(EcmaRuntimeCallInfo * info)695 JSTaggedValue BuiltinsArkTools::HeapObjectVerify([[maybe_unused]] EcmaRuntimeCallInfo *info)
696 {
697 JSThread *thread = info->GetThread();
698 RETURN_IF_DISALLOW_ARKTOOLS(thread);
699 CHECK(info && info->GetArgsNumber() == 1);
700 JSHandle<JSTaggedValue> arg = GetCallArg(info, 0);
701
702 if (arg->IsHeapObject()) {
703 JSHandle<TaggedObject> obj(arg);
704 CHECK(obj->GetClass()->GetClass()->IsHClass());
705
706 size_t failCount = 0;
707 VerifyObjectVisitor heapVerifier(thread->GetEcmaVM()->GetHeap(), &failCount);
708 heapVerifier(*obj);
709 CHECK(failCount == 0);
710 }
711 return JSTaggedValue::True();
712 }
713
714 // empty function for regress-xxx test cases
DisableOptimizationFinalization(EcmaRuntimeCallInfo * info)715 JSTaggedValue BuiltinsArkTools::DisableOptimizationFinalization([[maybe_unused]] EcmaRuntimeCallInfo *info)
716 {
717 return UnimplementedBuiltin(__func__, info);
718 }
719
720 // empty function for regress-xxx test cases
DeoptimizeNow(EcmaRuntimeCallInfo * info)721 JSTaggedValue BuiltinsArkTools::DeoptimizeNow([[maybe_unused]] EcmaRuntimeCallInfo *info)
722 {
723 return UnimplementedBuiltin(__func__, info);
724 }
725
726 // empty function for regress-xxx test cases
WaitForBackgroundOptimization(EcmaRuntimeCallInfo * info)727 JSTaggedValue BuiltinsArkTools::WaitForBackgroundOptimization([[maybe_unused]] EcmaRuntimeCallInfo *info)
728 {
729 return UnimplementedBuiltin(__func__, info);
730 }
731
Gc(EcmaRuntimeCallInfo * info)732 JSTaggedValue BuiltinsArkTools::Gc([[maybe_unused]] EcmaRuntimeCallInfo *info)
733 {
734 JSThread *thread = info->GetThread();
735 RETURN_IF_DISALLOW_ARKTOOLS(thread);
736 TriggerGCType gctype = TriggerGCType::FULL_GC;
737
738 if (info->GetArgsNumber() != 0) {
739 JSHandle<JSTaggedValue> arg = GetCallArg(info, 0);
740 if (arg->IsECMAObject()) {
741 return BuiltinFail(thread, "ArkTools.gc object parameter is not supported");
742 }
743 gctype = TriggerGCType::YOUNG_GC;
744 }
745 thread->GetEcmaVM()->CollectGarbage(gctype, GCReason::EXTERNAL_TRIGGER);
746 return JSTaggedValue::Undefined();
747 }
748
749 // empty function for pgoAssertType
PGOAssertType(EcmaRuntimeCallInfo * info)750 JSTaggedValue BuiltinsArkTools::PGOAssertType([[maybe_unused]] EcmaRuntimeCallInfo *info)
751 {
752 LOG_ECMA(DEBUG) << "Enter PGOAssertType";
753 [[maybe_unused]] JSThread *thread = info->GetThread();
754 RETURN_IF_DISALLOW_ARKTOOLS(thread);
755 return JSTaggedValue::Undefined();
756 }
757
ToLength(EcmaRuntimeCallInfo * info)758 JSTaggedValue BuiltinsArkTools::ToLength([[maybe_unused]] EcmaRuntimeCallInfo *info)
759 {
760 ASSERT(info);
761 JSThread *thread = info->GetThread();
762 RETURN_IF_DISALLOW_ARKTOOLS(thread);
763 [[maybe_unused]] EcmaHandleScope handleScope(thread);
764 JSHandle<JSTaggedValue> key = GetCallArg(info, 0);
765 return JSTaggedValue::ToLength(thread, key);
766 }
767
768 template <typename Pred>
TestElementsKind(EcmaRuntimeCallInfo * info,Pred const & pred)769 static JSTaggedValue TestElementsKind([[maybe_unused]] EcmaRuntimeCallInfo *info, Pred const &pred)
770 {
771 JSThread *thread = info->GetThread();
772 RETURN_IF_DISALLOW_ARKTOOLS(thread);
773 CHECK(info && info->GetArgsNumber() == 1);
774 JSHandle<JSTaggedValue> arg = base::BuiltinsBase::GetCallArg(info, 0);
775 CHECK(thread->GetEcmaVM()->IsEnableElementsKind());
776 CHECK(arg->IsJSObject());
777 ElementsKind kind = JSHandle<JSObject>::Cast(arg)->GetClass()->GetElementsKind();
778 return JSTaggedValue(pred(kind));
779 }
780
HasDictionaryElements(EcmaRuntimeCallInfo * info)781 JSTaggedValue BuiltinsArkTools::HasDictionaryElements([[maybe_unused]] EcmaRuntimeCallInfo *info)
782 {
783 JSThread *thread = info->GetThread();
784 RETURN_IF_DISALLOW_ARKTOOLS(thread);
785 CHECK(info && info->GetArgsNumber() == 1);
786 JSHandle<JSTaggedValue> arg = base::BuiltinsBase::GetCallArg(info, 0);
787 CHECK(thread->GetEcmaVM()->IsEnableElementsKind());
788 CHECK(arg->IsJSObject());
789 JSHandle<JSObject> obj(arg);
790 bool isDict = obj->GetClass()->IsDictionaryElement();
791 CHECK(isDict == ElementAccessor::IsDictionaryMode(obj));
792 CHECK(isDict == (obj->GetClass()->GetElementsKind() == ElementsKind::DICTIONARY));
793 return JSTaggedValue(isDict);
794 }
795
HasHoleyElements(EcmaRuntimeCallInfo * info)796 JSTaggedValue BuiltinsArkTools::HasHoleyElements([[maybe_unused]] EcmaRuntimeCallInfo *info)
797 {
798 return TestElementsKind(info, [](ElementsKind kind) {
799 return (helpers::ToUnderlying(kind) & helpers::ToUnderlying(ElementsKind::HOLE)) != 0;
800 });
801 }
802
HasSmiElements(EcmaRuntimeCallInfo * info)803 JSTaggedValue BuiltinsArkTools::HasSmiElements([[maybe_unused]] EcmaRuntimeCallInfo *info)
804 {
805 return TestElementsKind(info, [](ElementsKind kind) {
806 return kind == ElementsKind::INT || kind == ElementsKind::HOLE_INT;
807 });
808 }
809
HasDoubleElements(EcmaRuntimeCallInfo * info)810 JSTaggedValue BuiltinsArkTools::HasDoubleElements([[maybe_unused]] EcmaRuntimeCallInfo *info)
811 {
812 return TestElementsKind(info, [](ElementsKind kind) {
813 return kind == ElementsKind::NUMBER || kind == ElementsKind::HOLE_NUMBER;
814 });
815 }
816
HasObjectElements(EcmaRuntimeCallInfo * info)817 JSTaggedValue BuiltinsArkTools::HasObjectElements([[maybe_unused]] EcmaRuntimeCallInfo *info)
818 {
819 return TestElementsKind(info, [](ElementsKind kind) {
820 ElementsKind noHole = static_cast<ElementsKind>(helpers::ToUnderlying(kind)
821 & ~helpers::ToUnderlying(ElementsKind::HOLE));
822 return noHole == ElementsKind::STRING || noHole == ElementsKind::OBJECT || noHole == ElementsKind::TAGGED;
823 });
824 }
825
ArrayBufferDetach(EcmaRuntimeCallInfo * info)826 JSTaggedValue BuiltinsArkTools::ArrayBufferDetach([[maybe_unused]] EcmaRuntimeCallInfo *info)
827 {
828 JSThread *thread = info->GetThread();
829 RETURN_IF_DISALLOW_ARKTOOLS(thread);
830 CHECK(info && info->GetArgsNumber() == 1);
831 [[maybe_unused]] EcmaHandleScope handleScope(thread);
832 JSHandle<JSTaggedValue> obj1 = GetCallArg(info, 0);
833 JSHandle<JSArrayBuffer> arrBuf = JSHandle<JSArrayBuffer>::Cast(obj1);
834 arrBuf->Detach(thread);
835 return JSTaggedValue::Undefined();
836 }
837
HaveSameMap(EcmaRuntimeCallInfo * info)838 JSTaggedValue BuiltinsArkTools::HaveSameMap([[maybe_unused]] EcmaRuntimeCallInfo *info)
839 {
840 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
841 CHECK(info && info->GetArgsNumber() == 2); // 2 args
842 JSHandle<JSTaggedValue> obj1 = GetCallArg(info, 0);
843 JSHandle<JSTaggedValue> obj2 = GetCallArg(info, 1);
844 CHECK(obj1->IsHeapObject() && obj2->IsHeapObject());
845 return JSTaggedValue(obj1->GetTaggedObject()->GetClass() == obj2->GetTaggedObject()->GetClass());
846 }
847
IsSameHeapObject(EcmaRuntimeCallInfo * info)848 JSTaggedValue BuiltinsArkTools::IsSameHeapObject([[maybe_unused]] EcmaRuntimeCallInfo *info)
849 {
850 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
851 CHECK(info && info->GetArgsNumber() == 2); // 2 args
852 JSHandle<JSTaggedValue> obj1 = GetCallArg(info, 0);
853 JSHandle<JSTaggedValue> obj2 = GetCallArg(info, 1);
854 if (obj1->IsDouble() && obj2->IsDouble()) {
855 return JSTaggedValue(false); // mocked result
856 }
857 CHECK(obj1->IsHeapObject() && obj2->IsHeapObject());
858 return JSTaggedValue(obj1->GetTaggedObject() == obj2->GetTaggedObject());
859 }
860
861 // mock builtin
IsSmi(EcmaRuntimeCallInfo * info)862 JSTaggedValue BuiltinsArkTools::IsSmi([[maybe_unused]] EcmaRuntimeCallInfo *info)
863 {
864 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
865 CHECK(info && info->GetArgsNumber() == 1);
866 return JSTaggedValue(info->GetCallArg(0)->IsInt());
867 }
868
CreatePrivateSymbol(EcmaRuntimeCallInfo * info)869 JSTaggedValue BuiltinsArkTools::CreatePrivateSymbol([[maybe_unused]] EcmaRuntimeCallInfo *info)
870 {
871 JSThread *thread = info->GetThread();
872 RETURN_IF_DISALLOW_ARKTOOLS(thread);
873 CHECK(info && info->GetArgsNumber() == 1);
874 [[maybe_unused]] EcmaHandleScope handleScope(thread);
875 JSHandle<JSTaggedValue> symbolName = GetCallArg(info, 0);
876 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
877 JSHandle<JSSymbol> privateNameSymbol = factory->NewPrivateNameSymbol(symbolName);
878 JSHandle<JSTaggedValue> symbolValue = JSHandle<JSTaggedValue>::Cast(privateNameSymbol);
879 return symbolValue.GetTaggedValue();
880 }
881
IsArray(EcmaRuntimeCallInfo * info)882 JSTaggedValue BuiltinsArkTools::IsArray([[maybe_unused]] EcmaRuntimeCallInfo *info)
883 {
884 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
885 CHECK(info && info->GetArgsNumber() == 1);
886 return JSTaggedValue(info->GetCallArg(0)->IsJSArray());
887 }
888
CreateDataProperty(EcmaRuntimeCallInfo * info)889 JSTaggedValue BuiltinsArkTools::CreateDataProperty([[maybe_unused]] EcmaRuntimeCallInfo *info)
890 {
891 JSThread *thread = info->GetThread();
892 RETURN_IF_DISALLOW_ARKTOOLS(thread);
893 CHECK(info && info->GetArgsNumber() == 3); // 3 args
894 [[maybe_unused]] EcmaHandleScope handleScope(thread);
895 CHECK(GetCallArg(info, 0)->IsJSObject());
896 JSHandle<JSObject> obj(GetCallArg(info, 0)); // 0: object
897 JSHandle<JSTaggedValue> key = GetCallArg(info, 1); // 1: property key
898 JSHandle<JSTaggedValue> value = GetCallArg(info, 2); // 2: property value
899 JSObject::CreateDataPropertyOrThrow(thread, obj, key, value);
900 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
901 return value.GetTaggedValue();
902 }
903
FunctionGetInferredName(EcmaRuntimeCallInfo * info)904 JSTaggedValue BuiltinsArkTools::FunctionGetInferredName([[maybe_unused]] EcmaRuntimeCallInfo *info)
905 {
906 JSThread *thread = info->GetThread();
907 RETURN_IF_DISALLOW_ARKTOOLS(thread);
908 CHECK(info && info->GetArgsNumber() == 1);
909 [[maybe_unused]] EcmaHandleScope handleScope(thread);
910 JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
911 if (obj->IsJSFunction()) {
912 JSHandle<JSFunction> funcObj = JSHandle<JSFunction>::Cast(obj);
913 std::string name = Method::ConstCast(funcObj->GetMethod().GetTaggedObject())->ParseFunctionName();
914 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
915 return factory->NewFromStdString(name).GetTaggedValue();
916 }
917 return thread->GlobalConstants()->GetHandledEmptyString().GetTaggedValue();
918 }
919
StringLessThan(EcmaRuntimeCallInfo * info)920 JSTaggedValue BuiltinsArkTools::StringLessThan([[maybe_unused]] EcmaRuntimeCallInfo *info)
921 {
922 JSThread *thread = info->GetThread();
923 RETURN_IF_DISALLOW_ARKTOOLS(thread);
924 CHECK(info && info->GetArgsNumber() == 2); // 2 args
925 [[maybe_unused]] EcmaHandleScope handleScope(thread);
926 JSHandle<JSTaggedValue> x = GetCallArg(info, 0);
927 JSHandle<JSTaggedValue> y = GetCallArg(info, 1);
928 ComparisonResult result = JSTaggedValue::Compare(thread, x, y);
929 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
930 return JSTaggedValue(ComparisonResult::LESS == result);
931 }
932
StringMaxLength(EcmaRuntimeCallInfo * info)933 JSTaggedValue BuiltinsArkTools::StringMaxLength([[maybe_unused]] EcmaRuntimeCallInfo *info)
934 {
935 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
936 CHECK(info && info->GetArgsNumber() == 0);
937 return JSTaggedValue(static_cast<uint32_t>(EcmaString::MAX_STRING_LENGTH) - 1);
938 }
939
ArrayBufferMaxByteLength(EcmaRuntimeCallInfo * info)940 JSTaggedValue BuiltinsArkTools::ArrayBufferMaxByteLength([[maybe_unused]] EcmaRuntimeCallInfo *info)
941 {
942 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
943 CHECK(info && info->GetArgsNumber() == 0);
944 return JSTaggedValue(INT_MAX);
945 }
946
TypedArrayMaxLength(EcmaRuntimeCallInfo * info)947 JSTaggedValue BuiltinsArkTools::TypedArrayMaxLength([[maybe_unused]] EcmaRuntimeCallInfo *info)
948 {
949 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
950 CHECK(info && info->GetArgsNumber() == 0);
951 return JSTaggedValue(BuiltinsTypedArray::MAX_ARRAY_INDEX);
952 }
953
MaxSmi(EcmaRuntimeCallInfo * info)954 JSTaggedValue BuiltinsArkTools::MaxSmi([[maybe_unused]] EcmaRuntimeCallInfo *info)
955 {
956 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
957 CHECK(info && info->GetArgsNumber() == 0);
958 return JSTaggedValue(INT32_MAX);
959 }
960
Is64Bit(EcmaRuntimeCallInfo * info)961 JSTaggedValue BuiltinsArkTools::Is64Bit([[maybe_unused]] EcmaRuntimeCallInfo *info)
962 {
963 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
964 CHECK(info && info->GetArgsNumber() == 0);
965 return JSTaggedValue(sizeof(void*) == 8); // 8 is 64bit pointer size
966 }
967
968 // empty function for regress-xxx test cases
FinalizeOptimization(EcmaRuntimeCallInfo * info)969 JSTaggedValue BuiltinsArkTools::FinalizeOptimization([[maybe_unused]] EcmaRuntimeCallInfo *info)
970 {
971 return UnimplementedBuiltin(__func__, info);
972 }
973
EnsureFeedbackVectorForFunction(EcmaRuntimeCallInfo * info)974 JSTaggedValue BuiltinsArkTools::EnsureFeedbackVectorForFunction([[maybe_unused]] EcmaRuntimeCallInfo *info)
975 {
976 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
977 CHECK(info && info->GetArgsNumber() == 1);
978 CHECK(info->GetCallArg(0)->IsJSFunction());
979 JSHandle<JSFunction> func(info->GetCallArg(0));
980 auto prof = func->GetProfileTypeInfo();
981 CHECK(prof.IsUndefined() || prof.GetHeapObject()->GetClass()->IsTaggedArray());
982 return JSTaggedValue(!prof.IsUndefined());
983 }
984
985 // empty function for regress-xxx test cases
CompileBaseline(EcmaRuntimeCallInfo * info)986 JSTaggedValue BuiltinsArkTools::CompileBaseline([[maybe_unused]] EcmaRuntimeCallInfo *info)
987 {
988 return UnimplementedBuiltin(__func__, info);
989 }
990
DebugGetLoadedScriptIds(EcmaRuntimeCallInfo * info)991 JSTaggedValue BuiltinsArkTools::DebugGetLoadedScriptIds([[maybe_unused]] EcmaRuntimeCallInfo *info)
992 {
993 return UnimplementedBuiltin(__func__, info);
994 }
995
ToFastProperties(EcmaRuntimeCallInfo * info)996 JSTaggedValue BuiltinsArkTools::ToFastProperties([[maybe_unused]] EcmaRuntimeCallInfo *info)
997 {
998 JSThread *thread = info->GetThread();
999 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1000 CHECK(info && info->GetArgsNumber() == 1);
1001 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1002 JSHandle<JSTaggedValue> arg = info->GetCallArg(0);
1003
1004 if (arg->IsJSObject() && !arg->IsJSGlobalObject()) {
1005 JSHandle<JSObject> obj(arg);
1006 // NOTE: extracted from JSHClass::OptimizeAsFastElements
1007 if (obj->GetJSHClass()->IsDictionaryMode()) {
1008 JSObject::OptimizeAsFastProperties(thread, obj);
1009 } else {
1010 JSHClass::OptimizeAsFastProperties(thread, obj);
1011 }
1012 }
1013 return arg.GetTaggedValue();
1014 }
1015
AbortJS(EcmaRuntimeCallInfo * info)1016 JSTaggedValue BuiltinsArkTools::AbortJS([[maybe_unused]] EcmaRuntimeCallInfo *info)
1017 {
1018 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1019 CHECK(info && info->GetArgsNumber() == 1);
1020 CHECK(info->GetCallArg(0)->IsString());
1021 JSHandle<EcmaString> msg(info->GetCallArg(0));
1022 std::cerr << "AbortJS: " << EcmaStringAccessor(msg).ToCString(StringConvertedUsage::PRINT) << std::endl;
1023 panda::PrintStack(std::cerr);
1024 std::abort();
1025 }
1026
InternalizeString(EcmaRuntimeCallInfo * info)1027 JSTaggedValue BuiltinsArkTools::InternalizeString([[maybe_unused]] EcmaRuntimeCallInfo *info)
1028 {
1029 JSThread *thread = info->GetThread();
1030 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1031 CHECK(info && info->GetArgsNumber() == 1);
1032 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1033 CHECK(info->GetCallArg(0)->IsString());
1034 return JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(info->GetCallArg(0)));
1035 }
1036
1037 // empty function for regress-xxx test cases
HandleDebuggerStatement(EcmaRuntimeCallInfo * info)1038 JSTaggedValue BuiltinsArkTools::HandleDebuggerStatement([[maybe_unused]] EcmaRuntimeCallInfo *info)
1039 {
1040 return UnimplementedBuiltin(__func__, info);
1041 }
1042
1043 // empty function for regress-xxx test cases
SetAllocationTimeout(EcmaRuntimeCallInfo * info)1044 JSTaggedValue BuiltinsArkTools::SetAllocationTimeout([[maybe_unused]] EcmaRuntimeCallInfo *info)
1045 {
1046 return UnimplementedBuiltin(__func__, info);
1047 }
1048
HasFastProperties(EcmaRuntimeCallInfo * info)1049 JSTaggedValue BuiltinsArkTools::HasFastProperties([[maybe_unused]] EcmaRuntimeCallInfo *info)
1050 {
1051 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1052 CHECK(info && info->GetArgsNumber() == 1);
1053 CHECK(info->GetCallArg(0)->IsJSObject());
1054 JSHandle<JSObject> obj(info->GetCallArg(0));
1055 return JSTaggedValue(!obj->GetClass()->IsDictionaryMode());
1056 }
1057
HasOwnConstDataProperty(EcmaRuntimeCallInfo * info)1058 JSTaggedValue BuiltinsArkTools::HasOwnConstDataProperty([[maybe_unused]] EcmaRuntimeCallInfo *info)
1059 {
1060 JSThread *thread = info->GetThread();
1061 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1062 CHECK(info && info->GetArgsNumber() == 2); // 2 args
1063 JSHandle<JSTaggedValue> rec = info->GetCallArg(0);
1064 JSHandle<JSTaggedValue> prop = info->GetCallArg(1);
1065
1066 if (!(prop->IsNumber() || prop->IsString() || prop->IsSymbol())) {
1067 return JSTaggedValue::Undefined();
1068 }
1069 if (!rec->IsJSObject()) {
1070 return JSTaggedValue::Undefined();
1071 }
1072
1073 JSHandle<JSObject> obj(rec);
1074 ObjectOperator op(thread, rec, rec, prop, OperatorType::OWN);
1075 if (!op.IsFound()) {
1076 return JSTaggedValue::False();
1077 }
1078 if (!op.IsAccessorDescriptor()) {
1079 return JSTaggedValue(op.GetAttr().IsConstProps());
1080 }
1081 return JSTaggedValue::Undefined();
1082 }
1083
GetHoleNaNUpper(EcmaRuntimeCallInfo * info)1084 JSTaggedValue BuiltinsArkTools::GetHoleNaNUpper([[maybe_unused]] EcmaRuntimeCallInfo *info)
1085 {
1086 return NotSupportedBuiltin(__func__, info);
1087 }
1088
GetHoleNaNLower(EcmaRuntimeCallInfo * info)1089 JSTaggedValue BuiltinsArkTools::GetHoleNaNLower([[maybe_unused]] EcmaRuntimeCallInfo *info)
1090 {
1091 return NotSupportedBuiltin(__func__, info);
1092 }
1093
1094 // empty function for regress-xxx test cases
SystemBreak(EcmaRuntimeCallInfo * info)1095 JSTaggedValue BuiltinsArkTools::SystemBreak([[maybe_unused]] EcmaRuntimeCallInfo *info)
1096 {
1097 return UnimplementedBuiltin(__func__, info);
1098 }
1099
1100 // empty function for regress-xxx test cases
ScheduleBreak(EcmaRuntimeCallInfo * info)1101 JSTaggedValue BuiltinsArkTools::ScheduleBreak([[maybe_unused]] EcmaRuntimeCallInfo *info)
1102 {
1103 return UnimplementedBuiltin(__func__, info);
1104 }
1105
EnqueueMicrotask(EcmaRuntimeCallInfo * info)1106 JSTaggedValue BuiltinsArkTools::EnqueueMicrotask([[maybe_unused]] EcmaRuntimeCallInfo *info)
1107 {
1108 JSThread *thread = info->GetThread();
1109 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1110 CHECK(info && info->GetArgsNumber() == 1);
1111 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1112 CHECK(info->GetCallArg(0)->IsJSFunction());
1113 JSHandle<JSFunction> func(info->GetCallArg(0));
1114
1115 JSHandle<job::MicroJobQueue> queue = thread->GetCurrentEcmaContext()->GetMicroJobQueue();
1116 JSHandle<TaggedArray> argv(thread->GlobalConstants()->GetHandledEmptyArray());
1117
1118 job::MicroJobQueue::EnqueueJob(thread, queue, job::QueueType::QUEUE_PROMISE, func, argv);
1119 return JSTaggedValue::Undefined();
1120 }
1121
DebugPrint(EcmaRuntimeCallInfo * info)1122 JSTaggedValue BuiltinsArkTools::DebugPrint([[maybe_unused]] EcmaRuntimeCallInfo *info)
1123 {
1124 return UnimplementedBuiltin(__func__, info);
1125 }
1126
1127 // empty function for regress-xxx test cases
GetOptimizationStatus(EcmaRuntimeCallInfo * info)1128 JSTaggedValue BuiltinsArkTools::GetOptimizationStatus([[maybe_unused]] EcmaRuntimeCallInfo *info)
1129 {
1130 return UnimplementedBuiltin(__func__, info);
1131 }
1132
GetUndetectable(EcmaRuntimeCallInfo * info)1133 JSTaggedValue BuiltinsArkTools::GetUndetectable([[maybe_unused]] EcmaRuntimeCallInfo *info)
1134 {
1135 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1136 ASSERT(info && info->GetArgsNumber() == 0);
1137 return JSTaggedValue::Undefined(); // undetectable is just undefined
1138 }
1139
SetKeyedProperty(EcmaRuntimeCallInfo * info)1140 JSTaggedValue BuiltinsArkTools::SetKeyedProperty([[maybe_unused]] EcmaRuntimeCallInfo *info)
1141 {
1142 JSThread *thread = info->GetThread();
1143 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1144 CHECK(info && info->GetArgsNumber() == 3); // 3 args
1145 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1146 JSHandle<JSTaggedValue> obj = info->GetCallArg(0); // 0: object
1147 JSHandle<JSTaggedValue> key = info->GetCallArg(1); // 1: property key
1148 JSHandle<JSTaggedValue> val = info->GetCallArg(2); // 2: property value
1149
1150 JSTaggedValue::SetProperty(thread, obj, key, val, true);
1151 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1152 return JSTaggedValue::Undefined();
1153 }
1154
DisassembleFunction(EcmaRuntimeCallInfo * info)1155 JSTaggedValue BuiltinsArkTools::DisassembleFunction([[maybe_unused]] EcmaRuntimeCallInfo *info)
1156 {
1157 return UnimplementedBuiltin(__func__, info);
1158 }
1159
TryMigrateInstance(EcmaRuntimeCallInfo * info)1160 JSTaggedValue BuiltinsArkTools::TryMigrateInstance([[maybe_unused]] EcmaRuntimeCallInfo *info)
1161 {
1162 return NotSupportedBuiltin(__func__, info);
1163 }
1164
InLargeObjectSpace(EcmaRuntimeCallInfo * info)1165 JSTaggedValue BuiltinsArkTools::InLargeObjectSpace([[maybe_unused]] EcmaRuntimeCallInfo *info)
1166 {
1167 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1168 CHECK(info && info->GetArgsNumber() == 1);
1169 JSHandle<JSTaggedValue> arg = info->GetCallArg(0);
1170 CHECK(arg->IsHeapObject());
1171 Region *region = Region::ObjectAddressToRange(arg->GetTaggedObject());
1172 return JSTaggedValue(region->InHugeObjectSpace());
1173 }
1174
PerformMicrotaskCheckpoint(EcmaRuntimeCallInfo * info)1175 JSTaggedValue BuiltinsArkTools::PerformMicrotaskCheckpoint([[maybe_unused]] EcmaRuntimeCallInfo *info)
1176 {
1177 JSThread *thread = info->GetThread();
1178 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1179 ASSERT(info && info->GetArgsNumber() == 0);
1180 thread->GetCurrentEcmaContext()->ExecutePromisePendingJob();
1181 return JSTaggedValue::Undefined();
1182 }
1183
IsJSReceiver(EcmaRuntimeCallInfo * info)1184 JSTaggedValue BuiltinsArkTools::IsJSReceiver([[maybe_unused]] EcmaRuntimeCallInfo *info)
1185 {
1186 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1187 ASSERT(info && info->GetArgsNumber() == 1);
1188 return JSTaggedValue(info->GetCallArg(0)->IsECMAObject());
1189 }
1190
IsDictPropertyConstTrackingEnabled(EcmaRuntimeCallInfo * info)1191 JSTaggedValue BuiltinsArkTools::IsDictPropertyConstTrackingEnabled([[maybe_unused]] EcmaRuntimeCallInfo *info)
1192 {
1193 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1194 ASSERT(info && info->GetArgsNumber() == 0);
1195 return JSTaggedValue(false);
1196 }
1197
1198 // mock builtin
AllocateHeapNumber(EcmaRuntimeCallInfo * info)1199 JSTaggedValue BuiltinsArkTools::AllocateHeapNumber([[maybe_unused]] EcmaRuntimeCallInfo *info)
1200 {
1201 RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1202 ASSERT(info && info->GetArgsNumber() == 0);
1203 return JSTaggedValue(0.0);
1204 }
1205
ConstructConsString(EcmaRuntimeCallInfo * info)1206 JSTaggedValue BuiltinsArkTools::ConstructConsString([[maybe_unused]] EcmaRuntimeCallInfo *info)
1207 {
1208 JSThread *thread = info->GetThread();
1209 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1210 CHECK(info && info->GetArgsNumber() == 2); // 2 args
1211 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1212 CHECK(info->GetCallArg(0)->IsString());
1213 CHECK(info->GetCallArg(1)->IsString());
1214 JSHandle<EcmaString> str1(info->GetCallArg(0));
1215 JSHandle<EcmaString> str2(info->GetCallArg(1));
1216
1217 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1218 return factory->ConcatFromString(str1, str2).GetTaggedValue();
1219 }
1220
1221 // empty function for regress-xxx test cases
CompleteInobjectSlackTracking(EcmaRuntimeCallInfo * info)1222 JSTaggedValue BuiltinsArkTools::CompleteInobjectSlackTracking([[maybe_unused]] EcmaRuntimeCallInfo *info)
1223 {
1224 return UnimplementedBuiltin(__func__, info);
1225 }
1226
NormalizeElements(EcmaRuntimeCallInfo * info)1227 JSTaggedValue BuiltinsArkTools::NormalizeElements([[maybe_unused]] EcmaRuntimeCallInfo *info)
1228 {
1229 JSThread *thread = info->GetThread();
1230 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1231 CHECK(info && info->GetArgsNumber() == 1);
1232 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1233 CHECK(info->GetCallArg(0)->IsJSObject());
1234 JSHandle<JSObject> obj(info->GetCallArg(0));
1235 JSObject::ElementsToDictionary(thread, obj);
1236 return obj.GetTaggedValue();
1237 }
1238
Call(EcmaRuntimeCallInfo * info)1239 JSTaggedValue BuiltinsArkTools::Call([[maybe_unused]] EcmaRuntimeCallInfo *info)
1240 {
1241 JSThread *thread = info->GetThread();
1242 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1243 static constexpr uint32_t MIN_ARGS = 2;
1244 CHECK(info && info->GetArgsNumber() >= MIN_ARGS);
1245 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1246 uint32_t argc = info->GetArgsNumber() - MIN_ARGS;
1247 JSHandle<JSTaggedValue> callee = info->GetCallArg(0);
1248 JSHandle<JSTaggedValue> receiver = info->GetCallArg(1);
1249
1250 JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
1251 EcmaRuntimeCallInfo *calleeInfo = EcmaInterpreter::NewRuntimeCallInfo(thread, callee, receiver, undefined, argc);
1252 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1253 for (uint32_t i = 0; i < argc; ++i) {
1254 calleeInfo->SetCallArg(i, info->GetCallArg(i + MIN_ARGS).GetTaggedValue());
1255 }
1256 return JSFunction::Call(calleeInfo);
1257 }
1258
1259 // empty function for regress-xxx test cases
DebugPushPromise(EcmaRuntimeCallInfo * info)1260 JSTaggedValue BuiltinsArkTools::DebugPushPromise([[maybe_unused]] EcmaRuntimeCallInfo *info)
1261 {
1262 return UnimplementedBuiltin(__func__, info);
1263 }
1264
1265 // empty function for regress-xxx test cases
SetForceSlowPath(EcmaRuntimeCallInfo * info)1266 JSTaggedValue BuiltinsArkTools::SetForceSlowPath([[maybe_unused]] EcmaRuntimeCallInfo *info)
1267 {
1268 return UnimplementedBuiltin(__func__, info);
1269 }
1270
1271 // empty function for regress-xxx test cases
NotifyContextDisposed(EcmaRuntimeCallInfo * info)1272 JSTaggedValue BuiltinsArkTools::NotifyContextDisposed([[maybe_unused]] EcmaRuntimeCallInfo *info)
1273 {
1274 return UnimplementedBuiltin(__func__, info);
1275 }
1276
1277 // empty function for regress-xxx test cases
OptimizeObjectForAddingMultipleProperties(EcmaRuntimeCallInfo * info)1278 JSTaggedValue BuiltinsArkTools::OptimizeObjectForAddingMultipleProperties([[maybe_unused]] EcmaRuntimeCallInfo *info)
1279 {
1280 return UnimplementedBuiltin(__func__, info);
1281 }
1282
1283 // empty function for regress-xxx test cases
IsBeingInterpreted(EcmaRuntimeCallInfo * info)1284 JSTaggedValue BuiltinsArkTools::IsBeingInterpreted([[maybe_unused]] EcmaRuntimeCallInfo *info)
1285 {
1286 return UnimplementedBuiltin(__func__, info);
1287 }
1288
1289 // empty function for regress-xxx test cases
ClearFunctionFeedback(EcmaRuntimeCallInfo * info)1290 JSTaggedValue BuiltinsArkTools::ClearFunctionFeedback([[maybe_unused]] EcmaRuntimeCallInfo *info)
1291 {
1292 return UnimplementedBuiltin(__func__, info);
1293 }
1294
JitCompileSync(EcmaRuntimeCallInfo * info)1295 JSTaggedValue BuiltinsArkTools::JitCompileSync(EcmaRuntimeCallInfo *info)
1296 {
1297 JSThread *thread = info->GetThread();
1298 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1299 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1300
1301 JSHandle<JSTaggedValue> thisValue = GetCallArg(info, 0);
1302 if (!thisValue->IsJSFunction()) {
1303 return JSTaggedValue::False();
1304 }
1305 JSHandle<JSFunction> jsFunction(thisValue);
1306 Jit::Compile(thread->GetEcmaVM(), jsFunction, CompilerTier::FAST,
1307 MachineCode::INVALID_OSR_OFFSET, JitCompileMode::SYNC);
1308 return JSTaggedValue::True();
1309 }
1310
JitCompileAsync(EcmaRuntimeCallInfo * info)1311 JSTaggedValue BuiltinsArkTools::JitCompileAsync(EcmaRuntimeCallInfo *info)
1312 {
1313 JSThread *thread = info->GetThread();
1314 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1315 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1316
1317 JSHandle<JSTaggedValue> thisValue = GetCallArg(info, 0);
1318 if (!thisValue->IsJSFunction()) {
1319 return JSTaggedValue::False();
1320 }
1321 JSHandle<JSFunction> jsFunction(thisValue);
1322 Jit::Compile(thread->GetEcmaVM(), jsFunction, CompilerTier::FAST,
1323 MachineCode::INVALID_OSR_OFFSET, JitCompileMode::ASYNC);
1324 return JSTaggedValue::True();
1325 }
1326
WaitJitCompileFinish(EcmaRuntimeCallInfo * info)1327 JSTaggedValue BuiltinsArkTools::WaitJitCompileFinish(EcmaRuntimeCallInfo *info)
1328 {
1329 JSThread *thread = info->GetThread();
1330 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1331 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1332
1333 JSHandle<JSTaggedValue> thisValue = GetCallArg(info, 0);
1334 if (!thisValue->IsJSFunction()) {
1335 return JSTaggedValue::False();
1336 }
1337 JSHandle<JSFunction> jsFunction(thisValue);
1338
1339 auto jit = Jit::GetInstance();
1340 if (!jit->IsEnableFastJit()) {
1341 return JSTaggedValue::False();
1342 }
1343 if (jsFunction->GetMachineCode() == JSTaggedValue::Undefined()) {
1344 return JSTaggedValue::False();
1345 }
1346 while (jsFunction->GetMachineCode() == JSTaggedValue::Hole()) {
1347 // just spin check
1348 thread->CheckSafepoint();
1349 }
1350 return JSTaggedValue::True();
1351 }
1352
WaitAllJitCompileFinish(EcmaRuntimeCallInfo * info)1353 JSTaggedValue BuiltinsArkTools::WaitAllJitCompileFinish(EcmaRuntimeCallInfo *info)
1354 {
1355 JSThread *thread = info->GetThread();
1356 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1357
1358 auto jit = Jit::GetInstance();
1359 if (!jit->IsEnableFastJit()) {
1360 return JSTaggedValue::False();
1361 }
1362 while (Jit::GetInstance()->GetRunningTaskCnt(thread->GetEcmaVM())) {
1363 thread->CheckSafepoint();
1364 }
1365 thread->SetPGOProfilerEnable(false);
1366 thread->CheckOrSwitchPGOStubs();
1367 thread->GetEcmaVM()->GetJSOptions().SetEnablePGOProfiler(false);
1368 return JSTaggedValue::True();
1369 }
1370
StartRuntimeStat(EcmaRuntimeCallInfo * msg)1371 JSTaggedValue BuiltinsArkTools::StartRuntimeStat(EcmaRuntimeCallInfo *msg)
1372 {
1373 JSThread *thread = msg->GetThread();
1374 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1375 BUILTINS_API_TRACE(thread, Global, StartRuntimeStat);
1376 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1377 // start vm runtime stat statistic
1378 thread->GetCurrentEcmaContext()->SetRuntimeStatEnable(true);
1379 return JSTaggedValue::Undefined();
1380 }
1381
StopRuntimeStat(EcmaRuntimeCallInfo * msg)1382 JSTaggedValue BuiltinsArkTools::StopRuntimeStat(EcmaRuntimeCallInfo *msg)
1383 {
1384 JSThread *thread = msg->GetThread();
1385 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1386 BUILTINS_API_TRACE(thread, Global, StopRuntimeStat);
1387 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1388 // start vm runtime stat statistic
1389 thread->GetCurrentEcmaContext()->SetRuntimeStatEnable(false);
1390 return JSTaggedValue::Undefined();
1391 }
1392
IterateFrame(EcmaRuntimeCallInfo * info)1393 JSTaggedValue BuiltinsArkTools::IterateFrame(EcmaRuntimeCallInfo *info)
1394 {
1395 ASSERT(info);
1396 JSThread *thread = info->GetThread();
1397 RETURN_IF_DISALLOW_ARKTOOLS(thread);
1398 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1399
1400 JSTaggedType *currentFrame = const_cast<JSTaggedType *>(thread->GetCurrentFrame());
1401 RootVisitor visitor = []([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot slot) {};
1402 RootBaseAndDerivedVisitor derivedVisitor = []([[maybe_unused]] Root Type, [[maybe_unused]] ObjectSlot base,
1403 [[maybe_unused]] ObjectSlot derived,
1404 [[maybe_unused]] uintptr_t baseOldObject) {};
1405
1406 for (FrameIterator it(currentFrame, thread); !it.Done(); it.Advance<GCVisitedFlag::VISITED>()) {
1407 bool ret = it.IteratorStackMap(visitor, derivedVisitor);
1408 FrameType type = it.GetFrameType();
1409 int delta = it.ComputeDelta();
1410 kungfu::CalleeRegAndOffsetVec calleeRegInfo;
1411 it.GetCalleeRegAndOffsetVec(calleeRegInfo);
1412 LOG_BUILTINS(INFO) << "IterateFrameType: " << (int)type;
1413 LOG_BUILTINS(INFO) << "IterateFrameDelta: " << delta;
1414 LOG_BUILTINS(INFO) << "IterateFrameCalleeRegInfo: " << calleeRegInfo.size();
1415 if (!ret) {
1416 break;
1417 }
1418 }
1419
1420 for (FrameIterator it(currentFrame, thread); !it.Done(); it.Advance<GCVisitedFlag::DEOPT>()) {
1421 FrameType type = it.GetFrameType();
1422 int delta = it.ComputeDelta();
1423 kungfu::CalleeRegAndOffsetVec calleeRegInfo;
1424 it.GetCalleeRegAndOffsetVec(calleeRegInfo);
1425 LOG_BUILTINS(INFO) << "DeoptIterateFrameType: " << (int)type;
1426 LOG_BUILTINS(INFO) << "DeoptIterateFrameDelta: " << delta;
1427 LOG_BUILTINS(INFO) << "DeoptIterateFrameCalleeRegInfo: " << calleeRegInfo.size();
1428 }
1429
1430 return JSTaggedValue::Undefined();
1431 }
1432 } // namespace panda::ecmascript::builtins
1433