• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 (thread_->IsEnableCMCGC()) {
35         object = sHeap_->AllocateOldOrHugeObjectNoGC(thread_, size);
36     } else {
37         if (size > g_maxRegularHeapObjectSize) {
38             object = reinterpret_cast<TaggedObject *>(sHeap_->GetHugeObjectSpace()->Allocate(thread_, size));
39         } else {
40             object = reinterpret_cast<TaggedObject *>(sHeap_->GetOldSpace()->TryAllocateAndExpand(thread_, size, true));
41         }
42     }
43     if (object == nullptr) {
44         LOG_ECMA(FATAL) << "Alloc size " << size << " bytes string fail";
45         UNREACHABLE();
46     }
47     return EcmaString::Cast(object);
48 }
49 
AllocNonMovableLineStringObject(size_t size)50 EcmaString *ObjectFactory::AllocNonMovableLineStringObject(size_t size)
51 {
52     NewSObjectHook();
53     EcmaString* str = reinterpret_cast<EcmaString *>(sHeap_->AllocateNonMovableOrHugeObject(
54         thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()), size));
55     return str;
56 }
57 
AllocLineStringObject(size_t size)58 EcmaString *ObjectFactory::AllocLineStringObject(size_t size)
59 {
60     NewSObjectHook();
61     EcmaString* str = reinterpret_cast<EcmaString *>(sHeap_->AllocateOldOrHugeObject(
62         thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()), size));
63     return str;
64 }
65 
AllocOldSpaceLineStringObject(size_t size)66 EcmaString *ObjectFactory::AllocOldSpaceLineStringObject(size_t size)
67 {
68     NewSObjectHook();
69     EcmaString* str = reinterpret_cast<EcmaString *>(sHeap_->AllocateOldOrHugeObject(
70         thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()), size));
71     return str;
72 }
73 
AllocReadOnlyLineStringObject(size_t size)74 EcmaString *ObjectFactory::AllocReadOnlyLineStringObject(size_t size)
75 {
76     NewSObjectHook();
77     EcmaString* str = reinterpret_cast<EcmaString *>(sHeap_->AllocateReadOnlyOrHugeObject(
78         thread_, JSHClass::Cast(thread_->GlobalConstants()->GetLineStringClass().GetTaggedObject()), size));
79     return str;
80 }
81 
AllocSlicedStringObject(MemSpaceType type)82 EcmaString *ObjectFactory::AllocSlicedStringObject(MemSpaceType type)
83 {
84     ASSERT(IsSMemSpace(type));
85     NewSObjectHook();
86     EcmaString* str = reinterpret_cast<EcmaString *>(AllocObjectWithSpaceType(SlicedString::SIZE,
87         JSHClass::Cast(thread_->GlobalConstants()->GetSlicedStringClass().GetTaggedObject()), type));
88     return str;
89 }
90 
AllocTreeStringObject()91 EcmaString *ObjectFactory::AllocTreeStringObject()
92 {
93     NewSObjectHook();
94     EcmaString* str = reinterpret_cast<EcmaString *>(sHeap_->AllocateOldOrHugeObject(
95         thread_, JSHClass::Cast(thread_->GlobalConstants()->GetTreeStringClass().GetTaggedObject()),
96         TreeString::SIZE));
97     return str;
98 }
99 
NewJSNativePointer(void * externalPointer,const NativePointerCallback & callBack,void * data,bool nonMovable,size_t nativeBindingsize,Concurrent isConcurrent,NativeFlag flag)100 JSHandle<JSNativePointer> ObjectFactory::NewJSNativePointer(void *externalPointer,
101                                                             const NativePointerCallback &callBack,
102                                                             void *data,
103                                                             bool nonMovable,
104                                                             size_t nativeBindingsize,
105                                                             Concurrent isConcurrent,
106                                                             NativeFlag flag)
107 {
108     NewObjectHook();
109     TaggedObject *header;
110     auto jsNativePointerClass = JSHClass::Cast(thread_->GlobalConstants()->GetJSNativePointerClass().GetTaggedObject());
111     if (nonMovable) {
112         header = heap_->AllocateNonMovableOrHugeObject(jsNativePointerClass);
113     } else {
114         header = heap_->AllocateOldOrHugeObject(jsNativePointerClass);
115     }
116     JSHandle<JSNativePointer> obj(thread_, header);
117     obj->SetExternalPointer(externalPointer);
118     obj->SetDeleter(callBack);
119     obj->SetData(data);
120     uint32_t fixedNativeBindingsize = nativeBindingsize < UINT32_MAX ? nativeBindingsize
121                                                                      : UINT32_MAX;
122     obj->SetBindingSize(fixedNativeBindingsize);
123     obj->SetNativeFlag(flag);
124 
125     heap_->IncreaseNativeBindingSize(fixedNativeBindingsize);
126     if (callBack != nullptr) {
127         vm_->PushToNativePointerList(static_cast<JSNativePointer *>(header), isConcurrent);
128         // In some cases, the size of JS/TS object is too small and the native binding size is too large.
129         // Check and try trigger concurrent mark here.
130         if (!g_isEnableCMCGC) {
131             heap_->TryTriggerFullMarkOrGCByNativeSize();
132         }
133     }
134     return obj;
135 }
136 
InlineNewLexicalEnv(int numSlots)137 LexicalEnv *ObjectFactory::InlineNewLexicalEnv(int numSlots)
138 {
139     NewObjectHook();
140     size_t size = LexicalEnv::ComputeSize(numSlots);
141     auto header = heap_->TryAllocateYoungGeneration(
142         JSHClass::Cast(thread_->GlobalConstants()->GetLexicalEnvClass().GetTaggedObject()), size);
143     if (UNLIKELY(header == nullptr)) {
144         return nullptr;
145     }
146     LexicalEnv *array = LexicalEnv::Cast(header);
147     array->InitializeWithSpecialValue(JSTaggedValue::Hole(), numSlots + LexicalEnv::RESERVED_ENV_LENGTH);
148     return array;
149 }
150 
151 template<typename T, typename S>
NewJSIntlIcuData(const JSHandle<T> & obj,const S & icu,const NativePointerCallback & callback)152 void ObjectFactory::NewJSIntlIcuData(const JSHandle<T> &obj, const S &icu, const NativePointerCallback &callback)
153 {
154     S *icuPoint = vm_->GetNativeAreaAllocator()->New<S>(icu);
155     ASSERT(icuPoint != nullptr);
156     JSTaggedValue data = obj->GetIcuField(vm_->GetJSThread());
157     if (data.IsHeapObject() && data.IsJSNativePointer()) {
158         JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject());
159         native->ResetExternalPointer(thread_, icuPoint);
160         return;
161     }
162     JSHandle<JSNativePointer> pointer = NewJSNativePointer(icuPoint, callback, vm_);
163     obj->SetIcuField(thread_, pointer.GetTaggedValue());
164 }
165 
AllocObjectWithSpaceType(size_t size,JSHClass * cls,MemSpaceType type)166 TaggedObject *ObjectFactory::AllocObjectWithSpaceType(size_t size, JSHClass *cls, MemSpaceType type)
167 {
168     switch (type) {
169         case MemSpaceType::SEMI_SPACE:
170             return heap_->AllocateYoungOrHugeObject(cls, size);
171         case MemSpaceType::OLD_SPACE:
172             return heap_->AllocateOldOrHugeObject(cls, size);
173         case MemSpaceType::NON_MOVABLE:
174             return heap_->AllocateNonMovableOrHugeObject(cls, size);
175         case MemSpaceType::SHARED_OLD_SPACE:
176             return sHeap_->AllocateOldOrHugeObject(thread_, cls, size);
177         case MemSpaceType::SHARED_NON_MOVABLE:
178             return sHeap_->AllocateNonMovableOrHugeObject(thread_, cls, size);
179         default:
180             LOG_ECMA(FATAL) << "this branch is unreachable";
181             UNREACHABLE();
182     }
183 }
184 
185 template <MemSpaceType type>
NewBigIntWithoutInitData(uint32_t length)186 JSHandle<BigInt> ObjectFactory::NewBigIntWithoutInitData(uint32_t length)
187 {
188     NewObjectHook();
189     ASSERT(length > 0);
190     size_t size = BigInt::ComputeSize(length);
191     TaggedObject *header;
192     if (type == MemSpaceType::SHARED_READ_ONLY_SPACE) {
193         header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
194             JSHClass::Cast(thread_->GlobalConstants()->GetBigIntClass().GetTaggedObject()), size);
195     } else {
196         header = sHeap_->AllocateOldOrHugeObject(thread_,
197             JSHClass::Cast(thread_->GlobalConstants()->GetBigIntClass().GetTaggedObject()), size);
198     }
199     JSHandle<BigInt> bigint(thread_, header);
200     bigint->SetLength(length);
201     return bigint;
202 }
203 
204 template <MemSpaceType type>
NewBigInt(uint32_t length)205 JSHandle<BigInt> ObjectFactory::NewBigInt(uint32_t length)
206 {
207     JSHandle<BigInt> bigint = NewBigIntWithoutInitData<type>(length);
208     bigint->InitializationZero();
209     bigint->SetSign(false);
210     return bigint;
211 }
212 
213 template <MemSpaceType type>
NewSubBigInt(const JSHandle<BigInt> & x,uint32_t length)214 JSHandle<BigInt> ObjectFactory::NewSubBigInt(const JSHandle<BigInt>& x, uint32_t length)
215 {
216     JSHandle<BigInt> bigint = NewBigIntWithoutInitData<type>(length);
217     bigint->SetSign(x->GetSign());
218     ASSERT(x->GetLength() >= length);
219     std::copy(x->GetData(), x->GetData() + length, bigint->GetData());
220     return bigint;
221 }
222 }  // namespace panda::ecmascript
223 #endif  // ECMASCRIPT_OBJECT_FACTORY_INL_H
224