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