1 /*
2 * Copyright (c) 2021 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 #ifndef ECMASCRIPT_OBJECT_FACTORY_INL_H
17 #define ECMASCRIPT_OBJECT_FACTORY_INL_H
18
19 #include "ecmascript/global_env_constants-inl.h"
20 #include "ecmascript/global_env_constants.h"
21 #include "ecmascript/js_hclass-inl.h"
22 #include "ecmascript/js_thread.h"
23 #include "ecmascript/lexical_env.h"
24 #include "ecmascript/mem/heap-inl.h"
25 #include "ecmascript/mem/barriers-inl.h"
26 #include "ecmascript/mem/space.h"
27 #include "ecmascript/object_factory.h"
28 #include "ecmascript/tagged_array-inl.h"
29
30 namespace panda::ecmascript {
AllocLineStringObjectNoGC(size_t size)31 EcmaString *ObjectFactory::AllocLineStringObjectNoGC(size_t size)
32 {
33 TaggedObject *object = nullptr;
34 if (size > MAX_REGULAR_HEAP_OBJECT_SIZE) {
35 object = reinterpret_cast<TaggedObject *>(sHeap_->GetHugeObjectSpace()->Allocate(thread_, size));
36 } else {
37 object = reinterpret_cast<TaggedObject *>(sHeap_->GetOldSpace()->TryAllocateAndExpand(thread_, size, true));
38 }
39 ASSERT(object != nullptr);
40 object->SetClass(thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()));
41 return EcmaString::Cast(object);
42 }
43
AllocNonMovableLineStringObject(size_t size)44 EcmaString *ObjectFactory::AllocNonMovableLineStringObject(size_t size)
45 {
46 NewSObjectHook();
47 return reinterpret_cast<EcmaString *>(sHeap_->AllocateNonMovableOrHugeObject(
48 thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()), size));
49 }
50
AllocLineStringObject(size_t size)51 EcmaString *ObjectFactory::AllocLineStringObject(size_t size)
52 {
53 NewSObjectHook();
54 return reinterpret_cast<EcmaString *>(sHeap_->AllocateOldOrHugeObject(
55 thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()), size));
56 }
57
AllocOldSpaceLineStringObject(size_t size)58 EcmaString *ObjectFactory::AllocOldSpaceLineStringObject(size_t size)
59 {
60 NewSObjectHook();
61 return reinterpret_cast<EcmaString *>(sHeap_->AllocateOldOrHugeObject(
62 thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()), size));
63 }
64
AllocReadOnlyLineStringObject(size_t size)65 EcmaString *ObjectFactory::AllocReadOnlyLineStringObject(size_t size)
66 {
67 NewSObjectHook();
68 return reinterpret_cast<EcmaString *>(sHeap_->AllocateReadOnlyOrHugeObject(
69 thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()), size));
70 }
71
AllocSlicedStringObject(MemSpaceType type)72 EcmaString *ObjectFactory::AllocSlicedStringObject(MemSpaceType type)
73 {
74 ASSERT(IsSMemSpace(type));
75 NewSObjectHook();
76 return reinterpret_cast<EcmaString *>(AllocObjectWithSpaceType(SlicedString::SIZE,
77 JSHClass::Cast(thread_->GlobalConstants()->GetSlicedStringClass().GetTaggedObject()), type));
78 }
79
AllocConstantStringObject(MemSpaceType type)80 EcmaString *ObjectFactory::AllocConstantStringObject(MemSpaceType type)
81 {
82 ASSERT(IsSMemSpace(type));
83 NewSObjectHook();
84 return reinterpret_cast<EcmaString *>(AllocObjectWithSpaceType(ConstantString::SIZE,
85 JSHClass::Cast(thread_->GlobalConstants()->GetConstantStringClass().GetTaggedObject()), type));
86 }
87
AllocTreeStringObject()88 EcmaString *ObjectFactory::AllocTreeStringObject()
89 {
90 NewSObjectHook();
91 return reinterpret_cast<EcmaString *>(sHeap_->AllocateOldOrHugeObject(
92 thread_, JSHClass::Cast(thread_->GlobalConstants()->GetTreeStringClass().GetTaggedObject()),
93 TreeEcmaString::SIZE));
94 }
95
NewJSNativePointer(void * externalPointer,const NativePointerCallback & callBack,void * data,bool nonMovable,size_t nativeBindingsize,Concurrent isConcurrent,NativeFlag flag)96 JSHandle<JSNativePointer> ObjectFactory::NewJSNativePointer(void *externalPointer,
97 const NativePointerCallback &callBack,
98 void *data,
99 bool nonMovable,
100 size_t nativeBindingsize,
101 Concurrent isConcurrent,
102 NativeFlag flag)
103 {
104 NewObjectHook();
105 TaggedObject *header;
106 auto jsNativePointerClass = JSHClass::Cast(thread_->GlobalConstants()->GetJSNativePointerClass().GetTaggedObject());
107 if (nonMovable) {
108 header = heap_->AllocateNonMovableOrHugeObject(jsNativePointerClass);
109 } else {
110 header = heap_->AllocateOldOrHugeObject(jsNativePointerClass);
111 }
112 JSHandle<JSNativePointer> obj(thread_, header);
113 obj->SetExternalPointer(externalPointer);
114 obj->SetDeleter(callBack);
115 obj->SetData(data);
116 obj->SetBindingSize(nativeBindingsize);
117 obj->SetNativeFlag(flag);
118
119 heap_->IncreaseNativeBindingSize(nativeBindingsize);
120 if (callBack != nullptr) {
121 vm_->PushToNativePointerList(static_cast<JSNativePointer *>(header), isConcurrent);
122 // In some cases, the size of JS/TS object is too small and the native binding size is too large.
123 // Check and try trigger concurrent mark here.
124 heap_->TryTriggerFullMarkOrGCByNativeSize();
125 }
126 return obj;
127 }
128
InlineNewLexicalEnv(int numSlots)129 LexicalEnv *ObjectFactory::InlineNewLexicalEnv(int numSlots)
130 {
131 NewObjectHook();
132 size_t size = LexicalEnv::ComputeSize(numSlots);
133 auto header = heap_->TryAllocateYoungGeneration(
134 JSHClass::Cast(thread_->GlobalConstants()->GetEnvClass().GetTaggedObject()), size);
135 if (UNLIKELY(header == nullptr)) {
136 return nullptr;
137 }
138 LexicalEnv *array = LexicalEnv::Cast(header);
139 array->InitializeWithSpecialValue(JSTaggedValue::Hole(), numSlots + LexicalEnv::RESERVED_ENV_LENGTH);
140 return array;
141 }
142
143 template<typename T, typename S>
NewJSIntlIcuData(const JSHandle<T> & obj,const S & icu,const NativePointerCallback & callback)144 void ObjectFactory::NewJSIntlIcuData(const JSHandle<T> &obj, const S &icu, const NativePointerCallback &callback)
145 {
146 S *icuPoint = vm_->GetNativeAreaAllocator()->New<S>(icu);
147 ASSERT(icuPoint != nullptr);
148 JSTaggedValue data = obj->GetIcuField();
149 if (data.IsHeapObject() && data.IsJSNativePointer()) {
150 JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject());
151 native->ResetExternalPointer(thread_, icuPoint);
152 return;
153 }
154 JSHandle<JSNativePointer> pointer = NewJSNativePointer(icuPoint, callback, vm_);
155 obj->SetIcuField(thread_, pointer.GetTaggedValue());
156 }
157
AllocObjectWithSpaceType(size_t size,JSHClass * cls,MemSpaceType type)158 TaggedObject *ObjectFactory::AllocObjectWithSpaceType(size_t size, JSHClass *cls, MemSpaceType type)
159 {
160 switch (type) {
161 case MemSpaceType::SEMI_SPACE:
162 return heap_->AllocateYoungOrHugeObject(cls, size);
163 case MemSpaceType::OLD_SPACE:
164 return heap_->AllocateOldOrHugeObject(cls, size);
165 case MemSpaceType::NON_MOVABLE:
166 return heap_->AllocateNonMovableOrHugeObject(cls, size);
167 case MemSpaceType::SHARED_OLD_SPACE:
168 return sHeap_->AllocateOldOrHugeObject(thread_, cls, size);
169 case MemSpaceType::SHARED_NON_MOVABLE:
170 return sHeap_->AllocateNonMovableOrHugeObject(thread_, cls, size);
171 default:
172 LOG_ECMA(FATAL) << "this branch is unreachable";
173 UNREACHABLE();
174 }
175 }
176 } // namespace panda::ecmascript
177 #endif // ECMASCRIPT_OBJECT_FACTORY_INL_H
178