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