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