• 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 #ifndef ECMASCRIPT_COMPILER_HCR_CIRCUIT_BUILDER_H
17 #define ECMASCRIPT_COMPILER_HCR_CIRCUIT_BUILDER_H
18 
19 #include "ecmascript/compiler/circuit_builder_helper.h"
20 #include "ecmascript/mem/region.h"
21 #include "ecmascript/js_function.h"
22 
23 namespace panda::ecmascript::kungfu {
24 
IsSpecial(GateRef x,JSTaggedType type)25 GateRef CircuitBuilder::IsSpecial(GateRef x, JSTaggedType type)
26 {
27     auto specialValue = circuit_->GetConstantGate(
28         MachineType::I64, type, GateType::TaggedValue());
29 
30     return Equal(x, specialValue);
31 }
32 
IsJSHClass(GateRef obj)33 inline GateRef CircuitBuilder::IsJSHClass(GateRef obj)
34 {
35     return Int32Equal(GetObjectType(LoadHClass(obj)), Int32(static_cast<int32_t>(JSType::HCLASS)));
36 }
37 
IsJSFunction(GateRef obj)38 inline GateRef CircuitBuilder::IsJSFunction(GateRef obj)
39 {
40     GateRef objectType = GetObjectType(LoadHClass(obj));
41     GateRef greater = Int32GreaterThanOrEqual(objectType,
42         Int32(static_cast<int32_t>(JSType::JS_FUNCTION_FIRST)));
43     GateRef less = Int32LessThanOrEqual(objectType,
44         Int32(static_cast<int32_t>(JSType::JS_FUNCTION_LAST)));
45     return BitAnd(greater, less);
46 }
47 
IsJsType(GateRef obj,JSType type)48 GateRef CircuitBuilder::IsJsType(GateRef obj, JSType type)
49 {
50     GateRef objectType = GetObjectType(LoadHClass(obj));
51     return Equal(objectType, Int32(static_cast<int32_t>(type)));
52 }
53 
IsJSObject(GateRef obj)54 GateRef CircuitBuilder::IsJSObject(GateRef obj)
55 {
56     Label entryPass(env_);
57     SubCfgEntry(&entryPass);
58     DEFVALUE(result, env_, VariableType::BOOL(), False());
59     Label heapObj(env_);
60     Label exit(env_);
61     GateRef isHeapObject = TaggedIsHeapObject(obj);
62     BRANCH(isHeapObject, &heapObj, &exit);
63     Bind(&heapObj);
64     {
65         GateRef objectType = GetObjectType(LoadHClass(obj));
66         result = BitAnd(
67             Int32LessThanOrEqual(objectType, Int32(static_cast<int32_t>(JSType::JS_OBJECT_LAST))),
68             Int32GreaterThanOrEqual(objectType, Int32(static_cast<int32_t>(JSType::JS_OBJECT_FIRST))));
69         Jump(&exit);
70     }
71     Bind(&exit);
72     auto ret = *result;
73     SubCfgExit();
74     return ret;
75 }
76 
IsCallableFromBitField(GateRef bitfield)77 GateRef CircuitBuilder::IsCallableFromBitField(GateRef bitfield)
78 {
79     return NotEqual(
80         Int32And(Int32LSR(bitfield, Int32(JSHClass::CallableBit::START_BIT)),
81             Int32((1LU << JSHClass::CallableBit::SIZE) - 1)),
82         Int32(0));
83 }
84 
IsCallable(GateRef obj)85 GateRef CircuitBuilder::IsCallable(GateRef obj)
86 {
87     GateRef hClass = LoadHClass(obj);
88     GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
89     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
90     return IsCallableFromBitField(bitfield);
91 }
92 
AlreadyDeopt(GateRef method)93 GateRef CircuitBuilder::AlreadyDeopt(GateRef method)
94 {
95     GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
96     GateRef extraLiteralInfo = Load(VariableType::INT64(), method, extraLiteralInfoOffset);
97     return AlreadyDeoptFromExtraLiteralInfo(extraLiteralInfo);
98 }
99 
AlreadyDeoptFromExtraLiteralInfo(GateRef callfield)100 GateRef CircuitBuilder::AlreadyDeoptFromExtraLiteralInfo(GateRef callfield)
101 {
102     return NotEqual(Int64And(Int64LSR(callfield, Int64(Method::DeoptTypeBits::START_BIT)),
103                              Int64((1LU << Method::DeoptTypeBits::SIZE) - 1)),
104                     Int64(0));
105 }
106 
IsPrototypeHClass(GateRef hClass)107 GateRef CircuitBuilder::IsPrototypeHClass(GateRef hClass)
108 {
109     GateRef bitfield = LoadConstOffset(VariableType::INT32(), hClass, JSHClass::BIT_FIELD_OFFSET);
110     return TruncInt32ToInt1(Int32And(Int32LSR(bitfield,
111         Int32(JSHClass::IsPrototypeBit::START_BIT)),
112         Int32((1LU << JSHClass::IsPrototypeBit::SIZE) - 1)));
113 }
114 
IsJsProxy(GateRef obj)115 GateRef CircuitBuilder::IsJsProxy(GateRef obj)
116 {
117     GateRef objectType = GetObjectType(LoadHClass(obj));
118     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_PROXY)));
119 }
120 
IsTreeString(GateRef obj)121 GateRef CircuitBuilder::IsTreeString(GateRef obj)
122 {
123     GateRef objectType = GetObjectType(LoadHClass(obj));
124     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::TREE_STRING)));
125 }
126 
IsSlicedString(GateRef obj)127 GateRef CircuitBuilder::IsSlicedString(GateRef obj)
128 {
129     GateRef objectType = GetObjectType(LoadHClass(obj));
130     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::SLICED_STRING)));
131 }
132 
IsLineString(GateRef obj)133 GateRef CircuitBuilder::IsLineString(GateRef obj)
134 {
135     GateRef objectType = GetObjectType(LoadHClass(obj));
136     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::LINE_STRING)));
137 }
138 
IsConstantString(GateRef obj)139 GateRef CircuitBuilder::IsConstantString(GateRef obj)
140 {
141     GateRef objectType = GetObjectType(LoadHClass(obj));
142     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::CONSTANT_STRING)));
143 }
144 
ComputeSizeUtf8(GateRef length)145 GateRef CircuitBuilder::ComputeSizeUtf8(GateRef length)
146 {
147     return PtrAdd(IntPtr(LineEcmaString::DATA_OFFSET), length);
148 }
149 
ComputeSizeUtf16(GateRef length)150 GateRef CircuitBuilder::ComputeSizeUtf16(GateRef length)
151 {
152     return PtrAdd(IntPtr(LineEcmaString::DATA_OFFSET), PtrMul(length, IntPtr(sizeof(uint16_t))));
153 }
154 
AlignUp(GateRef x,GateRef alignment)155 GateRef CircuitBuilder::AlignUp(GateRef x, GateRef alignment)
156 {
157     GateRef x1 = PtrAdd(x, PtrSub(alignment, IntPtr(1)));
158     return IntPtrAnd(x1, IntPtrNot(PtrSub(alignment, IntPtr(1))));
159 }
160 
IsDictionaryMode(GateRef object)161 inline GateRef CircuitBuilder::IsDictionaryMode(GateRef object)
162 {
163     GateRef type = GetObjectType(LoadHClass(object));
164     return Int32Equal(type, Int32(static_cast<int32_t>(JSType::TAGGED_DICTIONARY)));
165 }
166 
IsStableArguments(GateRef hClass)167 GateRef CircuitBuilder::IsStableArguments(GateRef hClass)
168 {
169     GateRef objectType = GetObjectType(hClass);
170     GateRef isJsArguments = Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_ARGUMENTS)));
171     GateRef isStableElements = IsStableElements(hClass);
172     return BitAnd(isStableElements, isJsArguments);
173 }
174 
IsStableArray(GateRef hClass)175 GateRef CircuitBuilder::IsStableArray(GateRef hClass)
176 {
177     GateRef objectType = GetObjectType(hClass);
178     GateRef isJsArray = Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_ARRAY)));
179     GateRef isStableElements = IsStableElements(hClass);
180     return BitAnd(isStableElements, isJsArray);
181 }
182 
IsAOTLiteralInfo(GateRef x)183 GateRef CircuitBuilder::IsAOTLiteralInfo(GateRef x)
184 {
185     GateRef objType = GetObjectType(LoadHClass(x));
186     GateRef isAOTLiteralInfoObj = Equal(objType,
187         Int32(static_cast<int32_t>(JSType::AOT_LITERAL_INFO)));
188     return isAOTLiteralInfoObj;
189 }
190 
LoadHClass(GateRef object)191 GateRef CircuitBuilder::LoadHClass(GateRef object)
192 {
193     GateRef offset = IntPtr(TaggedObject::HCLASS_OFFSET);
194     return Load(VariableType::JS_POINTER(), object, offset);
195 }
196 
LoadHClassByConstOffset(GateRef object)197 GateRef CircuitBuilder::LoadHClassByConstOffset(GateRef object)
198 {
199     return LoadConstOffset(VariableType::JS_POINTER(), object, TaggedObject::HCLASS_OFFSET);
200 }
201 
LoadPrototype(GateRef hclass)202 GateRef CircuitBuilder::LoadPrototype(GateRef hclass)
203 {
204     return LoadConstOffset(VariableType::JS_POINTER(), hclass, JSHClass::PROTOTYPE_OFFSET);
205 }
206 
LoadPrototypeHClass(GateRef object)207 GateRef CircuitBuilder::LoadPrototypeHClass(GateRef object)
208 {
209     GateRef objectHClass = LoadHClassByConstOffset(object);
210     GateRef objectPrototype = LoadPrototype(objectHClass);
211     return LoadHClass(objectPrototype);
212 }
213 
LoadPrototypeOfPrototypeHClass(GateRef object)214 GateRef CircuitBuilder::LoadPrototypeOfPrototypeHClass(GateRef object)
215 {
216     GateRef objectHClass = LoadHClassByConstOffset(object);
217     GateRef objectPrototype = LoadPrototype(objectHClass);
218     GateRef objectPrototypeHClass = LoadHClassByConstOffset(objectPrototype);
219     GateRef objectPrototypeOfPrototype = LoadPrototype(objectPrototypeHClass);
220     return LoadHClass(objectPrototypeOfPrototype);
221 }
222 
GetObjectSizeFromHClass(GateRef hClass)223 GateRef CircuitBuilder::GetObjectSizeFromHClass(GateRef hClass)
224 {
225     // NOTE: check for special case of string and TAGGED_ARRAY
226     GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
227     GateRef objectSizeInWords = Int32And(Int32LSR(bitfield,
228         Int32(JSHClass::ObjectSizeInWordsBits::START_BIT)),
229         Int32((1LU << JSHClass::ObjectSizeInWordsBits::SIZE) - 1));
230     return PtrMul(ZExtInt32ToPtr(objectSizeInWords), IntPtr(JSTaggedValue::TaggedTypeSize()));
231 }
232 
IsDictionaryModeByHClass(GateRef hClass)233 GateRef CircuitBuilder::IsDictionaryModeByHClass(GateRef hClass)
234 {
235     GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
236     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
237     return NotEqual(Int32And(Int32LSR(bitfield,
238         Int32(JSHClass::IsDictionaryBit::START_BIT)),
239         Int32((1LU << JSHClass::IsDictionaryBit::SIZE) - 1)),
240         Int32(0));
241 }
242 
StoreHClass(GateRef glue,GateRef object,GateRef hClass)243 void CircuitBuilder::StoreHClass(GateRef glue, GateRef object, GateRef hClass)
244 {
245     Store(VariableType::JS_POINTER(), glue, object, IntPtr(TaggedObject::HCLASS_OFFSET), hClass,
246           MemoryAttribute::NeedBarrier());
247 }
248 
StoreHClassWithoutBarrier(GateRef glue,GateRef object,GateRef hClass)249 void CircuitBuilder::StoreHClassWithoutBarrier(GateRef glue, GateRef object, GateRef hClass)
250 {
251     Store(VariableType::JS_POINTER(), glue, object, IntPtr(TaggedObject::HCLASS_OFFSET), hClass,
252           MemoryAttribute::NoBarrier());
253 }
254 
StorePrototype(GateRef glue,GateRef hclass,GateRef prototype)255 void CircuitBuilder::StorePrototype(GateRef glue, GateRef hclass, GateRef prototype)
256 {
257     Store(VariableType::JS_POINTER(), glue, hclass, IntPtr(JSHClass::PROTOTYPE_OFFSET), prototype);
258 }
259 
GetObjectType(GateRef hClass)260 GateRef CircuitBuilder::GetObjectType(GateRef hClass)
261 {
262     GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
263     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
264     return Int32And(bitfield, Int32((1LU << JSHClass::ObjectTypeBits::SIZE) - 1));
265 }
266 
CanFastCall(GateRef jsFunc)267 inline GateRef CircuitBuilder::CanFastCall(GateRef jsFunc)
268 {
269     GateRef bitFieldOffset = IntPtr(JSFunctionBase::BIT_FIELD_OFFSET);
270     GateRef bitField = Load(VariableType::INT32(), jsFunc, bitFieldOffset);
271     return Int32NotEqual(
272         Int32And(
273             Int32LSR(bitField, Int32(JSFunctionBase::IsFastCallBit::START_BIT)),
274             Int32((1LU << JSFunctionBase::IsFastCallBit::SIZE) - 1)),
275         Int32(0));
276 }
277 
GetElementsKindByHClass(GateRef hClass)278 GateRef CircuitBuilder::GetElementsKindByHClass(GateRef hClass)
279 {
280     GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
281     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
282     return Int32And(Int32LSR(bitfield,
283         Int32(JSHClass::ElementsKindBits::START_BIT)),
284         Int32((1LLU << JSHClass::ElementsKindBits::SIZE) - 1));
285 }
286 
HasConstructorByHClass(GateRef hClass)287 GateRef CircuitBuilder::HasConstructorByHClass(GateRef hClass)
288 {
289     GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
290     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
291     return NotEqual(Int32And(Int32LSR(bitfield,
292         Int32(JSHClass::HasConstructorBits::START_BIT)),
293         Int32((1LU << JSHClass::HasConstructorBits::SIZE) - 1)),
294         Int32(0));
295 }
296 
IsDictionaryElement(GateRef hClass)297 GateRef CircuitBuilder::IsDictionaryElement(GateRef hClass)
298 {
299     GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
300     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
301     return NotEqual(Int32And(Int32LSR(bitfield,
302         Int32(JSHClass::DictionaryElementBits::START_BIT)),
303         Int32((1LU << JSHClass::DictionaryElementBits::SIZE) - 1)),
304         Int32(0));
305 }
306 
IsStableElements(GateRef hClass)307 GateRef CircuitBuilder::IsStableElements(GateRef hClass)
308 {
309     GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
310     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
311     return NotEqual(Int32And(Int32LSR(bitfield,
312         Int32(JSHClass::IsStableElementsBit::START_BIT)),
313         Int32((1LU << JSHClass::IsStableElementsBit::SIZE) - 1)),
314         Int32(0));
315 }
316 
IsJSArrayPrototypeModified(GateRef hClass)317 GateRef CircuitBuilder::IsJSArrayPrototypeModified(GateRef hClass)
318 {
319     GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
320     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
321     return NotEqual(Int32And(Int32LSR(bitfield,
322         Int32(JSHClass::IsJSArrayPrototypeModifiedBit::START_BIT)),
323         Int32((1LU << JSHClass::IsJSArrayPrototypeModifiedBit::SIZE) - 1)),
324         Int32(0));
325 }
326 
HasConstructor(GateRef object)327 GateRef CircuitBuilder::HasConstructor(GateRef object)
328 {
329     GateRef hClass = LoadHClass(object);
330     return HasConstructorByHClass(hClass);
331 }
332 
IsConstructor(GateRef object)333 GateRef CircuitBuilder::IsConstructor(GateRef object)
334 {
335     GateRef hClass = LoadHClass(object);
336     GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
337     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
338     // decode
339     return Int32NotEqual(
340         Int32And(Int32LSR(bitfield, Int32(JSHClass::ConstructorBit::START_BIT)),
341                  Int32((1LU << JSHClass::ConstructorBit::SIZE) - 1)),
342         Int32(0));
343 }
344 
IsClassConstructor(GateRef object)345 GateRef CircuitBuilder::IsClassConstructor(GateRef object)
346 {
347     GateRef hClass = LoadHClass(object);
348     GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
349     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
350     return IsClassConstructorWithBitField(bitfield);
351 }
352 
IsClassConstructorWithBitField(GateRef bitfield)353 GateRef CircuitBuilder::IsClassConstructorWithBitField(GateRef bitfield)
354 {
355     auto classBitMask = 1LU << JSHClass::IsClassConstructorOrPrototypeBit::START_BIT;
356     auto ctorBitMask = 1LU << JSHClass::ConstructorBit::START_BIT;
357     auto mask = Int32(classBitMask | ctorBitMask);
358     auto classCtor = Int32And(bitfield, mask);
359     return Int32Equal(classCtor, mask);
360 }
361 
IsExtensible(GateRef object)362 GateRef CircuitBuilder::IsExtensible(GateRef object)
363 {
364     GateRef hClass = LoadHClass(object);
365     GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
366     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
367     return NotEqual(Int32And(Int32LSR(bitfield,
368         Int32(JSHClass::ExtensibleBit::START_BIT)),
369         Int32((1LU << JSHClass::ExtensibleBit::SIZE) - 1)),
370         Int32(0));
371 }
372 
IsClassPrototype(GateRef object)373 GateRef CircuitBuilder::IsClassPrototype(GateRef object)
374 {
375     GateRef hClass = LoadHClass(object);
376     GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
377     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
378     // decode
379     return IsClassPrototypeWithBitField(bitfield);
380 }
381 
IsClassPrototypeWithBitField(GateRef bitfield)382 GateRef CircuitBuilder::IsClassPrototypeWithBitField(GateRef bitfield)
383 {
384     auto classBitMask = 1LU << JSHClass::IsClassConstructorOrPrototypeBit::START_BIT;
385     auto ptBitMask = 1LU << JSHClass::IsPrototypeBit::START_BIT;
386     auto mask = Int32(classBitMask | ptBitMask);
387     auto classPt = Int32And(bitfield, mask);
388     return Int32Equal(classPt, mask);
389 }
390 
CreateWeakRef(GateRef x)391 GateRef CircuitBuilder::CreateWeakRef(GateRef x)
392 {
393     return PtrAdd(x, IntPtr(JSTaggedValue::TAG_WEAK));
394 }
395 
LoadObjectFromWeakRef(GateRef x)396 GateRef CircuitBuilder::LoadObjectFromWeakRef(GateRef x)
397 {
398     return PtrAdd(x, IntPtr(-JSTaggedValue::TAG_WEAK));
399 }
400 
401 // ctor is base but not builtin
IsBase(GateRef ctor)402 inline GateRef CircuitBuilder::IsBase(GateRef ctor)
403 {
404     GateRef method = GetMethodFromFunction(ctor);
405     GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
406     GateRef bitfield = Load(VariableType::INT32(), method, extraLiteralInfoOffset);
407 
408     GateRef kind = Int32And(Int32LSR(bitfield, Int32(MethodLiteral::FunctionKindBits::START_BIT)),
409                             Int32((1LU << MethodLiteral::FunctionKindBits::SIZE) - 1));
410     return Int32LessThanOrEqual(kind, Int32(static_cast<int32_t>(FunctionKind::CLASS_CONSTRUCTOR)));
411 }
412 
IsDerived(GateRef ctor)413 inline GateRef CircuitBuilder::IsDerived(GateRef ctor)
414 {
415     GateRef method = GetMethodFromFunction(ctor);
416     GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
417     GateRef bitfield = Load(VariableType::INT32(), method, extraLiteralInfoOffset);
418 
419     GateRef kind = Int32And(Int32LSR(bitfield, Int32(MethodLiteral::FunctionKindBits::START_BIT)),
420                             Int32((1LU << MethodLiteral::FunctionKindBits::SIZE) - 1));
421     return Int32Equal(kind, Int32(static_cast<int32_t>(FunctionKind::DERIVED_CONSTRUCTOR)));
422 }
423 
GetMethodId(GateRef func)424 inline GateRef CircuitBuilder::GetMethodId(GateRef func)
425 {
426     GateRef method = GetMethodFromFunction(func);
427     GateRef literalInfoOffset = IntPtr(Method::LITERAL_INFO_OFFSET);
428     GateRef literalInfo = Load(VariableType::INT64(), method, literalInfoOffset);
429     GateRef methodId = Int64And(Int64LSR(literalInfo, Int64(MethodLiteral::MethodIdBits::START_BIT)),
430         Int64((1LLU << MethodLiteral::MethodIdBits::SIZE) - 1));
431     return methodId;
432 }
433 
GetBuiltinsId(GateRef func)434 inline GateRef CircuitBuilder::GetBuiltinsId(GateRef func)
435 {
436     GateRef method = GetMethodFromFunction(func);
437     GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
438     GateRef extraLiteralInfo = Load(VariableType::INT64(), method, extraLiteralInfoOffset);
439     GateRef builtinsId = Int64And(Int64LSR(extraLiteralInfo, Int64(MethodLiteral::BuiltinIdBits::START_BIT)),
440         Int64((1LLU << MethodLiteral::BuiltinIdBits::SIZE) - 1));
441     return builtinsId;
442 }
443 }
444 #endif  // ECMASCRIPT_COMPILER_HCR_CIRCUIT_BUILDER_H
445