14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_OBJECT_FACTORY_INL_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_OBJECT_FACTORY_INL_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include "ecmascript/global_env_constants-inl.h"
204514f5e3Sopenharmony_ci#include "ecmascript/global_env_constants.h"
214514f5e3Sopenharmony_ci#include "ecmascript/js_hclass-inl.h"
224514f5e3Sopenharmony_ci#include "ecmascript/js_thread.h"
234514f5e3Sopenharmony_ci#include "ecmascript/lexical_env.h"
244514f5e3Sopenharmony_ci#include "ecmascript/mem/heap-inl.h"
254514f5e3Sopenharmony_ci#include "ecmascript/mem/barriers-inl.h"
264514f5e3Sopenharmony_ci#include "ecmascript/mem/space.h"
274514f5e3Sopenharmony_ci#include "ecmascript/object_factory.h"
284514f5e3Sopenharmony_ci#include "ecmascript/tagged_array-inl.h"
294514f5e3Sopenharmony_ci
304514f5e3Sopenharmony_cinamespace panda::ecmascript {
314514f5e3Sopenharmony_ciEcmaString *ObjectFactory::AllocLineStringObjectNoGC(size_t size)
324514f5e3Sopenharmony_ci{
334514f5e3Sopenharmony_ci    TaggedObject *object = nullptr;
344514f5e3Sopenharmony_ci    if (size > MAX_REGULAR_HEAP_OBJECT_SIZE) {
354514f5e3Sopenharmony_ci        object = reinterpret_cast<TaggedObject *>(sHeap_->GetHugeObjectSpace()->Allocate(thread_, size));
364514f5e3Sopenharmony_ci    } else {
374514f5e3Sopenharmony_ci        object = reinterpret_cast<TaggedObject *>(sHeap_->GetOldSpace()->TryAllocateAndExpand(thread_, size, true));
384514f5e3Sopenharmony_ci    }
394514f5e3Sopenharmony_ci    if (object == nullptr) {
404514f5e3Sopenharmony_ci        LOG_ECMA(FATAL) << "Alloc size " << size << " bytes string fail";
414514f5e3Sopenharmony_ci        UNREACHABLE();
424514f5e3Sopenharmony_ci    }
434514f5e3Sopenharmony_ci    object->SetClass(thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()));
444514f5e3Sopenharmony_ci    return EcmaString::Cast(object);
454514f5e3Sopenharmony_ci}
464514f5e3Sopenharmony_ci
474514f5e3Sopenharmony_ciEcmaString *ObjectFactory::AllocNonMovableLineStringObject(size_t size)
484514f5e3Sopenharmony_ci{
494514f5e3Sopenharmony_ci    NewSObjectHook();
504514f5e3Sopenharmony_ci    return reinterpret_cast<EcmaString *>(sHeap_->AllocateNonMovableOrHugeObject(
514514f5e3Sopenharmony_ci        thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()), size));
524514f5e3Sopenharmony_ci}
534514f5e3Sopenharmony_ci
544514f5e3Sopenharmony_ciEcmaString *ObjectFactory::AllocLineStringObject(size_t size)
554514f5e3Sopenharmony_ci{
564514f5e3Sopenharmony_ci    NewSObjectHook();
574514f5e3Sopenharmony_ci    return reinterpret_cast<EcmaString *>(sHeap_->AllocateOldOrHugeObject(
584514f5e3Sopenharmony_ci        thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()), size));
594514f5e3Sopenharmony_ci}
604514f5e3Sopenharmony_ci
614514f5e3Sopenharmony_ciEcmaString *ObjectFactory::AllocOldSpaceLineStringObject(size_t size)
624514f5e3Sopenharmony_ci{
634514f5e3Sopenharmony_ci    NewSObjectHook();
644514f5e3Sopenharmony_ci    return reinterpret_cast<EcmaString *>(sHeap_->AllocateOldOrHugeObject(
654514f5e3Sopenharmony_ci        thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()), size));
664514f5e3Sopenharmony_ci}
674514f5e3Sopenharmony_ci
684514f5e3Sopenharmony_ciEcmaString *ObjectFactory::AllocReadOnlyLineStringObject(size_t size)
694514f5e3Sopenharmony_ci{
704514f5e3Sopenharmony_ci    NewSObjectHook();
714514f5e3Sopenharmony_ci    return reinterpret_cast<EcmaString *>(sHeap_->AllocateReadOnlyOrHugeObject(
724514f5e3Sopenharmony_ci        thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()), size));
734514f5e3Sopenharmony_ci}
744514f5e3Sopenharmony_ci
754514f5e3Sopenharmony_ciEcmaString *ObjectFactory::AllocSlicedStringObject(MemSpaceType type)
764514f5e3Sopenharmony_ci{
774514f5e3Sopenharmony_ci    ASSERT(IsSMemSpace(type));
784514f5e3Sopenharmony_ci    NewSObjectHook();
794514f5e3Sopenharmony_ci    return reinterpret_cast<EcmaString *>(AllocObjectWithSpaceType(SlicedString::SIZE,
804514f5e3Sopenharmony_ci        JSHClass::Cast(thread_->GlobalConstants()->GetSlicedStringClass().GetTaggedObject()), type));
814514f5e3Sopenharmony_ci}
824514f5e3Sopenharmony_ci
834514f5e3Sopenharmony_ciEcmaString *ObjectFactory::AllocConstantStringObject(MemSpaceType type)
844514f5e3Sopenharmony_ci{
854514f5e3Sopenharmony_ci    ASSERT(IsSMemSpace(type));
864514f5e3Sopenharmony_ci    NewSObjectHook();
874514f5e3Sopenharmony_ci    return reinterpret_cast<EcmaString *>(AllocObjectWithSpaceType(ConstantString::SIZE,
884514f5e3Sopenharmony_ci        JSHClass::Cast(thread_->GlobalConstants()->GetConstantStringClass().GetTaggedObject()), type));
894514f5e3Sopenharmony_ci}
904514f5e3Sopenharmony_ci
914514f5e3Sopenharmony_ciEcmaString *ObjectFactory::AllocTreeStringObject()
924514f5e3Sopenharmony_ci{
934514f5e3Sopenharmony_ci    NewSObjectHook();
944514f5e3Sopenharmony_ci    return reinterpret_cast<EcmaString *>(sHeap_->AllocateOldOrHugeObject(
954514f5e3Sopenharmony_ci        thread_, JSHClass::Cast(thread_->GlobalConstants()->GetTreeStringClass().GetTaggedObject()),
964514f5e3Sopenharmony_ci        TreeEcmaString::SIZE));
974514f5e3Sopenharmony_ci}
984514f5e3Sopenharmony_ci
994514f5e3Sopenharmony_ciJSHandle<JSNativePointer> ObjectFactory::NewJSNativePointer(void *externalPointer,
1004514f5e3Sopenharmony_ci                                                            const NativePointerCallback &callBack,
1014514f5e3Sopenharmony_ci                                                            void *data,
1024514f5e3Sopenharmony_ci                                                            bool nonMovable,
1034514f5e3Sopenharmony_ci                                                            size_t nativeBindingsize,
1044514f5e3Sopenharmony_ci                                                            Concurrent isConcurrent,
1054514f5e3Sopenharmony_ci                                                            NativeFlag flag)
1064514f5e3Sopenharmony_ci{
1074514f5e3Sopenharmony_ci    NewObjectHook();
1084514f5e3Sopenharmony_ci    TaggedObject *header;
1094514f5e3Sopenharmony_ci    auto jsNativePointerClass = JSHClass::Cast(thread_->GlobalConstants()->GetJSNativePointerClass().GetTaggedObject());
1104514f5e3Sopenharmony_ci    if (nonMovable) {
1114514f5e3Sopenharmony_ci        header = heap_->AllocateNonMovableOrHugeObject(jsNativePointerClass);
1124514f5e3Sopenharmony_ci    } else {
1134514f5e3Sopenharmony_ci        header = heap_->AllocateOldOrHugeObject(jsNativePointerClass);
1144514f5e3Sopenharmony_ci    }
1154514f5e3Sopenharmony_ci    JSHandle<JSNativePointer> obj(thread_, header);
1164514f5e3Sopenharmony_ci    obj->SetExternalPointer(externalPointer);
1174514f5e3Sopenharmony_ci    obj->SetDeleter(callBack);
1184514f5e3Sopenharmony_ci    obj->SetData(data);
1194514f5e3Sopenharmony_ci    uint32_t fixedNativeBindingsize = nativeBindingsize < UINT32_MAX ? nativeBindingsize
1204514f5e3Sopenharmony_ci                                                                     : UINT32_MAX;
1214514f5e3Sopenharmony_ci    obj->SetBindingSize(fixedNativeBindingsize);
1224514f5e3Sopenharmony_ci    obj->SetNativeFlag(flag);
1234514f5e3Sopenharmony_ci
1244514f5e3Sopenharmony_ci    heap_->IncreaseNativeBindingSize(fixedNativeBindingsize);
1254514f5e3Sopenharmony_ci    if (callBack != nullptr) {
1264514f5e3Sopenharmony_ci        vm_->PushToNativePointerList(static_cast<JSNativePointer *>(header), isConcurrent);
1274514f5e3Sopenharmony_ci        // In some cases, the size of JS/TS object is too small and the native binding size is too large.
1284514f5e3Sopenharmony_ci        // Check and try trigger concurrent mark here.
1294514f5e3Sopenharmony_ci        heap_->TryTriggerFullMarkOrGCByNativeSize();
1304514f5e3Sopenharmony_ci    }
1314514f5e3Sopenharmony_ci    return obj;
1324514f5e3Sopenharmony_ci}
1334514f5e3Sopenharmony_ci
1344514f5e3Sopenharmony_ciLexicalEnv *ObjectFactory::InlineNewLexicalEnv(int numSlots)
1354514f5e3Sopenharmony_ci{
1364514f5e3Sopenharmony_ci    NewObjectHook();
1374514f5e3Sopenharmony_ci    size_t size = LexicalEnv::ComputeSize(numSlots);
1384514f5e3Sopenharmony_ci    auto header = heap_->TryAllocateYoungGeneration(
1394514f5e3Sopenharmony_ci        JSHClass::Cast(thread_->GlobalConstants()->GetEnvClass().GetTaggedObject()), size);
1404514f5e3Sopenharmony_ci    if (UNLIKELY(header == nullptr)) {
1414514f5e3Sopenharmony_ci        return nullptr;
1424514f5e3Sopenharmony_ci    }
1434514f5e3Sopenharmony_ci    LexicalEnv *array = LexicalEnv::Cast(header);
1444514f5e3Sopenharmony_ci    array->InitializeWithSpecialValue(JSTaggedValue::Hole(), numSlots + LexicalEnv::RESERVED_ENV_LENGTH);
1454514f5e3Sopenharmony_ci    return array;
1464514f5e3Sopenharmony_ci}
1474514f5e3Sopenharmony_ci
1484514f5e3Sopenharmony_citemplate<typename T, typename S>
1494514f5e3Sopenharmony_civoid ObjectFactory::NewJSIntlIcuData(const JSHandle<T> &obj, const S &icu, const NativePointerCallback &callback)
1504514f5e3Sopenharmony_ci{
1514514f5e3Sopenharmony_ci    S *icuPoint = vm_->GetNativeAreaAllocator()->New<S>(icu);
1524514f5e3Sopenharmony_ci    ASSERT(icuPoint != nullptr);
1534514f5e3Sopenharmony_ci    JSTaggedValue data = obj->GetIcuField();
1544514f5e3Sopenharmony_ci    if (data.IsHeapObject() && data.IsJSNativePointer()) {
1554514f5e3Sopenharmony_ci        JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject());
1564514f5e3Sopenharmony_ci        native->ResetExternalPointer(thread_, icuPoint);
1574514f5e3Sopenharmony_ci        return;
1584514f5e3Sopenharmony_ci    }
1594514f5e3Sopenharmony_ci    JSHandle<JSNativePointer> pointer = NewJSNativePointer(icuPoint, callback, vm_);
1604514f5e3Sopenharmony_ci    obj->SetIcuField(thread_, pointer.GetTaggedValue());
1614514f5e3Sopenharmony_ci}
1624514f5e3Sopenharmony_ci
1634514f5e3Sopenharmony_ciTaggedObject *ObjectFactory::AllocObjectWithSpaceType(size_t size, JSHClass *cls, MemSpaceType type)
1644514f5e3Sopenharmony_ci{
1654514f5e3Sopenharmony_ci    switch (type) {
1664514f5e3Sopenharmony_ci        case MemSpaceType::SEMI_SPACE:
1674514f5e3Sopenharmony_ci            return heap_->AllocateYoungOrHugeObject(cls, size);
1684514f5e3Sopenharmony_ci        case MemSpaceType::OLD_SPACE:
1694514f5e3Sopenharmony_ci            return heap_->AllocateOldOrHugeObject(cls, size);
1704514f5e3Sopenharmony_ci        case MemSpaceType::NON_MOVABLE:
1714514f5e3Sopenharmony_ci            return heap_->AllocateNonMovableOrHugeObject(cls, size);
1724514f5e3Sopenharmony_ci        case MemSpaceType::SHARED_OLD_SPACE:
1734514f5e3Sopenharmony_ci            return sHeap_->AllocateOldOrHugeObject(thread_, cls, size);
1744514f5e3Sopenharmony_ci        case MemSpaceType::SHARED_NON_MOVABLE:
1754514f5e3Sopenharmony_ci            return sHeap_->AllocateNonMovableOrHugeObject(thread_, cls, size);
1764514f5e3Sopenharmony_ci        default:
1774514f5e3Sopenharmony_ci            LOG_ECMA(FATAL) << "this branch is unreachable";
1784514f5e3Sopenharmony_ci            UNREACHABLE();
1794514f5e3Sopenharmony_ci    }
1804514f5e3Sopenharmony_ci}
1814514f5e3Sopenharmony_ci}  // namespace panda::ecmascript
1824514f5e3Sopenharmony_ci#endif  // ECMASCRIPT_OBJECT_FACTORY_INL_H
183