• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "common_interfaces/objects/base_class.h"
17 #include "common_interfaces/objects/composite_base_class.h"
18 #include "ecmascript/jspandafile/program_object.h"
19 #include "ecmascript/layout_info-inl.h"
20 #include "ecmascript/lexical_env.h"
21 #include "ecmascript/mem/heap-inl.h"
22 #include "ecmascript/symbol_table.h"
23 #include "ecmascript/jspandafile/program_object.h"
24 
25 // class Object;
26 namespace panda::ecmascript {
NewSObjectHook() const27 void ObjectFactory::NewSObjectHook() const
28 {
29     CHECK_NO_HEAP_ALLOC;
30 #ifndef NDEBUG
31     static std::atomic<uint32_t> count = 0;
32     static uint32_t frequency = vm_->GetJSOptions().GetForceSharedGCFrequency();
33     static constexpr uint32_t CONCURRENT_MARK_FREQUENCY_FACTOR = 2;
34     if (frequency == 0 || !vm_->GetJSOptions().EnableForceGC() || !vm_->IsInitialized() ||
35         thread_->InGlobalEnvInitialize() || !Runtime::GetInstance()->SharedConstInited()) {
36         return;
37     }
38     if (g_isEnableCMCGC) {
39         common::BaseRuntime::RequestGC(common::GC_REASON_USER, true, common::GC_TYPE_FULL);
40     } else {
41         if (count++ % frequency == 0) {
42             if (count % (CONCURRENT_MARK_FREQUENCY_FACTOR * frequency) == 0) {
43                 sHeap_->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::OTHER>(thread_);
44             } else if (sHeap_->CheckCanTriggerConcurrentMarking(thread_)) {
45                 sHeap_->TriggerConcurrentMarking<TriggerGCType::SHARED_GC, MarkReason::OTHER>(thread_);
46             }
47             if (!ecmascript::AnFileDataManager::GetInstance()->IsEnable()) {
48                 if (count % (CONCURRENT_MARK_FREQUENCY_FACTOR * frequency) == 0) {
49                     sHeap_->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::OTHER>(thread_);
50                 } else if (sHeap_->CheckCanTriggerConcurrentMarking(thread_)) {
51                     sHeap_->TriggerConcurrentMarking<TriggerGCType::SHARED_GC, MarkReason::OTHER>(thread_);
52                 }
53                 if (!ecmascript::AnFileDataManager::GetInstance()->IsEnable()) {
54                     if (count % (CONCURRENT_MARK_FREQUENCY_FACTOR * frequency) == 0) {
55                         sHeap_->WaitGCFinished(thread_);
56                         sHeap_->CollectGarbage<TriggerGCType::SHARED_FULL_GC, GCReason::OTHER>(thread_);
57                     } else if (sHeap_->CheckCanTriggerConcurrentMarking(thread_)) {
58                         sHeap_->TriggerConcurrentMarking<TriggerGCType::SHARED_PARTIAL_GC, MarkReason::OTHER>(thread_);
59                     }
60                 }
61             }
62         }
63     }
64 #endif
65 }
66 
CreateSFunctionClass(uint32_t size,JSType type,const JSHandle<JSTaggedValue> & prototype,bool isAccessor,bool setProto)67 JSHandle<JSHClass> ObjectFactory::CreateSFunctionClass(uint32_t size, JSType type,
68                                                        const JSHandle<JSTaggedValue> &prototype,
69                                                        bool isAccessor, bool setProto)
70 {
71     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
72     uint32_t fieldOrder = 0;
73     ASSERT(JSFunction::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
74     PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
75     attributes.SetIsAccessor(isAccessor);
76     attributes.SetIsInlinedProps(true);
77     attributes.SetRepresentation(Representation::TAGGED);
78     JSHandle<LayoutInfo> layoutInfoHandle = CreateSLayoutInfo(JSFunction::LENGTH_OF_INLINE_PROPERTIES);
79     {
80         attributes.SetOffset(fieldOrder);
81         layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetLengthString(), attributes);
82         fieldOrder++;
83     }
84 
85     ASSERT(JSFunction::NAME_INLINE_PROPERTY_INDEX == fieldOrder);
86     {
87         attributes.SetOffset(fieldOrder);
88         layoutInfoHandle->AddKey(thread_, fieldOrder,
89                                  globalConst->GetHandledNameString().GetTaggedValue(), attributes);
90         fieldOrder++;
91     }
92     if (setProto) {
93         ASSERT(JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX == fieldOrder);
94         {
95             attributes.SetOffset(fieldOrder);
96             layoutInfoHandle->AddKey(thread_, fieldOrder,
97                                      globalConst->GetPrototypeString(), attributes);
98             fieldOrder++;
99         }
100     }
101     JSHandle<JSHClass> functionClass = NewSEcmaHClass(size, fieldOrder, type, prototype,
102         JSHandle<JSTaggedValue>(layoutInfoHandle));
103     functionClass->SetCallable(true);
104     return functionClass;
105 }
106 
NewSEcmaHClass(uint32_t size,JSType type,uint32_t inlinedProps)107 JSHandle<JSHClass> ObjectFactory::NewSEcmaHClass(uint32_t size, JSType type, uint32_t inlinedProps)
108 {
109     return NewSEcmaHClass(JSHClass::Cast(thread_->GlobalConstants()->GetHClassClass().GetTaggedObject()),
110                           size, type, inlinedProps);
111 }
112 
NewSEcmaHClass(JSHClass * hclass,uint32_t size,JSType type,uint32_t inlinedProps)113 JSHandle<JSHClass> ObjectFactory::NewSEcmaHClass(JSHClass *hclass, uint32_t size, JSType type, uint32_t inlinedProps)
114 {
115     NewSObjectHook();
116     uint32_t classSize = JSHClass::SIZE;
117     auto *newClass = static_cast<JSHClass *>(sHeap_->AllocateNonMovableOrHugeObject(thread_, hclass, classSize));
118     newClass->Initialize(thread_, size, type, inlinedProps, thread_->GlobalConstants()->GetHandledEmptySLayoutInfo());
119     return JSHandle<JSHClass>(thread_, newClass);
120 }
121 
122 // This function don't UpdateProtoClass
NewSEcmaHClass(uint32_t size,uint32_t inlinedProps,JSType type,const JSHandle<JSTaggedValue> & prototype,const JSHandle<JSTaggedValue> & layout)123 JSHandle<JSHClass> ObjectFactory::NewSEcmaHClass(uint32_t size, uint32_t inlinedProps, JSType type,
124     const JSHandle<JSTaggedValue> &prototype, const JSHandle<JSTaggedValue> &layout)
125 {
126     NewSObjectHook();
127     uint32_t classSize = JSHClass::SIZE;
128     auto *newClass = static_cast<JSHClass *>(sHeap_->AllocateNonMovableOrHugeObject(
129         thread_, JSHClass::Cast(thread_->GlobalConstants()->GetHClassClass().GetTaggedObject()), classSize));
130     newClass->Initialize(thread_, size, type, inlinedProps, layout);
131     JSHandle<JSHClass> hclass(thread_, newClass);
132     if (prototype->IsJSObject()) {
133         prototype->GetTaggedObject()->GetClass()->SetIsPrototype(true);
134     }
135     hclass->SetProto(thread_, prototype.GetTaggedValue());
136     hclass->SetNumberOfProps(inlinedProps);
137     hclass->SetExtensible(false);
138     return hclass;
139 }
140 
NewSEcmaHClassDictMode(uint32_t size,uint32_t inlinedProps,JSType type,const JSHandle<JSTaggedValue> & prototype)141 JSHandle<JSHClass> ObjectFactory::NewSEcmaHClassDictMode(uint32_t size, uint32_t inlinedProps, JSType type,
142                                                          const JSHandle<JSTaggedValue> &prototype)
143 {
144     NewSObjectHook();
145     uint32_t classSize = JSHClass::SIZE;
146     auto *newClass = static_cast<JSHClass *>(sHeap_->AllocateNonMovableOrHugeObject(thread_,
147         JSHClass::Cast(thread_->GlobalConstants()->GetHClassClass().GetTaggedObject()), classSize));
148     newClass->Initialize(thread_, size, type, inlinedProps, thread_->GlobalConstants()->GetHandledEmptySLayoutInfo());
149     JSHandle<JSHClass> hclass(thread_, newClass);
150     if (prototype->IsJSObject()) {
151         prototype->GetTaggedObject()->GetClass()->SetIsPrototype(true);
152     }
153     hclass->SetProto(thread_, prototype.GetTaggedValue());
154     hclass->SetNumberOfProps(0);
155     hclass->SetIsDictionaryMode(true);
156     hclass->SetExtensible(false);
157     return hclass;
158 }
159 
NewSEcmaHClassClass(JSHClass * hclass,uint32_t size,JSType type)160 JSHandle<JSHClass> ObjectFactory::NewSEcmaHClassClass(JSHClass *hclass, uint32_t size, JSType type)
161 {
162     NewSObjectHook();
163     uint32_t classSize = JSHClass::SIZE;
164     auto *newClass = static_cast<JSHClass *>(sHeap_->AllocateClassClass(thread_, hclass, classSize));
165     newClass->Initialize(thread_, size, type, 0, thread_->GlobalConstants()->GetHandledEmptySLayoutInfo());
166     return JSHandle<JSHClass>(thread_, newClass);
167 }
168 
NewSEcmaReadOnlyHClass(JSHClass * hclass,uint32_t size,JSType type,uint32_t inlinedProps)169 JSHandle<JSHClass> ObjectFactory::NewSEcmaReadOnlyHClass(JSHClass *hclass, uint32_t size, JSType type,
170                                                          uint32_t inlinedProps)
171 {
172     NewSObjectHook();
173     uint32_t classSize = JSHClass::SIZE;
174     auto *newClass = static_cast<JSHClass *>(sHeap_->AllocateReadOnlyOrHugeObject(thread_, hclass, classSize));
175     ASSERT(newClass != nullptr);
176     newClass->Initialize(thread_, size, type, inlinedProps, thread_->GlobalConstants()->GetHandledEmptySLayoutInfo());
177     return JSHandle<JSHClass>(thread_, newClass);
178 }
179 
NewSEcmaReadOnlySharedHClass(JSHClass * hclass,uint32_t size,JSType type,uint32_t inlinedProps)180 JSHandle<JSHClass> ObjectFactory::NewSEcmaReadOnlySharedHClass(JSHClass *hclass, uint32_t size, JSType type,
181                                                                uint32_t inlinedProps)
182 {
183     JSHandle<JSHClass> newClass = NewSEcmaReadOnlyHClass(hclass, size, type, inlinedProps);
184     newClass->SetIsJSShared(true);
185     ASSERT(newClass->IsInSharedHeap());
186     return newClass;
187 }
188 
InitHClassInCompositeBaseClass(JSHClass * hclass,common::CommonType type)189 JSTaggedValue ObjectFactory::InitHClassInCompositeBaseClass(JSHClass* hclass, common::CommonType type)
190 {
191     common::BaseClassRoots& classRoots = common::BaseRuntime::GetInstance()->GetBaseClassRoots();
192     auto* newClass = reinterpret_cast<JSHClass*>(classRoots.GetBaseClass(type));
193     newClass->SetClassWithoutBarrier(hclass);
194     newClass->SetObjectSize(0);
195     newClass->SetExtensible(true);
196     newClass->SetIsPrototype(false);
197     newClass->SetHasDeleteProperty(false);
198     newClass->SetIsAllTaggedProp(true);
199     newClass->SetElementsKind(ElementsKind::GENERIC);
200     newClass->SetConstructionCounter(0);
201     newClass->SetIsJSShared(true);
202     return JSTaggedValue(newClass);
203 }
204 
InitSClassClass()205 JSHandle<JSHClass> ObjectFactory::InitSClassClass()
206 {
207     JSHandle<JSHClass> hClassHandle = NewSEcmaHClassClass(nullptr, JSHClass::SIZE, JSType::HCLASS);
208     JSHClass *hclass = reinterpret_cast<JSHClass *>(hClassHandle.GetTaggedValue().GetTaggedObject());
209     hclass->SetClass(thread_, hclass);
210     return hClassHandle;
211 }
212 
NewSAccessorData()213 JSHandle<AccessorData> ObjectFactory::NewSAccessorData()
214 {
215     NewSObjectHook();
216     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(
217         thread_, JSHClass::Cast(thread_->GlobalConstants()->GetAccessorDataClass().GetTaggedObject()));
218     JSHandle<AccessorData> acc(thread_, AccessorData::Cast(header));
219     acc->SetGetter<SKIP_BARRIER>(thread_, JSTaggedValue::Undefined());
220     acc->SetSetter<SKIP_BARRIER>(thread_, JSTaggedValue::Undefined());
221     return acc;
222 }
223 
NewSMethod(const JSPandaFile * jsPandaFile,MethodLiteral * methodLiteral,JSHandle<ConstantPool> constpool,uint32_t entryIndex,bool needSetAotFlag,bool * canFastCall)224 JSHandle<Method> ObjectFactory::NewSMethod(const JSPandaFile *jsPandaFile, MethodLiteral *methodLiteral,
225                                            JSHandle<ConstantPool> constpool, uint32_t entryIndex,
226                                            bool needSetAotFlag, bool *canFastCall)
227 {
228     JSHandle<Method> method;
229     if (jsPandaFile->IsNewVersion()) {
230         method = Method::Create(thread_, jsPandaFile, methodLiteral);
231     } else {
232         method = NewSMethod(methodLiteral);
233         method->SetConstantPool(thread_, constpool);
234     }
235     if (needSetAotFlag) {
236         auto aotFileManager = thread_->GetEcmaVM()->GetAOTFileManager();
237         aotFileManager->SetAOTFuncEntry(jsPandaFile, nullptr, *method, entryIndex, canFastCall);
238     } else {
239         method->InitInterpreterStatusForCompiledMethod(thread_);
240     }
241     return method;
242 }
243 
NewSMethod(const MethodLiteral * methodLiteral,MemSpaceType spaceType)244 JSHandle<Method> ObjectFactory::NewSMethod(const MethodLiteral *methodLiteral, MemSpaceType spaceType)
245 {
246     ASSERT(spaceType == SHARED_READ_ONLY_SPACE ||
247            spaceType == SHARED_NON_MOVABLE ||
248            spaceType == SHARED_OLD_SPACE);
249     NewSObjectHook();
250     TaggedObject *header = nullptr;
251     if (spaceType == SHARED_READ_ONLY_SPACE) {
252         header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
253             JSHClass::Cast(thread_->GlobalConstants()->GetMethodClass().GetTaggedObject()));
254     } else if (spaceType == SHARED_NON_MOVABLE) {
255         header = sHeap_->AllocateNonMovableOrHugeObject(thread_,
256             JSHClass::Cast(thread_->GlobalConstants()->GetMethodClass().GetTaggedObject()));
257     } else {
258         header = sHeap_->AllocateOldOrHugeObject(thread_,
259             JSHClass::Cast(thread_->GlobalConstants()->GetMethodClass().GetTaggedObject()));
260     }
261     JSHandle<Method> method(thread_, header);
262     InitializeMethod(methodLiteral, method);
263     return method;
264 }
265 
NewSMethodForNativeFunction(const void * func,FunctionKind kind,kungfu::BuiltinsStubCSigns::ID builtinId,MemSpaceType spaceType)266 JSHandle<Method> ObjectFactory::NewSMethodForNativeFunction(const void *func, FunctionKind kind,
267                                                             kungfu::BuiltinsStubCSigns::ID builtinId,
268                                                             MemSpaceType spaceType)
269 {
270     uint32_t numArgs = 2;  // function object and this
271     auto method = NewSMethod(nullptr, spaceType);
272     method->SetNativePointer(const_cast<void *>(func));
273     method->SetNativeBit(true);
274     if (builtinId != BUILTINS_STUB_ID(INVALID)) {
275         bool isFast = kungfu::BuiltinsStubCSigns::IsFastBuiltin(builtinId);
276         method->SetFastBuiltinBit(isFast);
277         method->SetBuiltinId(static_cast<uint8_t>(builtinId));
278     }
279     method->SetNumArgsWithCallField(numArgs);
280     method->SetFunctionKind(kind);
281     return method;
282 }
283 
NewSFunctionByHClass(const JSHandle<Method> & method,const JSHandle<JSHClass> & hclass)284 JSHandle<JSFunction> ObjectFactory::NewSFunctionByHClass(const JSHandle<Method> &method,
285                                                          const JSHandle<JSHClass> &hclass)
286 {
287     JSHandle<JSFunction> function(NewSharedOldSpaceJSObject(hclass));
288     hclass->SetCallable(true);
289     JSFunction::InitializeSFunction(thread_, function, method->GetFunctionKind());
290     function->SetMethod(thread_, method);
291     function->SetTaskConcurrentFuncFlag(0); // 0 : default value
292     if (method->IsNativeWithCallField()) {
293         SetNativePointerToFunctionFromMethod(JSHandle<JSFunctionBase>::Cast(function), method);
294     } else if (method->IsAotWithCallField()) {
295         thread_->GetEcmaVM()->GetAOTFileManager()->
296             SetAOTFuncEntry(method->GetJSPandaFile(thread_), *function, *method);
297     } else {
298         SetCodeEntryToFunctionFromMethod(function, method);
299     }
300     return function;
301 }
302 
NewNativeSFunctionByHClass(const JSHandle<JSHClass> & hclass,const void * nativeFunc,FunctionKind kind)303 JSHandle<JSFunction> ObjectFactory::NewNativeSFunctionByHClass(const JSHandle<JSHClass> &hclass,
304                                                                const void *nativeFunc,
305                                                                FunctionKind kind)
306 {
307     JSHandle<JSFunction> function(NewSharedOldSpaceJSObject(hclass));
308     hclass->SetCallable(true);
309     JSFunction::InitializeSFunction(thread_, function, kind);
310     function->SetMethod(thread_, GetReadOnlyMethodForNativeFunction(kind));
311     function->SetNativePointer(const_cast<void *>(nativeFunc));
312     function->SetTaskConcurrentFuncFlag(0); // 0 : default value
313     return function;
314 }
315 
316 // new function with name/length accessor
NewSFunctionWithAccessor(const void * func,const JSHandle<JSHClass> & hclass,FunctionKind kind,kungfu::BuiltinsStubCSigns::ID builtinId,MemSpaceType spaceType)317 JSHandle<JSFunction> ObjectFactory::NewSFunctionWithAccessor(const void *func, const JSHandle<JSHClass> &hclass,
318     FunctionKind kind, kungfu::BuiltinsStubCSigns::ID builtinId, MemSpaceType spaceType)
319 {
320     ASSERT(spaceType == SHARED_NON_MOVABLE || spaceType == SHARED_OLD_SPACE);
321     if (builtinId != BUILTINS_STUB_ID(INVALID)) {
322         JSHandle<Method> method = NewSMethodForNativeFunction(func, kind, builtinId, spaceType);
323         return NewSFunctionByHClass(method, hclass);
324     }
325     return NewNativeSFunctionByHClass(hclass, func, kind);
326 }
327 
328 // new function without name/length accessor
NewSFunctionByHClass(const void * func,const JSHandle<JSHClass> & hclass,FunctionKind kind,kungfu::BuiltinsStubCSigns::ID builtinId,MemSpaceType spaceType)329 JSHandle<JSFunction> ObjectFactory::NewSFunctionByHClass(const void *func, const JSHandle<JSHClass> &hclass,
330     FunctionKind kind, kungfu::BuiltinsStubCSigns::ID builtinId, MemSpaceType spaceType)
331 {
332     ASSERT(spaceType == SHARED_NON_MOVABLE || spaceType == SHARED_OLD_SPACE);
333     JSHandle<JSFunction> function(NewSharedOldSpaceJSObject(hclass));
334     hclass->SetCallable(true);
335     JSFunction::InitializeWithDefaultValue(thread_, function);
336     if (builtinId != BUILTINS_STUB_ID(INVALID)) {
337         JSHandle<Method> method = NewSMethodForNativeFunction(func, kind, builtinId, spaceType);
338         function->SetMethod(thread_, method);
339     } else {
340         function->SetMethod(thread_, GetReadOnlyMethodForNativeFunction(kind));
341     }
342     function->SetNativePointer(const_cast<void *>(func));
343     return function;
344 }
345 
NewSharedOldSpaceObject(const JSHandle<JSHClass> & hclass)346 TaggedObject *ObjectFactory::NewSharedOldSpaceObject(const JSHandle<JSHClass> &hclass)
347 {
348     NewSObjectHook();
349     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_, *hclass);
350     if (header == nullptr) {
351         LOG_ECMA(FATAL) << "ObjectFactory::NewSharedOldSpaceObject:header is nullptr";
352     }
353     uint32_t inobjPropCount = hclass->GetInlinedProperties();
354     if (inobjPropCount > 0) {
355         InitializeExtraProperties(hclass, header, inobjPropCount);
356     }
357     return header;
358 }
359 
NewSharedOldSpaceJSObjectWithInit(const JSHandle<JSHClass> & jshclass)360 JSHandle<JSObject> ObjectFactory::NewSharedOldSpaceJSObjectWithInit(const JSHandle<JSHClass> &jshclass)
361 {
362     auto obj = NewSharedOldSpaceJSObject(jshclass);
363     InitializeJSObject(obj, jshclass);
364     return obj;
365 }
366 
NewSharedOldSpaceJSObject(const JSHandle<JSHClass> & jshclass)367 JSHandle<JSObject> ObjectFactory::NewSharedOldSpaceJSObject(const JSHandle<JSHClass> &jshclass)
368 {
369     JSHandle<JSObject> obj(thread_, JSObject::Cast(NewSharedOldSpaceObject(jshclass)));
370     JSHandle<TaggedArray> emptyArray = SharedEmptyArray();
371     obj->InitializeHash();
372     obj->SetElements(thread_, emptyArray);
373     obj->SetProperties(thread_, emptyArray);
374     return obj;
375 }
376 
CreateSObjectWithProperties(std::vector<PropertyDescriptor> & descs)377 JSHandle<JSTaggedValue> ObjectFactory::CreateSObjectWithProperties(std::vector<PropertyDescriptor> &descs)
378 {
379     JSHandle<JSHClass> hclass = JSHClass::CreateSHClass(thread_, descs);
380     JSHandle<JSObject> object = NewSharedOldSpaceJSObject(hclass);
381     JSObject::SetSProperties(thread_, object, descs);
382     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
383     JSHandle<JSTaggedValue> objFuncProto = env->GetSObjectFunctionPrototype();
384     hclass->SetPrototype(thread_, objFuncProto);
385     hclass->SetExtensible(false);
386     return JSHandle<JSTaggedValue>(object);
387 }
388 
SharedEmptyArray() const389 JSHandle<TaggedArray> ObjectFactory::SharedEmptyArray() const
390 {
391     return JSHandle<TaggedArray>(thread_->GlobalConstants()->GetHandledEmptyArray());
392 }
393 
NewEmptySFunctionEnv()394 JSHandle<SFunctionEnv> ObjectFactory::NewEmptySFunctionEnv()
395 {
396     NewObjectHook();
397     size_t size = SFunctionEnv::ComputeSize(0);
398     auto header = sHeap_->AllocateNonMovableOrHugeObject(thread_,
399         JSHClass::Cast(thread_->GlobalConstants()->GetSFunctionEnvClass().GetTaggedObject()), size);
400     JSHandle<SFunctionEnv> array(thread_, header);
401     array->InitializeWithSpecialValue(JSTaggedValue::Hole(), SFunctionEnv::RESERVED_ENV_LENGTH);
402     return array;
403 }
404 
NewSFunctionEnv(int numSlots)405 JSHandle<SFunctionEnv> ObjectFactory::NewSFunctionEnv(int numSlots)
406 {
407     NewObjectHook();
408     size_t size = SFunctionEnv::ComputeSize(numSlots);
409     auto header = sHeap_->AllocateOldOrHugeObject(thread_,
410         JSHClass::Cast(thread_->GlobalConstants()->GetSFunctionEnvClass().GetTaggedObject()), size);
411     JSHandle<SFunctionEnv> array(thread_, header);
412     array->InitializeWithSpecialValue(JSTaggedValue::Hole(), numSlots + SFunctionEnv::RESERVED_ENV_LENGTH);
413     return array;
414 }
415 
CopySArray(const JSHandle<TaggedArray> & old,uint32_t oldLength,uint32_t newLength,JSTaggedValue initVal,ElementsKind kind)416 JSHandle<TaggedArray> ObjectFactory::CopySArray(const JSHandle<TaggedArray> &old, uint32_t oldLength,
417                                                 uint32_t newLength, JSTaggedValue initVal, ElementsKind kind)
418 {
419     if (newLength == 0) {
420         return SharedEmptyArray();
421     }
422     if (newLength > oldLength) {
423         return ExtendSArray(old, newLength, initVal, kind);
424     }
425 
426     NewObjectHook();
427     // Shared-array does not support Mutantarray yet.
428     ASSERT(!old->GetClass()->IsMutantTaggedArray());
429 
430     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
431     JSHClass *arrayClass = nullptr;
432     if (LIKELY(!g_isEnableCMCGC)) {
433         arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetTaggedArrayClass().GetTaggedObject());
434     } else {
435         arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetSharedTaggedArrayClass().GetTaggedObject());
436     }
437     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_, arrayClass, size);
438     JSHandle<TaggedArray> newArray(thread_, header);
439     newArray->SetLength(newLength);
440     newArray->SetExtraLength(old->GetExtraLength());
441 
442     for (uint32_t i = 0; i < newLength; i++) {
443         newArray->Set(thread_, i, old->Get(thread_, i));
444     }
445 
446     ASSERT(!g_isEnableCMCGC || newArray->IsInSharedHeap());
447     return newArray;
448 }
449 
ExtendSArray(const JSHandle<TaggedArray> & old,uint32_t length,JSTaggedValue initVal,ElementsKind kind)450 JSHandle<TaggedArray> ObjectFactory::ExtendSArray(const JSHandle<TaggedArray> &old, uint32_t length,
451                                                   JSTaggedValue initVal, [[maybe_unused]] ElementsKind kind)
452 {
453     ASSERT(length > old->GetLength());
454     NewObjectHook();
455     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
456     JSHClass *arrayClass = nullptr;
457     // Shared-array does not support Mutantarray yet.
458     ASSERT(!old->GetClass()->IsMutantTaggedArray());
459     if (LIKELY(!g_isEnableCMCGC)) {
460         arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetTaggedArrayClass().GetTaggedObject());
461     } else {
462         arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetSharedTaggedArrayClass().GetTaggedObject());
463     }
464 
465     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_, arrayClass, size);
466     JSHandle<TaggedArray> newArray(thread_, header);
467     newArray->SetLength(length);
468     newArray->SetExtraLength(old->GetExtraLength());
469 
470     uint32_t oldLength = old->GetLength();
471     for (uint32_t i = 0; i < oldLength; i++) {
472         newArray->Set(thread_, i, old->Get(thread_, i));
473     }
474     for (uint32_t i = oldLength; i < length; i++) {
475         newArray->Set(thread_, i, initVal);
476     }
477     ASSERT(!g_isEnableCMCGC || newArray->IsInSharedHeap());
478     return newArray;
479 }
480 
NewSTaggedArrayWithoutInit(uint32_t length,MemSpaceType spaceType)481 JSHandle<TaggedArray> ObjectFactory::NewSTaggedArrayWithoutInit(uint32_t length, MemSpaceType spaceType)
482 {
483     NewSObjectHook();
484     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
485     TaggedObject *header;
486     JSHClass *arrayClass = nullptr;
487     if (LIKELY(!g_isEnableCMCGC)) {
488         arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetTaggedArrayClass().GetTaggedObject());
489     } else {
490         arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetSharedTaggedArrayClass().GetTaggedObject());
491     }
492     switch (spaceType) {
493         case MemSpaceType::SHARED_OLD_SPACE:
494             header = sHeap_->AllocateOldOrHugeObject(thread_, arrayClass, size);
495             break;
496         case MemSpaceType::SHARED_READ_ONLY_SPACE:
497             header = sHeap_->AllocateReadOnlyOrHugeObject(thread_, arrayClass, size);
498             break;
499         default:
500             LOG_ECMA(FATAL) << "this branch is unreachable";
501             UNREACHABLE();
502     }
503     JSHandle<TaggedArray> array(thread_, header);
504     array->SetLength(length);
505     ASSERT(!g_isEnableCMCGC || array->IsInSharedHeap());
506     return array;
507 }
508 
CreateSLayoutInfo(uint32_t properties)509 JSHandle<LayoutInfo> ObjectFactory::CreateSLayoutInfo(uint32_t properties)
510 {
511     uint32_t arrayLength = LayoutInfo::ComputeArrayLength(properties);
512     JSHandle<LayoutInfo> layoutInfoHandle = JSHandle<LayoutInfo>::Cast(NewSTaggedArrayWithoutInit(arrayLength));
513     layoutInfoHandle->Initialize(thread_);
514     return layoutInfoHandle;
515 }
516 
NewSEmptyLayoutInfo()517 JSHandle<LayoutInfo> ObjectFactory::NewSEmptyLayoutInfo()
518 {
519     JSHandle<LayoutInfo> layoutInfoHandle = JSHandle<LayoutInfo>::Cast(
520         NewSTaggedArrayWithoutInit(0, MemSpaceType::SHARED_READ_ONLY_SPACE));
521     layoutInfoHandle->Initialize(thread_);
522     return layoutInfoHandle;
523 }
524 
NewJSSArray()525 JSHandle<JSSharedArray> ObjectFactory::NewJSSArray()
526 {
527     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
528     JSHandle<JSFunction> function(env->GetSharedArrayFunction());
529     return JSHandle<JSSharedArray>(NewJSObjectByConstructor(function));
530 }
531 
NewSJsonFixedArray(size_t start,size_t length,const std::vector<JSHandle<JSTaggedValue>> & vec)532 JSHandle<TaggedArray> ObjectFactory::NewSJsonFixedArray(size_t start, size_t length,
533                                                         const std::vector<JSHandle<JSTaggedValue>> &vec)
534 {
535     if (length == 0) {
536         return SharedEmptyArray();
537     }
538 
539     JSHandle<TaggedArray> array = NewTaggedArrayWithoutInit(length, MemSpaceType::SHARED_OLD_SPACE);
540     array->SetExtraLength(0);
541     for (size_t i = 0; i < length; i++) {
542         array->Set(thread_, i, vec[start + i]);
543     }
544     return array;
545 }
546 
CopyAndReSortSLayoutInfo(const JSHandle<LayoutInfo> & old,int end,int capacity)547 JSHandle<LayoutInfo> ObjectFactory::CopyAndReSortSLayoutInfo(const JSHandle<LayoutInfo> &old, int end, int capacity)
548 {
549     ASSERT(capacity >= end);
550     JSHandle<LayoutInfo> newArr = CreateSLayoutInfo(capacity);
551     Span<struct Properties> sp(old->GetProperties(), end);
552     void *propertiesObj = reinterpret_cast<void *>(old->GetProperties());
553     size_t keyOffset = 0;
554     size_t attrOffset = sizeof(JSTaggedType);
555     for (int i = 0; i < end; i++) {
556         JSTaggedValue propKey(Barriers::GetTaggedValue(thread_, ToUintPtr(propertiesObj) + i * sizeof(Properties) +
557                                                        keyOffset));
558         JSTaggedValue propValue(Barriers::GetTaggedValue(thread_, ToUintPtr(propertiesObj) + i * sizeof(Properties) +
559                                                          attrOffset));
560         sp[i].key_ = propKey;
561         sp[i].attr_ = propValue;
562         newArr->AddKey(thread_, i, sp[i].key_, PropertyAttributes(sp[i].attr_));
563     }
564     return newArr;
565 }
566 
NewSDictionaryArray(uint32_t length)567 JSHandle<TaggedArray> ObjectFactory::NewSDictionaryArray(uint32_t length)
568 {
569     NewSObjectHook();
570     ASSERT(length > 0);
571     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
572     TaggedObject *header = nullptr;
573     if (LIKELY(!g_isEnableCMCGC)) {
574         header = sHeap_->AllocateOldOrHugeObject(
575             thread_, JSHClass::Cast(thread_->GlobalConstants()->GetDictionaryClass().GetTaggedObject()), size);
576     } else {
577         header = sHeap_->AllocateOldOrHugeObject(
578             thread_, JSHClass::Cast(thread_->GlobalConstants()->GetSharedDictionaryClass().GetTaggedObject()), size);
579     }
580     JSHandle<TaggedArray> array(thread_, header);
581     array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length);
582     ASSERT(!g_isEnableCMCGC || array->IsInSharedHeap());
583     return array;
584 }
585 
NewSEmptyProfileTypeInfoCell()586 JSHandle<ProfileTypeInfoCell> ObjectFactory::NewSEmptyProfileTypeInfoCell()
587 {
588     NewSObjectHook();
589     auto header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
590         JSHClass::Cast(thread_->GlobalConstants()->GetProfileTypeInfoCell0Class().GetTaggedObject()));
591     JSHandle<ProfileTypeInfoCell> profileTypeInfoCell(thread_, header);
592     profileTypeInfoCell->SetValue<SKIP_BARRIER>(thread_, JSTaggedValue::Undefined());
593     profileTypeInfoCell->SetMachineCode<SKIP_BARRIER>(thread_, JSTaggedValue::Hole());
594     profileTypeInfoCell->SetHandle<SKIP_BARRIER>(thread_, JSTaggedValue::Undefined());
595     return profileTypeInfoCell;
596 }
597 
NewSEmptyNativeFunctionMethod(FunctionKind kind)598 JSHandle<Method> ObjectFactory::NewSEmptyNativeFunctionMethod(FunctionKind kind)
599 {
600     uint32_t numArgs = 2;  // function object and this
601     auto method = NewSMethod(nullptr, MemSpaceType::SHARED_READ_ONLY_SPACE);
602     method->SetNativeBit(true);
603     method->SetNumArgsWithCallField(numArgs);
604     method->SetFunctionKind(kind);
605     return method;
606 }
607 
NewSFunctionTemplate(const JSHandle<Method> & method,const JSHandle<JSTaggedValue> & module,int32_t length)608 JSHandle<FunctionTemplate> ObjectFactory::NewSFunctionTemplate(
609     const JSHandle<Method> &method, const JSHandle<JSTaggedValue> &module, int32_t length)
610 {
611     NewSObjectHook();
612     auto globalConstants = thread_->GlobalConstants();
613     auto header = sHeap_->AllocateOldOrHugeObject(thread_,
614         JSHClass::Cast(globalConstants->GetFunctionTemplateClass().GetTaggedObject()));
615     JSHandle<FunctionTemplate> functionTemplate(thread_, header);
616     functionTemplate->SetMethod(thread_, method);
617     functionTemplate->SetModule(thread_, module);
618     functionTemplate->SetRawProfileTypeInfo<SKIP_BARRIER>(thread_, globalConstants->GetEmptyProfileTypeInfoCell());
619     functionTemplate->SetLength(length);
620     return functionTemplate;
621 }
622 
NewSEmptyArray()623 JSHandle<TaggedArray> ObjectFactory::NewSEmptyArray()
624 {
625     NewSObjectHook();
626     TaggedObject *header = nullptr;
627     if (LIKELY(!g_isEnableCMCGC)) {
628         header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
629             JSHClass::Cast(thread_->GlobalConstants()->GetTaggedArrayClass().GetTaggedObject()), TaggedArray::SIZE);
630     } else {
631         header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
632             JSHClass::Cast(thread_->GlobalConstants()->GetSharedTaggedArrayClass().GetTaggedObject()),
633             TaggedArray::SIZE);
634     }
635     JSHandle<TaggedArray> array(thread_, header);
636     array->SetLength(0);
637     array->SetExtraLength(0);
638     ASSERT(!g_isEnableCMCGC || array->IsInSharedHeap());
639     return array;
640 }
641 
NewSEmptyMutantArray()642 JSHandle<MutantTaggedArray> ObjectFactory::NewSEmptyMutantArray()
643 {
644     NewSObjectHook();
645     TaggedObject *header = nullptr;
646     if (LIKELY(!g_isEnableCMCGC)) {
647         header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
648             JSHClass::Cast(thread_->GlobalConstants()->GetMutantTaggedArrayClass().GetTaggedObject()),
649             TaggedArray::SIZE);
650     } else {
651         header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
652             JSHClass::Cast(thread_->GlobalConstants()->GetSharedMutantTaggedArrayClass().GetTaggedObject()),
653             TaggedArray::SIZE);
654     }
655     JSHandle<MutantTaggedArray> array(thread_, header);
656     array->SetLength(0);
657     array->SetExtraLength(0);
658     ASSERT(!g_isEnableCMCGC || array->IsInSharedHeap());
659     return array;
660 }
661 
NewSJSNativePointer(void * externalPointer,const NativePointerCallback & callBack,void * data,bool nonMovable,size_t nativeBindingsize,NativeFlag flag)662 JSHandle<JSNativePointer> ObjectFactory::NewSJSNativePointer(void *externalPointer,
663                                                              const NativePointerCallback &callBack,
664                                                              void *data,
665                                                              bool nonMovable,
666                                                              size_t nativeBindingsize,
667                                                              NativeFlag flag)
668 {
669     NewSObjectHook();
670     TaggedObject *header;
671     auto jsNativePointerClass =
672         JSHClass::Cast(thread_->GlobalConstants()->GetSJSNativePointerClass().GetTaggedObject());
673     jsNativePointerClass->SetIsJSShared(true);
674     if (nonMovable) {
675         header = sHeap_->AllocateNonMovableOrHugeObject(thread_, jsNativePointerClass);
676     } else {
677         header = sHeap_->AllocateOldOrHugeObject(thread_, jsNativePointerClass);
678     }
679     JSHandle<JSNativePointer> obj(thread_, header);
680     obj->SetExternalPointer(externalPointer);
681     obj->SetDeleter(callBack);
682     obj->SetData(data);
683     uint32_t fixedNativeBindingsize = nativeBindingsize < UINT32_MAX ? nativeBindingsize
684                                                                      : UINT32_MAX;
685     obj->SetBindingSize(fixedNativeBindingsize);
686     obj->SetNativeFlag(flag);
687 
688     if (callBack != nullptr) {
689         sHeap_->IncNativeSizeAfterLastGC(fixedNativeBindingsize);
690         Runtime::GetInstance()->PushToSharedNativePointerList(static_cast<JSNativePointer *>(header));
691         // In some cases, the size of JS/TS object is too small and the native binding size is too large.
692         // Check and try trigger concurrent mark here.
693         size_t nativeSizeAfterLastGC = sHeap_->GetNativeSizeAfterLastGC();
694         if (nativeSizeAfterLastGC > sHeap_->GetNativeSizeTriggerSharedCM()) {
695             sHeap_->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::NATIVE_LIMIT>(thread_);
696         }
697     }
698     ASSERT(!g_isEnableCMCGC || obj->IsInSharedHeap());
699     return obj;
700 }
701 
NewSReadOnlyJSNativePointer(void * externalPointer)702 JSHandle<JSNativePointer> ObjectFactory::NewSReadOnlyJSNativePointer(void* externalPointer)
703 {
704     NewSObjectHook();
705     auto jsNativePointerClass =
706         JSHClass::Cast(thread_->GlobalConstants()->GetSJSNativePointerClass().GetTaggedObject());
707     jsNativePointerClass->SetIsJSShared(true);
708     TaggedObject* header = sHeap_->AllocateReadOnlyOrHugeObject(thread_, jsNativePointerClass);
709     JSHandle<JSNativePointer> obj(thread_, header);
710     obj->SetExternalPointer(externalPointer);
711     obj->SetDeleter(nullptr);
712     obj->SetData(nullptr);
713     obj->SetBindingSize(0U);
714     obj->SetNativeFlag(NativeFlag::NO_DIV);
715     ASSERT(!g_isEnableCMCGC || obj->IsInSharedHeap());
716     return obj;
717 }
718 
NewSInternalAccessor(void * setter,void * getter)719 JSHandle<AccessorData> ObjectFactory::NewSInternalAccessor(void *setter, void *getter)
720 {
721     NewSObjectHook();
722     TaggedObject *header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
723         JSHClass::Cast(thread_->GlobalConstants()->GetInternalAccessorClass().GetTaggedObject()));
724     JSHandle<InternalAccessor> obj(thread_, InternalAccessor::Cast(header));
725 
726     obj->SetSetter(reinterpret_cast<InternalAccessor::InternalSetFunc>(setter));
727     obj->SetGetter(reinterpret_cast<InternalAccessor::InternalGetFunc>(getter));
728     return JSHandle<AccessorData>::Cast(obj);
729 }
730 
NewSConstantPool(uint32_t capacity)731 JSHandle<ConstantPool> ObjectFactory::NewSConstantPool(uint32_t capacity)
732 {
733     NewSObjectHook();
734     size_t size = ConstantPool::ComputeSize(capacity);
735     TaggedObject *header = nullptr;
736     if (LIKELY(!g_isEnableCMCGC)) {
737         header = sHeap_->AllocateOldOrHugeObject(
738             thread_, JSHClass::Cast(sHeap_->GetGlobalConst()->GetConstantPoolClass().GetTaggedObject()), size);
739     } else {
740         header = sHeap_->AllocateOldOrHugeObject(
741             thread_, JSHClass::Cast(sHeap_->GetGlobalConst()->GetSharedConstantPoolClass().GetTaggedObject()), size);
742     }
743     JSHandle<ConstantPool> array(thread_, header);
744     array->InitializeWithSpecialValue(thread_, JSTaggedValue::Hole(), capacity);
745     ASSERT(!g_isEnableCMCGC || array->IsInSharedHeap());
746     return array;
747 }
748 
NewSCOWTaggedArray(uint32_t length,JSTaggedValue initVal)749 JSHandle<COWTaggedArray> ObjectFactory::NewSCOWTaggedArray(uint32_t length, JSTaggedValue initVal)
750 {
751     NewSObjectHook();
752     ASSERT(length > 0);
753 
754     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
755     TaggedObject *header = nullptr;
756     if (LIKELY(!g_isEnableCMCGC)) {
757         header = sHeap_->AllocateNonMovableOrHugeObject(
758             thread_, JSHClass::Cast(sHeap_->GetGlobalConst()->GetCOWArrayClass().GetTaggedObject()), size);
759     } else {
760         header = sHeap_->AllocateNonMovableOrHugeObject(
761             thread_, JSHClass::Cast(sHeap_->GetGlobalConst()->GetSharedCOWArrayClass().GetTaggedObject()), size);
762     }
763     JSHandle<COWTaggedArray> cowArray(thread_, header);
764     cowArray->InitializeWithSpecialValue(initVal, length);
765     ASSERT(!g_isEnableCMCGC || cowArray->IsInSharedHeap());
766     return cowArray;
767 }
768 
NewSClassLiteral()769 JSHandle<ClassLiteral> ObjectFactory::NewSClassLiteral()
770 {
771     NewSObjectHook();
772     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(
773         thread_, JSHClass::Cast(sHeap_->GetGlobalConst()->GetClassLiteralClass().GetTaggedObject()));
774     JSHandle<TaggedArray> emptyArray = EmptyArray();
775 
776     JSHandle<ClassLiteral> classLiteral(thread_, header);
777     classLiteral->SetArray(thread_, emptyArray);
778     classLiteral->SetIsAOTUsed(false);
779 
780     return classLiteral;
781 }
782 
NewSClassInfoExtractor(JSHandle<JSTaggedValue> method)783 JSHandle<ClassInfoExtractor> ObjectFactory::NewSClassInfoExtractor(
784     JSHandle<JSTaggedValue> method)
785 {
786     NewSObjectHook();
787     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(
788         thread_, JSHClass::Cast(sHeap_->GetGlobalConst()->GetClassInfoExtractorHClass().GetTaggedObject()));
789     JSHandle<ClassInfoExtractor> obj(thread_, header);
790     obj->ClearBitField();
791     obj->SetConstructorMethod(thread_, method.GetTaggedValue());
792     JSHandle<TaggedArray> emptyArray = EmptyArray();
793     obj->SetNonStaticKeys<SKIP_BARRIER>(thread_, emptyArray);
794     obj->SetNonStaticProperties<SKIP_BARRIER>(thread_, emptyArray);
795     obj->SetNonStaticElements<SKIP_BARRIER>(thread_, emptyArray);
796     obj->SetStaticKeys<SKIP_BARRIER>(thread_, emptyArray);
797     obj->SetStaticProperties<SKIP_BARRIER>(thread_, emptyArray);
798     obj->SetStaticElements<SKIP_BARRIER>(thread_, emptyArray);
799     return obj;
800 }
801 
NewSOldSpaceTaggedArray(uint32_t length,JSTaggedValue initVal)802 JSHandle<TaggedArray> ObjectFactory::NewSOldSpaceTaggedArray(uint32_t length, JSTaggedValue initVal)
803 {
804     return NewSTaggedArray(length, initVal, MemSpaceType::SHARED_OLD_SPACE);
805 }
806 
NewSTaggedArray(uint32_t length,JSTaggedValue initVal,MemSpaceType spaceType)807 JSHandle<TaggedArray> ObjectFactory::NewSTaggedArray(uint32_t length, JSTaggedValue initVal, MemSpaceType spaceType)
808 {
809     NewSObjectHook();
810     if (length == 0) {
811         return EmptyArray();
812     }
813 
814     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
815     TaggedObject *header = nullptr;
816     JSHClass *arrayClass = nullptr;
817     if (LIKELY(!g_isEnableCMCGC)) {
818         arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetTaggedArrayClass().GetTaggedObject());
819     } else {
820         arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetSharedTaggedArrayClass().GetTaggedObject());
821     }
822     switch (spaceType) {
823         case MemSpaceType::SHARED_OLD_SPACE:
824             header = sHeap_->AllocateOldOrHugeObject(thread_, arrayClass, size);
825             break;
826         case MemSpaceType::SHARED_NON_MOVABLE:
827             header = sHeap_->AllocateNonMovableOrHugeObject(thread_, arrayClass, size);
828             break;
829         default:
830             LOG_ECMA(FATAL) << "this branch is unreachable";
831             UNREACHABLE();
832     }
833 
834     JSHandle<TaggedArray> array(thread_, header);
835     array->InitializeWithSpecialValue(initVal, length);
836     ASSERT(!g_isEnableCMCGC || array->IsInSharedHeap());
837     return array;
838 }
839 
NewSWellKnownSymbol(const JSHandle<JSTaggedValue> & name)840 JSHandle<JSSymbol> ObjectFactory::NewSWellKnownSymbol(const JSHandle<JSTaggedValue> &name)
841 {
842     NewSObjectHook();
843     TaggedObject *header = sHeap_->AllocateNonMovableOrHugeObject(
844         thread_, JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
845     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
846     obj->SetFlags(0);
847     obj->SetWellKnownSymbol();
848     obj->SetDescription(thread_, name);
849     obj->SetHashField(SymbolTable::Hash(thread_, name.GetTaggedValue()));
850     return obj;
851 }
852 
NewSPublicSymbol(const JSHandle<JSTaggedValue> & name)853 JSHandle<JSSymbol> ObjectFactory::NewSPublicSymbol(const JSHandle<JSTaggedValue> &name)
854 {
855     NewObjectHook();
856     TaggedObject *header = sHeap_->AllocateNonMovableOrHugeObject(
857         thread_, JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
858     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
859     obj->SetFlags(0);
860     obj->SetDescription(thread_, name);
861     obj->SetHashField(SymbolTable::Hash(thread_, name.GetTaggedValue()));
862     return obj;
863 }
864 
NewSConstantPrivateSymbol()865 JSHandle<JSSymbol> ObjectFactory::NewSConstantPrivateSymbol()
866 {
867     NewObjectHook();
868     TaggedObject *header = sHeap_->AllocateReadOnlyOrHugeObject(
869         thread_, JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
870     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
871     obj->SetDescription<SKIP_BARRIER>(thread_, JSTaggedValue::Undefined());
872     obj->SetFlags(0);
873     obj->SetHashField(SymbolTable::Hash(thread_, obj.GetTaggedValue()));
874     obj->SetPrivate();
875     return obj;
876 }
877 
NewSEmptySymbol()878 JSHandle<JSSymbol> ObjectFactory::NewSEmptySymbol()
879 {
880     NewObjectHook();
881     TaggedObject *header = sHeap_->AllocateNonMovableOrHugeObject(
882         thread_, JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
883     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
884     obj->SetDescription<SKIP_BARRIER>(thread_, JSTaggedValue::Undefined());
885     obj->SetFlags(0);
886     obj->SetHashField(0);
887     return obj;
888 }
889 
NewSWellKnownSymbolWithChar(std::string_view description)890 JSHandle<JSSymbol> ObjectFactory::NewSWellKnownSymbolWithChar(std::string_view description)
891 {
892     JSHandle<EcmaString> string = NewFromUtf8(description);
893     return NewSWellKnownSymbol(JSHandle<JSTaggedValue>(string));
894 }
895 
NewSPublicSymbolWithChar(std::string_view description)896 JSHandle<JSSymbol> ObjectFactory::NewSPublicSymbolWithChar(std::string_view description)
897 {
898     JSHandle<EcmaString> string = NewFromUtf8(description);
899     return NewSPublicSymbol(JSHandle<JSTaggedValue>(string));
900 }
901 
NewSSourceTextModule()902 JSHandle<SourceTextModule> ObjectFactory::NewSSourceTextModule()
903 {
904     NewObjectHook();
905     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
906         JSHClass::Cast(thread_->GlobalConstants()->GetSourceTextModuleClass().GetTaggedObject()));
907     JSHandle<SourceTextModule> obj(thread_, header);
908     JSTaggedValue undefinedValue = thread_->GlobalConstants()->GetUndefined();
909     obj->SetEnvironment(thread_, undefinedValue);
910     obj->SetNamespace(thread_, undefinedValue);
911     obj->SetModuleRequests(thread_, undefinedValue);
912     obj->SetRequestedModules(thread_, undefinedValue);
913     obj->SetImportEntries(thread_, undefinedValue);
914     obj->SetLocalExportEntries(thread_, undefinedValue);
915     obj->SetIndirectExportEntries(thread_, undefinedValue);
916     obj->SetStarExportEntries(thread_, undefinedValue);
917     obj->SetNameDictionary(thread_, undefinedValue);
918     // [[CycleRoot]]: For a module not in a cycle, this would be the module itself.
919     obj->SetCycleRoot(thread_, obj);
920     obj->SetTopLevelCapability(thread_, undefinedValue);
921     obj->SetAsyncParentModules(thread_, undefinedValue);
922     obj->SetHasTLA(false);
923     obj->SetAsyncEvaluatingOrdinal(SourceTextModule::NOT_ASYNC_EVALUATED);
924     obj->SetPendingAsyncDependencies(SourceTextModule::UNDEFINED_INDEX);
925     obj->SetDFSIndex(SourceTextModule::UNDEFINED_INDEX);
926     obj->SetDFSAncestorIndex(SourceTextModule::UNDEFINED_INDEX);
927     obj->SetException<SKIP_BARRIER>(thread_, JSTaggedValue::Hole());
928     obj->SetStatus(ModuleStatus::UNINSTANTIATED);
929     obj->SetTypes(ModuleTypes::UNKNOWN);
930     obj->SetIsNewBcVersion(false);
931     obj->SetRegisterCounts(UINT16_MAX);
932     obj->SetLazyImportStatus(ToUintPtr(nullptr));
933     obj->SetEcmaModuleFilename(ToUintPtr(nullptr));
934     obj->SetEcmaModuleRecordName(ToUintPtr(nullptr));
935     obj->SetSharedType(SharedTypes::UNSENDABLE_MODULE);
936     obj->SetSendableEnv(thread_, undefinedValue);
937     return obj;
938 }
939 
NewSModuleNamespace()940 JSHandle<ModuleNamespace> ObjectFactory::NewSModuleNamespace()
941 {
942     NewObjectHook();
943     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
944     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetSharedModuleNamespaceClass());
945     JSHandle<JSObject> obj = NewSharedOldSpaceJSObject(hclass);
946 
947     JSHandle<ModuleNamespace> moduleNamespace = JSHandle<ModuleNamespace>::Cast(obj);
948     moduleNamespace->SetModule<SKIP_BARRIER>(thread_, JSTaggedValue::Undefined());
949     moduleNamespace->SetExports<SKIP_BARRIER>(thread_, JSTaggedValue::Undefined());
950     moduleNamespace->SetDeregisterProcession<SKIP_BARRIER>(thread_, JSTaggedValue::Undefined());
951     return moduleNamespace;
952 }
953 
NewSImportEntry(const uint32_t moduleRequestIdx,const JSHandle<JSTaggedValue> & importName,const JSHandle<JSTaggedValue> & localName)954 JSHandle<ImportEntry> ObjectFactory::NewSImportEntry(const uint32_t moduleRequestIdx,
955                                                      const JSHandle<JSTaggedValue> &importName,
956                                                      const JSHandle<JSTaggedValue> &localName)
957 {
958     NewObjectHook();
959     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
960         JSHClass::Cast(thread_->GlobalConstants()->GetImportEntryClass().GetTaggedObject()));
961     JSHandle<ImportEntry> obj(thread_, header);
962     obj->SetModuleRequestIndex(moduleRequestIdx);
963     obj->SetImportName(thread_, importName);
964     obj->SetLocalName(thread_, localName);
965     return obj;
966 }
967 
NewSLocalExportEntry(const JSHandle<JSTaggedValue> & exportName,const JSHandle<JSTaggedValue> & localName,const uint32_t index)968 JSHandle<LocalExportEntry> ObjectFactory::NewSLocalExportEntry(const JSHandle<JSTaggedValue> &exportName,
969     const JSHandle<JSTaggedValue> &localName, const uint32_t index)
970 {
971     NewObjectHook();
972     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
973         JSHClass::Cast(thread_->GlobalConstants()->GetLocalExportEntryClass().GetTaggedObject()));
974     JSHandle<LocalExportEntry> obj(thread_, header);
975     obj->SetExportName(thread_, exportName);
976     obj->SetLocalName(thread_, localName);
977     obj->SetLocalIndex(index);
978     return obj;
979 }
980 
NewSIndirectExportEntry(const JSHandle<JSTaggedValue> & exportName,const uint32_t moduleRequestIdx,const JSHandle<JSTaggedValue> & importName)981 JSHandle<IndirectExportEntry> ObjectFactory::NewSIndirectExportEntry(const JSHandle<JSTaggedValue> &exportName,
982                                                                      const uint32_t moduleRequestIdx,
983                                                                      const JSHandle<JSTaggedValue> &importName)
984 {
985     NewObjectHook();
986     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
987         JSHClass::Cast(thread_->GlobalConstants()->GetIndirectExportEntryClass().GetTaggedObject()));
988     JSHandle<IndirectExportEntry> obj(thread_, header);
989     obj->SetExportName(thread_, exportName);
990     obj->SetModuleRequestIndex(moduleRequestIdx);
991     obj->SetImportName(thread_, importName);
992     return obj;
993 }
994 
NewSStarExportEntry(const uint32_t moduleRequestIdx)995 JSHandle<StarExportEntry> ObjectFactory::NewSStarExportEntry(const uint32_t moduleRequestIdx)
996 {
997     NewObjectHook();
998     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
999         JSHClass::Cast(thread_->GlobalConstants()->GetStarExportEntryClass().GetTaggedObject()));
1000     JSHandle<StarExportEntry> obj(thread_, header);
1001     obj->SetModuleRequestIndex(moduleRequestIdx);
1002     return obj;
1003 }
1004 
NewSResolvedIndexBindingRecord()1005 JSHandle<ResolvedIndexBinding> ObjectFactory::NewSResolvedIndexBindingRecord()
1006 {
1007     JSHandle<JSTaggedValue> undefinedValue = thread_->GlobalConstants()->GetHandledUndefined();
1008     JSHandle<SourceTextModule> ecmaModule(undefinedValue);
1009     int32_t index = 0;
1010     return NewSResolvedIndexBindingRecord(ecmaModule, index);
1011 }
1012 
NewSResolvedIndexBindingRecord(const JSHandle<SourceTextModule> & module,int32_t index)1013 JSHandle<ResolvedIndexBinding> ObjectFactory::NewSResolvedIndexBindingRecord(const JSHandle<SourceTextModule> &module,
1014                                                                              int32_t index)
1015 {
1016     NewObjectHook();
1017     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
1018         JSHClass::Cast(thread_->GlobalConstants()->GetResolvedIndexBindingClass().GetTaggedObject()));
1019     JSHandle<ResolvedIndexBinding> obj(thread_, header);
1020     obj->SetModule(thread_, module);
1021     obj->SetIndex(index);
1022     obj->SetIsUpdatedFromResolvedBinding(false);
1023     return obj;
1024 }
1025 
NewSResolvedBindingRecord()1026 JSHandle<ResolvedBinding> ObjectFactory::NewSResolvedBindingRecord()
1027 {
1028     JSHandle<JSTaggedValue> undefinedValue = thread_->GlobalConstants()->GetHandledUndefined();
1029     JSHandle<SourceTextModule> ecmaModule(undefinedValue);
1030     JSHandle<JSTaggedValue> bindingName(undefinedValue);
1031     return NewSResolvedBindingRecord(ecmaModule, bindingName);
1032 }
1033 
NewSResolvedBindingRecord(const JSHandle<SourceTextModule> & module,const JSHandle<JSTaggedValue> & bindingName)1034 JSHandle<ResolvedBinding> ObjectFactory::NewSResolvedBindingRecord(const JSHandle<SourceTextModule> &module,
1035                                                                    const JSHandle<JSTaggedValue> &bindingName)
1036 {
1037     NewObjectHook();
1038     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
1039         JSHClass::Cast(thread_->GlobalConstants()->GetResolvedBindingClass().GetTaggedObject()));
1040     JSHandle<ResolvedBinding> obj(thread_, header);
1041     obj->SetModule(thread_, module);
1042     obj->SetBindingName(thread_, bindingName);
1043     return obj;
1044 }
1045 
NewSResolvedRecordIndexBindingRecord()1046 JSHandle<ResolvedRecordIndexBinding> ObjectFactory::NewSResolvedRecordIndexBindingRecord()
1047 {
1048     JSHandle<JSTaggedValue> undefinedValue = thread_->GlobalConstants()->GetHandledUndefined();
1049     JSHandle<EcmaString> ecmaModule(undefinedValue);
1050     JSHandle<EcmaString> fileName(undefinedValue);
1051     int32_t index = 0;
1052     return NewSResolvedRecordIndexBindingRecord(ecmaModule, fileName, index);
1053 }
1054 
NewSResolvedRecordIndexBindingRecord(const JSHandle<EcmaString> & moduleRecord,const JSHandle<EcmaString> & abcFileName,int32_t index)1055 JSHandle<ResolvedRecordIndexBinding> ObjectFactory::NewSResolvedRecordIndexBindingRecord(
1056     const JSHandle<EcmaString> &moduleRecord, const JSHandle<EcmaString> &abcFileName, int32_t index)
1057 {
1058     NewObjectHook();
1059     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
1060         JSHClass::Cast(thread_->GlobalConstants()->GetResolvedRecordIndexBindingClass().GetTaggedObject()));
1061     JSHandle<ResolvedRecordIndexBinding> obj(thread_, header);
1062     obj->SetModuleRecord(thread_, moduleRecord);
1063     obj->SetAbcFileName(thread_, abcFileName);
1064     obj->SetIndex(index);
1065     return obj;
1066 }
1067 
NewSResolvedRecordBindingRecord()1068 JSHandle<ResolvedRecordBinding> ObjectFactory::NewSResolvedRecordBindingRecord()
1069 {
1070     JSHandle<JSTaggedValue> undefinedValue = thread_->GlobalConstants()->GetHandledUndefined();
1071     JSHandle<EcmaString> ecmaModule(undefinedValue);
1072     JSHandle<JSTaggedValue> bindingName(undefinedValue);
1073     return NewSResolvedRecordBindingRecord(ecmaModule, bindingName);
1074 }
1075 
NewSResolvedRecordBindingRecord(const JSHandle<EcmaString> & moduleRecord,const JSHandle<JSTaggedValue> & bindingName)1076 JSHandle<ResolvedRecordBinding> ObjectFactory::NewSResolvedRecordBindingRecord(
1077     const JSHandle<EcmaString> &moduleRecord, const JSHandle<JSTaggedValue> &bindingName)
1078 {
1079     NewObjectHook();
1080     TaggedObject *header = sHeap_->AllocateOldOrHugeObject(thread_,
1081         JSHClass::Cast(thread_->GlobalConstants()->GetResolvedRecordBindingClass().GetTaggedObject()));
1082     JSHandle<ResolvedRecordBinding> obj(thread_, header);
1083     obj->SetModuleRecord(thread_, moduleRecord);
1084     obj->SetBindingName(thread_, bindingName);
1085     return obj;
1086 }
1087 
NewSAOTLiteralInfo(uint32_t length,JSTaggedValue initVal)1088 JSHandle<AOTLiteralInfo> ObjectFactory::NewSAOTLiteralInfo(uint32_t length, JSTaggedValue initVal)
1089 {
1090     NewObjectHook();
1091     size_t size = AOTLiteralInfo::ComputeSize(length);
1092     TaggedObject *header = nullptr;
1093     if (LIKELY(!g_isEnableCMCGC)) {
1094         header = sHeap_->AllocateOldOrHugeObject(thread_,
1095             JSHClass::Cast(sHeap_->GetGlobalConst()->GetAOTLiteralInfoClass().GetTaggedObject()), size);
1096     } else {
1097         header = sHeap_->AllocateOldOrHugeObject(thread_,
1098             JSHClass::Cast(sHeap_->GetGlobalConst()->GetSharedAOTLiteralInfoClass().GetTaggedObject()), size);
1099     }
1100 
1101     JSHandle<AOTLiteralInfo> aotLiteralInfo(thread_, header);
1102     aotLiteralInfo->InitializeWithSpecialValue(initVal, length);
1103     return aotLiteralInfo;
1104 }
1105 
NewSendableEnv(int numSlots)1106 JSHandle<SendableEnv> ObjectFactory::NewSendableEnv(int numSlots)
1107 {
1108     NewObjectHook();
1109     size_t size = SendableEnv::ComputeSize(numSlots);
1110     auto header = sHeap_->AllocateOldOrHugeObject(thread_,
1111         JSHClass::Cast(sHeap_->GetGlobalConst()->GetSendableEnvClass().GetTaggedObject()), size);
1112     JSHandle<SendableEnv> array(thread_, header);
1113     array->InitializeWithSpecialValue(JSTaggedValue::Hole(), numSlots + SendableEnv::SENDABLE_RESERVED_ENV_LENGTH);
1114     return array;
1115 }
1116 
NewJSSendableFunction(const JSHandle<Method> & methodHandle)1117 JSHandle<JSFunction> ObjectFactory::NewJSSendableFunction(const JSHandle<Method> &methodHandle)
1118 {
1119     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1120     FunctionKind kind = methodHandle->GetFunctionKind();
1121     JSHandle<JSHClass> hclass;
1122     switch (kind) {
1123         case FunctionKind::ASYNC_FUNCTION: {
1124             hclass = JSHandle<JSHClass>::Cast(env->GetSAsyncFunctionClass());
1125             break;
1126         }
1127         case FunctionKind::BASE_CONSTRUCTOR: {
1128             hclass = JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithProto());
1129             break;
1130         }
1131         default:
1132             LOG_ECMA(FATAL) << "this branch is unreachable";
1133             UNREACHABLE();
1134     }
1135 
1136     JSHandle<JSFunction> func = NewSFunctionByHClass(methodHandle, hclass);
1137     ASSERT_NO_ABRUPT_COMPLETION(thread_);
1138     return func;
1139 }
1140 }  // namespace panda::ecmascript
1141