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