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