• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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_JS_HCLASS_H
17 #define ECMASCRIPT_JS_HCLASS_H
18 
19 #include "ecmascript/ecma_macros.h"
20 #include "ecmascript/elements.h"
21 #include "ecmascript/js_tagged_value.h"
22 #include "ecmascript/mem/tagged_object.h"
23 #include "ecmascript/mem/barriers.h"
24 #include "ecmascript/mem/slots.h"
25 #include "ecmascript/mem/visitor.h"
26 #include "ecmascript/property_attributes.h"
27 
28 #include "libpandabase/utils/bit_field.h"
29 
30 /*
31  *                         JS Object and JS HClass Layout
32  *
33  *      Properties                         JS Object                    JS HClass
34  *      +------------+                     +------------+               +------------------+
35  *      |arrayHClass + <---------|         |JS HClass   +-------------->|   meta hclass    |
36  *      +------------+           |         +------------+               +------------------+
37  *      | property 0 |           |         |Hash        |               |   hclass level   |
38  *      +------------+           |         +------------+               +------------------+
39  *      | property 1 |           |-------  |Properties  |               |   supers[]       |
40  *      +------------+                     +------------+               +------------------+
41  *      |...         |           |-------  |Elements    |               |   vtable[]       |
42  *      +------------+           |         +------------+               +------------------+
43  *                               |         |inl-prop-0  |               |   prototype      |
44  *      Elements                 |         +------------+               +------------------+
45  *      +------------+           |         |inl-prop-1  |               |   layout         |
46  *      |arrayHClass + <---------|         +------------+               +------------------+
47  *      +------------+                     |...         |               |   transitions    |
48  *      | value 0    |                     +------------+               +------------------+
49  *      +------------+                                                  |    parent        |
50  *      | value 1    |                                                  +------------------+
51  *      +------------+                                                  |ProtoChangeMarker |
52  *      |...         |                                                  +------------------+
53  *      +------------+                                                  |    EnumCache     |
54  *                                                                      +------------------+
55  *
56  *                          Proto: [[Prototype]] in Ecma spec
57  *                          Layout: record key and attr
58  *                          ProtoChangeMarker, ProtoChangeDetails: monitor [[prototype]] chain
59  *                          EnumCache: use for for-in syntax
60  *
61  */
62 namespace panda::ecmascript {
63 class ProtoChangeDetails;
64 class PropertyLookupResult;
65 class SharedHeap;
66 class JSSharedArray;
67 class LayoutInfo;
68 class NameDictionary;
69 namespace pgo {
70     class HClassLayoutDesc;
71     class PGOHClassTreeDesc;
72     class PGOHandler;
73 } // namespace pgo
74 using HClassLayoutDesc = pgo::HClassLayoutDesc;
75 using PGOHClassTreeDesc = pgo::PGOHClassTreeDesc;
76 using PGOHandler = pgo::PGOHandler;
77 
78 struct Reference;
79 
80 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
81 #define JSTYPE_DECL       /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
82     INVALID = 0,          /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
83         JS_OBJECT,        /* JS_OBJECT_FIRST ////////////////////////////////////////////////////////////////////// */ \
84         JS_SHARED_OBJECT, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
85         JS_REALM,         /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
86         JS_FUNCTION_BASE, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
87         JS_FUNCTION,      /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
88         JS_SHARED_FUNCTION,            /* /////////////////////////////////////////////////////////////////-PADDING */ \
89         JS_PROXY_REVOC_FUNCTION,       /* /////////////////////////////////////////////////////////////////-PADDING */ \
90         JS_PROMISE_REACTIONS_FUNCTION, /* /////////////////////////////////////////////////////////////////-PADDING */ \
91         JS_PROMISE_EXECUTOR_FUNCTION,  /* /////////////////////////////////////////////////////////////////-PADDING */ \
92         JS_ASYNC_MODULE_FULFILLED_FUNCTION, /* ////////////////////////////////////////////////////////////-PADDING */ \
93         JS_ASYNC_MODULE_REJECTED_FUNCTION, /* /////////////////////////////////////////////////////////////-PADDING */ \
94         JS_ASYNC_FROM_SYNC_ITER_UNWARP_FUNCTION,  /* //////////////////////////////////////////////////////-PADDING */ \
95         JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION,  /* //////////////////////////////////////////////////////-PADDING */ \
96         JS_ASYNC_GENERATOR_RESUME_NEXT_RETURN_PROCESSOR_RST_FTN, /* ///////////////////////////////////////-PADDING */ \
97         JS_PROMISE_ANY_REJECT_ELEMENT_FUNCTION,  /* ///////////////////////////////////////////////////////-PADDING */ \
98         JS_PROMISE_ALL_SETTLED_ELEMENT_FUNCTION,  /* //////////////////////////////////////////////////////-PADDING */ \
99         JS_PROMISE_FINALLY_FUNCTION,  /* //////////////////////////////////////////////////////////////////-PADDING */ \
100         JS_PROMISE_VALUE_THUNK_OR_THROWER_FUNCTION,  /* ///////////////////////////////////////////////////-PADDING */ \
101         JS_GENERATOR_FUNCTION, /* /////////////////////////////////////////////////////////////////////////-PADDING */ \
102         JS_ASYNC_GENERATOR_FUNCTION,  /* //////////////////////////////////////////////////////////////////-PADDING */ \
103         JS_ASYNC_FUNCTION, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
104         JS_SHARED_ASYNC_FUNCTION, /* //////////////////////////////////////////////////////////////////////-PADDING */ \
105         JS_INTL_BOUND_FUNCTION, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
106         JS_ASYNC_AWAIT_STATUS_FUNCTION, /* ////////////////////////////////////////////////////////////////-PADDING */ \
107         JS_BOUND_FUNCTION, /*  //////////////////////////////////////////////////////////////////////////////////// */ \
108                                                                                                                        \
109         JS_ERROR,           /* JS_ERROR_FIRST /////////////////////////////////////////////////////////////-PADDING */ \
110         JS_EVAL_ERROR,      /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
111         JS_RANGE_ERROR,     /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
112         JS_REFERENCE_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
113         JS_TYPE_ERROR,      /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
114         JS_AGGREGATE_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
115         JS_URI_ERROR,       /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
116         JS_SYNTAX_ERROR,    /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
117         JS_OOM_ERROR,       /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
118         JS_TERMINATION_ERROR, /* JS_ERROR_LAST //////////////////////////////////////////////////////////////////// */ \
119                                                                                                                        \
120         JS_REG_EXP,  /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
121         JS_SET,      /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
122         JS_SHARED_SET, /*  ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
123         JS_MAP,      /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
124         JS_SHARED_MAP, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
125         JS_WEAK_MAP, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
126         JS_WEAK_SET, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
127         JS_WEAK_REF, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
128         JS_FINALIZATION_REGISTRY, /* //////////////////////////////////////////////////////////////////////-PADDING */ \
129         JS_DATE,     /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
130         JS_ITERATOR, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
131         JS_ASYNCITERATOR, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
132         JS_ASYNC_FROM_SYNC_ITERATOR, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
133         JS_FORIN_ITERATOR,       /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
134         JS_MAP_ITERATOR,         /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
135         JS_SHARED_MAP_ITERATOR,  /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
136         JS_SET_ITERATOR,         /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
137         JS_SHARED_SET_ITERATOR,  /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
138         JS_REG_EXP_ITERATOR,        /* ////////////////////////////////////////////////////////////////////-PADDING */ \
139         JS_API_ARRAYLIST_ITERATOR, /* /////////////////////////////////////////////////////////////////////-PADDING */ \
140         JS_API_DEQUE_ITERATOR,   /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
141         JS_API_HASHMAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
142         JS_API_HASHSET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
143         JS_API_LIGHT_WEIGHT_MAP_ITERATOR, /* //////////////////////////////////////////////////////////////-PADDING */ \
144         JS_API_LIGHT_WEIGHT_SET_ITERATOR,  /* /////////////////////////////////////////////////////////////-PADDING */ \
145         JS_API_PLAIN_ARRAY_ITERATOR,  /* //////////////////////////////////////////////////////////////////-PADDING */ \
146         JS_API_QUEUE_ITERATOR,   /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
147         JS_API_STACK_ITERATOR,   /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
148         JS_API_TREEMAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
149         JS_API_TREESET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
150         JS_API_VECTOR_ITERATOR,  /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
151         JS_API_BITVECTOR_ITERATOR,  /* ////////////////////////////////////////////////////////////////////-PADDING */ \
152         JS_API_LINKED_LIST_ITERATOR, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
153         JS_API_LIST_ITERATOR,    /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
154         JS_ARRAY_ITERATOR,       /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
155         JS_SHARED_ARRAY_ITERATOR, /* //////////////////////////////////////////////////////////////////////-PADDING */ \
156         JS_SEGMENT_ITERATOR,       /* /////////////////////////////////////////////////////////////////////-PADDING */ \
157         JS_STRING_ITERATOR,      /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
158         JS_INTL, /* ///////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
159         JS_LOCALE, /* /////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
160         JS_DATE_TIME_FORMAT, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
161         JS_RELATIVE_TIME_FORMAT, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
162         JS_NUMBER_FORMAT, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
163         JS_COLLATOR, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
164         JS_PLURAL_RULES, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
165         JS_DISPLAYNAMES, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
166         JS_LIST_FORMAT,  /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
167         JS_SEGMENTER, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
168         JS_SEGMENTS, /* /////////////////////////////////////////////////////////////////////////// ///////-PADDING */ \
169                                                                                                                        \
170         JS_ARRAY_BUFFER, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
171         JS_SHARED_ARRAY_BUFFER, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
172         JS_SENDABLE_ARRAY_BUFFER, /* //////////////////////////////////////////////////////////////////////-PADDING */ \
173         JS_PROMISE,      /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
174         JS_DATA_VIEW,    /* /////////////////////////////////////////////////////////////////////////////////////// */ \
175         JS_ARGUMENTS, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
176         JS_GENERATOR_OBJECT,  /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
177         JS_ASYNC_GENERATOR_OBJECT,  /* ////////////////////////////////////////////////////////////////////-PADDING */ \
178         JS_ASYNC_FUNC_OBJECT, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
179                                                                                                                        \
180         /* SPECIAL indexed objects begin, DON'T CHANGE HERE ///////////////////////////////////////////////-PADDING */ \
181         JS_ARRAY,       /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
182         JS_SHARED_ARRAY, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
183         JS_API_ARRAY_LIST, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
184         JS_API_LIGHT_WEIGHT_MAP,      /* //////////////////////////////////////////////////////////////////-PADDING */ \
185         JS_API_LIGHT_WEIGHT_SET, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
186         JS_API_VECTOR,     /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
187         JS_API_BITVECTOR,     /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
188         JS_API_LINKED_LIST, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
189         JS_API_LIST,       /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
190         JS_API_HASH_MAP,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
191         JS_API_HASH_SET,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
192         JS_API_TREE_MAP,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
193         JS_API_TREE_SET,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
194         JS_API_DEQUE,      /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
195         JS_API_STACK,      /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
196         JS_API_PLAIN_ARRAY, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
197         JS_API_QUEUE,      /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
198         JS_TYPED_ARRAY, /* JS_TYPED_ARRAY_FIRST /////////////////////////////////////////////////////////////////// */ \
199         JS_INT8_ARRAY,  /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
200         JS_UINT8_ARRAY, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
201         JS_UINT8_CLAMPED_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
202         JS_INT16_ARRAY,         /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
203         JS_UINT16_ARRAY,        /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
204         JS_INT32_ARRAY,         /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
205         JS_UINT32_ARRAY,        /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
206         JS_FLOAT32_ARRAY,       /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
207         JS_FLOAT64_ARRAY,       /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
208         JS_BIGINT64_ARRAY,      /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
209         JS_BIGUINT64_ARRAY,     /* JS_TYPED_ARRAY_LAST //////////////////////////////////////////////////////////// */ \
210         JS_SHARED_TYPED_ARRAY,  /* JS_SHARED_TYPED_ARRAY_FIRST //////////////////////////////////////////////////// */ \
211         JS_SHARED_INT8_ARRAY,  /* /////////////////////////////////////////////////////////////////////////-PADDING */ \
212         JS_SHARED_UINT8_ARRAY, /* /////////////////////////////////////////////////////////////////////////-PADDING */ \
213         JS_SHARED_UINT8_CLAMPED_ARRAY, /* /////////////////////////////////////////////////////////////////-PADDING */ \
214         JS_SHARED_INT16_ARRAY,         /* /////////////////////////////////////////////////////////////////-PADDING */ \
215         JS_SHARED_UINT16_ARRAY,        /* /////////////////////////////////////////////////////////////////-PADDING */ \
216         JS_SHARED_INT32_ARRAY,         /* /////////////////////////////////////////////////////////////////-PADDING */ \
217         JS_SHARED_UINT32_ARRAY,        /* /////////////////////////////////////////////////////////////////-PADDING */ \
218         JS_SHARED_FLOAT32_ARRAY,       /* /////////////////////////////////////////////////////////////////-PADDING */ \
219         JS_SHARED_FLOAT64_ARRAY,       /* /////////////////////////////////////////////////////////////////-PADDING */ \
220         JS_SHARED_BIGINT64_ARRAY,      /* /////////////////////////////////////////////////////////////////-PADDING */ \
221         JS_SHARED_BIGUINT64_ARRAY,     /* JS_SHARED_TYPED_ARRAY_LAST ////////////////////////////////////////////// */ \
222         JS_PRIMITIVE_REF, /* number\boolean\string. SPECIAL indexed objects end, DON'T CHANGE HERE ////////-PADDING */ \
223         JS_MODULE_NAMESPACE, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
224         JS_CJS_MODULE, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
225         JS_CJS_EXPORTS, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
226         JS_CJS_REQUIRE, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
227         NATIVE_MODULE_FAILURE_INFO, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
228         JS_GLOBAL_OBJECT, /* JS_OBJECT_LAST////////////////////////////////////////////////////////////////-PADDING */ \
229         JS_PROXY, /* ECMA_OBJECT_LAST ///////////////////////////////////////////////////////////////////////////// */ \
230                                                                                                                        \
231         HCLASS,       /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
232         LINE_STRING,   /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
233         CONSTANT_STRING,  /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
234         SLICED_STRING,  /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
235         TREE_STRING,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
236         BIGINT,       /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
237         TAGGED_ARRAY, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
238         MUTANT_TAGGED_ARRAY, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
239         BYTE_ARRAY,   /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
240         LEXICAL_ENV,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
241         SENDABLE_ENV,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */\
242         TAGGED_DICTIONARY, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
243         CONSTANT_POOL, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
244         PROFILE_TYPE_INFO, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
245         COW_MUTANT_TAGGED_ARRAY, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
246         COW_TAGGED_ARRAY, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
247         LINKED_NODE,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
248         RB_TREENODE,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
249         FREE_OBJECT_WITH_ONE_FIELD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
250         FREE_OBJECT_WITH_NONE_FIELD, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
251         FREE_OBJECT_WITH_TWO_FIELD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
252         JS_NATIVE_POINTER, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
253         GLOBAL_ENV,        /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
254         ACCESSOR_DATA,     /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
255         INTERNAL_ACCESSOR, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
256         SYMBOL, /* ////////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
257         JS_GENERATOR_CONTEXT, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
258         PROTOTYPE_HANDLER,    /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
259         TRANSITION_HANDLER,   /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
260         TRANS_WITH_PROTO_HANDLER,    /* ///////////////////////////////////////////////////////////////////-PADDING */ \
261         STORE_TS_HANDLER,       /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
262         PROPERTY_BOX, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
263         PROTO_CHANGE_MARKER, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
264         MARKER_CELL, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
265         TRACK_INFO,  /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
266         PROTOTYPE_INFO,     /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
267         TEMPLATE_MAP,       /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
268         PROGRAM,       /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
269         METHOD,     /* ////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
270         CLASS_LITERAL,      /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
271                                                                                                                        \
272         PROMISE_CAPABILITY, /* JS_RECORD_FIRST //////////////////////////////////////////////////////////////////// */ \
273         PROMISE_RECORD,     /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
274         RESOLVING_FUNCTIONS_RECORD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
275         PROMISE_REACTIONS,          /* ////////////////////////////////////////////////////////////////////-PADDING */ \
276         ASYNC_GENERATOR_REQUEST, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
277         ASYNC_ITERATOR_RECORD,   /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
278         PROMISE_ITERATOR_RECORD,    /* ////////////////////////////////////////////////////////////////////-PADDING */ \
279         MICRO_JOB_QUEUE, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
280         PENDING_JOB,     /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
281         MODULE_RECORD, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
282         SOURCE_TEXT_MODULE_RECORD, /* /////////////////////////////////////////////////////////////////////-PADDING */ \
283         IMPORTENTRY_RECORD, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
284         LOCAL_EXPORTENTRY_RECORD, /* //////////////////////////////////////////////////////////////////////-PADDING */ \
285         INDIRECT_EXPORTENTRY_RECORD, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
286         STAR_EXPORTENTRY_RECORD, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
287         RESOLVEDBINDING_RECORD, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
288         RESOLVEDINDEXBINDING_RECORD, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
289         RESOLVEDRECORDINDEXBINDING_RECORD, /* /////////////////////////////////////////////////////////////-PADDING */ \
290         RESOLVEDRECORDBINDING_RECORD, /* //////////////////////////////////////////////////////////////////-PADDING */ \
291         CELL_RECORD,          /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
292         COMPLETION_RECORD, /* JS_RECORD_LAST ////////////////////////////////////////////////////////////////////// */ \
293         MACHINE_CODE_OBJECT,                                                                                           \
294         CLASS_INFO_EXTRACTOR, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
295                                                                                                                        \
296         PROFILE_TYPE_INFO_CELL_0,  /* PROFILE_TYPE_INFO_CELL_FIRST ////////////////////////////////////////-PADDING */ \
297         PROFILE_TYPE_INFO_CELL_1,  /* /////////////////////////////////////////////////////////////////////-PADDING */ \
298         PROFILE_TYPE_INFO_CELL_N,  /* PROFILE_TYPE_INFO_CELL_LAST /////////////////////////////////////////-PADDING */ \
299                                                                                                                        \
300         EXTRA_PROFILE_TYPE_INFO,      /* //////////////////////////////////////////////////////////////////-PADDING */ \
301         FUNCTION_TEMPLATE,            /* //////////////////////////////////////////////////////////////////-PADDING */ \
302                                                                                                                        \
303         VTABLE,                       /* //////////////////////////////////////////////////////////////////-PADDING */ \
304         AOT_LITERAL_INFO, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
305         TYPE_LAST = AOT_LITERAL_INFO, /* //////////////////////////////////////////////////////////////////-PADDING */ \
306                                                                                                                        \
307         JS_FUNCTION_FIRST = JS_FUNCTION, /* ///////////////////////////////////////////////////////////////-PADDING */ \
308         JS_FUNCTION_LAST = JS_ASYNC_AWAIT_STATUS_FUNCTION, /* /////////////////////////////////////////////-PADDING */ \
309                                                                                                                        \
310         JS_OBJECT_FIRST = JS_OBJECT, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
311         JS_OBJECT_LAST = JS_GLOBAL_OBJECT, /* /////////////////////////////////////////////////////////////-PADDING */ \
312                                                                                                                        \
313         ECMA_OBJECT_FIRST = JS_OBJECT, /* /////////////////////////////////////////////////////////////////-PADDING */ \
314         ECMA_OBJECT_LAST = JS_PROXY,    /* ////////////////////////////////////////////////////////////////-PADDING */ \
315                                                                                                                        \
316         JS_ERROR_FIRST = JS_ERROR,      /* ////////////////////////////////////////////////////////////////-PADDING */ \
317         JS_ERROR_LAST = JS_TERMINATION_ERROR,    /* ///////////////////////////////////////////////////////-PADDING */ \
318                                                                                                                        \
319         JS_ITERATOR_FIRST = JS_ITERATOR,      /* //////////////////////////////////////////////////////////-PADDING */ \
320         JS_ITERATOR_LAST = JS_STRING_ITERATOR, /* /////////////////////////////////////////////////////////-PADDING */ \
321                                                                                                                        \
322         JS_RECORD_FIRST = PROMISE_CAPABILITY, /* //////////////////////////////////////////////////////////-PADDING */ \
323         JS_RECORD_LAST = COMPLETION_RECORD,    /* /////////////////////////////////////////////////////////-PADDING */ \
324                                                                                                                        \
325         JS_TYPED_ARRAY_FIRST = JS_TYPED_ARRAY, /* /////////////////////////////////////////////////////////-PADDING */ \
326         JS_TYPED_ARRAY_LAST = JS_BIGUINT64_ARRAY, /* //////////////////////////////////////////////////////-PADDING */ \
327                                                                                                                        \
328         JS_SHARED_TYPED_ARRAY_FIRST = JS_SHARED_TYPED_ARRAY, /* ///////////////////////////////////////////-PADDING */ \
329         JS_SHARED_TYPED_ARRAY_LAST = JS_SHARED_BIGUINT64_ARRAY, /* ////////////////////////////////////////-PADDING */ \
330                                                                                                                        \
331         MODULE_RECORD_FIRST = MODULE_RECORD, /* ///////////////////////////////////////////////////////////-PADDING */ \
332         MODULE_RECORD_LAST = SOURCE_TEXT_MODULE_RECORD, /* ////////////////////////////////////////////////-PADDING */ \
333                                                                                                                        \
334         STRING_FIRST = LINE_STRING, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
335         STRING_LAST = TREE_STRING,  /* ////////////////////////////////////////////////////////////////////-PADDING */ \
336                                                                                                                        \
337         PROFILE_TYPE_INFO_CELL_FIRST = PROFILE_TYPE_INFO_CELL_0,  /* //////////////////////////////////////-PADDING */ \
338         PROFILE_TYPE_INFO_CELL_LAST = PROFILE_TYPE_INFO_CELL_N    /* //////////////////////////////////////-PADDING */
339 
340 enum class JSType : uint8_t {
341     JSTYPE_DECL,
342 };
343 
344 // EnumCache:
345 // +-----------------+----------------------+
346 // |      value      |     status           |
347 // +-----------------+----------------------+
348 // |      null       |    uninitialized     |
349 // ------------------------------------------
350 // |    undefined    | a fast path to check |
351 // |                 | simple enum cache    |
352 // ------------------------------------------
353 // |   empty array   |  enum keys is empty  |
354 // ------------------------------------------
355 // | non-empty array |  non-empty enum keys |
356 // +----------------------------------------+
357 // structure of non-empty array of EnumCache:
358 // 0: an int value indicating enum cache kind
359 // 1-n: enum keys
360 namespace EnumCache {
361 static constexpr uint32_t ENUM_CACHE_HEADER_SIZE = 1;
362 static constexpr uint32_t ENUM_CACHE_KIND_OFFSET = 0;
363 enum class EnumCacheKind : uint8_t {
364     NONE = 0,
365     SIMPLE,        // simple enum cache(used in for-in)
366                    // make sure EnumCache is empty array only for SIMPLE
367     PROTOCHAIN,    // enum cache with prototype chain info(used in for-in)
368     ONLY_OWN_KEYS  // enum cache with only own enum keys(used in Json.stringify and Object.keys)
369 };
370 
371 }  // namespace EnumCache
372 
373 struct TransitionResult {
374     bool isTagged;
375     bool isTransition;
376     JSTaggedValue value;
377 };
378 
379 class JSHClass : public TaggedObject {
380 public:
381     static constexpr int TYPE_BITFIELD_NUM = 8;
382     static constexpr int LEVEL_BTTFIELD_NUM = 5;
383     static constexpr int ELEMENTS_KIND_BITFIELD_NUM = 5;
384     static constexpr int CONSTRUCTION_COUNTER_BITFIELD_NUM = 3;
385     static constexpr unsigned BITS_PER_BYTE = 8;
386     using ObjectTypeBits = BitField<JSType, 0, TYPE_BITFIELD_NUM>;                                // 8
387     using CallableBit = ObjectTypeBits::NextFlag;                                                 // 9
388     using ConstructorBit = CallableBit::NextFlag;                                                 // 10
389     using ExtensibleBit = ConstructorBit::NextFlag;                                               // 11
390     using IsPrototypeBit = ExtensibleBit::NextFlag;                                               // 12
391     using ElementsKindBits = IsPrototypeBit::NextField<ElementsKind, ELEMENTS_KIND_BITFIELD_NUM>; // 13-17
392     using DictionaryElementBits = ElementsKindBits::NextFlag;                                     // 18
393     using IsDictionaryBit = DictionaryElementBits::NextFlag;                                      // 19
394     using IsStableElementsBit = IsDictionaryBit::NextFlag;                                        // 20
395     using HasConstructorBits = IsStableElementsBit::NextFlag;                                     // 21
396     using IsClassConstructorOrPrototypeBit = HasConstructorBits::NextFlag;                        // 22
397     using IsNativeBindingObjectBit = IsClassConstructorOrPrototypeBit::NextFlag;                  // 23
398     using IsAOTBit = IsNativeBindingObjectBit::NextFlag;                                          // 24
399     using IsJSArrayPrototypeModifiedBit = IsAOTBit::NextFlag;                                     // 25
400     using IsJSFunctionBit = IsJSArrayPrototypeModifiedBit::NextFlag;                              // 26
401     using IsOnHeap = IsJSFunctionBit::NextFlag;                                                   // 27
402     using IsJSSharedBit = IsOnHeap::NextFlag;                                                     // 28
403     using ConstructionCounterBits = IsJSSharedBit::NextField<uint8_t, CONSTRUCTION_COUNTER_BITFIELD_NUM>; // 29-31
404     using BitFieldLastBit = ConstructionCounterBits;
405     static_assert(BitFieldLastBit::START_BIT + BitFieldLastBit::SIZE <= sizeof(uint32_t) * BITS_PER_BYTE, "Invalid");
406 
407     static constexpr int DEFAULT_CAPACITY_OF_IN_OBJECTS = 4;
408     static constexpr int OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED = 5;
409     static constexpr int OFFSET_MAX_OBJECT_SIZE_IN_WORDS =
410         PropertyAttributes::MAX_FAST_PROPS_CAPACITY_LOG2 + OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED;
411     static constexpr int MAX_OBJECT_SIZE_IN_WORDS = (1U << OFFSET_MAX_OBJECT_SIZE_IN_WORDS) - 1;
412     static constexpr uint8_t SLACK_TRACKING_COUNT = (1 << CONSTRUCTION_COUNTER_BITFIELD_NUM) - 1;
413 
414     using NumberOfPropsBits = BitField<uint32_t, 0, PropertyAttributes::MAX_FAST_PROPS_CAPACITY_LOG2>;         // 10
415     using InlinedPropsStartBits = NumberOfPropsBits::NextField<uint32_t,
416         OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED>;                                                      // 15
417     using ObjectSizeInWordsBits = InlinedPropsStartBits::NextField<uint32_t, OFFSET_MAX_OBJECT_SIZE_IN_WORDS>; // 30
418     using HasDeletePropertyBit = ObjectSizeInWordsBits::NextFlag;                                              //
419     using IsAllTaggedPropBit = HasDeletePropertyBit::NextFlag;                                                 // 32
420     using BitField1LastBit = IsAllTaggedPropBit;
421     static_assert(BitField1LastBit::START_BIT + BitField1LastBit::SIZE <= sizeof(uint32_t) * BITS_PER_BYTE, "Invalid");
422 
Cast(const TaggedObject * object)423     static JSHClass *Cast(const TaggedObject *object)
424     {
425         ASSERT(JSTaggedValue(object).IsJSHClass());
426         return static_cast<JSHClass *>(const_cast<TaggedObject *>(object));
427     }
428 
429     inline size_t SizeFromJSHClass(TaggedObject *header);
430     inline bool HasReferenceField();
431 
432     // size need to add inlined property numbers
433     void Initialize(const JSThread *thread, uint32_t size, JSType type, uint32_t inlinedProps);
434     // for sharedHeap
435     void Initialize(const JSThread *thread, uint32_t size, JSType type, uint32_t inlinedProps,
436         const JSHandle<JSTaggedValue> &layout);
437     static JSHandle<JSHClass> Clone(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
438                                     bool withInlinedProperties = false, uint32_t inlinedProps = 0);
439     static JSHandle<JSHClass> CloneAndIncInlinedProperties(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
440                                                            uint32_t expectedOfProperties);
441     static JSHandle<JSHClass> CloneWithoutInlinedProperties(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
442     static JSHandle<JSHClass> CloneWithElementsKind(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
443                                                     const ElementsKind kind, bool isPrototype);
444 
445     static void TransitionElementsToDictionary(const JSThread *thread, const JSHandle<JSObject> &obj);
446     static void OptimizeAsFastElements(const JSThread *thread, JSHandle<JSObject> obj);
447     static void OptimizeAsFastProperties(const JSThread *thread, const JSHandle<JSObject> &obj,
448                                          const std::vector<int> &indexArray = {}, bool isDictionary = false);
449     template<bool checkDuplicateKeys = false>
450     static JSHandle<JSHClass> SetPropertyOfObjHClass(const JSThread *thread, JSHandle<JSHClass> &jshclass,
451                                                      const JSHandle<JSTaggedValue> &key,
452                                                      const PropertyAttributes &attr,
453                                                      const Representation &rep,
454                                                      bool withInlinedProperties = false,
455                                                      uint32_t numInlinedProps = 0);
456     static void PUBLIC_API AddProperty(const JSThread *thread, const JSHandle<JSObject> &obj,
457                                        const JSHandle<JSTaggedValue> &key, const PropertyAttributes &attr,
458                                        const Representation &rep = Representation::NONE);
459 
460     static void ProcessAotHClassTransition(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
461                                            const JSHandle<JSHClass> newHClass, const JSTaggedValue &key);
462 
463     inline static void RestoreElementsKindToGeneric(JSHClass *newJsHClass);
464 
465     static JSHandle<JSHClass> TransitionExtension(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
466     static void ReBuildFunctionInheritanceRelationship(const JSThread *thread,
467                                                        const JSHandle<JSTaggedValue> &proto,
468                                                        const JSHandle<JSTaggedValue> &baseIhc,
469                                                        const JSHandle<JSTaggedValue> &transIhc,
470                                                        const JSHandle<JSTaggedValue> &transPhc);
471     static JSHandle<JSHClass> TransitionProto(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
472                                               const JSHandle<JSTaggedValue> &proto, bool isChangeProto = false);
473     static JSHClass *FindTransitionProtoForAOT(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
474                                                const JSHandle<JSTaggedValue> &proto);
475     static JSHandle<JSHClass> TransProtoWithoutLayout(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
476                                                       const JSHandle<JSTaggedValue> &proto);
477     static JSHandle<JSHClass> CloneWithAddProto(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
478                                                 const JSHandle<JSTaggedValue> &key,
479                                                 const JSHandle<JSTaggedValue> &proto);
480     static void TransitionToDictionary(const JSThread *thread, const JSHandle<JSObject> &obj);
481     static void TransitionForRepChange(const JSThread *thread, const JSHandle<JSObject> &receiver,
482                                        const JSHandle<JSTaggedValue> &key, PropertyAttributes attr);
483     static void TransitionForElementsKindChange(const JSThread *thread, const JSHandle<JSObject> &receiver,
484                                          const ElementsKind newKind);
485     static bool IsInitialArrayHClassWithElementsKind(const JSThread *thread, const JSHClass *targetHClass,
486                                                      const ElementsKind targetKind);
487     static bool PUBLIC_API TransitToElementsKindUncheck(const JSThread *thread, const JSHandle<JSObject> &obj,
488                                                         ElementsKind newKind);
489     static void PUBLIC_API TransitToElementsKind(const JSThread *thread, const JSHandle<JSArray> &array,
490                                                  ElementsKind newKind = ElementsKind::NONE);
491     static bool PUBLIC_API TransitToElementsKind(const JSThread *thread, const JSHandle<JSObject> &object,
492                                                  const JSHandle<JSTaggedValue> &value,
493                                                  ElementsKind kind = ElementsKind::NONE);
494     static TransitionResult PUBLIC_API ConvertOrTransitionWithRep(const JSThread *thread,
495         const JSHandle<JSObject> &receiver, const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value,
496         PropertyAttributes &attr);
497     static void PUBLIC_API MergeRepresentation(const JSThread *thread, JSHClass *oldJsHClass, JSHClass *newJsHClass);
498 
499     static void UpdateFieldType(JSHClass *hclass, const PropertyAttributes &attr);
500     static JSHClass *FindFieldOwnHClass(JSHClass *hclass, const PropertyAttributes &attr);
501     static void VisitAndUpdateLayout(JSHClass *ownHClass, const PropertyAttributes &attr);
502     static void VisitTransitionAndUpdateObjSize(JSHClass *ownHClass, uint32_t finalInObjPropsNum);
503     static uint32_t VisitTransitionAndFindMaxNumOfProps(JSHClass *ownHClass);
504 
505     static JSHandle<JSTaggedValue> PUBLIC_API EnableProtoChangeMarker(
506         const JSThread *thread, const JSHandle<JSHClass> &jshclass);
507     static JSHandle<JSTaggedValue> EnablePHCProtoChangeMarker(
508         const JSThread *thread, const JSHandle<JSHClass> &protoClass);
509 
510     static void NotifyHclassChanged(const JSThread *thread, JSHandle<JSHClass> oldHclass, JSHandle<JSHClass> newHclass,
511                                     JSTaggedValue addedKey = JSTaggedValue::Undefined());
512 
513     static void NotifyHClassChangedForNotFound(const JSThread *thread, const JSHandle<JSHClass> oldHclass,
514                                                const JSHandle<JSHClass> newHclass, const JSTaggedValue addedKey);
515 
516     static void NotifyAccessorChanged(const JSThread *thread, JSHandle<JSHClass> hclass);
517 
518     static void RegisterOnProtoChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
519 
520     static bool UnregisterOnProtoChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
521 
522     static JSHandle<ProtoChangeDetails> GetProtoChangeDetails(const JSThread *thread,
523                                                               const JSHandle<JSHClass> &jshclass);
524 
525     static JSHandle<ProtoChangeDetails> GetProtoChangeDetails(const JSThread *thread, const JSHandle<JSObject> &obj);
526 
527     inline void UpdatePropertyMetaData(const JSThread *thread, const JSTaggedValue &key,
528                                       const PropertyAttributes &metaData);
529 
530     template<bool isOnlyIncludeNotFound>
531     static void MarkProtoChanged(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
532 
533     template<bool isOnlyIncludeNotFound = false>
534     static void NoticeThroughChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
535                                    JSTaggedValue addedKey = JSTaggedValue::Undefined());
536 
537     static void RefreshUsers(const JSThread *thread, const JSHandle<JSHClass> &oldHclass,
538                              const JSHandle<JSHClass> &newHclass);
539 
540     static bool IsNeedNotifyHclassChangedForAotTransition(const JSThread *thread, const JSHandle<JSHClass> &hclass,
541                                                           JSTaggedValue key);
542 
543     static JSHandle<JSTaggedValue> ParseKeyFromPGOCString(ObjectFactory* factory,
544                                                           const CString& key,
545                                                           const PGOHandler& handler);
546 
ClearBitField()547     inline void ClearBitField()
548     {
549         SetProfileType(0ULL);
550         SetBitField(0UL);
551         SetBitField1(0UL);
552     }
553 
GetObjectType()554     inline JSType GetObjectType() const
555     {
556         uint32_t bits = GetBitField();
557         return ObjectTypeBits::Decode(bits);
558     }
559 
SetObjectType(JSType type)560     inline void SetObjectType(JSType type)
561     {
562         uint32_t bits = GetBitField();
563         uint32_t newVal = ObjectTypeBits::Update(bits, type);
564         SetBitField(newVal);
565     }
566 
SetCallable(bool flag)567     inline void SetCallable(bool flag)
568     {
569         CallableBit::Set<uint32_t>(flag, GetBitFieldAddr());
570     }
571 
SetConstructor(bool flag)572     inline void SetConstructor(bool flag) const
573     {
574         ConstructorBit::Set<uint32_t>(flag, GetBitFieldAddr());
575     }
576 
SetExtensible(bool flag)577     inline void SetExtensible(bool flag) const
578     {
579         ExtensibleBit::Set<uint32_t>(flag, GetBitFieldAddr());
580     }
581 
SetIsPrototype(bool flag)582     inline void SetIsPrototype(bool flag) const
583     {
584         IsPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
585     }
586 
SetClassConstructor(bool flag)587     inline void SetClassConstructor(bool flag) const
588     {
589         IsClassConstructorOrPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
590         SetConstructor(flag);
591     }
592 
SetClassPrototype(bool flag)593     inline void SetClassPrototype(bool flag) const
594     {
595         IsClassConstructorOrPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
596         SetIsPrototype(flag);
597     }
598 
SetIsNativeBindingObject(bool flag)599     inline void SetIsNativeBindingObject(bool flag) const
600     {
601         IsNativeBindingObjectBit::Set<uint32_t>(flag, GetBitFieldAddr());
602     }
603 
SetIsDictionaryMode(bool flag)604     inline void SetIsDictionaryMode(bool flag) const
605     {
606         IsDictionaryBit::Set<uint32_t>(flag, GetBitFieldAddr());
607     }
608 
SetIsJSArrayPrototypeModified(bool flag)609     inline void SetIsJSArrayPrototypeModified(bool flag) const
610     {
611         IsJSArrayPrototypeModifiedBit::Set<uint32_t>(flag, GetBitFieldAddr());
612     }
613 
SetAOT(bool flag)614     inline void SetAOT(bool flag) const
615     {
616         IsAOTBit::Set<uint32_t>(flag, GetBitFieldAddr());
617     }
618 
SetIsJSFunction(bool flag)619     inline void SetIsJSFunction(bool flag) const
620     {
621         IsJSFunctionBit::Set<uint32_t>(flag, GetBitFieldAddr());
622     }
623 
SetIsOnHeap(bool flag)624     inline void SetIsOnHeap(bool flag) const
625     {
626         IsOnHeap::Set<uint32_t>(flag, GetBitFieldAddr());
627     }
628 
IsJSObject()629     inline bool IsJSObject() const
630     {
631         return IsJSTypeObject(GetObjectType());
632     }
633 
IsOnlyJSObject()634     inline bool IsOnlyJSObject() const
635     {
636         return GetObjectType() == JSType::JS_OBJECT;
637     }
638 
IsECMAObject()639     inline bool IsECMAObject() const
640     {
641         JSType jsType = GetObjectType();
642         return (JSType::ECMA_OBJECT_FIRST <= jsType && jsType <= JSType::ECMA_OBJECT_LAST);
643     }
644 
ShouldSetDefaultSupers()645     inline bool ShouldSetDefaultSupers() const
646     {
647         return IsECMAObject() || IsStringOrSymbol();
648     }
649 
IsRealm()650     inline bool IsRealm() const
651     {
652         return GetObjectType() == JSType::JS_REALM;
653     }
654 
IsHClass()655     inline bool IsHClass() const
656     {
657         return GetObjectType() == JSType::HCLASS;
658     }
659 
IsString()660     inline bool IsString() const
661     {
662         JSType jsType = GetObjectType();
663         return (JSType::STRING_FIRST <= jsType && jsType <= JSType::STRING_LAST);
664     }
665 
IsLineString()666     inline bool IsLineString() const
667     {
668         return GetObjectType() == JSType::LINE_STRING;
669     }
670 
IsConstantString()671     inline bool IsConstantString() const
672     {
673         return GetObjectType() == JSType::CONSTANT_STRING;
674     }
675 
IsSlicedString()676     inline bool IsSlicedString() const
677     {
678         return GetObjectType() == JSType::SLICED_STRING;
679     }
680 
IsTreeString()681     inline bool IsTreeString() const
682     {
683         return GetObjectType() == JSType::TREE_STRING;
684     }
685 
IsBigInt()686     inline bool IsBigInt() const
687     {
688         return GetObjectType() == JSType::BIGINT;
689     }
690 
IsSymbol()691     inline bool IsSymbol() const
692     {
693         return GetObjectType() == JSType::SYMBOL;
694     }
695 
IsStringOrSymbol()696     inline bool IsStringOrSymbol() const
697     {
698         JSType jsType = GetObjectType();
699         return (JSType::STRING_FIRST <= jsType && jsType <= JSType::STRING_LAST) || (jsType == JSType::SYMBOL);
700     }
701 
IsTaggedArray()702     inline bool IsTaggedArray() const
703     {
704         JSType jsType = GetObjectType();
705         switch (jsType) {
706             case JSType::TAGGED_ARRAY:
707             case JSType::TAGGED_DICTIONARY:
708             case JSType::LEXICAL_ENV:
709             case JSType::SENDABLE_ENV:
710             case JSType::CONSTANT_POOL:
711             case JSType::PROFILE_TYPE_INFO:
712             case JSType::AOT_LITERAL_INFO:
713             case JSType::VTABLE:
714             case JSType::COW_TAGGED_ARRAY:
715             case JSType::MUTANT_TAGGED_ARRAY:
716             case JSType::COW_MUTANT_TAGGED_ARRAY:
717                 return true;
718             default:
719                 return false;
720         }
721     }
722 
IsLexicalEnv()723     inline bool IsLexicalEnv() const
724     {
725         return GetObjectType() == JSType::LEXICAL_ENV;
726     }
IsByteArray()727     inline bool IsByteArray() const
728     {
729         return GetObjectType() == JSType::BYTE_ARRAY;
730     }
731 
IsConstantPool()732     inline bool IsConstantPool() const
733     {
734         return GetObjectType() == JSType::CONSTANT_POOL;
735     }
736 
IsDictionary()737     inline bool IsDictionary() const
738     {
739         return GetObjectType() == JSType::TAGGED_DICTIONARY;
740     }
741 
IsCOWArray()742     inline bool IsCOWArray() const
743     {
744         // Copy On Write ARRAY.
745         return GetObjectType() == JSType::COW_TAGGED_ARRAY ||
746                GetObjectType() == JSType::COW_MUTANT_TAGGED_ARRAY;
747     }
748 
IsMutantTaggedArray()749     inline bool IsMutantTaggedArray() const
750     {
751         return GetObjectType() == JSType::MUTANT_TAGGED_ARRAY ||
752                GetObjectType() == JSType::COW_MUTANT_TAGGED_ARRAY;
753     }
754 
IsJSNativePointer()755     inline bool IsJSNativePointer() const
756     {
757         return GetObjectType() == JSType::JS_NATIVE_POINTER;
758     }
759 
IsJSSymbol()760     inline bool IsJSSymbol() const
761     {
762         return GetObjectType() == JSType::SYMBOL;
763     }
764 
IsJSArray()765     inline bool IsJSArray() const
766     {
767         return GetObjectType() == JSType::JS_ARRAY;
768     }
769 
IsTypedArray()770     inline bool IsTypedArray() const
771     {
772         JSType jsType = GetObjectType();
773         return (JSType::JS_TYPED_ARRAY_FIRST < jsType && jsType <= JSType::JS_TYPED_ARRAY_LAST);
774     }
775 
IsSharedTypedArray()776     inline bool IsSharedTypedArray() const
777     {
778         JSType jsType = GetObjectType();
779         return (JSType::JS_SHARED_TYPED_ARRAY_FIRST < jsType && jsType <= JSType::JS_SHARED_TYPED_ARRAY_LAST);
780     }
781 
HasOrdinaryGet()782     inline bool HasOrdinaryGet() const
783     {
784         return (IsSpecialContainer() || IsModuleNamespace() || IsBigInt64Array());
785     }
786 
IsJSTypedArray()787     inline bool IsJSTypedArray() const
788     {
789         return GetObjectType() == JSType::JS_TYPED_ARRAY;
790     }
791 
IsJSInt8Array()792     inline bool IsJSInt8Array() const
793     {
794         return GetObjectType() == JSType::JS_INT8_ARRAY;
795     }
796 
IsJSUint8Array()797     inline bool IsJSUint8Array() const
798     {
799         return GetObjectType() == JSType::JS_UINT8_ARRAY;
800     }
801 
IsJSUint8ClampedArray()802     inline bool IsJSUint8ClampedArray() const
803     {
804         return GetObjectType() == JSType::JS_UINT8_CLAMPED_ARRAY;
805     }
806 
IsJSInt16Array()807     inline bool IsJSInt16Array() const
808     {
809         return GetObjectType() == JSType::JS_INT16_ARRAY;
810     }
811 
IsJSUint16Array()812     inline bool IsJSUint16Array() const
813     {
814         return GetObjectType() == JSType::JS_UINT16_ARRAY;
815     }
816 
IsJSInt32Array()817     inline bool IsJSInt32Array() const
818     {
819         return GetObjectType() == JSType::JS_INT32_ARRAY;
820     }
821 
IsJSUint32Array()822     inline bool IsJSUint32Array() const
823     {
824         return GetObjectType() == JSType::JS_UINT32_ARRAY;
825     }
826 
IsJSFloat32Array()827     inline bool IsJSFloat32Array() const
828     {
829         return GetObjectType() == JSType::JS_FLOAT32_ARRAY;
830     }
831 
IsJSFloat64Array()832     inline bool IsJSFloat64Array() const
833     {
834         return GetObjectType() == JSType::JS_FLOAT64_ARRAY;
835     }
836 
IsJSBigInt64Array()837     inline bool IsJSBigInt64Array() const
838     {
839         return GetObjectType() == JSType::JS_BIGINT64_ARRAY;
840     }
841 
IsJSBigUint64Array()842     inline bool IsJSBigUint64Array() const
843     {
844         return GetObjectType() == JSType::JS_BIGUINT64_ARRAY;
845     }
846 
IsJSSharedTypedArray()847     inline bool IsJSSharedTypedArray() const
848     {
849         return GetObjectType() == JSType::JS_SHARED_TYPED_ARRAY;
850     }
851 
IsJSSharedInt8Array()852     inline bool IsJSSharedInt8Array() const
853     {
854         return GetObjectType() == JSType::JS_SHARED_INT8_ARRAY;
855     }
856 
IsJSSharedUint8Array()857     inline bool IsJSSharedUint8Array() const
858     {
859         return GetObjectType() == JSType::JS_SHARED_UINT8_ARRAY;
860     }
861 
IsJSSharedUint8ClampedArray()862     inline bool IsJSSharedUint8ClampedArray() const
863     {
864         return GetObjectType() == JSType::JS_SHARED_UINT8_CLAMPED_ARRAY;
865     }
866 
IsJSSharedInt16Array()867     inline bool IsJSSharedInt16Array() const
868     {
869         return GetObjectType() == JSType::JS_SHARED_INT16_ARRAY;
870     }
871 
IsJSSharedUint16Array()872     inline bool IsJSSharedUint16Array() const
873     {
874         return GetObjectType() == JSType::JS_SHARED_UINT16_ARRAY;
875     }
876 
IsJSSharedInt32Array()877     inline bool IsJSSharedInt32Array() const
878     {
879         return GetObjectType() == JSType::JS_SHARED_INT32_ARRAY;
880     }
881 
IsJSSharedUint32Array()882     inline bool IsJSSharedUint32Array() const
883     {
884         return GetObjectType() == JSType::JS_SHARED_UINT32_ARRAY;
885     }
886 
IsJSSharedFloat32Array()887     inline bool IsJSSharedFloat32Array() const
888     {
889         return GetObjectType() == JSType::JS_SHARED_FLOAT32_ARRAY;
890     }
891 
IsJSSharedFloat64Array()892     inline bool IsJSSharedFloat64Array() const
893     {
894         return GetObjectType() == JSType::JS_SHARED_FLOAT64_ARRAY;
895     }
896 
IsJSSharedBigInt64Array()897     inline bool IsJSSharedBigInt64Array() const
898     {
899         return GetObjectType() == JSType::JS_SHARED_BIGINT64_ARRAY;
900     }
901 
IsJSSharedBigUint64Array()902     inline bool IsJSSharedBigUint64Array() const
903     {
904         return GetObjectType() == JSType::JS_SHARED_BIGUINT64_ARRAY;
905     }
906 
IsBigInt64Array()907     inline bool IsBigInt64Array() const
908     {
909         JSType jsType = GetObjectType();
910         return jsType == JSType::JS_SHARED_BIGUINT64_ARRAY || jsType == JSType::JS_SHARED_BIGINT64_ARRAY ||
911                jsType == JSType::JS_BIGUINT64_ARRAY || jsType == JSType::JS_BIGINT64_ARRAY;
912     }
913 
IsJsGlobalEnv()914     inline bool IsJsGlobalEnv() const
915     {
916         return GetObjectType() == JSType::GLOBAL_ENV;
917     }
918 
IsJSFunctionBase()919     inline bool IsJSFunctionBase() const
920     {
921         JSType jsType = GetObjectType();
922         return jsType >= JSType::JS_FUNCTION_BASE && jsType <= JSType::JS_BOUND_FUNCTION;
923     }
924 
IsJsBoundFunction()925     inline bool IsJsBoundFunction() const
926     {
927         return GetObjectType() == JSType::JS_BOUND_FUNCTION;
928     }
929 
IsJSIntlBoundFunction()930     inline bool IsJSIntlBoundFunction() const
931     {
932         return GetObjectType() == JSType::JS_INTL_BOUND_FUNCTION;
933     }
934 
IsJSProxyRevocFunction()935     inline bool IsJSProxyRevocFunction() const
936     {
937         return GetObjectType() == JSType::JS_PROXY_REVOC_FUNCTION;
938     }
939 
IsJSAsyncFunction()940     inline bool IsJSAsyncFunction() const
941     {
942         return GetObjectType() == JSType::JS_ASYNC_FUNCTION || GetObjectType() == JSType::JS_SHARED_ASYNC_FUNCTION;
943     }
944 
IsJSSharedAsyncFunction()945     inline bool IsJSSharedAsyncFunction() const
946     {
947         return GetObjectType() == JSType::JS_SHARED_ASYNC_FUNCTION;
948     }
949 
IsJSAsyncAwaitStatusFunction()950     inline bool IsJSAsyncAwaitStatusFunction() const
951     {
952         return GetObjectType() == JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION;
953     }
954 
IsJSPromiseReactionFunction()955     inline bool IsJSPromiseReactionFunction() const
956     {
957         return GetObjectType() == JSType::JS_PROMISE_REACTIONS_FUNCTION;
958     }
959 
IsJSPromiseExecutorFunction()960     inline bool IsJSPromiseExecutorFunction() const
961     {
962         return GetObjectType() == JSType::JS_PROMISE_EXECUTOR_FUNCTION;
963     }
964 
IsJSAsyncModuleFulfilledFunction()965     inline bool IsJSAsyncModuleFulfilledFunction() const
966     {
967         return GetObjectType() == JSType::JS_ASYNC_MODULE_FULFILLED_FUNCTION;
968     }
969 
IsJSAsyncModuleRejectedFunction()970     inline bool IsJSAsyncModuleRejectedFunction() const
971     {
972         return GetObjectType() == JSType::JS_ASYNC_MODULE_REJECTED_FUNCTION;
973     }
974 
IsJSAsyncFromSyncIterUnwarpFunction()975     inline bool IsJSAsyncFromSyncIterUnwarpFunction() const
976     {
977         return GetObjectType() == JSType::JS_ASYNC_FROM_SYNC_ITER_UNWARP_FUNCTION;
978     }
979 
IsJSPromiseAllResolveElementFunction()980     inline bool IsJSPromiseAllResolveElementFunction() const
981     {
982         return GetObjectType() == JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION;
983     }
984 
IsJSAsyncGeneratorResNextRetProRstFtn()985     inline bool IsJSAsyncGeneratorResNextRetProRstFtn() const
986     {
987         return GetObjectType() == JSType::JS_ASYNC_GENERATOR_RESUME_NEXT_RETURN_PROCESSOR_RST_FTN;
988     }
989 
IsJSPromiseAnyRejectElementFunction()990     inline bool IsJSPromiseAnyRejectElementFunction() const
991     {
992         return GetObjectType() == JSType::JS_PROMISE_ANY_REJECT_ELEMENT_FUNCTION;
993     }
994 
IsJSPromiseAllSettledElementFunction()995     inline bool IsJSPromiseAllSettledElementFunction() const
996     {
997         return GetObjectType() == JSType::JS_PROMISE_ALL_SETTLED_ELEMENT_FUNCTION;
998     }
999 
IsJSPromiseFinallyFunction()1000     inline bool IsJSPromiseFinallyFunction() const
1001     {
1002         return GetObjectType() == JSType::JS_PROMISE_FINALLY_FUNCTION;
1003     }
1004 
IsJSPromiseValueThunkOrThrowerFunction()1005     inline bool IsJSPromiseValueThunkOrThrowerFunction() const
1006     {
1007         return GetObjectType() == JSType::JS_PROMISE_VALUE_THUNK_OR_THROWER_FUNCTION;
1008     }
1009 
IsMicroJobQueue()1010     inline bool IsMicroJobQueue() const
1011     {
1012         return GetObjectType() == JSType::MICRO_JOB_QUEUE;
1013     }
1014 
IsPendingJob()1015     inline bool IsPendingJob() const
1016     {
1017         return GetObjectType() == JSType::PENDING_JOB;
1018     }
1019 
IsJsPrimitiveRef()1020     inline bool IsJsPrimitiveRef() const
1021     {
1022         return GetObjectType() == JSType::JS_PRIMITIVE_REF;
1023     }
1024 
IsJSSet()1025     bool IsJSSet() const
1026     {
1027         return GetObjectType() == JSType::JS_SET;
1028     }
1029 
IsJSSharedSet()1030     bool IsJSSharedSet() const
1031     {
1032         return GetObjectType() == JSType::JS_SHARED_SET;
1033     }
1034 
IsJSMap()1035     bool IsJSMap() const
1036     {
1037         return GetObjectType() == JSType::JS_MAP;
1038     }
1039 
IsJSSharedMap()1040     bool IsJSSharedMap() const
1041     {
1042         return GetObjectType() == JSType::JS_SHARED_MAP;
1043     }
1044 
IsJSWeakMap()1045     bool IsJSWeakMap() const
1046     {
1047         return GetObjectType() == JSType::JS_WEAK_MAP;
1048     }
1049 
IsJSWeakSet()1050     bool IsJSWeakSet() const
1051     {
1052         return GetObjectType() == JSType::JS_WEAK_SET;
1053     }
1054 
IsJSWeakRef()1055     bool IsJSWeakRef() const
1056     {
1057         return GetObjectType() == JSType::JS_WEAK_REF;
1058     }
1059 
IsJSFinalizationRegistry()1060     bool IsJSFinalizationRegistry() const
1061     {
1062         return GetObjectType() == JSType::JS_FINALIZATION_REGISTRY;
1063     }
1064 
IsJSFunction()1065     bool IsJSFunction() const
1066     {
1067         return GetObjectType() >= JSType::JS_FUNCTION_FIRST && GetObjectType() <= JSType::JS_FUNCTION_LAST;
1068     }
1069 
IsJSSharedFunction()1070     bool IsJSSharedFunction() const
1071     {
1072         return GetObjectType() == JSType::JS_SHARED_FUNCTION;
1073     }
1074 
IsJSShared()1075     bool IsJSShared() const
1076     {
1077         uint32_t bits = GetBitField();
1078         return IsJSSharedBit::Decode(bits);
1079     }
1080 
SetIsJSShared(bool flag)1081     inline void SetIsJSShared(bool flag) const
1082     {
1083         IsJSSharedBit::Set<uint32_t>(flag, GetBitFieldAddr());
1084     }
1085 
IsJSError()1086     inline bool IsJSError() const
1087     {
1088         JSType jsType = GetObjectType();
1089         return jsType >= JSType::JS_ERROR_FIRST && jsType <= JSType::JS_ERROR_LAST;
1090     }
1091 
IsArguments()1092     inline bool IsArguments() const
1093     {
1094         return GetObjectType() == JSType::JS_ARGUMENTS;
1095     }
1096 
IsDate()1097     inline bool IsDate() const
1098     {
1099         return GetObjectType() == JSType::JS_DATE;
1100     }
1101 
IsJSRegExp()1102     inline bool IsJSRegExp() const
1103     {
1104         return GetObjectType() == JSType::JS_REG_EXP;
1105     }
1106 
IsJSProxy()1107     inline bool IsJSProxy() const
1108     {
1109         return GetObjectType() == JSType::JS_PROXY;
1110     }
1111 
IsJSLocale()1112     inline bool IsJSLocale() const
1113     {
1114         return GetObjectType() == JSType::JS_LOCALE;
1115     }
1116 
IsJSIntl()1117     inline bool IsJSIntl() const
1118     {
1119         return GetObjectType() == JSType::JS_INTL;
1120     }
1121 
IsJSDateTimeFormat()1122     inline bool IsJSDateTimeFormat() const
1123     {
1124         return GetObjectType() == JSType::JS_DATE_TIME_FORMAT;
1125     }
1126 
IsJSRelativeTimeFormat()1127     inline bool IsJSRelativeTimeFormat() const
1128     {
1129         return GetObjectType() == JSType::JS_RELATIVE_TIME_FORMAT;
1130     }
1131 
IsJSNumberFormat()1132     inline bool IsJSNumberFormat() const
1133     {
1134         return GetObjectType() == JSType::JS_NUMBER_FORMAT;
1135     }
1136 
IsJSCollator()1137     inline bool IsJSCollator() const
1138     {
1139         return GetObjectType() == JSType::JS_COLLATOR;
1140     }
1141 
IsJSPluralRules()1142     inline bool IsJSPluralRules() const
1143     {
1144         return GetObjectType() == JSType::JS_PLURAL_RULES;
1145     }
1146 
IsJSDisplayNames()1147     inline bool IsJSDisplayNames() const
1148     {
1149         return GetObjectType() == JSType::JS_DISPLAYNAMES;
1150     }
1151 
IsJSSegmenter()1152     inline bool IsJSSegmenter() const
1153     {
1154         return GetObjectType() == JSType::JS_SEGMENTER;
1155     }
1156 
IsJSSegments()1157     inline bool IsJSSegments() const
1158     {
1159         return GetObjectType() == JSType::JS_SEGMENTS;
1160     }
1161 
IsJSSegmentIterator()1162     inline bool IsJSSegmentIterator() const
1163     {
1164         return GetObjectType() == JSType::JS_SEGMENT_ITERATOR;
1165     }
1166 
IsJSListFormat()1167     inline bool IsJSListFormat() const
1168     {
1169         return GetObjectType() == JSType::JS_LIST_FORMAT;
1170     }
1171 
IsMethod()1172     inline bool IsMethod() const
1173     {
1174         return GetObjectType() == JSType::METHOD;
1175     }
1176 
IsClassLiteral()1177     inline bool IsClassLiteral() const
1178     {
1179         return GetObjectType() == JSType::CLASS_LITERAL;
1180     }
1181 
1182     // non ECMA standard jsapi containers.
IsSpecialContainer()1183     inline bool IsSpecialContainer() const
1184     {
1185         return GetObjectType() >= JSType::JS_API_ARRAY_LIST && GetObjectType() <= JSType::JS_API_QUEUE;
1186     }
1187 
IsRegularObject()1188     inline bool IsRegularObject() const
1189     {
1190         return GetObjectType() < JSType::JS_API_ARRAY_LIST;
1191     }
1192 
IsJSAPIArrayList()1193     inline bool IsJSAPIArrayList() const
1194     {
1195         return GetObjectType() == JSType::JS_API_ARRAY_LIST;
1196     }
1197 
IsJSAPIArrayListIterator()1198     inline bool IsJSAPIArrayListIterator() const
1199     {
1200         return GetObjectType() == JSType::JS_API_ARRAYLIST_ITERATOR;
1201     }
IsJSAPILightWeightMap()1202     inline bool IsJSAPILightWeightMap() const
1203     {
1204         return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_MAP;
1205     }
IsJSAPILightWeightMapIterator()1206     inline bool IsJSAPILightWeightMapIterator() const
1207     {
1208         return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_MAP_ITERATOR;
1209     }
IsJSAPILightWeightSet()1210     inline bool IsJSAPILightWeightSet() const
1211     {
1212         return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_SET;
1213     }
IsJSAPILightWeightSetIterator()1214     inline bool IsJSAPILightWeightSetIterator() const
1215     {
1216         return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_SET_ITERATOR;
1217     }
IsJSAPIStack()1218     inline bool IsJSAPIStack() const
1219     {
1220         return GetObjectType() == JSType::JS_API_STACK;
1221     }
IsJSAPIDeque()1222     inline bool IsJSAPIDeque() const
1223     {
1224         return GetObjectType() == JSType::JS_API_DEQUE;
1225     }
IsLinkedNode()1226     inline bool IsLinkedNode() const
1227     {
1228         return GetObjectType() == JSType::LINKED_NODE;
1229     }
1230 
IsRBTreeNode()1231     inline bool IsRBTreeNode() const
1232     {
1233         return GetObjectType() == JSType::RB_TREENODE;
1234     }
1235 
IsJSAPIHashMap()1236     inline bool IsJSAPIHashMap() const
1237     {
1238         return GetObjectType() == JSType::JS_API_HASH_MAP;
1239     }
1240 
IsJSAPIHashSet()1241     inline bool IsJSAPIHashSet() const
1242     {
1243         return GetObjectType() == JSType::JS_API_HASH_SET;
1244     }
1245 
IsJSAPIHashMapIterator()1246     inline bool IsJSAPIHashMapIterator() const
1247     {
1248         return GetObjectType() == JSType::JS_API_HASHMAP_ITERATOR;
1249     }
1250 
IsJSAPIHashSetIterator()1251     inline bool IsJSAPIHashSetIterator() const
1252     {
1253         return GetObjectType() == JSType::JS_API_HASHSET_ITERATOR;
1254     }
IsJSAPIQueue()1255     inline bool IsJSAPIQueue() const
1256     {
1257         return GetObjectType() == JSType::JS_API_QUEUE;
1258     }
1259 
IsJSAPIPlainArray()1260     inline bool IsJSAPIPlainArray() const
1261     {
1262         return GetObjectType() == JSType::JS_API_PLAIN_ARRAY;
1263     }
1264 
IsJSAPIQueueIterator()1265     inline bool IsJSAPIQueueIterator() const
1266     {
1267         return GetObjectType() == JSType::JS_API_QUEUE_ITERATOR;
1268     }
IsJSAPIList()1269     inline bool IsJSAPIList() const
1270     {
1271         return GetObjectType() == JSType::JS_API_LIST;
1272     }
IsJSAPILinkedList()1273     inline bool IsJSAPILinkedList() const
1274     {
1275         return GetObjectType() == JSType::JS_API_LINKED_LIST;
1276     }
IsJSAPITreeMap()1277     inline bool IsJSAPITreeMap() const
1278     {
1279         return GetObjectType() == JSType::JS_API_TREE_MAP;
1280     }
1281 
IsJSAPITreeSet()1282     inline bool IsJSAPITreeSet() const
1283     {
1284         return GetObjectType() == JSType::JS_API_TREE_SET;
1285     }
1286 
IsJSAPITreeMapIterator()1287     inline bool IsJSAPITreeMapIterator() const
1288     {
1289         return GetObjectType() == JSType::JS_API_TREEMAP_ITERATOR;
1290     }
1291 
IsJSAPITreeSetIterator()1292     inline bool IsJSAPITreeSetIterator() const
1293     {
1294         return GetObjectType() == JSType::JS_API_TREESET_ITERATOR;
1295     }
IsJSAPIVector()1296     inline bool IsJSAPIVector() const
1297     {
1298         return GetObjectType() == JSType::JS_API_VECTOR;
1299     }
IsJSAPIVectorIterator()1300     inline bool IsJSAPIVectorIterator() const
1301     {
1302         return GetObjectType() == JSType::JS_API_VECTOR_ITERATOR;
1303     }
IsJSAPIBitVector()1304     inline bool IsJSAPIBitVector() const
1305     {
1306         return GetObjectType() == JSType::JS_API_BITVECTOR;
1307     }
IsJSAPIBitVectorIterator()1308     inline bool IsJSAPIBitVectorIterator() const
1309     {
1310         return GetObjectType() == JSType::JS_API_BITVECTOR_ITERATOR;
1311     }
1312 
IsAccessorData()1313     inline bool IsAccessorData() const
1314     {
1315         return GetObjectType() == JSType::ACCESSOR_DATA;
1316     }
1317 
IsInternalAccessor()1318     inline bool IsInternalAccessor() const
1319     {
1320         return GetObjectType() == JSType::INTERNAL_ACCESSOR;
1321     }
1322 
IsIterator()1323     inline bool IsIterator() const
1324     {
1325         JSType jsType = GetObjectType();
1326         return jsType >= JSType::JS_ITERATOR_FIRST && jsType <= JSType::JS_ITERATOR_LAST;
1327     }
1328 
IsAsyncIterator()1329     inline bool IsAsyncIterator() const
1330     {
1331         return GetObjectType() == JSType::JS_ASYNCITERATOR;
1332     }
1333 
IsAsyncFromSyncIterator()1334     inline bool IsAsyncFromSyncIterator() const
1335     {
1336         return GetObjectType() == JSType::JS_ASYNC_FROM_SYNC_ITERATOR;
1337     }
1338 
IsForinIterator()1339     inline bool IsForinIterator() const
1340     {
1341         return GetObjectType() == JSType::JS_FORIN_ITERATOR;
1342     }
1343 
IsStringIterator()1344     inline bool IsStringIterator() const
1345     {
1346         return GetObjectType() == JSType::JS_STRING_ITERATOR;
1347     }
1348 
IsArrayBuffer()1349     inline bool IsArrayBuffer() const
1350     {
1351         return GetObjectType() == JSType::JS_ARRAY_BUFFER;
1352     }
1353 
IsSharedArrayBuffer()1354     inline bool IsSharedArrayBuffer() const
1355     {
1356         return GetObjectType() == JSType::JS_SHARED_ARRAY_BUFFER;
1357     }
1358 
IsSendableArrayBuffer()1359     inline bool IsSendableArrayBuffer() const
1360     {
1361         return GetObjectType() == JSType::JS_SENDABLE_ARRAY_BUFFER;
1362     }
1363 
IsDataView()1364     inline bool IsDataView() const
1365     {
1366         return GetObjectType() == JSType::JS_DATA_VIEW;
1367     }
1368 
IsJSSetIterator()1369     inline bool IsJSSetIterator() const
1370     {
1371         return GetObjectType() == JSType::JS_SET_ITERATOR;
1372     }
1373 
1374     // iterator of shared set
IsJSSharedSetIterator()1375     inline bool IsJSSharedSetIterator() const
1376     {
1377         return GetObjectType() == JSType::JS_SHARED_SET_ITERATOR;
1378     }
1379 
IsJSRegExpIterator()1380     inline bool IsJSRegExpIterator() const
1381     {
1382         return GetObjectType() == JSType::JS_REG_EXP_ITERATOR;
1383     }
1384 
IsJSMapIterator()1385     inline bool IsJSMapIterator() const
1386     {
1387         return GetObjectType() == JSType::JS_MAP_ITERATOR;
1388     }
1389 
1390     // iterator of shared map
IsJSSharedMapIterator()1391     inline bool IsJSSharedMapIterator() const
1392     {
1393         return GetObjectType() == JSType::JS_SHARED_MAP_ITERATOR;
1394     }
1395 
IsJSArrayIterator()1396     inline bool IsJSArrayIterator() const
1397     {
1398         return GetObjectType() == JSType::JS_ARRAY_ITERATOR;
1399     }
1400 
IsJSSharedArrayIterator()1401     inline bool IsJSSharedArrayIterator() const
1402     {
1403         return GetObjectType() == JSType::JS_SHARED_ARRAY_ITERATOR;
1404     }
1405 
IsJSAPIPlainArrayIterator()1406     inline bool IsJSAPIPlainArrayIterator() const
1407     {
1408         return GetObjectType() == JSType::JS_API_PLAIN_ARRAY_ITERATOR;
1409     }
1410 
IsJSAPIDequeIterator()1411     inline bool IsJSAPIDequeIterator() const
1412     {
1413         return GetObjectType() == JSType::JS_API_DEQUE_ITERATOR;
1414     }
1415 
IsJSAPIStackIterator()1416     inline bool IsJSAPIStackIterator() const
1417     {
1418         return GetObjectType() == JSType::JS_API_STACK_ITERATOR;
1419     }
1420 
IsJSAPILinkedListIterator()1421     inline bool IsJSAPILinkedListIterator() const
1422     {
1423         return GetObjectType() == JSType::JS_API_LINKED_LIST_ITERATOR;
1424     }
1425 
IsJSAPIListIterator()1426     inline bool IsJSAPIListIterator() const
1427     {
1428         return GetObjectType() == JSType::JS_API_LIST_ITERATOR;
1429     }
1430 
IsPrototypeHandler()1431     inline bool IsPrototypeHandler() const
1432     {
1433         return GetObjectType() == JSType::PROTOTYPE_HANDLER;
1434     }
1435 
IsTransitionHandler()1436     inline bool IsTransitionHandler() const
1437     {
1438         return GetObjectType() == JSType::TRANSITION_HANDLER;
1439     }
1440 
IsTransWithProtoHandler()1441     inline bool IsTransWithProtoHandler() const
1442     {
1443         return GetObjectType() == JSType::TRANS_WITH_PROTO_HANDLER;
1444     }
1445 
IsStoreAOTHandler()1446     inline bool IsStoreAOTHandler() const
1447     {
1448         return GetObjectType() == JSType::STORE_TS_HANDLER;
1449     }
1450 
IsPropertyBox()1451     inline bool IsPropertyBox() const
1452     {
1453         return GetObjectType() == JSType::PROPERTY_BOX;
1454     }
IsProtoChangeMarker()1455     inline bool IsProtoChangeMarker() const
1456     {
1457         return GetObjectType() == JSType::PROTO_CHANGE_MARKER;
1458     }
1459 
IsMarkerCell()1460     inline bool IsMarkerCell() const
1461     {
1462         return GetObjectType() == JSType::MARKER_CELL;
1463     }
1464 
IsTrackInfoObject()1465     inline bool IsTrackInfoObject() const
1466     {
1467         return GetObjectType() == JSType::TRACK_INFO;
1468     }
1469 
IsProtoChangeDetails()1470     inline bool IsProtoChangeDetails() const
1471     {
1472         return GetObjectType() == JSType::PROTOTYPE_INFO;
1473     }
1474 
IsProgram()1475     inline bool IsProgram() const
1476     {
1477         return GetObjectType() == JSType::PROGRAM;
1478     }
1479 
IsClassInfoExtractor()1480     inline bool IsClassInfoExtractor() const
1481     {
1482         return GetObjectType() == JSType::CLASS_INFO_EXTRACTOR;
1483     }
1484 
IsCallable()1485     inline bool IsCallable() const
1486     {
1487         uint32_t bits = GetBitField();
1488         return CallableBit::Decode(bits);
1489     }
1490 
IsConstructor()1491     inline bool IsConstructor() const
1492     {
1493         uint32_t bits = GetBitField();
1494         return ConstructorBit::Decode(bits);
1495     }
1496 
IsExtensible()1497     inline bool IsExtensible() const
1498     {
1499         uint32_t bits = GetBitField();
1500         return ExtensibleBit::Decode(bits);
1501     }
1502 
IsPrototype()1503     inline bool IsPrototype() const
1504     {
1505         uint32_t bits = GetBitField();
1506         return IsPrototypeBit::Decode(bits);
1507     }
1508 
IsClassConstructor()1509     inline bool IsClassConstructor() const
1510     {
1511         uint32_t bits = GetBitField();
1512         return IsClassConstructorOrPrototypeBit::Decode(bits) && IsConstructor();
1513     }
1514 
IsJSGlobalObject()1515     inline bool IsJSGlobalObject() const
1516     {
1517         return GetObjectType() == JSType::JS_GLOBAL_OBJECT;
1518     }
1519 
IsClassPrototype()1520     inline bool IsClassPrototype() const
1521     {
1522         uint32_t bits = GetBitField();
1523         return IsClassConstructorOrPrototypeBit::Decode(bits) && IsPrototype();
1524     }
1525 
IsNativeBindingObject()1526     inline bool IsNativeBindingObject() const
1527     {
1528         uint32_t bits = GetBitField();
1529         return IsNativeBindingObjectBit::Decode(bits);
1530     }
1531 
IsDictionaryMode()1532     inline bool IsDictionaryMode() const
1533     {
1534         uint32_t bits = GetBitField();
1535         return IsDictionaryBit::Decode(bits);
1536     }
1537 
IsJSArrayPrototypeModifiedFromBitField()1538     inline bool IsJSArrayPrototypeModifiedFromBitField() const
1539     {
1540         uint32_t bits = GetBitField();
1541         return IsJSArrayPrototypeModifiedBit::Decode(bits);
1542     }
1543 
1544     // created from AOT
IsAOT()1545     inline bool IsAOT() const
1546     {
1547         uint32_t bits = GetBitField();
1548         return IsAOTBit::Decode(bits);
1549     }
1550 
IsJSFunctionFromBitField()1551     inline bool IsJSFunctionFromBitField() const
1552     {
1553         uint32_t bits = GetBitField();
1554         return IsJSFunctionBit::Decode(bits);
1555     }
1556 
IsOnHeapFromBitField()1557     inline bool IsOnHeapFromBitField() const
1558     {
1559         uint32_t bits = GetBitField();
1560         return IsOnHeap::Decode(bits);
1561     }
1562 
IsGeneratorFunction()1563     inline bool IsGeneratorFunction() const
1564     {
1565         return GetObjectType() == JSType::JS_GENERATOR_FUNCTION;
1566     }
1567 
IsAsyncGeneratorFunction()1568     inline bool IsAsyncGeneratorFunction() const
1569     {
1570         return GetObjectType() == JSType::JS_ASYNC_GENERATOR_FUNCTION;
1571     }
1572 
IsGeneratorObject()1573     inline bool IsGeneratorObject() const
1574     {
1575         JSType jsType = GetObjectType();
1576         return jsType == JSType::JS_GENERATOR_OBJECT || jsType == JSType::JS_ASYNC_FUNC_OBJECT;
1577     }
1578 
IsAsyncGeneratorObject()1579     inline bool IsAsyncGeneratorObject() const
1580     {
1581         JSType jsType = GetObjectType();
1582         return jsType == JSType::JS_ASYNC_GENERATOR_OBJECT;
1583     }
1584 
IsGeneratorContext()1585     inline bool IsGeneratorContext() const
1586     {
1587         return GetObjectType() == JSType::JS_GENERATOR_CONTEXT;
1588     }
1589 
IsAsyncGeneratorRequest()1590     inline bool IsAsyncGeneratorRequest() const
1591     {
1592         JSType jsType = GetObjectType();
1593         return jsType == JSType::ASYNC_GENERATOR_REQUEST;
1594     }
1595 
IsAsyncIteratorRecord()1596     inline bool IsAsyncIteratorRecord() const
1597     {
1598         JSType jsType = GetObjectType();
1599         return jsType == JSType::ASYNC_ITERATOR_RECORD;
1600     }
1601 
IsAsyncFuncObject()1602     inline bool IsAsyncFuncObject() const
1603     {
1604         return GetObjectType() == JSType::JS_ASYNC_FUNC_OBJECT;
1605     }
1606 
IsJSPromise()1607     inline bool IsJSPromise() const
1608     {
1609         return GetObjectType() == JSType::JS_PROMISE;
1610     }
1611 
IsResolvingFunctionsRecord()1612     inline bool IsResolvingFunctionsRecord() const
1613     {
1614         return GetObjectType() == JSType::RESOLVING_FUNCTIONS_RECORD;
1615     }
1616 
IsPromiseRecord()1617     inline bool IsPromiseRecord() const
1618     {
1619         return GetObjectType() == JSType::PROMISE_RECORD;
1620     }
1621 
IsPromiseIteratorRecord()1622     inline bool IsPromiseIteratorRecord() const
1623     {
1624         return GetObjectType() == JSType::PROMISE_ITERATOR_RECORD;
1625     }
1626 
IsPromiseCapability()1627     inline bool IsPromiseCapability() const
1628     {
1629         return GetObjectType() == JSType::PROMISE_CAPABILITY;
1630     }
1631 
IsPromiseReaction()1632     inline bool IsPromiseReaction() const
1633     {
1634         return GetObjectType() == JSType::PROMISE_REACTIONS;
1635     }
1636 
IsCellRecord()1637     inline bool IsCellRecord() const
1638     {
1639         return GetObjectType() == JSType::CELL_RECORD;
1640     }
1641 
IsCompletionRecord()1642     inline bool IsCompletionRecord() const
1643     {
1644         return GetObjectType() == JSType::COMPLETION_RECORD;
1645     }
1646 
IsRecord()1647     inline bool IsRecord() const
1648     {
1649         JSType jsType = GetObjectType();
1650         return jsType >= JSType::JS_RECORD_FIRST && jsType <= JSType::JS_RECORD_LAST;
1651     }
1652 
IsTemplateMap()1653     inline bool IsTemplateMap() const
1654     {
1655         return GetObjectType() == JSType::TEMPLATE_MAP;
1656     }
1657 
IsFreeObject()1658     inline bool IsFreeObject() const
1659     {
1660         JSType t = GetObjectType();
1661         return (t >= JSType::FREE_OBJECT_WITH_ONE_FIELD) && (t <= JSType::FREE_OBJECT_WITH_TWO_FIELD);
1662     }
1663 
IsFreeObjectWithShortField()1664     inline bool IsFreeObjectWithShortField() const
1665     {
1666         switch (GetObjectType()) {
1667             case JSType::FREE_OBJECT_WITH_ONE_FIELD:
1668             case JSType::FREE_OBJECT_WITH_NONE_FIELD:
1669                 return true;
1670             default:
1671                 return false;
1672         }
1673     }
1674 
IsFreeObjectWithOneField()1675     inline bool IsFreeObjectWithOneField() const
1676     {
1677         return GetObjectType() == JSType::FREE_OBJECT_WITH_ONE_FIELD;
1678     }
1679 
IsFreeObjectWithNoneField()1680     inline bool IsFreeObjectWithNoneField() const
1681     {
1682         return GetObjectType() == JSType::FREE_OBJECT_WITH_NONE_FIELD;
1683     }
1684 
IsFreeObjectWithTwoField()1685     inline bool IsFreeObjectWithTwoField() const
1686     {
1687         return GetObjectType() == JSType::FREE_OBJECT_WITH_TWO_FIELD;
1688     }
1689 
IsMachineCodeObject()1690     inline bool IsMachineCodeObject() const
1691     {
1692         return GetObjectType() == JSType::MACHINE_CODE_OBJECT;
1693     }
1694 
IsAOTLiteralInfo()1695     inline bool IsAOTLiteralInfo() const
1696     {
1697         return GetObjectType() == JSType::AOT_LITERAL_INFO;
1698     }
1699 
IsExtraProfileTypeInfo()1700     inline bool IsExtraProfileTypeInfo() const
1701     {
1702         return GetObjectType() == JSType::EXTRA_PROFILE_TYPE_INFO;
1703     }
1704 
IsProfileTypeInfoCell()1705     inline bool IsProfileTypeInfoCell() const
1706     {
1707         JSType jsType = GetObjectType();
1708         return jsType >= JSType::PROFILE_TYPE_INFO_CELL_FIRST && jsType <= JSType::PROFILE_TYPE_INFO_CELL_LAST;
1709     }
1710 
IsProfileTypeInfoCell0()1711     inline bool IsProfileTypeInfoCell0() const
1712     {
1713         JSType jsType = GetObjectType();
1714         return jsType == JSType::PROFILE_TYPE_INFO_CELL_0;
1715     }
1716 
IsFunctionTemplate()1717     inline bool IsFunctionTemplate() const
1718     {
1719         JSType jsType = GetObjectType();
1720         return jsType == JSType::FUNCTION_TEMPLATE;
1721     }
1722 
IsVTable()1723     inline bool IsVTable() const
1724     {
1725         return GetObjectType() == JSType::VTABLE;
1726     }
1727 
IsModuleRecord()1728     inline bool IsModuleRecord() const
1729     {
1730         JSType jsType = GetObjectType();
1731         return jsType >= JSType::MODULE_RECORD_FIRST && jsType <= JSType::MODULE_RECORD_LAST;
1732     }
1733 
IsSourceTextModule()1734     inline bool IsSourceTextModule() const
1735     {
1736         return GetObjectType() == JSType::SOURCE_TEXT_MODULE_RECORD;
1737     }
1738 
IsCjsExports()1739     inline bool IsCjsExports() const
1740     {
1741         return GetObjectType() == JSType::JS_CJS_EXPORTS;
1742     }
1743 
IsCjsModule()1744     inline bool IsCjsModule() const
1745     {
1746         return GetObjectType() == JSType::JS_CJS_MODULE;
1747     }
1748 
IsCjsRequire()1749     inline bool IsCjsRequire() const
1750     {
1751         return GetObjectType() == JSType::JS_CJS_REQUIRE;
1752     }
1753 
IsImportEntry()1754     inline bool IsImportEntry() const
1755     {
1756         return GetObjectType() == JSType::IMPORTENTRY_RECORD;
1757     }
1758 
IsLocalExportEntry()1759     inline bool IsLocalExportEntry() const
1760     {
1761         return GetObjectType() == JSType::LOCAL_EXPORTENTRY_RECORD;
1762     }
1763 
IsIndirectExportEntry()1764     inline bool IsIndirectExportEntry() const
1765     {
1766         return GetObjectType() == JSType::INDIRECT_EXPORTENTRY_RECORD;
1767     }
1768 
IsStarExportEntry()1769     inline bool IsStarExportEntry() const
1770     {
1771         return GetObjectType() == JSType::STAR_EXPORTENTRY_RECORD;
1772     }
1773 
IsResolvedBinding()1774     inline bool IsResolvedBinding() const
1775     {
1776         return GetObjectType() == JSType::RESOLVEDBINDING_RECORD;
1777     }
1778 
IsResolvedIndexBinding()1779     inline bool IsResolvedIndexBinding() const
1780     {
1781         return GetObjectType() == JSType::RESOLVEDINDEXBINDING_RECORD;
1782     }
1783 
IsResolvedRecordIndexBinding()1784     inline bool IsResolvedRecordIndexBinding() const
1785     {
1786         return GetObjectType() == JSType::RESOLVEDRECORDINDEXBINDING_RECORD;
1787     }
1788 
IsResolvedRecordBinding()1789     inline bool IsResolvedRecordBinding() const
1790     {
1791         return GetObjectType() == JSType::RESOLVEDRECORDBINDING_RECORD;
1792     }
1793 
IsModuleNamespace()1794     inline bool IsModuleNamespace() const
1795     {
1796         return GetObjectType() == JSType::JS_MODULE_NAMESPACE;
1797     }
1798 
IsNativeModuleFailureInfo()1799     inline bool IsNativeModuleFailureInfo() const
1800     {
1801         return GetObjectType() == JSType::NATIVE_MODULE_FAILURE_INFO;
1802     }
1803 
IsJSSharedObject()1804     inline bool IsJSSharedObject() const
1805     {
1806         return GetObjectType() == JSType::JS_SHARED_OBJECT;
1807     }
1808 
IsJSSharedArray()1809     inline bool IsJSSharedArray() const
1810     {
1811         return GetObjectType() == JSType::JS_SHARED_ARRAY;
1812     }
1813 
SetElementsKind(ElementsKind kind)1814     inline void SetElementsKind(ElementsKind kind)
1815     {
1816         uint32_t bits = GetBitField();
1817         uint32_t newVal = ElementsKindBits::Update(bits, kind);
1818         SetBitField(newVal);
1819     }
1820 
GetElementsKind()1821     inline ElementsKind GetElementsKind() const
1822     {
1823         uint32_t bits = GetBitField();
1824         return ElementsKindBits::Decode(bits);
1825     }
1826 
SetConstructionCounter(uint8_t count)1827     inline void SetConstructionCounter(uint8_t count)
1828     {
1829         uint32_t bits = GetBitField();
1830         uint32_t newVal = ConstructionCounterBits::Update(bits, count);
1831         SetBitField(newVal);
1832     }
1833 
GetConstructionCounter()1834     inline uint8_t GetConstructionCounter() const
1835     {
1836         uint32_t bits = GetBitField();
1837         return ConstructionCounterBits::Decode(bits);
1838     }
1839 
SetIsDictionaryElement(bool value)1840     inline void SetIsDictionaryElement(bool value)
1841     {
1842         uint32_t newVal = DictionaryElementBits::Update(GetBitField(), value);
1843         SetBitField(newVal);
1844     }
IsDictionaryElement()1845     inline bool IsDictionaryElement() const
1846     {
1847         return DictionaryElementBits::Decode(GetBitField());
1848     }
SetIsStableElements(bool value)1849     inline void SetIsStableElements(bool value)
1850     {
1851         uint32_t newVal = IsStableElementsBit::Update(GetBitField(), value);
1852         SetBitField(newVal);
1853     }
IsStableElements()1854     inline bool IsStableElements() const
1855     {
1856         return IsStableElementsBit::Decode(GetBitField());
1857     }
IsStableJSArguments()1858     inline bool IsStableJSArguments() const
1859     {
1860         uint32_t bits = GetBitField();
1861         auto type = ObjectTypeBits::Decode(bits);
1862         return IsStableElementsBit::Decode(bits) && (type == JSType::JS_ARGUMENTS);
1863     }
IsStableJSArray()1864     inline bool IsStableJSArray() const
1865     {
1866         uint32_t bits = GetBitField();
1867         auto type = ObjectTypeBits::Decode(bits);
1868         return IsStableElementsBit::Decode(bits) && (type == JSType::JS_ARRAY);
1869     }
SetHasConstructor(bool value)1870     inline void SetHasConstructor(bool value)
1871     {
1872         // only array and typedArray use this bitfield
1873         JSTaggedType newVal = HasConstructorBits::Update(GetBitField(), value);
1874         SetBitField(newVal);
1875     }
HasConstructor()1876     inline bool HasConstructor() const
1877     {
1878         // only array and typedArray use this bitfield
1879         return HasConstructorBits::Decode(GetBitField());
1880     }
1881 
SetNumberOfProps(uint32_t num)1882     inline void SetNumberOfProps(uint32_t num)
1883     {
1884         uint32_t bits = GetBitField1();
1885         uint32_t newVal = NumberOfPropsBits::Update(bits, num);
1886         SetBitField1(newVal);
1887     }
1888 
IncNumberOfProps()1889     inline void IncNumberOfProps()
1890     {
1891         ASSERT(NumberOfProps() < PropertyAttributes::MAX_FAST_PROPS_CAPACITY);
1892         SetNumberOfProps(NumberOfProps() + 1);
1893     }
1894 
NumberOfProps()1895     inline uint32_t NumberOfProps() const
1896     {
1897         uint32_t bits = GetBitField1();
1898         return NumberOfPropsBits::Decode(bits);
1899     }
1900 
HasProps()1901     inline bool HasProps() const
1902     {
1903         return NumberOfProps() > 0;
1904     }
1905 
PropsIsEmpty()1906     inline bool PropsIsEmpty() const
1907     {
1908         return NumberOfProps() == 0;
1909     }
1910 
LastPropIndex()1911     inline uint32_t LastPropIndex() const
1912     {
1913         ASSERT(NumberOfProps() > 0);
1914         return NumberOfProps() - 1;
1915     }
1916 
GetNextInlinedPropsIndex()1917     inline int32_t GetNextInlinedPropsIndex() const
1918     {
1919         uint32_t inlinedProperties = GetInlinedProperties();
1920         uint32_t numberOfProps = NumberOfProps();
1921         if (numberOfProps < inlinedProperties) {
1922             return numberOfProps;
1923         }
1924         return -1;
1925     }
1926 
GetNextNonInlinedPropsIndex()1927     inline int32_t GetNextNonInlinedPropsIndex() const
1928     {
1929         uint32_t inlinedProperties = GetInlinedProperties();
1930         uint32_t numberOfProps = NumberOfProps();
1931         if (numberOfProps >= inlinedProperties) {
1932             return numberOfProps - inlinedProperties;
1933         }
1934         return -1;
1935     }
1936 
GetObjectSize()1937     inline uint32_t GetObjectSize() const
1938     {
1939         uint32_t bits = GetBitField1();
1940         return ObjectSizeInWordsBits::Decode(bits) * JSTaggedValue::TaggedTypeSize();
1941     }
1942 
GetObjectSizeExcludeInlinedProps()1943     inline uint32_t GetObjectSizeExcludeInlinedProps() const
1944     {
1945         return GetObjectSize() - GetInlinedProperties() * JSTaggedValue::TaggedTypeSize();
1946     }
1947 
SetObjectSize(uint32_t num)1948     inline void SetObjectSize(uint32_t num)
1949     {
1950         ASSERT((num / JSTaggedValue::TaggedTypeSize()) <= MAX_OBJECT_SIZE_IN_WORDS);
1951         uint32_t bits = GetBitField1();
1952         uint32_t newVal = ObjectSizeInWordsBits::Update(bits, num / JSTaggedValue::TaggedTypeSize());
1953         SetBitField1(newVal);
1954     }
1955 
GetInlinedPropertiesOffset(uint32_t index)1956     inline uint32_t GetInlinedPropertiesOffset(uint32_t index) const
1957     {
1958         ASSERT(index < GetInlinedProperties());
1959         return GetInlinedPropertiesIndex(index) * JSTaggedValue::TaggedTypeSize();
1960     }
1961 
GetInlinedPropertiesIndex(uint32_t index)1962     inline uint32_t GetInlinedPropertiesIndex(uint32_t index) const
1963     {
1964         ASSERT(index < GetInlinedProperties());
1965         uint32_t bits = GetBitField1();
1966         return InlinedPropsStartBits::Decode(bits) + index;
1967     }
1968 
SetInlinedPropsStart(uint32_t num)1969     inline void SetInlinedPropsStart(uint32_t num)
1970     {
1971         uint32_t bits = GetBitField1();
1972         uint32_t newVal = InlinedPropsStartBits::Update(bits, num / JSTaggedValue::TaggedTypeSize());
1973         SetBitField1(newVal);
1974     }
1975 
GetInlinedPropsStartSize()1976     inline uint32_t GetInlinedPropsStartSize() const
1977     {
1978         uint32_t bits = GetBitField1();
1979         return InlinedPropsStartBits::Decode(bits) * JSTaggedValue::TaggedTypeSize();
1980     }
1981 
GetInlinedProperties()1982     inline uint32_t GetInlinedProperties() const
1983     {
1984         if (IsJSObject()) {
1985             uint32_t bits = GetBitField1();
1986             return static_cast<uint32_t>(ObjectSizeInWordsBits::Decode(bits) - InlinedPropsStartBits::Decode(bits));
1987         } else {
1988             return 0;
1989         }
1990     }
1991 
SetHasDeleteProperty(bool flag)1992     inline void SetHasDeleteProperty(bool flag) const
1993     {
1994         HasDeletePropertyBit::Set<uint32_t>(flag, GetBitField1Addr());
1995     }
1996 
HasDeleteProperty()1997     inline bool HasDeleteProperty() const
1998     {
1999         uint32_t bits = GetBitField1();
2000         return HasDeletePropertyBit::Decode(bits);
2001     }
2002 
SetIsAllTaggedProp(bool flag)2003     inline void SetIsAllTaggedProp(bool flag) const
2004     {
2005         IsAllTaggedPropBit::Set<uint32_t>(flag, GetBitField1Addr());
2006     }
2007 
IsAllTaggedProp()2008     inline bool IsAllTaggedProp() const
2009     {
2010         uint32_t bits = GetBitField1();
2011         return IsAllTaggedPropBit::Decode(bits);
2012     }
2013 
IsObjSizeTrackingInProgress()2014     inline bool IsObjSizeTrackingInProgress() const
2015     {
2016         return GetConstructionCounter() != 0;
2017     }
2018 
StartObjSizeTracking()2019     inline void StartObjSizeTracking()
2020     {
2021         SetConstructionCounter(SLACK_TRACKING_COUNT);
2022     }
2023 
2024     inline void CompleteObjSizeTracking();
2025 
2026     inline void ObjSizeTrackingStep();
2027 
2028     inline static JSHClass *FindRootHClass(JSHClass *hclass);
2029     inline static JSTaggedValue FindProtoHClass(JSHClass *hclass);
2030     inline static JSTaggedValue FindProtoRootHClass(JSHClass *hclass);
2031     inline static void UpdateRootHClass(const JSThread *thread, const JSHandle<JSHClass> &parent,
2032                                         const JSHandle<JSHClass> &child);
2033 
2034     inline static int FindPropertyEntry(const JSThread *thread, JSHClass *hclass, JSTaggedValue key);
2035 
2036     static PUBLIC_API PropertyLookupResult LookupPropertyInAotHClass(const JSThread *thread, JSHClass *hclass,
2037         JSTaggedValue key);
2038     static PUBLIC_API PropertyLookupResult LookupPropertyInPGOHClass(const JSThread *thread, JSHClass *hclass,
2039         JSTaggedValue key);
2040     static PUBLIC_API PropertyLookupResult LookupPropertyInBuiltinPrototypeHClass(const JSThread *thread,
2041                                                                                   JSHClass *hclass, JSTaggedValue key);
2042     static PUBLIC_API PropertyLookupResult LookupPropertyInBuiltinHClass(const JSThread *thread, JSHClass *hclass,
2043                                                                          JSTaggedValue key);
2044 
2045     static constexpr size_t PROTOTYPE_OFFSET = TaggedObjectSize();
2046     ACCESSORS(Proto, PROTOTYPE_OFFSET, LAYOUT_OFFSET);
2047     ACCESSORS_SYNCHRONIZED(Layout, LAYOUT_OFFSET, TRANSTIONS_OFFSET);
2048     ACCESSORS(Transitions, TRANSTIONS_OFFSET, PARENT_OFFSET);
2049     ACCESSORS(Parent, PARENT_OFFSET, PROTO_CHANGE_MARKER_OFFSET);
2050     ACCESSORS(ProtoChangeMarker, PROTO_CHANGE_MARKER_OFFSET, PROTO_CHANGE_DETAILS_OFFSET);
2051     ACCESSORS(ProtoChangeDetails, PROTO_CHANGE_DETAILS_OFFSET, ENUM_CACHE_OFFSET);
2052     ACCESSORS(EnumCache, ENUM_CACHE_OFFSET, PROFILE_TYPE);
2053     ACCESSORS_PRIMITIVE_FIELD(ProfileType, uint64_t, PROFILE_TYPE, BIT_FIELD_OFFSET);
2054     ACCESSORS_PRIMITIVE_FIELD(BitField, uint32_t, BIT_FIELD_OFFSET, BIT_FIELD1_OFFSET);
2055     ACCESSORS_PRIMITIVE_FIELD(BitField1, uint32_t, BIT_FIELD1_OFFSET, LAST_OFFSET);
2056     DEFINE_ALIGN_SIZE(LAST_OFFSET);
2057 
2058     static JSHandle<JSHClass> SetPrototypeWithNotification(const JSThread *thread,
2059                                                            const JSHandle<JSHClass> &hclass,
2060                                                            const JSHandle<JSTaggedValue> &proto,
2061                                                            bool isChangeProto = false);
2062     static void SetPrototypeTransition(JSThread *thread, const JSHandle<JSObject> &object,
2063                                        const JSHandle<JSTaggedValue> &proto,
2064                                        bool isChangeProto = false);
2065     void SetPrototype(const JSThread *thread, JSTaggedValue proto, bool isChangeProto = false);
2066     void PUBLIC_API SetPrototype(const JSThread *thread,
2067                                  const JSHandle<JSTaggedValue> &proto,
2068                                  bool isChangeProto = false);
2069     static void OptimizePrototypeForIC(const JSThread *thread,
2070                                        const JSHandle<JSTaggedValue> &proto,
2071                                        bool isChangeProto = false);
GetPrototype()2072     inline JSTaggedValue GetPrototype() const
2073     {
2074         return GetProto();
2075     }
2076 
2077     inline JSHClass *FindTransitions(const JSTaggedValue &key,
2078                                      const JSTaggedValue &metaData,
2079                                      const Representation &rep);
2080     inline JSHClass *CheckHClassForRep(JSHClass *hclass, const Representation &rep);
2081 
2082     DECL_DUMP()
2083 
2084     static CString DumpJSType(JSType type);
2085 
2086     static void CalculateMaxNumForChild(const HClassLayoutDesc* desc, uint32_t maxNum);
2087     static JSHandle<JSHClass> CreateRootHClassFromPGO(const JSThread* thread,
2088                                                       const HClassLayoutDesc* desc,
2089                                                       uint32_t maxNum);
2090     static JSHandle<JSHClass> CreateRootHClassWithCached(const JSThread* thread,
2091                                                          const HClassLayoutDesc* desc,
2092                                                          uint32_t literalLength,
2093                                                          uint32_t maxPropsNum);
2094     static JSHandle<JSHClass> CreateChildHClassFromPGO(const JSThread* thread,
2095                                                        const JSHandle<JSHClass>& parent,
2096                                                        const HClassLayoutDesc* desc);
2097     static bool DumpRootHClassByPGO(const JSHClass* hclass, HClassLayoutDesc* desc);
2098     static bool DumpChildHClassByPGO(const JSHClass* hclass, HClassLayoutDesc* desc);
2099     static bool UpdateRootLayoutDescByPGO(const JSHClass* hclass, HClassLayoutDesc* rootDesc);
2100     static bool UpdateChildLayoutDescByPGO(const JSHClass* hclass, HClassLayoutDesc* childDesc);
2101     static std::pair<bool, CString> DumpToString(JSTaggedType hclassVal);
2102 
2103     DECL_VISIT_OBJECT(PROTOTYPE_OFFSET, PROFILE_TYPE);
2104     inline JSHClass *FindProtoTransitions(const JSTaggedValue &key, const JSTaggedValue &proto);
HasTransitions()2105     inline bool HasTransitions() const
2106     {
2107         return !GetTransitions().IsUndefined();
2108     }
2109 
2110     static JSHandle<JSHClass> CreateSHClass(JSThread *thread,
2111                                             const std::vector<PropertyDescriptor> &descs,
2112                                             const JSHClass *parentHClass = nullptr,
2113                                             bool isFunction = false);
2114     static JSHandle<JSHClass> CreateSConstructorHClass(JSThread *thread, const std::vector<PropertyDescriptor> &descs);
2115     static JSHandle<JSHClass> CreateSPrototypeHClass(JSThread *thread, const std::vector<PropertyDescriptor> &descs);
2116 
2117 private:
2118 
2119     static inline bool ProtoIsFastJSArray(const JSThread *thread, const JSHandle<JSTaggedValue> proto,
2120                                           const JSHandle<JSHClass> hclass);
2121 
2122     static void CreateSInlinedLayout(JSThread *thread,
2123                                      const std::vector<PropertyDescriptor> &descs,
2124                                      const JSHandle<JSHClass> &hclass,
2125                                      const JSHClass *parentHClass = nullptr);
2126     static void CreateSDictLayout(JSThread *thread,
2127                                   const std::vector<PropertyDescriptor> &descs,
2128                                   const JSHandle<JSHClass> &hclass,
2129                                   const JSHClass *parentHClass = nullptr);
2130     static inline void AddTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
2131                                       const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key,
2132                                       PropertyAttributes attr);
2133     static inline void AddExtensionTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
2134                                                const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key);
2135     static inline void AddProtoTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
2136                                            const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key,
2137                                            const JSHandle<JSTaggedValue> &proto);
2138     template<bool checkDuplicateKeys = false>
2139     static inline void AddPropertyToNewHClass(const JSThread *thread, JSHandle<JSHClass> &jshclass,
2140                                               JSHandle<JSHClass> &newJsHClass, const JSHandle<JSTaggedValue> &key,
2141                                               const PropertyAttributes &attr);
2142 
2143     void InitializeWithDefaultValue(const JSThread *thread, uint32_t size, JSType type, uint32_t inlinedProps);
2144 
IsJSTypeObject(JSType type)2145     static bool IsJSTypeObject(JSType type)
2146     {
2147         return JSType::JS_OBJECT_FIRST <= type && type <= JSType::JS_OBJECT_LAST;
2148     }
2149 
2150     static bool IsJSTypeShared(JSType type);
2151 
2152     inline void Copy(const JSThread *thread, const JSHClass *jshclass);
2153 
GetBitFieldAddr()2154     uint32_t *GetBitFieldAddr() const
2155     {
2156         return reinterpret_cast<uint32_t *>(ToUintPtr(this) + BIT_FIELD_OFFSET);
2157     }
2158 
GetBitField1Addr()2159     uint32_t *GetBitField1Addr() const
2160     {
2161         return reinterpret_cast<uint32_t *>(ToUintPtr(this) + BIT_FIELD1_OFFSET);
2162     }
2163     friend class RuntimeStubs;
2164 };
2165 static_assert(JSHClass::BIT_FIELD_OFFSET % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT) == 0);
2166 
2167 // record property look up info in local and vtable
2168 class PropertyLookupResult {
2169 public:
2170     static constexpr uint32_t OFFSET_BITFIELD_NUM = 14;
2171     using IsFoundBit = BitField<bool, 0, 1>;
2172     using IsLocalBit = IsFoundBit::NextFlag;
2173     using IsNotHoleBit = IsLocalBit::NextFlag;
2174     using IsAccessorBit = IsNotHoleBit::NextFlag;
2175     using OffsetBits = IsAccessorBit::NextField<uint32_t, OFFSET_BITFIELD_NUM>;
2176     using WritableField = OffsetBits::NextFlag;
2177     using RepresentationBits = WritableField::NextField<Representation, PropertyAttributes::REPRESENTATION_NUM>;
2178     using IsInlinedPropsBits = RepresentationBits::NextFlag;
2179 
data_(data)2180     explicit PropertyLookupResult(uint32_t data = 0) : data_(data) {}
2181     ~PropertyLookupResult() = default;
2182     DEFAULT_NOEXCEPT_MOVE_SEMANTIC(PropertyLookupResult);
2183     DEFAULT_COPY_SEMANTIC(PropertyLookupResult);
2184 
IsFound()2185     inline bool IsFound() const
2186     {
2187         return IsFoundBit::Get(data_);
2188     }
2189 
SetIsFound(bool flag)2190     inline void SetIsFound(bool flag)
2191     {
2192         IsFoundBit::Set(flag, &data_);
2193     }
2194 
IsWritable()2195     inline bool IsWritable() const
2196     {
2197         return WritableField::Get(data_);
2198     }
2199 
SetIsWritable(bool flag)2200     inline void SetIsWritable(bool flag)
2201     {
2202         WritableField::Set(flag, &data_);
2203     }
2204 
IsLocal()2205     inline bool IsLocal() const
2206     {
2207         return IsLocalBit::Get(data_);
2208     }
2209 
SetIsLocal(bool flag)2210     inline void SetIsLocal(bool flag)
2211     {
2212         IsLocalBit::Set(flag, &data_);
2213     }
2214 
IsNotHole()2215     inline bool IsNotHole() const
2216     {
2217         return IsNotHoleBit::Get(data_);
2218     }
2219 
SetIsNotHole(bool flag)2220     inline void SetIsNotHole(bool flag)
2221     {
2222         IsNotHoleBit::Set(flag, &data_);
2223     }
2224 
IsVtable()2225     inline bool IsVtable() const
2226     {
2227         return IsFound() && !IsLocal();
2228     }
2229 
SetIsVtable()2230     inline void SetIsVtable()
2231     {
2232         SetIsFound(true);
2233         SetIsLocal(false);
2234     }
2235 
IsAccessor()2236     inline bool IsAccessor() const
2237     {
2238         return IsAccessorBit::Get(data_);
2239     }
2240 
SetIsAccessor(bool flag)2241     inline void SetIsAccessor(bool flag)
2242     {
2243         IsAccessorBit::Set(flag, &data_);
2244     }
2245 
IsFunction()2246     inline bool IsFunction() const
2247     {
2248         return IsVtable() && !IsAccessor();
2249     }
2250 
GetOffset()2251     inline uint32_t GetOffset() const
2252     {
2253         return OffsetBits::Get(data_);
2254     }
2255 
SetOffset(uint32_t offset)2256     inline void SetOffset(uint32_t offset)
2257     {
2258         OffsetBits::Set<uint32_t>(offset, &data_);
2259     }
2260 
SetRepresentation(Representation rep)2261     inline void SetRepresentation(Representation rep)
2262     {
2263         RepresentationBits::Set(rep, &data_);
2264     }
2265 
GetRepresentation()2266     inline Representation GetRepresentation()
2267     {
2268         return RepresentationBits::Get(data_);
2269     }
2270 
SetIsInlinedProps(bool flag)2271     inline void SetIsInlinedProps(bool flag)
2272     {
2273         IsInlinedPropsBits::Set(flag, &data_);
2274     }
2275 
IsInlinedProps()2276     inline bool IsInlinedProps()
2277     {
2278         return IsInlinedPropsBits::Get(data_);
2279     }
2280 
GetData()2281     inline uint32_t GetData() const
2282     {
2283         return data_;
2284     }
2285 
2286 private:
2287     uint32_t data_ {0};
2288 };
2289 static_assert(PropertyLookupResult::OffsetBits::MaxValue() >
2290               (PropertyAttributes::MAX_FAST_PROPS_CAPACITY * JSTaggedValue::TaggedTypeSize()));
2291 }  // namespace panda::ecmascript
2292 
2293 #endif  // ECMASCRIPT_JS_HCLASS_H
2294