Home | History | Annotate | Download | only in src
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_OBJECTS_H_
      6 #define V8_OBJECTS_H_
      7 
      8 #include <iosfwd>
      9 #include <memory>
     10 
     11 #include "src/assert-scope.h"
     12 #include "src/bailout-reason.h"
     13 #include "src/base/bits.h"
     14 #include "src/base/flags.h"
     15 #include "src/builtins/builtins.h"
     16 #include "src/checks.h"
     17 #include "src/elements-kind.h"
     18 #include "src/field-index.h"
     19 #include "src/flags.h"
     20 #include "src/list.h"
     21 #include "src/messages.h"
     22 #include "src/property-details.h"
     23 #include "src/unicode-decoder.h"
     24 #include "src/unicode.h"
     25 #include "src/zone/zone.h"
     26 
     27 #if V8_TARGET_ARCH_ARM
     28 #include "src/arm/constants-arm.h"  // NOLINT
     29 #elif V8_TARGET_ARCH_ARM64
     30 #include "src/arm64/constants-arm64.h"  // NOLINT
     31 #elif V8_TARGET_ARCH_MIPS
     32 #include "src/mips/constants-mips.h"  // NOLINT
     33 #elif V8_TARGET_ARCH_MIPS64
     34 #include "src/mips64/constants-mips64.h"  // NOLINT
     35 #elif V8_TARGET_ARCH_PPC
     36 #include "src/ppc/constants-ppc.h"  // NOLINT
     37 #elif V8_TARGET_ARCH_S390
     38 #include "src/s390/constants-s390.h"  // NOLINT
     39 #endif
     40 
     41 // Has to be the last include (doesn't have include guards):
     42 #include "src/objects/object-macros.h"
     43 
     44 //
     45 // Most object types in the V8 JavaScript are described in this file.
     46 //
     47 // Inheritance hierarchy:
     48 // - Object
     49 //   - Smi          (immediate small integer)
     50 //   - HeapObject   (superclass for everything allocated in the heap)
     51 //     - JSReceiver  (suitable for property access)
     52 //       - JSObject
     53 //         - JSArray
     54 //         - JSArrayBuffer
     55 //         - JSArrayBufferView
     56 //           - JSTypedArray
     57 //           - JSDataView
     58 //         - JSBoundFunction
     59 //         - JSCollection
     60 //           - JSSet
     61 //           - JSMap
     62 //         - JSStringIterator
     63 //         - JSSetIterator
     64 //         - JSMapIterator
     65 //         - JSWeakCollection
     66 //           - JSWeakMap
     67 //           - JSWeakSet
     68 //         - JSRegExp
     69 //         - JSFunction
     70 //         - JSGeneratorObject
     71 //         - JSGlobalObject
     72 //         - JSGlobalProxy
     73 //         - JSValue
     74 //           - JSDate
     75 //         - JSMessageObject
     76 //         - JSModuleNamespace
     77 //       - JSProxy
     78 //     - FixedArrayBase
     79 //       - ByteArray
     80 //       - BytecodeArray
     81 //       - FixedArray
     82 //         - DescriptorArray
     83 //         - FrameArray
     84 //         - HashTable
     85 //           - Dictionary
     86 //           - StringTable
     87 //           - StringSet
     88 //           - CompilationCacheTable
     89 //           - CodeCacheHashTable
     90 //           - MapCache
     91 //         - OrderedHashTable
     92 //           - OrderedHashSet
     93 //           - OrderedHashMap
     94 //         - Context
     95 //         - FeedbackMetadata
     96 //         - FeedbackVector
     97 //         - TemplateList
     98 //         - TransitionArray
     99 //         - ScopeInfo
    100 //         - ModuleInfo
    101 //         - ScriptContextTable
    102 //         - WeakFixedArray
    103 //       - FixedDoubleArray
    104 //     - Name
    105 //       - String
    106 //         - SeqString
    107 //           - SeqOneByteString
    108 //           - SeqTwoByteString
    109 //         - SlicedString
    110 //         - ConsString
    111 //         - ThinString
    112 //         - ExternalString
    113 //           - ExternalOneByteString
    114 //           - ExternalTwoByteString
    115 //         - InternalizedString
    116 //           - SeqInternalizedString
    117 //             - SeqOneByteInternalizedString
    118 //             - SeqTwoByteInternalizedString
    119 //           - ConsInternalizedString
    120 //           - ExternalInternalizedString
    121 //             - ExternalOneByteInternalizedString
    122 //             - ExternalTwoByteInternalizedString
    123 //       - Symbol
    124 //     - HeapNumber
    125 //     - Cell
    126 //     - PropertyCell
    127 //     - Code
    128 //     - AbstractCode, a wrapper around Code or BytecodeArray
    129 //     - Map
    130 //     - Oddball
    131 //     - Foreign
    132 //     - SharedFunctionInfo
    133 //     - Struct
    134 //       - AccessorInfo
    135 //       - PromiseResolveThenableJobInfo
    136 //       - PromiseReactionJobInfo
    137 //       - AccessorPair
    138 //       - AccessCheckInfo
    139 //       - InterceptorInfo
    140 //       - CallHandlerInfo
    141 //       - TemplateInfo
    142 //         - FunctionTemplateInfo
    143 //         - ObjectTemplateInfo
    144 //       - Script
    145 //       - DebugInfo
    146 //       - BreakPointInfo
    147 //       - CodeCache
    148 //       - PrototypeInfo
    149 //       - Module
    150 //       - ModuleInfoEntry
    151 //     - WeakCell
    152 //
    153 // Formats of Object*:
    154 //  Smi:        [31 bit signed int] 0
    155 //  HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
    156 
    157 namespace v8 {
    158 namespace internal {
    159 
    160 struct InliningPosition;
    161 
    162 enum KeyedAccessStoreMode {
    163   STANDARD_STORE,
    164   STORE_TRANSITION_TO_OBJECT,
    165   STORE_TRANSITION_TO_DOUBLE,
    166   STORE_AND_GROW_NO_TRANSITION,
    167   STORE_AND_GROW_TRANSITION_TO_OBJECT,
    168   STORE_AND_GROW_TRANSITION_TO_DOUBLE,
    169   STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS,
    170   STORE_NO_TRANSITION_HANDLE_COW
    171 };
    172 
    173 enum MutableMode {
    174   MUTABLE,
    175   IMMUTABLE
    176 };
    177 
    178 
    179 static inline bool IsTransitionStoreMode(KeyedAccessStoreMode store_mode) {
    180   return store_mode == STORE_TRANSITION_TO_OBJECT ||
    181          store_mode == STORE_TRANSITION_TO_DOUBLE ||
    182          store_mode == STORE_AND_GROW_TRANSITION_TO_OBJECT ||
    183          store_mode == STORE_AND_GROW_TRANSITION_TO_DOUBLE;
    184 }
    185 
    186 
    187 static inline KeyedAccessStoreMode GetNonTransitioningStoreMode(
    188     KeyedAccessStoreMode store_mode) {
    189   if (store_mode >= STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
    190     return store_mode;
    191   }
    192   if (store_mode >= STORE_AND_GROW_NO_TRANSITION) {
    193     return STORE_AND_GROW_NO_TRANSITION;
    194   }
    195   return STANDARD_STORE;
    196 }
    197 
    198 
    199 static inline bool IsGrowStoreMode(KeyedAccessStoreMode store_mode) {
    200   return store_mode >= STORE_AND_GROW_NO_TRANSITION &&
    201          store_mode <= STORE_AND_GROW_TRANSITION_TO_DOUBLE;
    202 }
    203 
    204 
    205 enum IcCheckType { ELEMENT, PROPERTY };
    206 
    207 
    208 // SKIP_WRITE_BARRIER skips the write barrier.
    209 // UPDATE_WEAK_WRITE_BARRIER skips the marking part of the write barrier and
    210 // only performs the generational part.
    211 // UPDATE_WRITE_BARRIER is doing the full barrier, marking and generational.
    212 enum WriteBarrierMode {
    213   SKIP_WRITE_BARRIER,
    214   UPDATE_WEAK_WRITE_BARRIER,
    215   UPDATE_WRITE_BARRIER
    216 };
    217 
    218 
    219 // PropertyNormalizationMode is used to specify whether to keep
    220 // inobject properties when normalizing properties of a JSObject.
    221 enum PropertyNormalizationMode {
    222   CLEAR_INOBJECT_PROPERTIES,
    223   KEEP_INOBJECT_PROPERTIES
    224 };
    225 
    226 
    227 // Indicates how aggressively the prototype should be optimized. FAST_PROTOTYPE
    228 // will give the fastest result by tailoring the map to the prototype, but that
    229 // will cause polymorphism with other objects. REGULAR_PROTOTYPE is to be used
    230 // (at least for now) when dynamically modifying the prototype chain of an
    231 // object using __proto__ or Object.setPrototypeOf.
    232 enum PrototypeOptimizationMode { REGULAR_PROTOTYPE, FAST_PROTOTYPE };
    233 
    234 
    235 // Indicates whether transitions can be added to a source map or not.
    236 enum TransitionFlag {
    237   INSERT_TRANSITION,
    238   OMIT_TRANSITION
    239 };
    240 
    241 
    242 // Indicates whether the transition is simple: the target map of the transition
    243 // either extends the current map with a new property, or it modifies the
    244 // property that was added last to the current map.
    245 enum SimpleTransitionFlag {
    246   SIMPLE_PROPERTY_TRANSITION,
    247   PROPERTY_TRANSITION,
    248   SPECIAL_TRANSITION
    249 };
    250 
    251 
    252 // Indicates whether we are only interested in the descriptors of a particular
    253 // map, or in all descriptors in the descriptor array.
    254 enum DescriptorFlag {
    255   ALL_DESCRIPTORS,
    256   OWN_DESCRIPTORS
    257 };
    258 
    259 // ICs store extra state in a Code object. The default extra state is
    260 // kNoExtraICState.
    261 typedef int ExtraICState;
    262 static const ExtraICState kNoExtraICState = 0;
    263 
    264 // Instance size sentinel for objects of variable size.
    265 const int kVariableSizeSentinel = 0;
    266 
    267 // We may store the unsigned bit field as signed Smi value and do not
    268 // use the sign bit.
    269 const int kStubMajorKeyBits = 8;
    270 const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
    271 
    272 // All Maps have a field instance_type containing a InstanceType.
    273 // It describes the type of the instances.
    274 //
    275 // As an example, a JavaScript object is a heap object and its map
    276 // instance_type is JS_OBJECT_TYPE.
    277 //
    278 // The names of the string instance types are intended to systematically
    279 // mirror their encoding in the instance_type field of the map.  The default
    280 // encoding is considered TWO_BYTE.  It is not mentioned in the name.  ONE_BYTE
    281 // encoding is mentioned explicitly in the name.  Likewise, the default
    282 // representation is considered sequential.  It is not mentioned in the
    283 // name.  The other representations (e.g. CONS, EXTERNAL) are explicitly
    284 // mentioned.  Finally, the string is either a STRING_TYPE (if it is a normal
    285 // string) or a INTERNALIZED_STRING_TYPE (if it is a internalized string).
    286 //
    287 // NOTE: The following things are some that depend on the string types having
    288 // instance_types that are less than those of all other types:
    289 // HeapObject::Size, HeapObject::IterateBody, the typeof operator, and
    290 // Object::IsString.
    291 //
    292 // NOTE: Everything following JS_VALUE_TYPE is considered a
    293 // JSObject for GC purposes. The first four entries here have typeof
    294 // 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
    295 #define INSTANCE_TYPE_LIST(V)                                   \
    296   V(INTERNALIZED_STRING_TYPE)                                   \
    297   V(EXTERNAL_INTERNALIZED_STRING_TYPE)                          \
    298   V(ONE_BYTE_INTERNALIZED_STRING_TYPE)                          \
    299   V(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE)                 \
    300   V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE)       \
    301   V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE)                    \
    302   V(SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE)           \
    303   V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
    304   V(STRING_TYPE)                                                \
    305   V(CONS_STRING_TYPE)                                           \
    306   V(EXTERNAL_STRING_TYPE)                                       \
    307   V(SLICED_STRING_TYPE)                                         \
    308   V(THIN_STRING_TYPE)                                           \
    309   V(ONE_BYTE_STRING_TYPE)                                       \
    310   V(CONS_ONE_BYTE_STRING_TYPE)                                  \
    311   V(EXTERNAL_ONE_BYTE_STRING_TYPE)                              \
    312   V(SLICED_ONE_BYTE_STRING_TYPE)                                \
    313   V(THIN_ONE_BYTE_STRING_TYPE)                                  \
    314   V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE)                    \
    315   V(SHORT_EXTERNAL_STRING_TYPE)                                 \
    316   V(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE)                        \
    317   V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE)              \
    318                                                                 \
    319   V(SYMBOL_TYPE)                                                \
    320   V(HEAP_NUMBER_TYPE)                                           \
    321   V(ODDBALL_TYPE)                                               \
    322                                                                 \
    323   V(MAP_TYPE)                                                   \
    324   V(CODE_TYPE)                                                  \
    325   V(MUTABLE_HEAP_NUMBER_TYPE)                                   \
    326   V(FOREIGN_TYPE)                                               \
    327   V(BYTE_ARRAY_TYPE)                                            \
    328   V(BYTECODE_ARRAY_TYPE)                                        \
    329   V(FREE_SPACE_TYPE)                                            \
    330                                                                 \
    331   V(FIXED_INT8_ARRAY_TYPE)                                      \
    332   V(FIXED_UINT8_ARRAY_TYPE)                                     \
    333   V(FIXED_INT16_ARRAY_TYPE)                                     \
    334   V(FIXED_UINT16_ARRAY_TYPE)                                    \
    335   V(FIXED_INT32_ARRAY_TYPE)                                     \
    336   V(FIXED_UINT32_ARRAY_TYPE)                                    \
    337   V(FIXED_FLOAT32_ARRAY_TYPE)                                   \
    338   V(FIXED_FLOAT64_ARRAY_TYPE)                                   \
    339   V(FIXED_UINT8_CLAMPED_ARRAY_TYPE)                             \
    340                                                                 \
    341   V(FIXED_DOUBLE_ARRAY_TYPE)                                    \
    342   V(FILLER_TYPE)                                                \
    343                                                                 \
    344   V(ACCESSOR_INFO_TYPE)                                         \
    345   V(ACCESSOR_PAIR_TYPE)                                         \
    346   V(ACCESS_CHECK_INFO_TYPE)                                     \
    347   V(INTERCEPTOR_INFO_TYPE)                                      \
    348   V(CALL_HANDLER_INFO_TYPE)                                     \
    349   V(FUNCTION_TEMPLATE_INFO_TYPE)                                \
    350   V(OBJECT_TEMPLATE_INFO_TYPE)                                  \
    351   V(ALLOCATION_SITE_TYPE)                                       \
    352   V(ALLOCATION_MEMENTO_TYPE)                                    \
    353   V(SCRIPT_TYPE)                                                \
    354   V(TYPE_FEEDBACK_INFO_TYPE)                                    \
    355   V(ALIASED_ARGUMENTS_ENTRY_TYPE)                               \
    356   V(PROMISE_RESOLVE_THENABLE_JOB_INFO_TYPE)                     \
    357   V(PROMISE_REACTION_JOB_INFO_TYPE)                             \
    358   V(DEBUG_INFO_TYPE)                                            \
    359   V(BREAK_POINT_INFO_TYPE)                                      \
    360   V(PROTOTYPE_INFO_TYPE)                                        \
    361   V(TUPLE2_TYPE)                                                \
    362   V(TUPLE3_TYPE)                                                \
    363   V(CONTEXT_EXTENSION_TYPE)                                     \
    364   V(CONSTANT_ELEMENTS_PAIR_TYPE)                                \
    365   V(MODULE_TYPE)                                                \
    366   V(MODULE_INFO_ENTRY_TYPE)                                     \
    367   V(FIXED_ARRAY_TYPE)                                           \
    368   V(TRANSITION_ARRAY_TYPE)                                      \
    369   V(SHARED_FUNCTION_INFO_TYPE)                                  \
    370   V(CELL_TYPE)                                                  \
    371   V(WEAK_CELL_TYPE)                                             \
    372   V(PROPERTY_CELL_TYPE)                                         \
    373                                                                 \
    374   V(JS_PROXY_TYPE)                                              \
    375   V(JS_GLOBAL_OBJECT_TYPE)                                      \
    376   V(JS_GLOBAL_PROXY_TYPE)                                       \
    377   V(JS_SPECIAL_API_OBJECT_TYPE)                                 \
    378   V(JS_VALUE_TYPE)                                              \
    379   V(JS_MESSAGE_OBJECT_TYPE)                                     \
    380   V(JS_DATE_TYPE)                                               \
    381   V(JS_API_OBJECT_TYPE)                                         \
    382   V(JS_OBJECT_TYPE)                                             \
    383   V(JS_ARGUMENTS_TYPE)                                          \
    384   V(JS_CONTEXT_EXTENSION_OBJECT_TYPE)                           \
    385   V(JS_GENERATOR_OBJECT_TYPE)                                   \
    386   V(JS_MODULE_NAMESPACE_TYPE)                                   \
    387   V(JS_ARRAY_TYPE)                                              \
    388   V(JS_ARRAY_BUFFER_TYPE)                                       \
    389   V(JS_TYPED_ARRAY_TYPE)                                        \
    390   V(JS_DATA_VIEW_TYPE)                                          \
    391   V(JS_SET_TYPE)                                                \
    392   V(JS_MAP_TYPE)                                                \
    393   V(JS_SET_ITERATOR_TYPE)                                       \
    394   V(JS_MAP_ITERATOR_TYPE)                                       \
    395   V(JS_WEAK_MAP_TYPE)                                           \
    396   V(JS_WEAK_SET_TYPE)                                           \
    397   V(JS_PROMISE_CAPABILITY_TYPE)                                 \
    398   V(JS_PROMISE_TYPE)                                            \
    399   V(JS_REGEXP_TYPE)                                             \
    400   V(JS_ERROR_TYPE)                                              \
    401   V(JS_ASYNC_FROM_SYNC_ITERATOR_TYPE)                           \
    402   V(JS_STRING_ITERATOR_TYPE)                                    \
    403                                                                 \
    404   V(JS_TYPED_ARRAY_KEY_ITERATOR_TYPE)                           \
    405   V(JS_FAST_ARRAY_KEY_ITERATOR_TYPE)                            \
    406   V(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)                         \
    407                                                                 \
    408   V(JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE)                     \
    409   V(JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE)                      \
    410   V(JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE)                    \
    411   V(JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE)                     \
    412   V(JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE)                    \
    413   V(JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE)                     \
    414   V(JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE)                   \
    415   V(JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE)                   \
    416   V(JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE)             \
    417                                                                 \
    418   V(JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE)                  \
    419   V(JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE)            \
    420   V(JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)                      \
    421   V(JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE)                \
    422   V(JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE)               \
    423   V(JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE)         \
    424   V(JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE)                   \
    425                                                                 \
    426   V(JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE)                         \
    427   V(JS_INT8_ARRAY_VALUE_ITERATOR_TYPE)                          \
    428   V(JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE)                        \
    429   V(JS_INT16_ARRAY_VALUE_ITERATOR_TYPE)                         \
    430   V(JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE)                        \
    431   V(JS_INT32_ARRAY_VALUE_ITERATOR_TYPE)                         \
    432   V(JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE)                       \
    433   V(JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE)                       \
    434   V(JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE)                 \
    435                                                                 \
    436   V(JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE)                      \
    437   V(JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE)                \
    438   V(JS_FAST_ARRAY_VALUE_ITERATOR_TYPE)                          \
    439   V(JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE)                    \
    440   V(JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE)                   \
    441   V(JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE)             \
    442   V(JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE)                       \
    443                                                                 \
    444   V(JS_BOUND_FUNCTION_TYPE)                                     \
    445   V(JS_FUNCTION_TYPE)
    446 
    447 // Since string types are not consecutive, this macro is used to
    448 // iterate over them.
    449 #define STRING_TYPE_LIST(V)                                                   \
    450   V(STRING_TYPE, kVariableSizeSentinel, string, String)                       \
    451   V(ONE_BYTE_STRING_TYPE, kVariableSizeSentinel, one_byte_string,             \
    452     OneByteString)                                                            \
    453   V(CONS_STRING_TYPE, ConsString::kSize, cons_string, ConsString)             \
    454   V(CONS_ONE_BYTE_STRING_TYPE, ConsString::kSize, cons_one_byte_string,       \
    455     ConsOneByteString)                                                        \
    456   V(SLICED_STRING_TYPE, SlicedString::kSize, sliced_string, SlicedString)     \
    457   V(SLICED_ONE_BYTE_STRING_TYPE, SlicedString::kSize, sliced_one_byte_string, \
    458     SlicedOneByteString)                                                      \
    459   V(EXTERNAL_STRING_TYPE, ExternalTwoByteString::kSize, external_string,      \
    460     ExternalString)                                                           \
    461   V(EXTERNAL_ONE_BYTE_STRING_TYPE, ExternalOneByteString::kSize,              \
    462     external_one_byte_string, ExternalOneByteString)                          \
    463   V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE, ExternalTwoByteString::kSize,    \
    464     external_string_with_one_byte_data, ExternalStringWithOneByteData)        \
    465   V(SHORT_EXTERNAL_STRING_TYPE, ExternalTwoByteString::kShortSize,            \
    466     short_external_string, ShortExternalString)                               \
    467   V(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE, ExternalOneByteString::kShortSize,   \
    468     short_external_one_byte_string, ShortExternalOneByteString)               \
    469   V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE,                            \
    470     ExternalTwoByteString::kShortSize,                                        \
    471     short_external_string_with_one_byte_data,                                 \
    472     ShortExternalStringWithOneByteData)                                       \
    473                                                                               \
    474   V(INTERNALIZED_STRING_TYPE, kVariableSizeSentinel, internalized_string,     \
    475     InternalizedString)                                                       \
    476   V(ONE_BYTE_INTERNALIZED_STRING_TYPE, kVariableSizeSentinel,                 \
    477     one_byte_internalized_string, OneByteInternalizedString)                  \
    478   V(EXTERNAL_INTERNALIZED_STRING_TYPE, ExternalTwoByteString::kSize,          \
    479     external_internalized_string, ExternalInternalizedString)                 \
    480   V(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE, ExternalOneByteString::kSize, \
    481     external_one_byte_internalized_string, ExternalOneByteInternalizedString) \
    482   V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE,                     \
    483     ExternalTwoByteString::kSize,                                             \
    484     external_internalized_string_with_one_byte_data,                          \
    485     ExternalInternalizedStringWithOneByteData)                                \
    486   V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE,                                  \
    487     ExternalTwoByteString::kShortSize, short_external_internalized_string,    \
    488     ShortExternalInternalizedString)                                          \
    489   V(SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE,                         \
    490     ExternalOneByteString::kShortSize,                                        \
    491     short_external_one_byte_internalized_string,                              \
    492     ShortExternalOneByteInternalizedString)                                   \
    493   V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE,               \
    494     ExternalTwoByteString::kShortSize,                                        \
    495     short_external_internalized_string_with_one_byte_data,                    \
    496     ShortExternalInternalizedStringWithOneByteData)                           \
    497   V(THIN_STRING_TYPE, ThinString::kSize, thin_string, ThinString)             \
    498   V(THIN_ONE_BYTE_STRING_TYPE, ThinString::kSize, thin_one_byte_string,       \
    499     ThinOneByteString)
    500 
    501 // A struct is a simple object a set of object-valued fields.  Including an
    502 // object type in this causes the compiler to generate most of the boilerplate
    503 // code for the class including allocation and garbage collection routines,
    504 // casts and predicates.  All you need to define is the class, methods and
    505 // object verification routines.  Easy, no?
    506 //
    507 // Note that for subtle reasons related to the ordering or numerical values of
    508 // type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
    509 // manually.
    510 #define STRUCT_LIST(V)                                                       \
    511   V(ACCESSOR_INFO, AccessorInfo, accessor_info)                              \
    512   V(ACCESSOR_PAIR, AccessorPair, accessor_pair)                              \
    513   V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info)                   \
    514   V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info)                     \
    515   V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info)                   \
    516   V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info)    \
    517   V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info)          \
    518   V(ALLOCATION_SITE, AllocationSite, allocation_site)                        \
    519   V(ALLOCATION_MEMENTO, AllocationMemento, allocation_memento)               \
    520   V(SCRIPT, Script, script)                                                  \
    521   V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info)                \
    522   V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry) \
    523   V(PROMISE_RESOLVE_THENABLE_JOB_INFO, PromiseResolveThenableJobInfo,        \
    524     promise_resolve_thenable_job_info)                                       \
    525   V(PROMISE_REACTION_JOB_INFO, PromiseReactionJobInfo,                       \
    526     promise_reaction_job_info)                                               \
    527   V(DEBUG_INFO, DebugInfo, debug_info)                                       \
    528   V(BREAK_POINT_INFO, BreakPointInfo, break_point_info)                      \
    529   V(PROTOTYPE_INFO, PrototypeInfo, prototype_info)                           \
    530   V(TUPLE2, Tuple2, tuple2)                                                  \
    531   V(TUPLE3, Tuple3, tuple3)                                                  \
    532   V(CONTEXT_EXTENSION, ContextExtension, context_extension)                  \
    533   V(CONSTANT_ELEMENTS_PAIR, ConstantElementsPair, constant_elements_pair)    \
    534   V(MODULE, Module, module)                                                  \
    535   V(MODULE_INFO_ENTRY, ModuleInfoEntry, module_info_entry)
    536 
    537 // We use the full 8 bits of the instance_type field to encode heap object
    538 // instance types.  The high-order bit (bit 7) is set if the object is not a
    539 // string, and cleared if it is a string.
    540 const uint32_t kIsNotStringMask = 0x80;
    541 const uint32_t kStringTag = 0x0;
    542 const uint32_t kNotStringTag = 0x80;
    543 
    544 // Bit 6 indicates that the object is an internalized string (if set) or not.
    545 // Bit 7 has to be clear as well.
    546 const uint32_t kIsNotInternalizedMask = 0x40;
    547 const uint32_t kNotInternalizedTag = 0x40;
    548 const uint32_t kInternalizedTag = 0x0;
    549 
    550 // If bit 7 is clear then bit 3 indicates whether the string consists of
    551 // two-byte characters or one-byte characters.
    552 const uint32_t kStringEncodingMask = 0x8;
    553 const uint32_t kTwoByteStringTag = 0x0;
    554 const uint32_t kOneByteStringTag = 0x8;
    555 
    556 // If bit 7 is clear, the low-order 3 bits indicate the representation
    557 // of the string.
    558 const uint32_t kStringRepresentationMask = 0x07;
    559 enum StringRepresentationTag {
    560   kSeqStringTag = 0x0,
    561   kConsStringTag = 0x1,
    562   kExternalStringTag = 0x2,
    563   kSlicedStringTag = 0x3,
    564   kThinStringTag = 0x5
    565 };
    566 const uint32_t kIsIndirectStringMask = 0x1;
    567 const uint32_t kIsIndirectStringTag = 0x1;
    568 STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0);  // NOLINT
    569 STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0);  // NOLINT
    570 STATIC_ASSERT((kConsStringTag &
    571                kIsIndirectStringMask) == kIsIndirectStringTag);  // NOLINT
    572 STATIC_ASSERT((kSlicedStringTag &
    573                kIsIndirectStringMask) == kIsIndirectStringTag);  // NOLINT
    574 STATIC_ASSERT((kThinStringTag & kIsIndirectStringMask) == kIsIndirectStringTag);
    575 
    576 // If bit 7 is clear, then bit 4 indicates whether this two-byte
    577 // string actually contains one byte data.
    578 const uint32_t kOneByteDataHintMask = 0x10;
    579 const uint32_t kOneByteDataHintTag = 0x10;
    580 
    581 // If bit 7 is clear and string representation indicates an external string,
    582 // then bit 5 indicates whether the data pointer is cached.
    583 const uint32_t kShortExternalStringMask = 0x20;
    584 const uint32_t kShortExternalStringTag = 0x20;
    585 
    586 // A ConsString with an empty string as the right side is a candidate
    587 // for being shortcut by the garbage collector. We don't allocate any
    588 // non-flat internalized strings, so we do not shortcut them thereby
    589 // avoiding turning internalized strings into strings. The bit-masks
    590 // below contain the internalized bit as additional safety.
    591 // See heap.cc, mark-compact.cc and objects-visiting.cc.
    592 const uint32_t kShortcutTypeMask =
    593     kIsNotStringMask |
    594     kIsNotInternalizedMask |
    595     kStringRepresentationMask;
    596 const uint32_t kShortcutTypeTag = kConsStringTag | kNotInternalizedTag;
    597 
    598 static inline bool IsShortcutCandidate(int type) {
    599   return ((type & kShortcutTypeMask) == kShortcutTypeTag);
    600 }
    601 
    602 enum InstanceType {
    603   // String types.
    604   INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag |
    605                              kInternalizedTag,  // FIRST_PRIMITIVE_TYPE
    606   ONE_BYTE_INTERNALIZED_STRING_TYPE =
    607       kOneByteStringTag | kSeqStringTag | kInternalizedTag,
    608   EXTERNAL_INTERNALIZED_STRING_TYPE =
    609       kTwoByteStringTag | kExternalStringTag | kInternalizedTag,
    610   EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
    611       kOneByteStringTag | kExternalStringTag | kInternalizedTag,
    612   EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
    613       EXTERNAL_INTERNALIZED_STRING_TYPE | kOneByteDataHintTag |
    614       kInternalizedTag,
    615   SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE = EXTERNAL_INTERNALIZED_STRING_TYPE |
    616                                             kShortExternalStringTag |
    617                                             kInternalizedTag,
    618   SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
    619       EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kShortExternalStringTag |
    620       kInternalizedTag,
    621   SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
    622       EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
    623       kShortExternalStringTag | kInternalizedTag,
    624   STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
    625   ONE_BYTE_STRING_TYPE =
    626       ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
    627   CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag | kNotInternalizedTag,
    628   CONS_ONE_BYTE_STRING_TYPE =
    629       kOneByteStringTag | kConsStringTag | kNotInternalizedTag,
    630   SLICED_STRING_TYPE =
    631       kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
    632   SLICED_ONE_BYTE_STRING_TYPE =
    633       kOneByteStringTag | kSlicedStringTag | kNotInternalizedTag,
    634   EXTERNAL_STRING_TYPE =
    635       EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
    636   EXTERNAL_ONE_BYTE_STRING_TYPE =
    637       EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
    638   EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
    639       EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
    640       kNotInternalizedTag,
    641   SHORT_EXTERNAL_STRING_TYPE =
    642       SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
    643   SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE =
    644       SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
    645   SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
    646       SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
    647       kNotInternalizedTag,
    648   THIN_STRING_TYPE = kTwoByteStringTag | kThinStringTag | kNotInternalizedTag,
    649   THIN_ONE_BYTE_STRING_TYPE =
    650       kOneByteStringTag | kThinStringTag | kNotInternalizedTag,
    651 
    652   // Non-string names
    653   SYMBOL_TYPE = kNotStringTag,  // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE
    654 
    655   // Other primitives (cannot contain non-map-word pointers to heap objects).
    656   HEAP_NUMBER_TYPE,
    657   ODDBALL_TYPE,  // LAST_PRIMITIVE_TYPE
    658 
    659   // Objects allocated in their own spaces (never in new space).
    660   MAP_TYPE,
    661   CODE_TYPE,
    662 
    663   // "Data", objects that cannot contain non-map-word pointers to heap
    664   // objects.
    665   MUTABLE_HEAP_NUMBER_TYPE,
    666   FOREIGN_TYPE,
    667   BYTE_ARRAY_TYPE,
    668   BYTECODE_ARRAY_TYPE,
    669   FREE_SPACE_TYPE,
    670   FIXED_INT8_ARRAY_TYPE,  // FIRST_FIXED_TYPED_ARRAY_TYPE
    671   FIXED_UINT8_ARRAY_TYPE,
    672   FIXED_INT16_ARRAY_TYPE,
    673   FIXED_UINT16_ARRAY_TYPE,
    674   FIXED_INT32_ARRAY_TYPE,
    675   FIXED_UINT32_ARRAY_TYPE,
    676   FIXED_FLOAT32_ARRAY_TYPE,
    677   FIXED_FLOAT64_ARRAY_TYPE,
    678   FIXED_UINT8_CLAMPED_ARRAY_TYPE,  // LAST_FIXED_TYPED_ARRAY_TYPE
    679   FIXED_DOUBLE_ARRAY_TYPE,
    680   FILLER_TYPE,  // LAST_DATA_TYPE
    681 
    682   // Structs.
    683   ACCESSOR_INFO_TYPE,
    684   ACCESSOR_PAIR_TYPE,
    685   ACCESS_CHECK_INFO_TYPE,
    686   INTERCEPTOR_INFO_TYPE,
    687   CALL_HANDLER_INFO_TYPE,
    688   FUNCTION_TEMPLATE_INFO_TYPE,
    689   OBJECT_TEMPLATE_INFO_TYPE,
    690   ALLOCATION_SITE_TYPE,
    691   ALLOCATION_MEMENTO_TYPE,
    692   SCRIPT_TYPE,
    693   TYPE_FEEDBACK_INFO_TYPE,
    694   ALIASED_ARGUMENTS_ENTRY_TYPE,
    695   PROMISE_RESOLVE_THENABLE_JOB_INFO_TYPE,
    696   PROMISE_REACTION_JOB_INFO_TYPE,
    697   DEBUG_INFO_TYPE,
    698   BREAK_POINT_INFO_TYPE,
    699   PROTOTYPE_INFO_TYPE,
    700   TUPLE2_TYPE,
    701   TUPLE3_TYPE,
    702   CONTEXT_EXTENSION_TYPE,
    703   CONSTANT_ELEMENTS_PAIR_TYPE,
    704   MODULE_TYPE,
    705   MODULE_INFO_ENTRY_TYPE,
    706   FIXED_ARRAY_TYPE,
    707   TRANSITION_ARRAY_TYPE,
    708   SHARED_FUNCTION_INFO_TYPE,
    709   CELL_TYPE,
    710   WEAK_CELL_TYPE,
    711   PROPERTY_CELL_TYPE,
    712 
    713   // All the following types are subtypes of JSReceiver, which corresponds to
    714   // objects in the JS sense. The first and the last type in this range are
    715   // the two forms of function. This organization enables using the same
    716   // compares for checking the JS_RECEIVER and the NONCALLABLE_JS_OBJECT range.
    717   JS_PROXY_TYPE,          // FIRST_JS_RECEIVER_TYPE
    718   JS_GLOBAL_OBJECT_TYPE,  // FIRST_JS_OBJECT_TYPE
    719   JS_GLOBAL_PROXY_TYPE,
    720   // Like JS_API_OBJECT_TYPE, but requires access checks and/or has
    721   // interceptors.
    722   JS_SPECIAL_API_OBJECT_TYPE,  // LAST_SPECIAL_RECEIVER_TYPE
    723   JS_VALUE_TYPE,               // LAST_CUSTOM_ELEMENTS_RECEIVER
    724   JS_MESSAGE_OBJECT_TYPE,
    725   JS_DATE_TYPE,
    726   // Like JS_OBJECT_TYPE, but created from API function.
    727   JS_API_OBJECT_TYPE,
    728   JS_OBJECT_TYPE,
    729   JS_ARGUMENTS_TYPE,
    730   JS_CONTEXT_EXTENSION_OBJECT_TYPE,
    731   JS_GENERATOR_OBJECT_TYPE,
    732   JS_MODULE_NAMESPACE_TYPE,
    733   JS_ARRAY_TYPE,
    734   JS_ARRAY_BUFFER_TYPE,
    735   JS_TYPED_ARRAY_TYPE,
    736   JS_DATA_VIEW_TYPE,
    737   JS_SET_TYPE,
    738   JS_MAP_TYPE,
    739   JS_SET_ITERATOR_TYPE,
    740   JS_MAP_ITERATOR_TYPE,
    741   JS_WEAK_MAP_TYPE,
    742   JS_WEAK_SET_TYPE,
    743   JS_PROMISE_CAPABILITY_TYPE,
    744   JS_PROMISE_TYPE,
    745   JS_REGEXP_TYPE,
    746   JS_ERROR_TYPE,
    747   JS_ASYNC_FROM_SYNC_ITERATOR_TYPE,
    748   JS_STRING_ITERATOR_TYPE,
    749 
    750   JS_TYPED_ARRAY_KEY_ITERATOR_TYPE,
    751   JS_FAST_ARRAY_KEY_ITERATOR_TYPE,
    752   JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE,
    753 
    754   JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    755   JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    756   JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    757   JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    758   JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    759   JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    760   JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    761   JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    762   JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    763 
    764   JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    765   JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    766   JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    767   JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    768   JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    769   JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    770   JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    771 
    772   JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE,
    773   JS_INT8_ARRAY_VALUE_ITERATOR_TYPE,
    774   JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE,
    775   JS_INT16_ARRAY_VALUE_ITERATOR_TYPE,
    776   JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE,
    777   JS_INT32_ARRAY_VALUE_ITERATOR_TYPE,
    778   JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE,
    779   JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE,
    780   JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE,
    781 
    782   JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE,
    783   JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE,
    784   JS_FAST_ARRAY_VALUE_ITERATOR_TYPE,
    785   JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE,
    786   JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE,
    787   JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE,
    788   JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE,
    789 
    790   JS_BOUND_FUNCTION_TYPE,
    791   JS_FUNCTION_TYPE,  // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
    792 
    793   // Pseudo-types
    794   FIRST_TYPE = 0x0,
    795   LAST_TYPE = JS_FUNCTION_TYPE,
    796   FIRST_NAME_TYPE = FIRST_TYPE,
    797   LAST_NAME_TYPE = SYMBOL_TYPE,
    798   FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
    799   LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
    800   FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
    801   FIRST_PRIMITIVE_TYPE = FIRST_NAME_TYPE,
    802   LAST_PRIMITIVE_TYPE = ODDBALL_TYPE,
    803   FIRST_FUNCTION_TYPE = JS_BOUND_FUNCTION_TYPE,
    804   LAST_FUNCTION_TYPE = JS_FUNCTION_TYPE,
    805   // Boundaries for testing for a fixed typed array.
    806   FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
    807   LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_UINT8_CLAMPED_ARRAY_TYPE,
    808   // Boundary for promotion to old space.
    809   LAST_DATA_TYPE = FILLER_TYPE,
    810   // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
    811   // Note that there is no range for JSObject or JSProxy, since their subtypes
    812   // are not continuous in this enum! The enum ranges instead reflect the
    813   // external class names, where proxies are treated as either ordinary objects,
    814   // or functions.
    815   FIRST_JS_RECEIVER_TYPE = JS_PROXY_TYPE,
    816   LAST_JS_RECEIVER_TYPE = LAST_TYPE,
    817   // Boundaries for testing the types represented as JSObject
    818   FIRST_JS_OBJECT_TYPE = JS_GLOBAL_OBJECT_TYPE,
    819   LAST_JS_OBJECT_TYPE = LAST_TYPE,
    820   // Boundary for testing JSReceivers that need special property lookup handling
    821   LAST_SPECIAL_RECEIVER_TYPE = JS_SPECIAL_API_OBJECT_TYPE,
    822   // Boundary case for testing JSReceivers that may have elements while having
    823   // an empty fixed array as elements backing store. This is true for string
    824   // wrappers.
    825   LAST_CUSTOM_ELEMENTS_RECEIVER = JS_VALUE_TYPE,
    826 
    827   FIRST_ARRAY_KEY_ITERATOR_TYPE = JS_TYPED_ARRAY_KEY_ITERATOR_TYPE,
    828   LAST_ARRAY_KEY_ITERATOR_TYPE = JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE,
    829 
    830   FIRST_ARRAY_KEY_VALUE_ITERATOR_TYPE = JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    831   LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE = JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE,
    832 
    833   FIRST_ARRAY_VALUE_ITERATOR_TYPE = JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE,
    834   LAST_ARRAY_VALUE_ITERATOR_TYPE = JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE,
    835 
    836   FIRST_ARRAY_ITERATOR_TYPE = FIRST_ARRAY_KEY_ITERATOR_TYPE,
    837   LAST_ARRAY_ITERATOR_TYPE = LAST_ARRAY_VALUE_ITERATOR_TYPE,
    838 };
    839 
    840 STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
    841 STATIC_ASSERT(JS_API_OBJECT_TYPE == Internals::kJSApiObjectType);
    842 STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
    843 STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType);
    844 STATIC_ASSERT(FOREIGN_TYPE == Internals::kForeignType);
    845 
    846 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
    847                                            InstanceType instance_type);
    848 
    849 #define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V)    \
    850   V(BYTECODE_ARRAY_CONSTANT_POOL_SUB_TYPE)       \
    851   V(BYTECODE_ARRAY_HANDLER_TABLE_SUB_TYPE)       \
    852   V(CODE_STUBS_TABLE_SUB_TYPE)                   \
    853   V(COMPILATION_CACHE_TABLE_SUB_TYPE)            \
    854   V(CONTEXT_SUB_TYPE)                            \
    855   V(COPY_ON_WRITE_SUB_TYPE)                      \
    856   V(DEOPTIMIZATION_DATA_SUB_TYPE)                \
    857   V(DESCRIPTOR_ARRAY_SUB_TYPE)                   \
    858   V(EMBEDDED_OBJECT_SUB_TYPE)                    \
    859   V(ENUM_CACHE_SUB_TYPE)                         \
    860   V(ENUM_INDICES_CACHE_SUB_TYPE)                 \
    861   V(DEPENDENT_CODE_SUB_TYPE)                     \
    862   V(DICTIONARY_ELEMENTS_SUB_TYPE)                \
    863   V(DICTIONARY_PROPERTIES_SUB_TYPE)              \
    864   V(EMPTY_PROPERTIES_DICTIONARY_SUB_TYPE)        \
    865   V(FAST_ELEMENTS_SUB_TYPE)                      \
    866   V(FAST_PROPERTIES_SUB_TYPE)                    \
    867   V(FAST_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE) \
    868   V(HANDLER_TABLE_SUB_TYPE)                      \
    869   V(JS_COLLECTION_SUB_TYPE)                      \
    870   V(JS_WEAK_COLLECTION_SUB_TYPE)                 \
    871   V(MAP_CODE_CACHE_SUB_TYPE)                     \
    872   V(NOSCRIPT_SHARED_FUNCTION_INFOS_SUB_TYPE)     \
    873   V(NUMBER_STRING_CACHE_SUB_TYPE)                \
    874   V(OBJECT_TO_CODE_SUB_TYPE)                     \
    875   V(OPTIMIZED_CODE_LITERALS_SUB_TYPE)            \
    876   V(OPTIMIZED_CODE_MAP_SUB_TYPE)                 \
    877   V(PROTOTYPE_USERS_SUB_TYPE)                    \
    878   V(REGEXP_MULTIPLE_CACHE_SUB_TYPE)              \
    879   V(RETAINED_MAPS_SUB_TYPE)                      \
    880   V(SCOPE_INFO_SUB_TYPE)                         \
    881   V(SCRIPT_LIST_SUB_TYPE)                        \
    882   V(SERIALIZED_TEMPLATES_SUB_TYPE)               \
    883   V(SHARED_FUNCTION_INFOS_SUB_TYPE)              \
    884   V(SINGLE_CHARACTER_STRING_CACHE_SUB_TYPE)      \
    885   V(SLOW_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE) \
    886   V(STRING_SPLIT_CACHE_SUB_TYPE)                 \
    887   V(STRING_TABLE_SUB_TYPE)                       \
    888   V(TEMPLATE_INFO_SUB_TYPE)                      \
    889   V(FEEDBACK_VECTOR_SUB_TYPE)                    \
    890   V(FEEDBACK_METADATA_SUB_TYPE)                  \
    891   V(WEAK_NEW_SPACE_OBJECT_TO_CODE_SUB_TYPE)
    892 
    893 enum FixedArraySubInstanceType {
    894 #define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
    895   FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
    896 #undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
    897       LAST_FIXED_ARRAY_SUB_TYPE = WEAK_NEW_SPACE_OBJECT_TO_CODE_SUB_TYPE
    898 };
    899 
    900 
    901 // TODO(bmeurer): Remove this in favor of the ComparisonResult below.
    902 enum CompareResult {
    903   LESS      = -1,
    904   EQUAL     =  0,
    905   GREATER   =  1,
    906 
    907   NOT_EQUAL = GREATER
    908 };
    909 
    910 
    911 // Result of an abstract relational comparison of x and y, implemented according
    912 // to ES6 section 7.2.11 Abstract Relational Comparison.
    913 enum class ComparisonResult {
    914   kLessThan,     // x < y
    915   kEqual,        // x = y
    916   kGreaterThan,  // x > y
    917   kUndefined     // at least one of x or y was undefined or NaN
    918 };
    919 
    920 
    921 class AbstractCode;
    922 class AccessorPair;
    923 class AllocationSite;
    924 class AllocationSiteCreationContext;
    925 class AllocationSiteUsageContext;
    926 class Cell;
    927 class ConsString;
    928 class ElementsAccessor;
    929 class FindAndReplacePattern;
    930 class FixedArrayBase;
    931 class FunctionLiteral;
    932 class JSGlobalObject;
    933 class KeyAccumulator;
    934 class LayoutDescriptor;
    935 class LookupIterator;
    936 class FieldType;
    937 class Module;
    938 class ModuleDescriptor;
    939 class ModuleInfoEntry;
    940 class ModuleInfo;
    941 class ObjectHashTable;
    942 class ObjectVisitor;
    943 class PropertyCell;
    944 class PropertyDescriptor;
    945 class SafepointEntry;
    946 class SharedFunctionInfo;
    947 class StringStream;
    948 class TypeFeedbackInfo;
    949 class FeedbackMetadata;
    950 class FeedbackVector;
    951 class WeakCell;
    952 class TransitionArray;
    953 class TemplateList;
    954 
    955 // A template-ized version of the IsXXX functions.
    956 template <class C> inline bool Is(Object* obj);
    957 
    958 #ifdef OBJECT_PRINT
    959 #define DECLARE_PRINTER(Name) void Name##Print(std::ostream& os);  // NOLINT
    960 #else
    961 #define DECLARE_PRINTER(Name)
    962 #endif
    963 
    964 #define OBJECT_TYPE_LIST(V) \
    965   V(Smi)                    \
    966   V(LayoutDescriptor)       \
    967   V(HeapObject)             \
    968   V(Primitive)              \
    969   V(Number)
    970 
    971 #define HEAP_OBJECT_TYPE_LIST(V) \
    972   V(HeapNumber)                  \
    973   V(MutableHeapNumber)           \
    974   V(Name)                        \
    975   V(UniqueName)                  \
    976   V(String)                      \
    977   V(SeqString)                   \
    978   V(ExternalString)              \
    979   V(ConsString)                  \
    980   V(SlicedString)                \
    981   V(ExternalTwoByteString)       \
    982   V(ExternalOneByteString)       \
    983   V(SeqTwoByteString)            \
    984   V(SeqOneByteString)            \
    985   V(InternalizedString)          \
    986   V(ThinString)                  \
    987   V(Symbol)                      \
    988                                  \
    989   V(FixedTypedArrayBase)         \
    990   V(FixedUint8Array)             \
    991   V(FixedInt8Array)              \
    992   V(FixedUint16Array)            \
    993   V(FixedInt16Array)             \
    994   V(FixedUint32Array)            \
    995   V(FixedInt32Array)             \
    996   V(FixedFloat32Array)           \
    997   V(FixedFloat64Array)           \
    998   V(FixedUint8ClampedArray)      \
    999   V(ByteArray)                   \
   1000   V(BytecodeArray)               \
   1001   V(FreeSpace)                   \
   1002   V(JSReceiver)                  \
   1003   V(JSObject)                    \
   1004   V(JSArgumentsObject)           \
   1005   V(JSContextExtensionObject)    \
   1006   V(JSGeneratorObject)           \
   1007   V(JSModuleNamespace)           \
   1008   V(Map)                         \
   1009   V(DescriptorArray)             \
   1010   V(FrameArray)                  \
   1011   V(TransitionArray)             \
   1012   V(FeedbackMetadata)            \
   1013   V(FeedbackVector)              \
   1014   V(DeoptimizationInputData)     \
   1015   V(DeoptimizationOutputData)    \
   1016   V(DependentCode)               \
   1017   V(HandlerTable)                \
   1018   V(FixedArray)                  \
   1019   V(BoilerplateDescription)      \
   1020   V(FixedDoubleArray)            \
   1021   V(WeakFixedArray)              \
   1022   V(ArrayList)                   \
   1023   V(RegExpMatchInfo)             \
   1024   V(Context)                     \
   1025   V(ScriptContextTable)          \
   1026   V(NativeContext)               \
   1027   V(ScopeInfo)                   \
   1028   V(ModuleInfo)                  \
   1029   V(JSBoundFunction)             \
   1030   V(JSFunction)                  \
   1031   V(Code)                        \
   1032   V(AbstractCode)                \
   1033   V(Oddball)                     \
   1034   V(SharedFunctionInfo)          \
   1035   V(JSValue)                     \
   1036   V(JSDate)                      \
   1037   V(JSMessageObject)             \
   1038   V(StringWrapper)               \
   1039   V(Foreign)                     \
   1040   V(Boolean)                     \
   1041   V(JSArray)                     \
   1042   V(JSArrayBuffer)               \
   1043   V(JSArrayBufferView)           \
   1044   V(JSAsyncFromSyncIterator)     \
   1045   V(JSCollection)                \
   1046   V(JSTypedArray)                \
   1047   V(JSArrayIterator)             \
   1048   V(JSDataView)                  \
   1049   V(JSProxy)                     \
   1050   V(JSError)                     \
   1051   V(JSPromiseCapability)         \
   1052   V(JSPromise)                   \
   1053   V(JSStringIterator)            \
   1054   V(JSSet)                       \
   1055   V(JSMap)                       \
   1056   V(JSSetIterator)               \
   1057   V(JSMapIterator)               \
   1058   V(JSWeakCollection)            \
   1059   V(JSWeakMap)                   \
   1060   V(JSWeakSet)                   \
   1061   V(JSRegExp)                    \
   1062   V(HashTable)                   \
   1063   V(Dictionary)                  \
   1064   V(UnseededNumberDictionary)    \
   1065   V(StringTable)                 \
   1066   V(StringSet)                   \
   1067   V(NormalizedMapCache)          \
   1068   V(CompilationCacheTable)       \
   1069   V(CodeCacheHashTable)          \
   1070   V(MapCache)                    \
   1071   V(JSGlobalObject)              \
   1072   V(JSGlobalProxy)               \
   1073   V(Undetectable)                \
   1074   V(AccessCheckNeeded)           \
   1075   V(Callable)                    \
   1076   V(Function)                    \
   1077   V(Constructor)                 \
   1078   V(TemplateInfo)                \
   1079   V(Filler)                      \
   1080   V(FixedArrayBase)              \
   1081   V(External)                    \
   1082   V(Struct)                      \
   1083   V(Cell)                        \
   1084   V(TemplateList)                \
   1085   V(PropertyCell)                \
   1086   V(WeakCell)                    \
   1087   V(ObjectHashTable)             \
   1088   V(ObjectHashSet)               \
   1089   V(WeakHashTable)               \
   1090   V(OrderedHashTable)
   1091 
   1092 #define ODDBALL_LIST(V)                 \
   1093   V(Undefined, undefined_value)         \
   1094   V(Null, null_value)                   \
   1095   V(TheHole, the_hole_value)            \
   1096   V(Exception, exception)               \
   1097   V(Uninitialized, uninitialized_value) \
   1098   V(True, true_value)                   \
   1099   V(False, false_value)                 \
   1100   V(ArgumentsMarker, arguments_marker)  \
   1101   V(OptimizedOut, optimized_out)        \
   1102   V(StaleRegister, stale_register)
   1103 
   1104 // The element types selection for CreateListFromArrayLike.
   1105 enum class ElementTypes { kAll, kStringAndSymbol };
   1106 
   1107 // Object is the abstract superclass for all classes in the
   1108 // object hierarchy.
   1109 // Object does not use any virtual functions to avoid the
   1110 // allocation of the C++ vtable.
   1111 // Since both Smi and HeapObject are subclasses of Object no
   1112 // data members can be present in Object.
   1113 class Object {
   1114  public:
   1115   // Type testing.
   1116   bool IsObject() const { return true; }
   1117 
   1118 #define IS_TYPE_FUNCTION_DECL(Type) INLINE(bool Is##Type() const);
   1119   OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
   1120   HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
   1121 #undef IS_TYPE_FUNCTION_DECL
   1122 
   1123 #define IS_TYPE_FUNCTION_DECL(Type, Value) \
   1124   INLINE(bool Is##Type(Isolate* isolate) const);
   1125   ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
   1126 #undef IS_TYPE_FUNCTION_DECL
   1127 
   1128   INLINE(bool IsNullOrUndefined(Isolate* isolate) const);
   1129 
   1130   // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
   1131   // a keyed store is of the form a[expression] = foo.
   1132   enum StoreFromKeyed {
   1133     MAY_BE_STORE_FROM_KEYED,
   1134     CERTAINLY_NOT_STORE_FROM_KEYED
   1135   };
   1136 
   1137   enum ShouldThrow { THROW_ON_ERROR, DONT_THROW };
   1138 
   1139 #define RETURN_FAILURE(isolate, should_throw, call) \
   1140   do {                                              \
   1141     if ((should_throw) == DONT_THROW) {             \
   1142       return Just(false);                           \
   1143     } else {                                        \
   1144       isolate->Throw(*isolate->factory()->call);    \
   1145       return Nothing<bool>();                       \
   1146     }                                               \
   1147   } while (false)
   1148 
   1149 #define MAYBE_RETURN(call, value)         \
   1150   do {                                    \
   1151     if ((call).IsNothing()) return value; \
   1152   } while (false)
   1153 
   1154 #define MAYBE_RETURN_NULL(call) MAYBE_RETURN(call, MaybeHandle<Object>())
   1155 
   1156 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \
   1157   INLINE(bool Is##Name() const);
   1158   STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
   1159 #undef DECLARE_STRUCT_PREDICATE
   1160 
   1161   // ES6, section 7.2.2 IsArray.  NOT to be confused with %_IsArray.
   1162   MUST_USE_RESULT static Maybe<bool> IsArray(Handle<Object> object);
   1163 
   1164   INLINE(bool IsNameDictionary() const);
   1165   INLINE(bool IsGlobalDictionary() const);
   1166   INLINE(bool IsSeededNumberDictionary() const);
   1167   INLINE(bool IsOrderedHashSet() const);
   1168   INLINE(bool IsOrderedHashMap() const);
   1169 
   1170   // Extract the number.
   1171   inline double Number() const;
   1172   INLINE(bool IsNaN() const);
   1173   INLINE(bool IsMinusZero() const);
   1174   bool ToInt32(int32_t* value);
   1175   inline bool ToUint32(uint32_t* value);
   1176 
   1177   inline Representation OptimalRepresentation();
   1178 
   1179   inline ElementsKind OptimalElementsKind();
   1180 
   1181   inline bool FitsRepresentation(Representation representation);
   1182 
   1183   // Checks whether two valid primitive encodings of a property name resolve to
   1184   // the same logical property. E.g., the smi 1, the string "1" and the double
   1185   // 1 all refer to the same property, so this helper will return true.
   1186   inline bool KeyEquals(Object* other);
   1187 
   1188   inline bool FilterKey(PropertyFilter filter);
   1189 
   1190   Handle<FieldType> OptimalType(Isolate* isolate,
   1191                                 Representation representation);
   1192 
   1193   inline static Handle<Object> NewStorageFor(Isolate* isolate,
   1194                                              Handle<Object> object,
   1195                                              Representation representation);
   1196 
   1197   inline static Handle<Object> WrapForRead(Isolate* isolate,
   1198                                            Handle<Object> object,
   1199                                            Representation representation);
   1200 
   1201   // Returns true if the object is of the correct type to be used as a
   1202   // implementation of a JSObject's elements.
   1203   inline bool HasValidElements();
   1204 
   1205   inline bool HasSpecificClassOf(String* name);
   1206 
   1207   bool BooleanValue();                                      // ECMA-262 9.2.
   1208 
   1209   // ES6 section 7.2.11 Abstract Relational Comparison
   1210   MUST_USE_RESULT static Maybe<ComparisonResult> Compare(Handle<Object> x,
   1211                                                          Handle<Object> y);
   1212 
   1213   // ES6 section 7.2.12 Abstract Equality Comparison
   1214   MUST_USE_RESULT static Maybe<bool> Equals(Handle<Object> x, Handle<Object> y);
   1215 
   1216   // ES6 section 7.2.13 Strict Equality Comparison
   1217   bool StrictEquals(Object* that);
   1218 
   1219   // Convert to a JSObject if needed.
   1220   // native_context is used when creating wrapper object.
   1221   MUST_USE_RESULT static inline MaybeHandle<JSReceiver> ToObject(
   1222       Isolate* isolate, Handle<Object> object);
   1223   MUST_USE_RESULT static MaybeHandle<JSReceiver> ToObject(
   1224       Isolate* isolate, Handle<Object> object, Handle<Context> context);
   1225 
   1226   // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
   1227   MUST_USE_RESULT static MaybeHandle<JSReceiver> ConvertReceiver(
   1228       Isolate* isolate, Handle<Object> object);
   1229 
   1230   // ES6 section 7.1.14 ToPropertyKey
   1231   MUST_USE_RESULT static inline MaybeHandle<Name> ToName(Isolate* isolate,
   1232                                                          Handle<Object> input);
   1233 
   1234   // ES6 section 7.1.1 ToPrimitive
   1235   MUST_USE_RESULT static inline MaybeHandle<Object> ToPrimitive(
   1236       Handle<Object> input, ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
   1237 
   1238   // ES6 section 7.1.3 ToNumber
   1239   MUST_USE_RESULT static inline MaybeHandle<Object> ToNumber(
   1240       Handle<Object> input);
   1241 
   1242   // ES6 section 7.1.4 ToInteger
   1243   MUST_USE_RESULT static inline MaybeHandle<Object> ToInteger(
   1244       Isolate* isolate, Handle<Object> input);
   1245 
   1246   // ES6 section 7.1.5 ToInt32
   1247   MUST_USE_RESULT static inline MaybeHandle<Object> ToInt32(
   1248       Isolate* isolate, Handle<Object> input);
   1249 
   1250   // ES6 section 7.1.6 ToUint32
   1251   MUST_USE_RESULT inline static MaybeHandle<Object> ToUint32(
   1252       Isolate* isolate, Handle<Object> input);
   1253 
   1254   // ES6 section 7.1.12 ToString
   1255   MUST_USE_RESULT static inline MaybeHandle<String> ToString(
   1256       Isolate* isolate, Handle<Object> input);
   1257 
   1258   static Handle<String> NoSideEffectsToString(Isolate* isolate,
   1259                                               Handle<Object> input);
   1260 
   1261   // ES6 section 7.1.14 ToPropertyKey
   1262   MUST_USE_RESULT static inline MaybeHandle<Object> ToPropertyKey(
   1263       Isolate* isolate, Handle<Object> value);
   1264 
   1265   // ES6 section 7.1.15 ToLength
   1266   MUST_USE_RESULT static inline MaybeHandle<Object> ToLength(
   1267       Isolate* isolate, Handle<Object> input);
   1268 
   1269   // ES6 section 7.1.17 ToIndex
   1270   MUST_USE_RESULT static inline MaybeHandle<Object> ToIndex(
   1271       Isolate* isolate, Handle<Object> input,
   1272       MessageTemplate::Template error_index);
   1273 
   1274   // ES6 section 7.3.9 GetMethod
   1275   MUST_USE_RESULT static MaybeHandle<Object> GetMethod(
   1276       Handle<JSReceiver> receiver, Handle<Name> name);
   1277 
   1278   // ES6 section 7.3.17 CreateListFromArrayLike
   1279   MUST_USE_RESULT static MaybeHandle<FixedArray> CreateListFromArrayLike(
   1280       Isolate* isolate, Handle<Object> object, ElementTypes element_types);
   1281 
   1282   // Get length property and apply ToLength.
   1283   MUST_USE_RESULT static MaybeHandle<Object> GetLengthFromArrayLike(
   1284       Isolate* isolate, Handle<Object> object);
   1285 
   1286   // ES6 section 12.5.6 The typeof Operator
   1287   static Handle<String> TypeOf(Isolate* isolate, Handle<Object> object);
   1288 
   1289   // ES6 section 12.6 Multiplicative Operators
   1290   MUST_USE_RESULT static MaybeHandle<Object> Multiply(Isolate* isolate,
   1291                                                       Handle<Object> lhs,
   1292                                                       Handle<Object> rhs);
   1293   MUST_USE_RESULT static MaybeHandle<Object> Divide(Isolate* isolate,
   1294                                                     Handle<Object> lhs,
   1295                                                     Handle<Object> rhs);
   1296   MUST_USE_RESULT static MaybeHandle<Object> Modulus(Isolate* isolate,
   1297                                                      Handle<Object> lhs,
   1298                                                      Handle<Object> rhs);
   1299 
   1300   // ES6 section 12.7 Additive Operators
   1301   MUST_USE_RESULT static MaybeHandle<Object> Add(Isolate* isolate,
   1302                                                  Handle<Object> lhs,
   1303                                                  Handle<Object> rhs);
   1304   MUST_USE_RESULT static MaybeHandle<Object> Subtract(Isolate* isolate,
   1305                                                       Handle<Object> lhs,
   1306                                                       Handle<Object> rhs);
   1307 
   1308   // ES6 section 12.8 Bitwise Shift Operators
   1309   MUST_USE_RESULT static MaybeHandle<Object> ShiftLeft(Isolate* isolate,
   1310                                                        Handle<Object> lhs,
   1311                                                        Handle<Object> rhs);
   1312   MUST_USE_RESULT static MaybeHandle<Object> ShiftRight(Isolate* isolate,
   1313                                                         Handle<Object> lhs,
   1314                                                         Handle<Object> rhs);
   1315   MUST_USE_RESULT static MaybeHandle<Object> ShiftRightLogical(
   1316       Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs);
   1317 
   1318   // ES6 section 12.9 Relational Operators
   1319   MUST_USE_RESULT static inline Maybe<bool> GreaterThan(Handle<Object> x,
   1320                                                         Handle<Object> y);
   1321   MUST_USE_RESULT static inline Maybe<bool> GreaterThanOrEqual(
   1322       Handle<Object> x, Handle<Object> y);
   1323   MUST_USE_RESULT static inline Maybe<bool> LessThan(Handle<Object> x,
   1324                                                      Handle<Object> y);
   1325   MUST_USE_RESULT static inline Maybe<bool> LessThanOrEqual(Handle<Object> x,
   1326                                                             Handle<Object> y);
   1327 
   1328   // ES6 section 12.11 Binary Bitwise Operators
   1329   MUST_USE_RESULT static MaybeHandle<Object> BitwiseAnd(Isolate* isolate,
   1330                                                         Handle<Object> lhs,
   1331                                                         Handle<Object> rhs);
   1332   MUST_USE_RESULT static MaybeHandle<Object> BitwiseOr(Isolate* isolate,
   1333                                                        Handle<Object> lhs,
   1334                                                        Handle<Object> rhs);
   1335   MUST_USE_RESULT static MaybeHandle<Object> BitwiseXor(Isolate* isolate,
   1336                                                         Handle<Object> lhs,
   1337                                                         Handle<Object> rhs);
   1338 
   1339   // ES6 section 7.3.19 OrdinaryHasInstance (C, O).
   1340   MUST_USE_RESULT static MaybeHandle<Object> OrdinaryHasInstance(
   1341       Isolate* isolate, Handle<Object> callable, Handle<Object> object);
   1342 
   1343   // ES6 section 12.10.4 Runtime Semantics: InstanceofOperator(O, C)
   1344   MUST_USE_RESULT static MaybeHandle<Object> InstanceOf(
   1345       Isolate* isolate, Handle<Object> object, Handle<Object> callable);
   1346 
   1347   V8_EXPORT_PRIVATE MUST_USE_RESULT static MaybeHandle<Object> GetProperty(
   1348       LookupIterator* it);
   1349 
   1350   // ES6 [[Set]] (when passed DONT_THROW)
   1351   // Invariants for this and related functions (unless stated otherwise):
   1352   // 1) When the result is Nothing, an exception is pending.
   1353   // 2) When passed THROW_ON_ERROR, the result is never Just(false).
   1354   // In some cases, an exception is thrown regardless of the ShouldThrow
   1355   // argument.  These cases are either in accordance with the spec or not
   1356   // covered by it (eg., concerning API callbacks).
   1357   MUST_USE_RESULT static Maybe<bool> SetProperty(LookupIterator* it,
   1358                                                  Handle<Object> value,
   1359                                                  LanguageMode language_mode,
   1360                                                  StoreFromKeyed store_mode);
   1361   MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
   1362       Handle<Object> object, Handle<Name> name, Handle<Object> value,
   1363       LanguageMode language_mode,
   1364       StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
   1365   MUST_USE_RESULT static inline MaybeHandle<Object> SetPropertyOrElement(
   1366       Handle<Object> object, Handle<Name> name, Handle<Object> value,
   1367       LanguageMode language_mode,
   1368       StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
   1369 
   1370   MUST_USE_RESULT static Maybe<bool> SetSuperProperty(
   1371       LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
   1372       StoreFromKeyed store_mode);
   1373 
   1374   MUST_USE_RESULT static Maybe<bool> CannotCreateProperty(
   1375       Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
   1376       Handle<Object> value, ShouldThrow should_throw);
   1377   MUST_USE_RESULT static Maybe<bool> WriteToReadOnlyProperty(
   1378       LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
   1379   MUST_USE_RESULT static Maybe<bool> WriteToReadOnlyProperty(
   1380       Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
   1381       Handle<Object> value, ShouldThrow should_throw);
   1382   MUST_USE_RESULT static Maybe<bool> RedefineIncompatibleProperty(
   1383       Isolate* isolate, Handle<Object> name, Handle<Object> value,
   1384       ShouldThrow should_throw);
   1385   MUST_USE_RESULT static Maybe<bool> SetDataProperty(LookupIterator* it,
   1386                                                      Handle<Object> value);
   1387   MUST_USE_RESULT static Maybe<bool> AddDataProperty(
   1388       LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
   1389       ShouldThrow should_throw, StoreFromKeyed store_mode);
   1390   MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
   1391       Handle<Object> object, Handle<Name> name);
   1392   MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
   1393       Handle<Object> receiver, Handle<Name> name, Handle<JSReceiver> holder);
   1394   MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
   1395       Handle<Object> object, Handle<Name> name);
   1396 
   1397   MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
   1398       LookupIterator* it);
   1399   MUST_USE_RESULT static Maybe<bool> SetPropertyWithAccessor(
   1400       LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
   1401 
   1402   MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
   1403       Handle<Object> receiver,
   1404       Handle<JSReceiver> getter);
   1405   MUST_USE_RESULT static Maybe<bool> SetPropertyWithDefinedSetter(
   1406       Handle<Object> receiver, Handle<JSReceiver> setter, Handle<Object> value,
   1407       ShouldThrow should_throw);
   1408 
   1409   MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
   1410       Isolate* isolate, Handle<Object> object, uint32_t index);
   1411 
   1412   MUST_USE_RESULT static inline MaybeHandle<Object> SetElement(
   1413       Isolate* isolate, Handle<Object> object, uint32_t index,
   1414       Handle<Object> value, LanguageMode language_mode);
   1415 
   1416   // Returns the permanent hash code associated with this object. May return
   1417   // undefined if not yet created.
   1418   Object* GetHash();
   1419 
   1420   // Returns the permanent hash code associated with this object depending on
   1421   // the actual object type. May create and store a hash code if needed and none
   1422   // exists.
   1423   static Smi* GetOrCreateHash(Isolate* isolate, Handle<Object> object);
   1424 
   1425   // Checks whether this object has the same value as the given one.  This
   1426   // function is implemented according to ES5, section 9.12 and can be used
   1427   // to implement the Harmony "egal" function.
   1428   V8_EXPORT_PRIVATE bool SameValue(Object* other);
   1429 
   1430   // Checks whether this object has the same value as the given one.
   1431   // +0 and -0 are treated equal. Everything else is the same as SameValue.
   1432   // This function is implemented according to ES6, section 7.2.4 and is used
   1433   // by ES6 Map and Set.
   1434   bool SameValueZero(Object* other);
   1435 
   1436   // ES6 section 9.4.2.3 ArraySpeciesCreate (part of it)
   1437   MUST_USE_RESULT static MaybeHandle<Object> ArraySpeciesConstructor(
   1438       Isolate* isolate, Handle<Object> original_array);
   1439 
   1440   // Tries to convert an object to an array length. Returns true and sets the
   1441   // output parameter if it succeeds.
   1442   inline bool ToArrayLength(uint32_t* index);
   1443 
   1444   // Tries to convert an object to an array index. Returns true and sets the
   1445   // output parameter if it succeeds. Equivalent to ToArrayLength, but does not
   1446   // allow kMaxUInt32.
   1447   inline bool ToArrayIndex(uint32_t* index);
   1448 
   1449   // Returns true if the result of iterating over the object is the same
   1450   // (including observable effects) as simply accessing the properties between 0
   1451   // and length.
   1452   bool IterationHasObservableEffects();
   1453 
   1454   DECLARE_VERIFIER(Object)
   1455 #ifdef VERIFY_HEAP
   1456   // Verify a pointer is a valid object pointer.
   1457   static void VerifyPointer(Object* p);
   1458 #endif
   1459 
   1460   inline void VerifyApiCallResultType();
   1461 
   1462   // Prints this object without details.
   1463   void ShortPrint(FILE* out = stdout);
   1464 
   1465   // Prints this object without details to a message accumulator.
   1466   void ShortPrint(StringStream* accumulator);
   1467 
   1468   void ShortPrint(std::ostream& os);  // NOLINT
   1469 
   1470   DECLARE_CAST(Object)
   1471 
   1472   // Layout description.
   1473   static const int kHeaderSize = 0;  // Object does not take up any space.
   1474 
   1475 #ifdef OBJECT_PRINT
   1476   // For our gdb macros, we should perhaps change these in the future.
   1477   void Print();
   1478 
   1479   // Prints this object with details.
   1480   void Print(std::ostream& os);  // NOLINT
   1481 #else
   1482   void Print() { ShortPrint(); }
   1483   void Print(std::ostream& os) { ShortPrint(os); }  // NOLINT
   1484 #endif
   1485 
   1486  private:
   1487   friend class LookupIterator;
   1488   friend class StringStream;
   1489 
   1490   // Return the map of the root of object's prototype chain.
   1491   Map* GetPrototypeChainRootMap(Isolate* isolate);
   1492 
   1493   // Helper for SetProperty and SetSuperProperty.
   1494   // Return value is only meaningful if [found] is set to true on return.
   1495   MUST_USE_RESULT static Maybe<bool> SetPropertyInternal(
   1496       LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
   1497       StoreFromKeyed store_mode, bool* found);
   1498 
   1499   MUST_USE_RESULT static MaybeHandle<Name> ConvertToName(Isolate* isolate,
   1500                                                          Handle<Object> input);
   1501   MUST_USE_RESULT static MaybeHandle<Object> ConvertToPropertyKey(
   1502       Isolate* isolate, Handle<Object> value);
   1503   MUST_USE_RESULT static MaybeHandle<String> ConvertToString(
   1504       Isolate* isolate, Handle<Object> input);
   1505   MUST_USE_RESULT static MaybeHandle<Object> ConvertToNumber(
   1506       Isolate* isolate, Handle<Object> input);
   1507   MUST_USE_RESULT static MaybeHandle<Object> ConvertToInteger(
   1508       Isolate* isolate, Handle<Object> input);
   1509   MUST_USE_RESULT static MaybeHandle<Object> ConvertToInt32(
   1510       Isolate* isolate, Handle<Object> input);
   1511   MUST_USE_RESULT static MaybeHandle<Object> ConvertToUint32(
   1512       Isolate* isolate, Handle<Object> input);
   1513   MUST_USE_RESULT static MaybeHandle<Object> ConvertToLength(
   1514       Isolate* isolate, Handle<Object> input);
   1515   MUST_USE_RESULT static MaybeHandle<Object> ConvertToIndex(
   1516       Isolate* isolate, Handle<Object> input,
   1517       MessageTemplate::Template error_index);
   1518 
   1519   DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
   1520 };
   1521 
   1522 
   1523 // In objects.h to be usable without objects-inl.h inclusion.
   1524 bool Object::IsSmi() const { return HAS_SMI_TAG(this); }
   1525 bool Object::IsHeapObject() const { return Internals::HasHeapObjectTag(this); }
   1526 
   1527 
   1528 struct Brief {
   1529   explicit Brief(const Object* const v) : value(v) {}
   1530   const Object* value;
   1531 };
   1532 
   1533 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const Brief& v);
   1534 
   1535 // Smi represents integer Numbers that can be stored in 31 bits.
   1536 // Smis are immediate which means they are NOT allocated in the heap.
   1537 // The this pointer has the following format: [31 bit signed int] 0
   1538 // For long smis it has the following format:
   1539 //     [32 bit signed int] [31 bits zero padding] 0
   1540 // Smi stands for small integer.
   1541 class Smi: public Object {
   1542  public:
   1543   // Returns the integer value.
   1544   inline int value() const { return Internals::SmiValue(this); }
   1545   inline Smi* ToUint32Smi() {
   1546     if (value() <= 0) return Smi::kZero;
   1547     return Smi::FromInt(static_cast<uint32_t>(value()));
   1548   }
   1549 
   1550   // Convert a value to a Smi object.
   1551   static inline Smi* FromInt(int value) {
   1552     DCHECK(Smi::IsValid(value));
   1553     return reinterpret_cast<Smi*>(Internals::IntToSmi(value));
   1554   }
   1555 
   1556   static inline Smi* FromIntptr(intptr_t value) {
   1557     DCHECK(Smi::IsValid(value));
   1558     int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
   1559     return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
   1560   }
   1561 
   1562   // Returns whether value can be represented in a Smi.
   1563   static inline bool IsValid(intptr_t value) {
   1564     bool result = Internals::IsValidSmi(value);
   1565     DCHECK_EQ(result, value >= kMinValue && value <= kMaxValue);
   1566     return result;
   1567   }
   1568 
   1569   DECLARE_CAST(Smi)
   1570 
   1571   // Dispatched behavior.
   1572   V8_EXPORT_PRIVATE void SmiPrint(std::ostream& os) const;  // NOLINT
   1573   DECLARE_VERIFIER(Smi)
   1574 
   1575   static constexpr Smi* const kZero = nullptr;
   1576   static const int kMinValue =
   1577       (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
   1578   static const int kMaxValue = -(kMinValue + 1);
   1579 
   1580  private:
   1581   DISALLOW_IMPLICIT_CONSTRUCTORS(Smi);
   1582 };
   1583 
   1584 
   1585 // Heap objects typically have a map pointer in their first word.  However,
   1586 // during GC other data (e.g. mark bits, forwarding addresses) is sometimes
   1587 // encoded in the first word.  The class MapWord is an abstraction of the
   1588 // value in a heap object's first word.
   1589 class MapWord BASE_EMBEDDED {
   1590  public:
   1591   // Normal state: the map word contains a map pointer.
   1592 
   1593   // Create a map word from a map pointer.
   1594   static inline MapWord FromMap(const Map* map);
   1595 
   1596   // View this map word as a map pointer.
   1597   inline Map* ToMap();
   1598 
   1599 
   1600   // Scavenge collection: the map word of live objects in the from space
   1601   // contains a forwarding address (a heap object pointer in the to space).
   1602 
   1603   // True if this map word is a forwarding address for a scavenge
   1604   // collection.  Only valid during a scavenge collection (specifically,
   1605   // when all map words are heap object pointers, i.e. not during a full GC).
   1606   inline bool IsForwardingAddress() const;
   1607 
   1608   // Create a map word from a forwarding address.
   1609   static inline MapWord FromForwardingAddress(HeapObject* object);
   1610 
   1611   // View this map word as a forwarding address.
   1612   inline HeapObject* ToForwardingAddress();
   1613 
   1614   static inline MapWord FromRawValue(uintptr_t value) {
   1615     return MapWord(value);
   1616   }
   1617 
   1618   inline uintptr_t ToRawValue() {
   1619     return value_;
   1620   }
   1621 
   1622  private:
   1623   // HeapObject calls the private constructor and directly reads the value.
   1624   friend class HeapObject;
   1625 
   1626   explicit MapWord(uintptr_t value) : value_(value) {}
   1627 
   1628   uintptr_t value_;
   1629 };
   1630 
   1631 
   1632 // HeapObject is the superclass for all classes describing heap allocated
   1633 // objects.
   1634 class HeapObject: public Object {
   1635  public:
   1636   // [map]: Contains a map which contains the object's reflective
   1637   // information.
   1638   inline Map* map() const;
   1639   inline void set_map(Map* value);
   1640   // The no-write-barrier version.  This is OK if the object is white and in
   1641   // new space, or if the value is an immortal immutable object, like the maps
   1642   // of primitive (non-JS) objects like strings, heap numbers etc.
   1643   inline void set_map_no_write_barrier(Map* value);
   1644 
   1645   // Get the map using acquire load.
   1646   inline Map* synchronized_map();
   1647   inline MapWord synchronized_map_word() const;
   1648 
   1649   // Set the map using release store
   1650   inline void synchronized_set_map(Map* value);
   1651   inline void synchronized_set_map_no_write_barrier(Map* value);
   1652   inline void synchronized_set_map_word(MapWord map_word);
   1653 
   1654   // During garbage collection, the map word of a heap object does not
   1655   // necessarily contain a map pointer.
   1656   inline MapWord map_word() const;
   1657   inline void set_map_word(MapWord map_word);
   1658 
   1659   // The Heap the object was allocated in. Used also to access Isolate.
   1660   inline Heap* GetHeap() const;
   1661 
   1662   // Convenience method to get current isolate.
   1663   inline Isolate* GetIsolate() const;
   1664 
   1665 #define IS_TYPE_FUNCTION_DECL(Type) INLINE(bool Is##Type() const);
   1666   HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
   1667 #undef IS_TYPE_FUNCTION_DECL
   1668 
   1669 #define IS_TYPE_FUNCTION_DECL(Type, Value) \
   1670   INLINE(bool Is##Type(Isolate* isolate) const);
   1671   ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
   1672 #undef IS_TYPE_FUNCTION_DECL
   1673 
   1674   INLINE(bool IsNullOrUndefined(Isolate* isolate) const);
   1675 
   1676 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \
   1677   INLINE(bool Is##Name() const);
   1678   STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
   1679 #undef DECLARE_STRUCT_PREDICATE
   1680 
   1681   // Converts an address to a HeapObject pointer.
   1682   static inline HeapObject* FromAddress(Address address) {
   1683     DCHECK_TAG_ALIGNED(address);
   1684     return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
   1685   }
   1686 
   1687   // Returns the address of this HeapObject.
   1688   inline Address address() {
   1689     return reinterpret_cast<Address>(this) - kHeapObjectTag;
   1690   }
   1691 
   1692   // Iterates over pointers contained in the object (including the Map).
   1693   // If it's not performance critical iteration use the non-templatized
   1694   // version.
   1695   void Iterate(ObjectVisitor* v);
   1696 
   1697   template <typename ObjectVisitor>
   1698   inline void IterateFast(ObjectVisitor* v);
   1699 
   1700   // Iterates over all pointers contained in the object except the
   1701   // first map pointer.  The object type is given in the first
   1702   // parameter. This function does not access the map pointer in the
   1703   // object, and so is safe to call while the map pointer is modified.
   1704   // If it's not performance critical iteration use the non-templatized
   1705   // version.
   1706   void IterateBody(ObjectVisitor* v);
   1707   void IterateBody(InstanceType type, int object_size, ObjectVisitor* v);
   1708 
   1709   template <typename ObjectVisitor>
   1710   inline void IterateBodyFast(ObjectVisitor* v);
   1711 
   1712   template <typename ObjectVisitor>
   1713   inline void IterateBodyFast(InstanceType type, int object_size,
   1714                               ObjectVisitor* v);
   1715 
   1716   // Returns true if the object contains a tagged value at given offset.
   1717   // It is used for invalid slots filtering. If the offset points outside
   1718   // of the object or to the map word, the result is UNDEFINED (!!!).
   1719   bool IsValidSlot(int offset);
   1720 
   1721   // Returns the heap object's size in bytes
   1722   inline int Size();
   1723 
   1724   // Given a heap object's map pointer, returns the heap size in bytes
   1725   // Useful when the map pointer field is used for other purposes.
   1726   // GC internal.
   1727   inline int SizeFromMap(Map* map);
   1728 
   1729   // Returns the field at offset in obj, as a read/write Object* reference.
   1730   // Does no checking, and is safe to use during GC, while maps are invalid.
   1731   // Does not invoke write barrier, so should only be assigned to
   1732   // during marking GC.
   1733   static inline Object** RawField(HeapObject* obj, int offset);
   1734 
   1735   // Adds the |code| object related to |name| to the code cache of this map. If
   1736   // this map is a dictionary map that is shared, the map copied and installed
   1737   // onto the object.
   1738   static void UpdateMapCodeCache(Handle<HeapObject> object,
   1739                                  Handle<Name> name,
   1740                                  Handle<Code> code);
   1741 
   1742   DECLARE_CAST(HeapObject)
   1743 
   1744   // Return the write barrier mode for this. Callers of this function
   1745   // must be able to present a reference to an DisallowHeapAllocation
   1746   // object as a sign that they are not going to use this function
   1747   // from code that allocates and thus invalidates the returned write
   1748   // barrier mode.
   1749   inline WriteBarrierMode GetWriteBarrierMode(
   1750       const DisallowHeapAllocation& promise);
   1751 
   1752   // Dispatched behavior.
   1753   void HeapObjectShortPrint(std::ostream& os);  // NOLINT
   1754 #ifdef OBJECT_PRINT
   1755   void PrintHeader(std::ostream& os, const char* id);  // NOLINT
   1756 #endif
   1757   DECLARE_PRINTER(HeapObject)
   1758   DECLARE_VERIFIER(HeapObject)
   1759 #ifdef VERIFY_HEAP
   1760   inline void VerifyObjectField(int offset);
   1761   inline void VerifySmiField(int offset);
   1762 
   1763   // Verify a pointer is a valid HeapObject pointer that points to object
   1764   // areas in the heap.
   1765   static void VerifyHeapPointer(Object* p);
   1766 #endif
   1767 
   1768   inline AllocationAlignment RequiredAlignment();
   1769 
   1770   // Layout description.
   1771   // First field in a heap object is map.
   1772   static const int kMapOffset = Object::kHeaderSize;
   1773   static const int kHeaderSize = kMapOffset + kPointerSize;
   1774 
   1775   STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset);
   1776 
   1777  private:
   1778   DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
   1779 };
   1780 
   1781 
   1782 template <int start_offset, int end_offset, int size>
   1783 class FixedBodyDescriptor;
   1784 
   1785 
   1786 template <int start_offset>
   1787 class FlexibleBodyDescriptor;
   1788 
   1789 
   1790 // The HeapNumber class describes heap allocated numbers that cannot be
   1791 // represented in a Smi (small integer)
   1792 class HeapNumber: public HeapObject {
   1793  public:
   1794   // [value]: number value.
   1795   inline double value() const;
   1796   inline void set_value(double value);
   1797 
   1798   inline uint64_t value_as_bits() const;
   1799   inline void set_value_as_bits(uint64_t bits);
   1800 
   1801   DECLARE_CAST(HeapNumber)
   1802 
   1803   // Dispatched behavior.
   1804   bool HeapNumberBooleanValue();
   1805 
   1806   V8_EXPORT_PRIVATE void HeapNumberPrint(std::ostream& os);  // NOLINT
   1807   DECLARE_VERIFIER(HeapNumber)
   1808 
   1809   inline int get_exponent();
   1810   inline int get_sign();
   1811 
   1812   // Layout description.
   1813   static const int kValueOffset = HeapObject::kHeaderSize;
   1814   // IEEE doubles are two 32 bit words.  The first is just mantissa, the second
   1815   // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit
   1816   // words within double numbers are endian dependent and they are set
   1817   // accordingly.
   1818 #if defined(V8_TARGET_LITTLE_ENDIAN)
   1819   static const int kMantissaOffset = kValueOffset;
   1820   static const int kExponentOffset = kValueOffset + 4;
   1821 #elif defined(V8_TARGET_BIG_ENDIAN)
   1822   static const int kMantissaOffset = kValueOffset + 4;
   1823   static const int kExponentOffset = kValueOffset;
   1824 #else
   1825 #error Unknown byte ordering
   1826 #endif
   1827 
   1828   static const int kSize = kValueOffset + kDoubleSize;
   1829   static const uint32_t kSignMask = 0x80000000u;
   1830   static const uint32_t kExponentMask = 0x7ff00000u;
   1831   static const uint32_t kMantissaMask = 0xfffffu;
   1832   static const int kMantissaBits = 52;
   1833   static const int kExponentBits = 11;
   1834   static const int kExponentBias = 1023;
   1835   static const int kExponentShift = 20;
   1836   static const int kInfinityOrNanExponent =
   1837       (kExponentMask >> kExponentShift) - kExponentBias;
   1838   static const int kMantissaBitsInTopWord = 20;
   1839   static const int kNonMantissaBitsInTopWord = 12;
   1840 
   1841  private:
   1842   DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
   1843 };
   1844 
   1845 enum EnsureElementsMode {
   1846   DONT_ALLOW_DOUBLE_ELEMENTS,
   1847   ALLOW_COPIED_DOUBLE_ELEMENTS,
   1848   ALLOW_CONVERTED_DOUBLE_ELEMENTS
   1849 };
   1850 
   1851 
   1852 // Indicator for one component of an AccessorPair.
   1853 enum AccessorComponent {
   1854   ACCESSOR_GETTER,
   1855   ACCESSOR_SETTER
   1856 };
   1857 
   1858 enum class GetKeysConversion { kKeepNumbers, kConvertToString };
   1859 
   1860 enum class KeyCollectionMode {
   1861   kOwnOnly = static_cast<int>(v8::KeyCollectionMode::kOwnOnly),
   1862   kIncludePrototypes =
   1863       static_cast<int>(v8::KeyCollectionMode::kIncludePrototypes)
   1864 };
   1865 
   1866 enum class AllocationSiteUpdateMode { kUpdate, kCheckOnly };
   1867 
   1868 // JSReceiver includes types on which properties can be defined, i.e.,
   1869 // JSObject and JSProxy.
   1870 class JSReceiver: public HeapObject {
   1871  public:
   1872   // [properties]: Backing storage for properties.
   1873   // properties is a FixedArray in the fast case and a Dictionary in the
   1874   // slow case.
   1875   DECL_ACCESSORS(properties, FixedArray)  // Get and set fast properties.
   1876   inline void initialize_properties();
   1877   inline bool HasFastProperties();
   1878   // Gets slow properties for non-global objects.
   1879   inline NameDictionary* property_dictionary();
   1880 
   1881   // Deletes an existing named property in a normalized object.
   1882   static void DeleteNormalizedProperty(Handle<JSReceiver> object,
   1883                                        Handle<Name> name, int entry);
   1884 
   1885   DECLARE_CAST(JSReceiver)
   1886 
   1887   // ES6 section 7.1.1 ToPrimitive
   1888   MUST_USE_RESULT static MaybeHandle<Object> ToPrimitive(
   1889       Handle<JSReceiver> receiver,
   1890       ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
   1891 
   1892   // ES6 section 7.1.1.1 OrdinaryToPrimitive
   1893   MUST_USE_RESULT static MaybeHandle<Object> OrdinaryToPrimitive(
   1894       Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint);
   1895 
   1896   static MaybeHandle<Context> GetFunctionRealm(Handle<JSReceiver> receiver);
   1897 
   1898   // Get the first non-hidden prototype.
   1899   static inline MaybeHandle<Object> GetPrototype(Isolate* isolate,
   1900                                                  Handle<JSReceiver> receiver);
   1901 
   1902   MUST_USE_RESULT static Maybe<bool> HasInPrototypeChain(
   1903       Isolate* isolate, Handle<JSReceiver> object, Handle<Object> proto);
   1904 
   1905   // Reads all enumerable own properties of source and adds them to
   1906   // target, using either Set or CreateDataProperty depending on the
   1907   // use_set argument. This only copies values not present in the
   1908   // maybe_excluded_properties list.
   1909   MUST_USE_RESULT static Maybe<bool> SetOrCopyDataProperties(
   1910       Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source,
   1911       const ScopedVector<Handle<Object>>* excluded_properties = nullptr,
   1912       bool use_set = true);
   1913 
   1914   // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
   1915   MUST_USE_RESULT static Maybe<bool> HasProperty(LookupIterator* it);
   1916   MUST_USE_RESULT static inline Maybe<bool> HasProperty(
   1917       Handle<JSReceiver> object, Handle<Name> name);
   1918   MUST_USE_RESULT static inline Maybe<bool> HasElement(
   1919       Handle<JSReceiver> object, uint32_t index);
   1920 
   1921   MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(
   1922       Handle<JSReceiver> object, Handle<Name> name);
   1923   MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(
   1924       Handle<JSReceiver> object, uint32_t index);
   1925 
   1926   MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
   1927       Isolate* isolate, Handle<JSReceiver> receiver, const char* key);
   1928   MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
   1929       Handle<JSReceiver> receiver, Handle<Name> name);
   1930   MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
   1931       Isolate* isolate, Handle<JSReceiver> receiver, uint32_t index);
   1932 
   1933   // Implementation of ES6 [[Delete]]
   1934   MUST_USE_RESULT static Maybe<bool> DeletePropertyOrElement(
   1935       Handle<JSReceiver> object, Handle<Name> name,
   1936       LanguageMode language_mode = SLOPPY);
   1937   MUST_USE_RESULT static Maybe<bool> DeleteProperty(
   1938       Handle<JSReceiver> object, Handle<Name> name,
   1939       LanguageMode language_mode = SLOPPY);
   1940   MUST_USE_RESULT static Maybe<bool> DeleteProperty(LookupIterator* it,
   1941                                                     LanguageMode language_mode);
   1942   MUST_USE_RESULT static Maybe<bool> DeleteElement(
   1943       Handle<JSReceiver> object, uint32_t index,
   1944       LanguageMode language_mode = SLOPPY);
   1945 
   1946   MUST_USE_RESULT static Object* DefineProperty(Isolate* isolate,
   1947                                                 Handle<Object> object,
   1948                                                 Handle<Object> name,
   1949                                                 Handle<Object> attributes);
   1950   MUST_USE_RESULT static MaybeHandle<Object> DefineProperties(
   1951       Isolate* isolate, Handle<Object> object, Handle<Object> properties);
   1952 
   1953   // "virtual" dispatcher to the correct [[DefineOwnProperty]] implementation.
   1954   MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
   1955       Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key,
   1956       PropertyDescriptor* desc, ShouldThrow should_throw);
   1957 
   1958   // ES6 7.3.4 (when passed DONT_THROW)
   1959   MUST_USE_RESULT static Maybe<bool> CreateDataProperty(
   1960       LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
   1961 
   1962   // ES6 9.1.6.1
   1963   MUST_USE_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
   1964       Isolate* isolate, Handle<JSObject> object, Handle<Object> key,
   1965       PropertyDescriptor* desc, ShouldThrow should_throw);
   1966   MUST_USE_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
   1967       LookupIterator* it, PropertyDescriptor* desc, ShouldThrow should_throw);
   1968   // ES6 9.1.6.2
   1969   MUST_USE_RESULT static Maybe<bool> IsCompatiblePropertyDescriptor(
   1970       Isolate* isolate, bool extensible, PropertyDescriptor* desc,
   1971       PropertyDescriptor* current, Handle<Name> property_name,
   1972       ShouldThrow should_throw);
   1973   // ES6 9.1.6.3
   1974   // |it| can be NULL in cases where the ES spec passes |undefined| as the
   1975   // receiver. Exactly one of |it| and |property_name| must be provided.
   1976   MUST_USE_RESULT static Maybe<bool> ValidateAndApplyPropertyDescriptor(
   1977       Isolate* isolate, LookupIterator* it, bool extensible,
   1978       PropertyDescriptor* desc, PropertyDescriptor* current,
   1979       ShouldThrow should_throw, Handle<Name> property_name = Handle<Name>());
   1980 
   1981   V8_EXPORT_PRIVATE MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
   1982       Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key,
   1983       PropertyDescriptor* desc);
   1984   MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
   1985       LookupIterator* it, PropertyDescriptor* desc);
   1986 
   1987   typedef PropertyAttributes IntegrityLevel;
   1988 
   1989   // ES6 7.3.14 (when passed DONT_THROW)
   1990   // 'level' must be SEALED or FROZEN.
   1991   MUST_USE_RESULT static Maybe<bool> SetIntegrityLevel(
   1992       Handle<JSReceiver> object, IntegrityLevel lvl, ShouldThrow should_throw);
   1993 
   1994   // ES6 7.3.15
   1995   // 'level' must be SEALED or FROZEN.
   1996   MUST_USE_RESULT static Maybe<bool> TestIntegrityLevel(
   1997       Handle<JSReceiver> object, IntegrityLevel lvl);
   1998 
   1999   // ES6 [[PreventExtensions]] (when passed DONT_THROW)
   2000   MUST_USE_RESULT static Maybe<bool> PreventExtensions(
   2001       Handle<JSReceiver> object, ShouldThrow should_throw);
   2002 
   2003   MUST_USE_RESULT static Maybe<bool> IsExtensible(Handle<JSReceiver> object);
   2004 
   2005   // Returns the class name ([[Class]] property in the specification).
   2006   String* class_name();
   2007 
   2008   // Returns the constructor name (the name (possibly, inferred name) of the
   2009   // function that was used to instantiate the object).
   2010   static Handle<String> GetConstructorName(Handle<JSReceiver> receiver);
   2011 
   2012   Handle<Context> GetCreationContext();
   2013 
   2014   MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetPropertyAttributes(
   2015       Handle<JSReceiver> object, Handle<Name> name);
   2016   MUST_USE_RESULT static inline Maybe<PropertyAttributes>
   2017   GetOwnPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name);
   2018   MUST_USE_RESULT static inline Maybe<PropertyAttributes>
   2019   GetOwnPropertyAttributes(Handle<JSReceiver> object, uint32_t index);
   2020 
   2021   MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetElementAttributes(
   2022       Handle<JSReceiver> object, uint32_t index);
   2023   MUST_USE_RESULT static inline Maybe<PropertyAttributes>
   2024   GetOwnElementAttributes(Handle<JSReceiver> object, uint32_t index);
   2025 
   2026   MUST_USE_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
   2027       LookupIterator* it);
   2028 
   2029   // Set the object's prototype (only JSReceiver and null are allowed values).
   2030   MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSReceiver> object,
   2031                                                   Handle<Object> value,
   2032                                                   bool from_javascript,
   2033                                                   ShouldThrow should_throw);
   2034 
   2035   inline static Handle<Object> GetDataProperty(Handle<JSReceiver> object,
   2036                                                Handle<Name> name);
   2037   static Handle<Object> GetDataProperty(LookupIterator* it);
   2038 
   2039 
   2040   // Retrieves a permanent object identity hash code. The undefined value might
   2041   // be returned in case no hash was created yet.
   2042   static inline Object* GetIdentityHash(Isolate* isolate,
   2043                                         Handle<JSReceiver> object);
   2044 
   2045   // Retrieves a permanent object identity hash code. May create and store a
   2046   // hash code if needed and none exists.
   2047   inline static Smi* GetOrCreateIdentityHash(Isolate* isolate,
   2048                                              Handle<JSReceiver> object);
   2049 
   2050   // ES6 [[OwnPropertyKeys]] (modulo return type)
   2051   MUST_USE_RESULT static inline MaybeHandle<FixedArray> OwnPropertyKeys(
   2052       Handle<JSReceiver> object);
   2053 
   2054   MUST_USE_RESULT static MaybeHandle<FixedArray> GetOwnValues(
   2055       Handle<JSReceiver> object, PropertyFilter filter);
   2056 
   2057   MUST_USE_RESULT static MaybeHandle<FixedArray> GetOwnEntries(
   2058       Handle<JSReceiver> object, PropertyFilter filter);
   2059 
   2060   // Layout description.
   2061   static const int kPropertiesOffset = HeapObject::kHeaderSize;
   2062   static const int kHeaderSize = HeapObject::kHeaderSize + kPointerSize;
   2063 
   2064   bool HasProxyInPrototype(Isolate* isolate);
   2065 
   2066  private:
   2067   DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
   2068 };
   2069 
   2070 
   2071 // The JSObject describes real heap allocated JavaScript objects with
   2072 // properties.
   2073 // Note that the map of JSObject changes during execution to enable inline
   2074 // caching.
   2075 class JSObject: public JSReceiver {
   2076  public:
   2077   static MUST_USE_RESULT MaybeHandle<JSObject> New(
   2078       Handle<JSFunction> constructor, Handle<JSReceiver> new_target,
   2079       Handle<AllocationSite> site = Handle<AllocationSite>::null());
   2080 
   2081   // Gets global object properties.
   2082   inline GlobalDictionary* global_dictionary();
   2083 
   2084   static MaybeHandle<Context> GetFunctionRealm(Handle<JSObject> object);
   2085 
   2086   // [elements]: The elements (properties with names that are integers).
   2087   //
   2088   // Elements can be in two general modes: fast and slow. Each mode
   2089   // corresponds to a set of object representations of elements that
   2090   // have something in common.
   2091   //
   2092   // In the fast mode elements is a FixedArray and so each element can
   2093   // be quickly accessed. This fact is used in the generated code. The
   2094   // elements array can have one of three maps in this mode:
   2095   // fixed_array_map, sloppy_arguments_elements_map or
   2096   // fixed_cow_array_map (for copy-on-write arrays). In the latter case
   2097   // the elements array may be shared by a few objects and so before
   2098   // writing to any element the array must be copied. Use
   2099   // EnsureWritableFastElements in this case.
   2100   //
   2101   // In the slow mode the elements is either a NumberDictionary, a
   2102   // FixedArray parameter map for a (sloppy) arguments object.
   2103   DECL_ACCESSORS(elements, FixedArrayBase)
   2104   inline void initialize_elements();
   2105   static void ResetElements(Handle<JSObject> object);
   2106   static inline void SetMapAndElements(Handle<JSObject> object,
   2107                                        Handle<Map> map,
   2108                                        Handle<FixedArrayBase> elements);
   2109   inline ElementsKind GetElementsKind();
   2110   ElementsAccessor* GetElementsAccessor();
   2111   // Returns true if an object has elements of FAST_SMI_ELEMENTS ElementsKind.
   2112   inline bool HasFastSmiElements();
   2113   // Returns true if an object has elements of FAST_ELEMENTS ElementsKind.
   2114   inline bool HasFastObjectElements();
   2115   // Returns true if an object has elements of FAST_ELEMENTS or
   2116   // FAST_SMI_ONLY_ELEMENTS.
   2117   inline bool HasFastSmiOrObjectElements();
   2118   // Returns true if an object has any of the fast elements kinds.
   2119   inline bool HasFastElements();
   2120   // Returns true if an object has elements of FAST_DOUBLE_ELEMENTS
   2121   // ElementsKind.
   2122   inline bool HasFastDoubleElements();
   2123   // Returns true if an object has elements of FAST_HOLEY_*_ELEMENTS
   2124   // ElementsKind.
   2125   inline bool HasFastHoleyElements();
   2126   inline bool HasSloppyArgumentsElements();
   2127   inline bool HasStringWrapperElements();
   2128   inline bool HasDictionaryElements();
   2129 
   2130   inline bool HasFixedTypedArrayElements();
   2131 
   2132   inline bool HasFixedUint8ClampedElements();
   2133   inline bool HasFixedArrayElements();
   2134   inline bool HasFixedInt8Elements();
   2135   inline bool HasFixedUint8Elements();
   2136   inline bool HasFixedInt16Elements();
   2137   inline bool HasFixedUint16Elements();
   2138   inline bool HasFixedInt32Elements();
   2139   inline bool HasFixedUint32Elements();
   2140   inline bool HasFixedFloat32Elements();
   2141   inline bool HasFixedFloat64Elements();
   2142 
   2143   inline bool HasFastArgumentsElements();
   2144   inline bool HasSlowArgumentsElements();
   2145   inline bool HasFastStringWrapperElements();
   2146   inline bool HasSlowStringWrapperElements();
   2147   bool HasEnumerableElements();
   2148 
   2149   inline SeededNumberDictionary* element_dictionary();  // Gets slow elements.
   2150 
   2151   // Requires: HasFastElements().
   2152   static void EnsureWritableFastElements(Handle<JSObject> object);
   2153 
   2154   // Collects elements starting at index 0.
   2155   // Undefined values are placed after non-undefined values.
   2156   // Returns the number of non-undefined values.
   2157   static Handle<Object> PrepareElementsForSort(Handle<JSObject> object,
   2158                                                uint32_t limit);
   2159   // As PrepareElementsForSort, but only on objects where elements is
   2160   // a dictionary, and it will stay a dictionary.  Collates undefined and
   2161   // unexisting elements below limit from position zero of the elements.
   2162   static Handle<Object> PrepareSlowElementsForSort(Handle<JSObject> object,
   2163                                                    uint32_t limit);
   2164 
   2165   MUST_USE_RESULT static Maybe<bool> SetPropertyWithInterceptor(
   2166       LookupIterator* it, ShouldThrow should_throw, Handle<Object> value);
   2167 
   2168   // The API currently still wants DefineOwnPropertyIgnoreAttributes to convert
   2169   // AccessorInfo objects to data fields. We allow FORCE_FIELD as an exception
   2170   // to the default behavior that calls the setter.
   2171   enum AccessorInfoHandling { FORCE_FIELD, DONT_FORCE_FIELD };
   2172 
   2173   MUST_USE_RESULT static MaybeHandle<Object> DefineOwnPropertyIgnoreAttributes(
   2174       LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
   2175       AccessorInfoHandling handling = DONT_FORCE_FIELD);
   2176 
   2177   MUST_USE_RESULT static Maybe<bool> DefineOwnPropertyIgnoreAttributes(
   2178       LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
   2179       ShouldThrow should_throw,
   2180       AccessorInfoHandling handling = DONT_FORCE_FIELD);
   2181 
   2182   MUST_USE_RESULT static MaybeHandle<Object> SetOwnPropertyIgnoreAttributes(
   2183       Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
   2184       PropertyAttributes attributes);
   2185 
   2186   MUST_USE_RESULT static MaybeHandle<Object> SetOwnElementIgnoreAttributes(
   2187       Handle<JSObject> object, uint32_t index, Handle<Object> value,
   2188       PropertyAttributes attributes);
   2189 
   2190   // Equivalent to one of the above depending on whether |name| can be converted
   2191   // to an array index.
   2192   MUST_USE_RESULT static MaybeHandle<Object>
   2193   DefinePropertyOrElementIgnoreAttributes(Handle<JSObject> object,
   2194                                           Handle<Name> name,
   2195                                           Handle<Object> value,
   2196                                           PropertyAttributes attributes = NONE);
   2197 
   2198   // Adds or reconfigures a property to attributes NONE. It will fail when it
   2199   // cannot.
   2200   MUST_USE_RESULT static Maybe<bool> CreateDataProperty(
   2201       LookupIterator* it, Handle<Object> value,
   2202       ShouldThrow should_throw = DONT_THROW);
   2203 
   2204   static void AddProperty(Handle<JSObject> object, Handle<Name> name,
   2205                           Handle<Object> value, PropertyAttributes attributes);
   2206 
   2207   MUST_USE_RESULT static Maybe<bool> AddDataElement(
   2208       Handle<JSObject> receiver, uint32_t index, Handle<Object> value,
   2209       PropertyAttributes attributes, ShouldThrow should_throw);
   2210   MUST_USE_RESULT static MaybeHandle<Object> AddDataElement(
   2211       Handle<JSObject> receiver, uint32_t index, Handle<Object> value,
   2212       PropertyAttributes attributes);
   2213 
   2214   // Extend the receiver with a single fast property appeared first in the
   2215   // passed map. This also extends the property backing store if necessary.
   2216   static void AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map);
   2217 
   2218   // Migrates the given object to a map whose field representations are the
   2219   // lowest upper bound of all known representations for that field.
   2220   static void MigrateInstance(Handle<JSObject> instance);
   2221 
   2222   // Migrates the given object only if the target map is already available,
   2223   // or returns false if such a map is not yet available.
   2224   static bool TryMigrateInstance(Handle<JSObject> instance);
   2225 
   2226   // Sets the property value in a normalized object given (key, value, details).
   2227   // Handles the special representation of JS global objects.
   2228   static void SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
   2229                                     Handle<Object> value,
   2230                                     PropertyDetails details);
   2231   static void SetDictionaryElement(Handle<JSObject> object, uint32_t index,
   2232                                    Handle<Object> value,
   2233                                    PropertyAttributes attributes);
   2234   static void SetDictionaryArgumentsElement(Handle<JSObject> object,
   2235                                             uint32_t index,
   2236                                             Handle<Object> value,
   2237                                             PropertyAttributes attributes);
   2238 
   2239   static void OptimizeAsPrototype(Handle<JSObject> object,
   2240                                   PrototypeOptimizationMode mode);
   2241   static void ReoptimizeIfPrototype(Handle<JSObject> object);
   2242   static void MakePrototypesFast(Handle<Object> receiver,
   2243                                  WhereToStart where_to_start, Isolate* isolate);
   2244   static void LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate);
   2245   static void UpdatePrototypeUserRegistration(Handle<Map> old_map,
   2246                                               Handle<Map> new_map,
   2247                                               Isolate* isolate);
   2248   static bool UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate);
   2249   static void InvalidatePrototypeChains(Map* map);
   2250 
   2251   // Updates prototype chain tracking information when an object changes its
   2252   // map from |old_map| to |new_map|.
   2253   static void NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
   2254                               Isolate* isolate);
   2255 
   2256   // Utility used by many Array builtins and runtime functions
   2257   static inline bool PrototypeHasNoElements(Isolate* isolate, JSObject* object);
   2258 
   2259   // Alternative implementation of WeakFixedArray::NullCallback.
   2260   class PrototypeRegistryCompactionCallback {
   2261    public:
   2262     static void Callback(Object* value, int old_index, int new_index);
   2263   };
   2264 
   2265   // Retrieve interceptors.
   2266   inline InterceptorInfo* GetNamedInterceptor();
   2267   inline InterceptorInfo* GetIndexedInterceptor();
   2268 
   2269   // Used from JSReceiver.
   2270   MUST_USE_RESULT static Maybe<PropertyAttributes>
   2271   GetPropertyAttributesWithInterceptor(LookupIterator* it);
   2272   MUST_USE_RESULT static Maybe<PropertyAttributes>
   2273       GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
   2274 
   2275   // Defines an AccessorPair property on the given object.
   2276   // TODO(mstarzinger): Rename to SetAccessor().
   2277   static MaybeHandle<Object> DefineAccessor(Handle<JSObject> object,
   2278                                             Handle<Name> name,
   2279                                             Handle<Object> getter,
   2280                                             Handle<Object> setter,
   2281                                             PropertyAttributes attributes);
   2282   static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
   2283                                             Handle<Object> getter,
   2284                                             Handle<Object> setter,
   2285                                             PropertyAttributes attributes);
   2286 
   2287   // Defines an AccessorInfo property on the given object.
   2288   MUST_USE_RESULT static MaybeHandle<Object> SetAccessor(
   2289       Handle<JSObject> object,
   2290       Handle<AccessorInfo> info);
   2291 
   2292   // The result must be checked first for exceptions. If there's no exception,
   2293   // the output parameter |done| indicates whether the interceptor has a result
   2294   // or not.
   2295   MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
   2296       LookupIterator* it, bool* done);
   2297 
   2298   static void ValidateElements(Handle<JSObject> object);
   2299 
   2300   // Makes sure that this object can contain HeapObject as elements.
   2301   static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
   2302 
   2303   // Makes sure that this object can contain the specified elements.
   2304   static inline void EnsureCanContainElements(
   2305       Handle<JSObject> object,
   2306       Object** elements,
   2307       uint32_t count,
   2308       EnsureElementsMode mode);
   2309   static inline void EnsureCanContainElements(
   2310       Handle<JSObject> object,
   2311       Handle<FixedArrayBase> elements,
   2312       uint32_t length,
   2313       EnsureElementsMode mode);
   2314   static void EnsureCanContainElements(
   2315       Handle<JSObject> object,
   2316       Arguments* arguments,
   2317       uint32_t first_arg,
   2318       uint32_t arg_count,
   2319       EnsureElementsMode mode);
   2320 
   2321   // Would we convert a fast elements array to dictionary mode given
   2322   // an access at key?
   2323   bool WouldConvertToSlowElements(uint32_t index);
   2324 
   2325   // Computes the new capacity when expanding the elements of a JSObject.
   2326   static uint32_t NewElementsCapacity(uint32_t old_capacity) {
   2327     // (old_capacity + 50%) + 16
   2328     return old_capacity + (old_capacity >> 1) + 16;
   2329   }
   2330 
   2331   // These methods do not perform access checks!
   2332   template <AllocationSiteUpdateMode update_or_check =
   2333                 AllocationSiteUpdateMode::kUpdate>
   2334   static bool UpdateAllocationSite(Handle<JSObject> object,
   2335                                    ElementsKind to_kind);
   2336 
   2337   // Lookup interceptors are used for handling properties controlled by host
   2338   // objects.
   2339   inline bool HasNamedInterceptor();
   2340   inline bool HasIndexedInterceptor();
   2341 
   2342   // Support functions for v8 api (needed for correct interceptor behavior).
   2343   MUST_USE_RESULT static Maybe<bool> HasRealNamedProperty(
   2344       Handle<JSObject> object, Handle<Name> name);
   2345   MUST_USE_RESULT static Maybe<bool> HasRealElementProperty(
   2346       Handle<JSObject> object, uint32_t index);
   2347   MUST_USE_RESULT static Maybe<bool> HasRealNamedCallbackProperty(
   2348       Handle<JSObject> object, Handle<Name> name);
   2349 
   2350   // Get the header size for a JSObject.  Used to compute the index of
   2351   // internal fields as well as the number of internal fields.
   2352   static inline int GetHeaderSize(InstanceType instance_type);
   2353   inline int GetHeaderSize();
   2354 
   2355   static inline int GetInternalFieldCount(Map* map);
   2356   inline int GetInternalFieldCount();
   2357   inline int GetInternalFieldOffset(int index);
   2358   inline Object* GetInternalField(int index);
   2359   inline void SetInternalField(int index, Object* value);
   2360   inline void SetInternalField(int index, Smi* value);
   2361   bool WasConstructedFromApiFunction();
   2362 
   2363   // Returns a new map with all transitions dropped from the object's current
   2364   // map and the ElementsKind set.
   2365   static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
   2366                                               ElementsKind to_kind);
   2367   static void TransitionElementsKind(Handle<JSObject> object,
   2368                                      ElementsKind to_kind);
   2369 
   2370   // Always use this to migrate an object to a new map.
   2371   // |expected_additional_properties| is only used for fast-to-slow transitions
   2372   // and ignored otherwise.
   2373   static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
   2374                            int expected_additional_properties = 0);
   2375 
   2376   // Forces a prototype without any of the checks that the regular SetPrototype
   2377   // would do.
   2378   static void ForceSetPrototype(Handle<JSObject> object, Handle<Object> proto);
   2379 
   2380   // Convert the object to use the canonical dictionary
   2381   // representation. If the object is expected to have additional properties
   2382   // added this number can be indicated to have the backing store allocated to
   2383   // an initial capacity for holding these properties.
   2384   static void NormalizeProperties(Handle<JSObject> object,
   2385                                   PropertyNormalizationMode mode,
   2386                                   int expected_additional_properties,
   2387                                   const char* reason);
   2388 
   2389   // Convert and update the elements backing store to be a
   2390   // SeededNumberDictionary dictionary.  Returns the backing after conversion.
   2391   static Handle<SeededNumberDictionary> NormalizeElements(
   2392       Handle<JSObject> object);
   2393 
   2394   void RequireSlowElements(SeededNumberDictionary* dictionary);
   2395 
   2396   // Transform slow named properties to fast variants.
   2397   static void MigrateSlowToFast(Handle<JSObject> object,
   2398                                 int unused_property_fields, const char* reason);
   2399 
   2400   inline bool IsUnboxedDoubleField(FieldIndex index);
   2401 
   2402   // Access fast-case object properties at index.
   2403   static Handle<Object> FastPropertyAt(Handle<JSObject> object,
   2404                                        Representation representation,
   2405                                        FieldIndex index);
   2406   inline Object* RawFastPropertyAt(FieldIndex index);
   2407   inline double RawFastDoublePropertyAt(FieldIndex index);
   2408   inline uint64_t RawFastDoublePropertyAsBitsAt(FieldIndex index);
   2409 
   2410   inline void FastPropertyAtPut(FieldIndex index, Object* value);
   2411   inline void RawFastPropertyAtPut(FieldIndex index, Object* value);
   2412   inline void RawFastDoublePropertyAsBitsAtPut(FieldIndex index, uint64_t bits);
   2413   inline void WriteToField(int descriptor, PropertyDetails details,
   2414                            Object* value);
   2415 
   2416   // Access to in object properties.
   2417   inline int GetInObjectPropertyOffset(int index);
   2418   inline Object* InObjectPropertyAt(int index);
   2419   inline Object* InObjectPropertyAtPut(int index,
   2420                                        Object* value,
   2421                                        WriteBarrierMode mode
   2422                                        = UPDATE_WRITE_BARRIER);
   2423 
   2424   // Set the object's prototype (only JSReceiver and null are allowed values).
   2425   MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSObject> object,
   2426                                                   Handle<Object> value,
   2427                                                   bool from_javascript,
   2428                                                   ShouldThrow should_throw);
   2429 
   2430   // Makes the object prototype immutable
   2431   // Never called from JavaScript
   2432   static void SetImmutableProto(Handle<JSObject> object);
   2433 
   2434   // Initializes the body starting at |start_offset|. It is responsibility of
   2435   // the caller to initialize object header. Fill the pre-allocated fields with
   2436   // pre_allocated_value and the rest with filler_value.
   2437   // Note: this call does not update write barrier, the caller is responsible
   2438   // to ensure that |filler_value| can be collected without WB here.
   2439   inline void InitializeBody(Map* map, int start_offset,
   2440                              Object* pre_allocated_value, Object* filler_value);
   2441 
   2442   // Check whether this object references another object
   2443   bool ReferencesObject(Object* obj);
   2444 
   2445   MUST_USE_RESULT static Maybe<bool> PreventExtensions(
   2446       Handle<JSObject> object, ShouldThrow should_throw);
   2447 
   2448   static bool IsExtensible(Handle<JSObject> object);
   2449 
   2450   // Copy object.
   2451   enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 };
   2452 
   2453   MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopy(
   2454       Handle<JSObject> object,
   2455       AllocationSiteUsageContext* site_context,
   2456       DeepCopyHints hints = kNoHints);
   2457   MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
   2458       Handle<JSObject> object,
   2459       AllocationSiteCreationContext* site_context);
   2460 
   2461   DECLARE_CAST(JSObject)
   2462 
   2463   // Dispatched behavior.
   2464   void JSObjectShortPrint(StringStream* accumulator);
   2465   DECLARE_PRINTER(JSObject)
   2466   DECLARE_VERIFIER(JSObject)
   2467 #ifdef OBJECT_PRINT
   2468   bool PrintProperties(std::ostream& os);  // NOLINT
   2469   bool PrintElements(std::ostream& os);    // NOLINT
   2470 #endif
   2471 #if defined(DEBUG) || defined(OBJECT_PRINT)
   2472   void PrintTransitions(std::ostream& os);  // NOLINT
   2473 #endif
   2474 
   2475   static void PrintElementsTransition(
   2476       FILE* file, Handle<JSObject> object,
   2477       ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
   2478       ElementsKind to_kind, Handle<FixedArrayBase> to_elements);
   2479 
   2480   void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map);
   2481 
   2482 #ifdef DEBUG
   2483   // Structure for collecting spill information about JSObjects.
   2484   class SpillInformation {
   2485    public:
   2486     void Clear();
   2487     void Print();
   2488     int number_of_objects_;
   2489     int number_of_objects_with_fast_properties_;
   2490     int number_of_objects_with_fast_elements_;
   2491     int number_of_fast_used_fields_;
   2492     int number_of_fast_unused_fields_;
   2493     int number_of_slow_used_properties_;
   2494     int number_of_slow_unused_properties_;
   2495     int number_of_fast_used_elements_;
   2496     int number_of_fast_unused_elements_;
   2497     int number_of_slow_used_elements_;
   2498     int number_of_slow_unused_elements_;
   2499   };
   2500 
   2501   void IncrementSpillStatistics(SpillInformation* info);
   2502 #endif
   2503 
   2504 #ifdef VERIFY_HEAP
   2505   // If a GC was caused while constructing this object, the elements pointer
   2506   // may point to a one pointer filler map. The object won't be rooted, but
   2507   // our heap verification code could stumble across it.
   2508   bool ElementsAreSafeToExamine();
   2509 #endif
   2510 
   2511   Object* SlowReverseLookup(Object* value);
   2512 
   2513   // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
   2514   // Also maximal value of JSArray's length property.
   2515   static const uint32_t kMaxElementCount = 0xffffffffu;
   2516 
   2517   // Constants for heuristics controlling conversion of fast elements
   2518   // to slow elements.
   2519 
   2520   // Maximal gap that can be introduced by adding an element beyond
   2521   // the current elements length.
   2522   static const uint32_t kMaxGap = 1024;
   2523 
   2524   // Maximal length of fast elements array that won't be checked for
   2525   // being dense enough on expansion.
   2526   static const int kMaxUncheckedFastElementsLength = 5000;
   2527 
   2528   // Same as above but for old arrays. This limit is more strict. We
   2529   // don't want to be wasteful with long lived objects.
   2530   static const int kMaxUncheckedOldFastElementsLength = 500;
   2531 
   2532   // This constant applies only to the initial map of "global.Object" and
   2533   // not to arbitrary other JSObject maps.
   2534   static const int kInitialGlobalObjectUnusedPropertiesCount = 4;
   2535 
   2536   static const int kMaxInstanceSize = 255 * kPointerSize;
   2537   // When extending the backing storage for property values, we increase
   2538   // its size by more than the 1 entry necessary, so sequentially adding fields
   2539   // to the same object requires fewer allocations and copies.
   2540   static const int kFieldsAdded = 3;
   2541 
   2542   // Layout description.
   2543   static const int kElementsOffset = JSReceiver::kHeaderSize;
   2544   static const int kHeaderSize = kElementsOffset + kPointerSize;
   2545 
   2546   STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
   2547 
   2548   typedef FlexibleBodyDescriptor<JSReceiver::kPropertiesOffset> BodyDescriptor;
   2549 
   2550   // Gets the number of currently used elements.
   2551   int GetFastElementsUsage();
   2552 
   2553   static bool AllCanRead(LookupIterator* it);
   2554   static bool AllCanWrite(LookupIterator* it);
   2555 
   2556  private:
   2557   friend class JSReceiver;
   2558   friend class Object;
   2559 
   2560   // Used from Object::GetProperty().
   2561   MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
   2562       LookupIterator* it);
   2563 
   2564   MUST_USE_RESULT static Maybe<bool> SetPropertyWithFailedAccessCheck(
   2565       LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
   2566 
   2567   MUST_USE_RESULT static Maybe<bool> DeletePropertyWithInterceptor(
   2568       LookupIterator* it, ShouldThrow should_throw);
   2569 
   2570   bool ReferencesObjectFromElements(FixedArray* elements,
   2571                                     ElementsKind kind,
   2572                                     Object* object);
   2573 
   2574   static Object* GetIdentityHash(Isolate* isolate, Handle<JSObject> object);
   2575 
   2576   static Smi* GetOrCreateIdentityHash(Isolate* isolate,
   2577                                       Handle<JSObject> object);
   2578 
   2579   // Helper for fast versions of preventExtensions, seal, and freeze.
   2580   // attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
   2581   template <PropertyAttributes attrs>
   2582   MUST_USE_RESULT static Maybe<bool> PreventExtensionsWithTransition(
   2583       Handle<JSObject> object, ShouldThrow should_throw);
   2584 
   2585   DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
   2586 };
   2587 
   2588 
   2589 // JSAccessorPropertyDescriptor is just a JSObject with a specific initial
   2590 // map. This initial map adds in-object properties for "get", "set",
   2591 // "enumerable" and "configurable" properties, as assigned by the
   2592 // FromPropertyDescriptor function for regular accessor properties.
   2593 class JSAccessorPropertyDescriptor: public JSObject {
   2594  public:
   2595   // Offsets of object fields.
   2596   static const int kGetOffset = JSObject::kHeaderSize;
   2597   static const int kSetOffset = kGetOffset + kPointerSize;
   2598   static const int kEnumerableOffset = kSetOffset + kPointerSize;
   2599   static const int kConfigurableOffset = kEnumerableOffset + kPointerSize;
   2600   static const int kSize = kConfigurableOffset + kPointerSize;
   2601   // Indices of in-object properties.
   2602   static const int kGetIndex = 0;
   2603   static const int kSetIndex = 1;
   2604   static const int kEnumerableIndex = 2;
   2605   static const int kConfigurableIndex = 3;
   2606 
   2607  private:
   2608   DISALLOW_IMPLICIT_CONSTRUCTORS(JSAccessorPropertyDescriptor);
   2609 };
   2610 
   2611 
   2612 // JSDataPropertyDescriptor is just a JSObject with a specific initial map.
   2613 // This initial map adds in-object properties for "value", "writable",
   2614 // "enumerable" and "configurable" properties, as assigned by the
   2615 // FromPropertyDescriptor function for regular data properties.
   2616 class JSDataPropertyDescriptor: public JSObject {
   2617  public:
   2618   // Offsets of object fields.
   2619   static const int kValueOffset = JSObject::kHeaderSize;
   2620   static const int kWritableOffset = kValueOffset + kPointerSize;
   2621   static const int kEnumerableOffset = kWritableOffset + kPointerSize;
   2622   static const int kConfigurableOffset = kEnumerableOffset + kPointerSize;
   2623   static const int kSize = kConfigurableOffset + kPointerSize;
   2624   // Indices of in-object properties.
   2625   static const int kValueIndex = 0;
   2626   static const int kWritableIndex = 1;
   2627   static const int kEnumerableIndex = 2;
   2628   static const int kConfigurableIndex = 3;
   2629 
   2630  private:
   2631   DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataPropertyDescriptor);
   2632 };
   2633 
   2634 
   2635 // JSIteratorResult is just a JSObject with a specific initial map.
   2636 // This initial map adds in-object properties for "done" and "value",
   2637 // as specified by ES6 section 25.1.1.3 The IteratorResult Interface
   2638 class JSIteratorResult: public JSObject {
   2639  public:
   2640   DECL_ACCESSORS(value, Object)
   2641 
   2642   DECL_ACCESSORS(done, Object)
   2643 
   2644   // Offsets of object fields.
   2645   static const int kValueOffset = JSObject::kHeaderSize;
   2646   static const int kDoneOffset = kValueOffset + kPointerSize;
   2647   static const int kSize = kDoneOffset + kPointerSize;
   2648   // Indices of in-object properties.
   2649   static const int kValueIndex = 0;
   2650   static const int kDoneIndex = 1;
   2651 
   2652  private:
   2653   DISALLOW_IMPLICIT_CONSTRUCTORS(JSIteratorResult);
   2654 };
   2655 
   2656 
   2657 // Common superclass for JSSloppyArgumentsObject and JSStrictArgumentsObject.
   2658 class JSArgumentsObject: public JSObject {
   2659  public:
   2660   // Offsets of object fields.
   2661   static const int kLengthOffset = JSObject::kHeaderSize;
   2662   static const int kHeaderSize = kLengthOffset + kPointerSize;
   2663   // Indices of in-object properties.
   2664   static const int kLengthIndex = 0;
   2665 
   2666  private:
   2667   DISALLOW_IMPLICIT_CONSTRUCTORS(JSArgumentsObject);
   2668 };
   2669 
   2670 
   2671 // JSSloppyArgumentsObject is just a JSObject with specific initial map.
   2672 // This initial map adds in-object properties for "length" and "callee".
   2673 class JSSloppyArgumentsObject: public JSArgumentsObject {
   2674  public:
   2675   // Offsets of object fields.
   2676   static const int kCalleeOffset = JSArgumentsObject::kHeaderSize;
   2677   static const int kSize = kCalleeOffset + kPointerSize;
   2678   // Indices of in-object properties.
   2679   static const int kCalleeIndex = 1;
   2680 
   2681  private:
   2682   DISALLOW_IMPLICIT_CONSTRUCTORS(JSSloppyArgumentsObject);
   2683 };
   2684 
   2685 
   2686 // JSStrictArgumentsObject is just a JSObject with specific initial map.
   2687 // This initial map adds an in-object property for "length".
   2688 class JSStrictArgumentsObject: public JSArgumentsObject {
   2689  public:
   2690   // Offsets of object fields.
   2691   static const int kSize = JSArgumentsObject::kHeaderSize;
   2692 
   2693  private:
   2694   DISALLOW_IMPLICIT_CONSTRUCTORS(JSStrictArgumentsObject);
   2695 };
   2696 
   2697 
   2698 // Common superclass for FixedArrays that allow implementations to share
   2699 // common accessors and some code paths.
   2700 class FixedArrayBase: public HeapObject {
   2701  public:
   2702   // [length]: length of the array.
   2703   inline int length() const;
   2704   inline void set_length(int value);
   2705 
   2706   // Get and set the length using acquire loads and release stores.
   2707   inline int synchronized_length() const;
   2708   inline void synchronized_set_length(int value);
   2709 
   2710   DECLARE_CAST(FixedArrayBase)
   2711 
   2712   static int GetMaxLengthForNewSpaceAllocation(ElementsKind kind);
   2713 
   2714   // Layout description.
   2715   // Length is smi tagged when it is stored.
   2716   static const int kLengthOffset = HeapObject::kHeaderSize;
   2717   static const int kHeaderSize = kLengthOffset + kPointerSize;
   2718 };
   2719 
   2720 
   2721 class FixedDoubleArray;
   2722 class IncrementalMarking;
   2723 
   2724 
   2725 // FixedArray describes fixed-sized arrays with element type Object*.
   2726 class FixedArray: public FixedArrayBase {
   2727  public:
   2728   // Setter and getter for elements.
   2729   inline Object* get(int index) const;
   2730   static inline Handle<Object> get(FixedArray* array, int index,
   2731                                    Isolate* isolate);
   2732   template <class T>
   2733   MaybeHandle<T> GetValue(Isolate* isolate, int index) const;
   2734 
   2735   template <class T>
   2736   Handle<T> GetValueChecked(Isolate* isolate, int index) const;
   2737 
   2738   // Return a grown copy if the index is bigger than the array's length.
   2739   static Handle<FixedArray> SetAndGrow(Handle<FixedArray> array, int index,
   2740                                        Handle<Object> value);
   2741 
   2742   // Setter that uses write barrier.
   2743   inline void set(int index, Object* value);
   2744   inline bool is_the_hole(Isolate* isolate, int index);
   2745 
   2746   // Setter that doesn't need write barrier.
   2747   inline void set(int index, Smi* value);
   2748   // Setter with explicit barrier mode.
   2749   inline void set(int index, Object* value, WriteBarrierMode mode);
   2750 
   2751   // Setters for frequently used oddballs located in old space.
   2752   inline void set_undefined(int index);
   2753   inline void set_undefined(Isolate* isolate, int index);
   2754   inline void set_null(int index);
   2755   inline void set_null(Isolate* isolate, int index);
   2756   inline void set_the_hole(int index);
   2757   inline void set_the_hole(Isolate* isolate, int index);
   2758 
   2759   inline Object** GetFirstElementAddress();
   2760   inline bool ContainsOnlySmisOrHoles();
   2761 
   2762   // Gives access to raw memory which stores the array's data.
   2763   inline Object** data_start();
   2764 
   2765   inline void FillWithHoles(int from, int to);
   2766 
   2767   // Shrink length and insert filler objects.
   2768   void Shrink(int length);
   2769 
   2770   // Copy a sub array from the receiver to dest.
   2771   void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
   2772 
   2773   // Garbage collection support.
   2774   static constexpr int SizeFor(int length) {
   2775     return kHeaderSize + length * kPointerSize;
   2776   }
   2777 
   2778   // Code Generation support.
   2779   static constexpr int OffsetOfElementAt(int index) { return SizeFor(index); }
   2780 
   2781   // Garbage collection support.
   2782   inline Object** RawFieldOfElementAt(int index);
   2783 
   2784   DECLARE_CAST(FixedArray)
   2785 
   2786   // Maximal allowed size, in bytes, of a single FixedArray.
   2787   // Prevents overflowing size computations, as well as extreme memory
   2788   // consumption.
   2789   static const int kMaxSize = 128 * MB * kPointerSize;
   2790   // Maximally allowed length of a FixedArray.
   2791   static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
   2792 
   2793   // Dispatched behavior.
   2794   DECLARE_PRINTER(FixedArray)
   2795   DECLARE_VERIFIER(FixedArray)
   2796 #ifdef DEBUG
   2797   // Checks if two FixedArrays have identical contents.
   2798   bool IsEqualTo(FixedArray* other);
   2799 #endif
   2800 
   2801   typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
   2802 
   2803  protected:
   2804   // Set operation on FixedArray without using write barriers. Can
   2805   // only be used for storing old space objects or smis.
   2806   static inline void NoWriteBarrierSet(FixedArray* array,
   2807                                        int index,
   2808                                        Object* value);
   2809 
   2810  private:
   2811   STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
   2812 
   2813   DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
   2814 };
   2815 
   2816 // FixedDoubleArray describes fixed-sized arrays with element type double.
   2817 class FixedDoubleArray: public FixedArrayBase {
   2818  public:
   2819   // Setter and getter for elements.
   2820   inline double get_scalar(int index);
   2821   inline uint64_t get_representation(int index);
   2822   static inline Handle<Object> get(FixedDoubleArray* array, int index,
   2823                                    Isolate* isolate);
   2824   inline void set(int index, double value);
   2825   inline void set_the_hole(Isolate* isolate, int index);
   2826   inline void set_the_hole(int index);
   2827 
   2828   // Checking for the hole.
   2829   inline bool is_the_hole(Isolate* isolate, int index);
   2830   inline bool is_the_hole(int index);
   2831 
   2832   // Garbage collection support.
   2833   inline static int SizeFor(int length) {
   2834     return kHeaderSize + length * kDoubleSize;
   2835   }
   2836 
   2837   // Gives access to raw memory which stores the array's data.
   2838   inline double* data_start();
   2839 
   2840   inline void FillWithHoles(int from, int to);
   2841 
   2842   // Code Generation support.
   2843   static int OffsetOfElementAt(int index) { return SizeFor(index); }
   2844 
   2845   DECLARE_CAST(FixedDoubleArray)
   2846 
   2847   // Maximal allowed size, in bytes, of a single FixedDoubleArray.
   2848   // Prevents overflowing size computations, as well as extreme memory
   2849   // consumption.
   2850   static const int kMaxSize = 512 * MB;
   2851   // Maximally allowed length of a FixedArray.
   2852   static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
   2853 
   2854   // Dispatched behavior.
   2855   DECLARE_PRINTER(FixedDoubleArray)
   2856   DECLARE_VERIFIER(FixedDoubleArray)
   2857 
   2858  private:
   2859   DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
   2860 };
   2861 
   2862 
   2863 class WeakFixedArray : public FixedArray {
   2864  public:
   2865   // If |maybe_array| is not a WeakFixedArray, a fresh one will be allocated.
   2866   // This function does not check if the value exists already, callers must
   2867   // ensure this themselves if necessary.
   2868   static Handle<WeakFixedArray> Add(Handle<Object> maybe_array,
   2869                                     Handle<HeapObject> value,
   2870                                     int* assigned_index = NULL);
   2871 
   2872   // Returns true if an entry was found and removed.
   2873   bool Remove(Handle<HeapObject> value);
   2874 
   2875   class NullCallback {
   2876    public:
   2877     static void Callback(Object* value, int old_index, int new_index) {}
   2878   };
   2879 
   2880   template <class CompactionCallback>
   2881   void Compact();
   2882 
   2883   inline Object* Get(int index) const;
   2884   inline void Clear(int index);
   2885   inline int Length() const;
   2886 
   2887   inline bool IsEmptySlot(int index) const;
   2888   static Object* Empty() { return Smi::kZero; }
   2889 
   2890   class Iterator {
   2891    public:
   2892     explicit Iterator(Object* maybe_array) : list_(NULL) { Reset(maybe_array); }
   2893     void Reset(Object* maybe_array);
   2894 
   2895     template <class T>
   2896     inline T* Next();
   2897 
   2898    private:
   2899     int index_;
   2900     WeakFixedArray* list_;
   2901 #ifdef DEBUG
   2902     int last_used_index_;
   2903     DisallowHeapAllocation no_gc_;
   2904 #endif  // DEBUG
   2905     DISALLOW_COPY_AND_ASSIGN(Iterator);
   2906   };
   2907 
   2908   DECLARE_CAST(WeakFixedArray)
   2909 
   2910  private:
   2911   static const int kLastUsedIndexIndex = 0;
   2912   static const int kFirstIndex = 1;
   2913 
   2914   static Handle<WeakFixedArray> Allocate(
   2915       Isolate* isolate, int size, Handle<WeakFixedArray> initialize_from);
   2916 
   2917   static void Set(Handle<WeakFixedArray> array, int index,
   2918                   Handle<HeapObject> value);
   2919   inline void clear(int index);
   2920 
   2921   inline int last_used_index() const;
   2922   inline void set_last_used_index(int index);
   2923 
   2924   // Disallow inherited setters.
   2925   void set(int index, Smi* value);
   2926   void set(int index, Object* value);
   2927   void set(int index, Object* value, WriteBarrierMode mode);
   2928   DISALLOW_IMPLICIT_CONSTRUCTORS(WeakFixedArray);
   2929 };
   2930 
   2931 // Generic array grows dynamically with O(1) amortized insertion.
   2932 class ArrayList : public FixedArray {
   2933  public:
   2934   enum AddMode {
   2935     kNone,
   2936     // Use this if GC can delete elements from the array.
   2937     kReloadLengthAfterAllocation,
   2938   };
   2939   static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj,
   2940                                AddMode mode = kNone);
   2941   static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj1,
   2942                                Handle<Object> obj2, AddMode = kNone);
   2943   static Handle<ArrayList> New(Isolate* isolate, int size);
   2944   inline int Length();
   2945   inline void SetLength(int length);
   2946   inline Object* Get(int index);
   2947   inline Object** Slot(int index);
   2948   inline void Set(int index, Object* obj,
   2949                   WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
   2950   inline void Clear(int index, Object* undefined);
   2951   bool IsFull();
   2952   DECLARE_CAST(ArrayList)
   2953 
   2954  private:
   2955   static Handle<ArrayList> EnsureSpace(Handle<ArrayList> array, int length);
   2956   static const int kLengthIndex = 0;
   2957   static const int kFirstIndex = 1;
   2958   DISALLOW_IMPLICIT_CONSTRUCTORS(ArrayList);
   2959 };
   2960 
   2961 #define FRAME_ARRAY_FIELD_LIST(V) \
   2962   V(WasmInstance, Object)         \
   2963   V(WasmFunctionIndex, Smi)       \
   2964   V(Receiver, Object)             \
   2965   V(Function, JSFunction)         \
   2966   V(Code, AbstractCode)           \
   2967   V(Offset, Smi)                  \
   2968   V(Flags, Smi)
   2969 
   2970 // Container object for data collected during simple stack trace captures.
   2971 class FrameArray : public FixedArray {
   2972  public:
   2973 #define DECLARE_FRAME_ARRAY_ACCESSORS(name, type) \
   2974   inline type* name(int frame_ix) const;          \
   2975   inline void Set##name(int frame_ix, type* value);
   2976   FRAME_ARRAY_FIELD_LIST(DECLARE_FRAME_ARRAY_ACCESSORS)
   2977 #undef DECLARE_FRAME_ARRAY_ACCESSORS
   2978 
   2979   inline bool IsWasmFrame(int frame_ix) const;
   2980   inline bool IsAsmJsWasmFrame(int frame_ix) const;
   2981   inline int FrameCount() const;
   2982 
   2983   void ShrinkToFit();
   2984 
   2985   // Flags.
   2986   static const int kIsWasmFrame = 1 << 0;
   2987   static const int kIsAsmJsWasmFrame = 1 << 1;
   2988   static const int kIsStrict = 1 << 2;
   2989   static const int kForceConstructor = 1 << 3;
   2990   static const int kAsmJsAtNumberConversion = 1 << 4;
   2991 
   2992   static Handle<FrameArray> AppendJSFrame(Handle<FrameArray> in,
   2993                                           Handle<Object> receiver,
   2994                                           Handle<JSFunction> function,
   2995                                           Handle<AbstractCode> code, int offset,
   2996                                           int flags);
   2997   static Handle<FrameArray> AppendWasmFrame(Handle<FrameArray> in,
   2998                                             Handle<Object> wasm_instance,
   2999                                             int wasm_function_index,
   3000                                             Handle<AbstractCode> code,
   3001                                             int offset, int flags);
   3002 
   3003   DECLARE_CAST(FrameArray)
   3004 
   3005  private:
   3006   // The underlying fixed array embodies a captured stack trace. Frame i
   3007   // occupies indices
   3008   //
   3009   // kFirstIndex + 1 + [i * kElementsPerFrame, (i + 1) * kElementsPerFrame[,
   3010   //
   3011   // with internal offsets as below:
   3012 
   3013   static const int kWasmInstanceOffset = 0;
   3014   static const int kWasmFunctionIndexOffset = 1;
   3015 
   3016   static const int kReceiverOffset = 0;
   3017   static const int kFunctionOffset = 1;
   3018 
   3019   static const int kCodeOffset = 2;
   3020   static const int kOffsetOffset = 3;
   3021 
   3022   static const int kFlagsOffset = 4;
   3023 
   3024   static const int kElementsPerFrame = 5;
   3025 
   3026   // Array layout indices.
   3027 
   3028   static const int kFrameCountIndex = 0;
   3029   static const int kFirstIndex = 1;
   3030 
   3031   static int LengthFor(int frame_count) {
   3032     return kFirstIndex + frame_count * kElementsPerFrame;
   3033   }
   3034 
   3035   static Handle<FrameArray> EnsureSpace(Handle<FrameArray> array, int length);
   3036 
   3037   friend class Factory;
   3038   DISALLOW_IMPLICIT_CONSTRUCTORS(FrameArray);
   3039 };
   3040 
   3041 // DescriptorArrays are fixed arrays used to hold instance descriptors.
   3042 // The format of the these objects is:
   3043 //   [0]: Number of descriptors
   3044 //   [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
   3045 //          [0]: pointer to fixed array with enum cache
   3046 //          [1]: either Smi(0) or pointer to fixed array with indices
   3047 //   [2]: first key
   3048 //   [2 + number of descriptors * kEntrySize]: start of slack
   3049 class DescriptorArray: public FixedArray {
   3050  public:
   3051   // Returns true for both shared empty_descriptor_array and for smis, which the
   3052   // map uses to encode additional bit fields when the descriptor array is not
   3053   // yet used.
   3054   inline bool IsEmpty();
   3055 
   3056   // Returns the number of descriptors in the array.
   3057   inline int number_of_descriptors();
   3058 
   3059   inline int number_of_descriptors_storage();
   3060 
   3061   inline int NumberOfSlackDescriptors();
   3062 
   3063   inline void SetNumberOfDescriptors(int number_of_descriptors);
   3064   inline int number_of_entries();
   3065 
   3066   inline bool HasEnumCache();
   3067 
   3068   inline void CopyEnumCacheFrom(DescriptorArray* array);
   3069 
   3070   inline FixedArray* GetEnumCache();
   3071 
   3072   inline bool HasEnumIndicesCache();
   3073 
   3074   inline FixedArray* GetEnumIndicesCache();
   3075 
   3076   inline Object** GetEnumCacheSlot();
   3077 
   3078   void ClearEnumCache();
   3079 
   3080   // Initialize or change the enum cache,
   3081   // using the supplied storage for the small "bridge".
   3082   static void SetEnumCache(Handle<DescriptorArray> descriptors,
   3083                            Isolate* isolate, Handle<FixedArray> new_cache,
   3084                            Handle<FixedArray> new_index_cache);
   3085 
   3086   // Accessors for fetching instance descriptor at descriptor number.
   3087   inline Name* GetKey(int descriptor_number);
   3088   inline Object** GetKeySlot(int descriptor_number);
   3089   inline Object* GetValue(int descriptor_number);
   3090   inline void SetValue(int descriptor_number, Object* value);
   3091   inline Object** GetValueSlot(int descriptor_number);
   3092   static inline int GetValueOffset(int descriptor_number);
   3093   inline Object** GetDescriptorStartSlot(int descriptor_number);
   3094   inline Object** GetDescriptorEndSlot(int descriptor_number);
   3095   inline PropertyDetails GetDetails(int descriptor_number);
   3096   inline int GetFieldIndex(int descriptor_number);
   3097   inline FieldType* GetFieldType(int descriptor_number);
   3098 
   3099   inline Name* GetSortedKey(int descriptor_number);
   3100   inline int GetSortedKeyIndex(int descriptor_number);
   3101   inline void SetSortedKey(int pointer, int descriptor_number);
   3102 
   3103   // Accessor for complete descriptor.
   3104   inline void Get(int descriptor_number, Descriptor* desc);
   3105   inline void Set(int descriptor_number, Descriptor* desc);
   3106   inline void Set(int descriptor_number, Name* key, Object* value,
   3107                   PropertyDetails details);
   3108   void Replace(int descriptor_number, Descriptor* descriptor);
   3109 
   3110   // Generalizes constness, representation and field type of all field
   3111   // descriptors.
   3112   void GeneralizeAllFields();
   3113 
   3114   // Append automatically sets the enumeration index. This should only be used
   3115   // to add descriptors in bulk at the end, followed by sorting the descriptor
   3116   // array.
   3117   inline void Append(Descriptor* desc);
   3118 
   3119   static Handle<DescriptorArray> CopyUpTo(Handle<DescriptorArray> desc,
   3120                                           int enumeration_index,
   3121                                           int slack = 0);
   3122 
   3123   static Handle<DescriptorArray> CopyUpToAddAttributes(
   3124       Handle<DescriptorArray> desc,
   3125       int enumeration_index,
   3126       PropertyAttributes attributes,
   3127       int slack = 0);
   3128 
   3129   // Sort the instance descriptors by the hash codes of their keys.
   3130   void Sort();
   3131 
   3132   // Search the instance descriptors for given name.
   3133   INLINE(int Search(Name* name, int number_of_own_descriptors));
   3134 
   3135   // As the above, but uses DescriptorLookupCache and updates it when
   3136   // necessary.
   3137   INLINE(int SearchWithCache(Isolate* isolate, Name* name, Map* map));
   3138 
   3139   bool IsEqualUpTo(DescriptorArray* desc, int nof_descriptors);
   3140 
   3141   // Allocates a DescriptorArray, but returns the singleton
   3142   // empty descriptor array object if number_of_descriptors is 0.
   3143   static Handle<DescriptorArray> Allocate(
   3144       Isolate* isolate, int number_of_descriptors, int slack,
   3145       PretenureFlag pretenure = NOT_TENURED);
   3146 
   3147   DECLARE_CAST(DescriptorArray)
   3148 
   3149   // Constant for denoting key was not found.
   3150   static const int kNotFound = -1;
   3151 
   3152   static const int kDescriptorLengthIndex = 0;
   3153   static const int kEnumCacheIndex = 1;
   3154   static const int kFirstIndex = 2;
   3155 
   3156   // The length of the "bridge" to the enum cache.
   3157   static const int kEnumCacheBridgeLength = 2;
   3158   static const int kEnumCacheBridgeCacheIndex = 0;
   3159   static const int kEnumCacheBridgeIndicesCacheIndex = 1;
   3160 
   3161   // Layout description.
   3162   static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
   3163   static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
   3164   static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
   3165 
   3166   // Layout description for the bridge array.
   3167   static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize;
   3168 
   3169   // Layout of descriptor.
   3170   // Naming is consistent with Dictionary classes for easy templating.
   3171   static const int kEntryKeyIndex = 0;
   3172   static const int kEntryDetailsIndex = 1;
   3173   static const int kEntryValueIndex = 2;
   3174   static const int kEntrySize = 3;
   3175 
   3176 #if defined(DEBUG) || defined(OBJECT_PRINT)
   3177   // For our gdb macros, we should perhaps change these in the future.
   3178   void Print();
   3179 
   3180   // Print all the descriptors.
   3181   void PrintDescriptors(std::ostream& os);  // NOLINT
   3182 
   3183   void PrintDescriptorDetails(std::ostream& os, int descriptor,
   3184                               PropertyDetails::PrintMode mode);
   3185 #endif
   3186 
   3187 #ifdef DEBUG
   3188   // Is the descriptor array sorted and without duplicates?
   3189   bool IsSortedNoDuplicates(int valid_descriptors = -1);
   3190 
   3191   // Is the descriptor array consistent with the back pointers in targets?
   3192   bool IsConsistentWithBackPointers(Map* current_map);
   3193 
   3194   // Are two DescriptorArrays equal?
   3195   bool IsEqualTo(DescriptorArray* other);
   3196 #endif
   3197 
   3198   // Returns the fixed array length required to hold number_of_descriptors
   3199   // descriptors.
   3200   static int LengthFor(int number_of_descriptors) {
   3201     return ToKeyIndex(number_of_descriptors);
   3202   }
   3203 
   3204   static int ToDetailsIndex(int descriptor_number) {
   3205     return kFirstIndex + (descriptor_number * kEntrySize) + kEntryDetailsIndex;
   3206   }
   3207 
   3208   // Conversion from descriptor number to array indices.
   3209   static int ToKeyIndex(int descriptor_number) {
   3210     return kFirstIndex + (descriptor_number * kEntrySize) + kEntryKeyIndex;
   3211   }
   3212 
   3213   static int ToValueIndex(int descriptor_number) {
   3214     return kFirstIndex + (descriptor_number * kEntrySize) + kEntryValueIndex;
   3215   }
   3216 
   3217  private:
   3218   // Transfer a complete descriptor from the src descriptor array to this
   3219   // descriptor array.
   3220   void CopyFrom(int index, DescriptorArray* src);
   3221 
   3222   // Swap first and second descriptor.
   3223   inline void SwapSortedKeys(int first, int second);
   3224 
   3225   DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
   3226 };
   3227 
   3228 
   3229 enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
   3230 
   3231 template <SearchMode search_mode, typename T>
   3232 inline int Search(T* array, Name* name, int valid_entries = 0,
   3233                   int* out_insertion_index = NULL);
   3234 
   3235 
   3236 // HashTable is a subclass of FixedArray that implements a hash table
   3237 // that uses open addressing and quadratic probing.
   3238 //
   3239 // In order for the quadratic probing to work, elements that have not
   3240 // yet been used and elements that have been deleted are
   3241 // distinguished.  Probing continues when deleted elements are
   3242 // encountered and stops when unused elements are encountered.
   3243 //
   3244 // - Elements with key == undefined have not been used yet.
   3245 // - Elements with key == the_hole have been deleted.
   3246 //
   3247 // The hash table class is parameterized with a Shape and a Key.
   3248 // Shape must be a class with the following interface:
   3249 //   class ExampleShape {
   3250 //    public:
   3251 //      // Tells whether key matches other.
   3252 //     static bool IsMatch(Key key, Object* other);
   3253 //     // Returns the hash value for key.
   3254 //     static uint32_t Hash(Key key);
   3255 //     // Returns the hash value for object.
   3256 //     static uint32_t HashForObject(Key key, Object* object);
   3257 //     // Convert key to an object.
   3258 //     static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
   3259 //     // The prefix size indicates number of elements in the beginning
   3260 //     // of the backing storage.
   3261 //     static const int kPrefixSize = ..;
   3262 //     // The Element size indicates number of elements per entry.
   3263 //     static const int kEntrySize = ..;
   3264 //   };
   3265 // The prefix size indicates an amount of memory in the
   3266 // beginning of the backing storage that can be used for non-element
   3267 // information by subclasses.
   3268 
   3269 template<typename Key>
   3270 class BaseShape {
   3271  public:
   3272   static const bool UsesSeed = false;
   3273   static uint32_t Hash(Key key) { return 0; }
   3274   static uint32_t SeededHash(Key key, uint32_t seed) {
   3275     DCHECK(UsesSeed);
   3276     return Hash(key);
   3277   }
   3278   static uint32_t HashForObject(Key key, Object* object) { return 0; }
   3279   static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) {
   3280     DCHECK(UsesSeed);
   3281     return HashForObject(key, object);
   3282   }
   3283   static inline Map* GetMap(Isolate* isolate);
   3284 };
   3285 
   3286 
   3287 class HashTableBase : public FixedArray {
   3288  public:
   3289   // Returns the number of elements in the hash table.
   3290   inline int NumberOfElements();
   3291 
   3292   // Returns the number of deleted elements in the hash table.
   3293   inline int NumberOfDeletedElements();
   3294 
   3295   // Returns the capacity of the hash table.
   3296   inline int Capacity();
   3297 
   3298   // ElementAdded should be called whenever an element is added to a
   3299   // hash table.
   3300   inline void ElementAdded();
   3301 
   3302   // ElementRemoved should be called whenever an element is removed from
   3303   // a hash table.
   3304   inline void ElementRemoved();
   3305   inline void ElementsRemoved(int n);
   3306 
   3307   // Computes the required capacity for a table holding the given
   3308   // number of elements. May be more than HashTable::kMaxCapacity.
   3309   static inline int ComputeCapacity(int at_least_space_for);
   3310 
   3311   // Tells whether k is a real key.  The hole and undefined are not allowed
   3312   // as keys and can be used to indicate missing or deleted elements.
   3313   inline bool IsKey(Object* k);
   3314   inline bool IsKey(Isolate* isolate, Object* k);
   3315 
   3316   // Compute the probe offset (quadratic probing).
   3317   INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
   3318     return (n + n * n) >> 1;
   3319   }
   3320 
   3321   static const int kNumberOfElementsIndex = 0;
   3322   static const int kNumberOfDeletedElementsIndex = 1;
   3323   static const int kCapacityIndex = 2;
   3324   static const int kPrefixStartIndex = 3;
   3325 
   3326   // Constant used for denoting a absent entry.
   3327   static const int kNotFound = -1;
   3328 
   3329   // Minimum capacity for newly created hash tables.
   3330   static const int kMinCapacity = 4;
   3331 
   3332  protected:
   3333   // Update the number of elements in the hash table.
   3334   inline void SetNumberOfElements(int nof);
   3335 
   3336   // Update the number of deleted elements in the hash table.
   3337   inline void SetNumberOfDeletedElements(int nod);
   3338 
   3339   // Returns probe entry.
   3340   static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) {
   3341     DCHECK(base::bits::IsPowerOfTwo32(size));
   3342     return (hash + GetProbeOffset(number)) & (size - 1);
   3343   }
   3344 
   3345   inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
   3346     return hash & (size - 1);
   3347   }
   3348 
   3349   inline static uint32_t NextProbe(
   3350       uint32_t last, uint32_t number, uint32_t size) {
   3351     return (last + number) & (size - 1);
   3352   }
   3353 };
   3354 
   3355 
   3356 template <typename Derived, typename Shape, typename Key>
   3357 class HashTable : public HashTableBase {
   3358  public:
   3359   typedef Shape ShapeT;
   3360 
   3361   // Wrapper methods
   3362   inline uint32_t Hash(Key key) {
   3363     if (Shape::UsesSeed) {
   3364       return Shape::SeededHash(key, GetHeap()->HashSeed());
   3365     } else {
   3366       return Shape::Hash(key);
   3367     }
   3368   }
   3369 
   3370   inline uint32_t HashForObject(Key key, Object* object) {
   3371     if (Shape::UsesSeed) {
   3372       return Shape::SeededHashForObject(key, GetHeap()->HashSeed(), object);
   3373     } else {
   3374       return Shape::HashForObject(key, object);
   3375     }
   3376   }
   3377 
   3378   // Returns a new HashTable object.
   3379   MUST_USE_RESULT static Handle<Derived> New(
   3380       Isolate* isolate, int at_least_space_for,
   3381       MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
   3382       PretenureFlag pretenure = NOT_TENURED);
   3383 
   3384   DECLARE_CAST(HashTable)
   3385 
   3386   // Garbage collection support.
   3387   void IteratePrefix(ObjectVisitor* visitor);
   3388   void IterateElements(ObjectVisitor* visitor);
   3389 
   3390   // Find entry for key otherwise return kNotFound.
   3391   inline int FindEntry(Key key);
   3392   inline int FindEntry(Isolate* isolate, Key key, int32_t hash);
   3393   int FindEntry(Isolate* isolate, Key key);
   3394   inline bool Has(Isolate* isolate, Key key);
   3395   inline bool Has(Key key);
   3396 
   3397   // Rehashes the table in-place.
   3398   void Rehash(Key key);
   3399 
   3400   // Returns the key at entry.
   3401   Object* KeyAt(int entry) { return get(EntryToIndex(entry) + kEntryKeyIndex); }
   3402 
   3403   static const int kElementsStartIndex = kPrefixStartIndex + Shape::kPrefixSize;
   3404   static const int kEntrySize = Shape::kEntrySize;
   3405   STATIC_ASSERT(kEntrySize > 0);
   3406   static const int kEntryKeyIndex = 0;
   3407   static const int kElementsStartOffset =
   3408       kHeaderSize + kElementsStartIndex * kPointerSize;
   3409   // Maximal capacity of HashTable. Based on maximal length of underlying
   3410   // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex
   3411   // cannot overflow.
   3412   static const int kMaxCapacity =
   3413       (FixedArray::kMaxLength - kElementsStartIndex) / kEntrySize;
   3414 
   3415   // Returns the index for an entry (of the key)
   3416   static inline int EntryToIndex(int entry) {
   3417     return (entry * kEntrySize) + kElementsStartIndex;
   3418   }
   3419 
   3420  protected:
   3421   friend class ObjectHashTable;
   3422 
   3423   MUST_USE_RESULT static Handle<Derived> New(Isolate* isolate, int capacity,
   3424                                              PretenureFlag pretenure);
   3425 
   3426   // Find the entry at which to insert element with the given key that
   3427   // has the given hash value.
   3428   uint32_t FindInsertionEntry(uint32_t hash);
   3429 
   3430   // Attempt to shrink hash table after removal of key.
   3431   MUST_USE_RESULT static Handle<Derived> Shrink(Handle<Derived> table, Key key);
   3432 
   3433   // Ensure enough space for n additional elements.
   3434   MUST_USE_RESULT static Handle<Derived> EnsureCapacity(
   3435       Handle<Derived> table,
   3436       int n,
   3437       Key key,
   3438       PretenureFlag pretenure = NOT_TENURED);
   3439 
   3440   // Returns true if this table has sufficient capacity for adding n elements.
   3441   bool HasSufficientCapacityToAdd(int number_of_additional_elements);
   3442 
   3443   // Sets the capacity of the hash table.
   3444   void SetCapacity(int capacity) {
   3445     // To scale a computed hash code to fit within the hash table, we
   3446     // use bit-wise AND with a mask, so the capacity must be positive
   3447     // and non-zero.
   3448     DCHECK(capacity > 0);
   3449     DCHECK(capacity <= kMaxCapacity);
   3450     set(kCapacityIndex, Smi::FromInt(capacity));
   3451   }
   3452 
   3453  private:
   3454   // Returns _expected_ if one of entries given by the first _probe_ probes is
   3455   // equal to  _expected_. Otherwise, returns the entry given by the probe
   3456   // number _probe_.
   3457   uint32_t EntryForProbe(Key key, Object* k, int probe, uint32_t expected);
   3458 
   3459   void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
   3460 
   3461   // Rehashes this hash-table into the new table.
   3462   void Rehash(Handle<Derived> new_table, Key key);
   3463 };
   3464 
   3465 
   3466 // HashTableKey is an abstract superclass for virtual key behavior.
   3467 class HashTableKey {
   3468  public:
   3469   // Returns whether the other object matches this key.
   3470   virtual bool IsMatch(Object* other) = 0;
   3471   // Returns the hash value for this key.
   3472   virtual uint32_t Hash() = 0;
   3473   // Returns the hash value for object.
   3474   virtual uint32_t HashForObject(Object* key) = 0;
   3475   // Returns the key object for storing into the hash table.
   3476   MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) = 0;
   3477   // Required.
   3478   virtual ~HashTableKey() {}
   3479 };
   3480 
   3481 
   3482 class StringTableShape : public BaseShape<HashTableKey*> {
   3483  public:
   3484   static inline bool IsMatch(HashTableKey* key, Object* value) {
   3485     return key->IsMatch(value);
   3486   }
   3487 
   3488   static inline uint32_t Hash(HashTableKey* key) {
   3489     return key->Hash();
   3490   }
   3491 
   3492   static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
   3493     return key->HashForObject(object);
   3494   }
   3495 
   3496   static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
   3497 
   3498   static const int kPrefixSize = 0;
   3499   static const int kEntrySize = 1;
   3500 };
   3501 
   3502 class SeqOneByteString;
   3503 
   3504 // StringTable.
   3505 //
   3506 // No special elements in the prefix and the element size is 1
   3507 // because only the string itself (the key) needs to be stored.
   3508 class StringTable: public HashTable<StringTable,
   3509                                     StringTableShape,
   3510                                     HashTableKey*> {
   3511  public:
   3512   // Find string in the string table. If it is not there yet, it is
   3513   // added. The return value is the string found.
   3514   V8_EXPORT_PRIVATE static Handle<String> LookupString(Isolate* isolate,
   3515                                                        Handle<String> key);
   3516   static Handle<String> LookupKey(Isolate* isolate, HashTableKey* key);
   3517   static String* LookupKeyIfExists(Isolate* isolate, HashTableKey* key);
   3518 
   3519   // Tries to internalize given string and returns string handle on success
   3520   // or an empty handle otherwise.
   3521   MUST_USE_RESULT static MaybeHandle<String> InternalizeStringIfExists(
   3522       Isolate* isolate,
   3523       Handle<String> string);
   3524 
   3525   // Looks up a string that is equal to the given string and returns
   3526   // string handle if it is found, or an empty handle otherwise.
   3527   MUST_USE_RESULT static MaybeHandle<String> LookupStringIfExists(
   3528       Isolate* isolate,
   3529       Handle<String> str);
   3530   MUST_USE_RESULT static MaybeHandle<String> LookupTwoCharsStringIfExists(
   3531       Isolate* isolate,
   3532       uint16_t c1,
   3533       uint16_t c2);
   3534 
   3535   static void EnsureCapacityForDeserialization(Isolate* isolate, int expected);
   3536 
   3537   DECLARE_CAST(StringTable)
   3538 
   3539  private:
   3540   template <bool seq_one_byte>
   3541   friend class JsonParser;
   3542 
   3543   DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable);
   3544 };
   3545 
   3546 class StringSetShape : public BaseShape<String*> {
   3547  public:
   3548   static inline bool IsMatch(String* key, Object* value);
   3549   static inline uint32_t Hash(String* key);
   3550   static inline uint32_t HashForObject(String* key, Object* object);
   3551 
   3552   static const int kPrefixSize = 0;
   3553   static const int kEntrySize = 1;
   3554 };
   3555 
   3556 class StringSet : public HashTable<StringSet, StringSetShape, String*> {
   3557  public:
   3558   static Handle<StringSet> New(Isolate* isolate);
   3559   static Handle<StringSet> Add(Handle<StringSet> blacklist,
   3560                                Handle<String> name);
   3561   bool Has(Handle<String> name);
   3562 
   3563   DECLARE_CAST(StringSet)
   3564 };
   3565 
   3566 template <typename Derived, typename Shape, typename Key>
   3567 class Dictionary: public HashTable<Derived, Shape, Key> {
   3568   typedef HashTable<Derived, Shape, Key> DerivedHashTable;
   3569 
   3570  public:
   3571   // Returns the value at entry.
   3572   Object* ValueAt(int entry) {
   3573     return this->get(Derived::EntryToIndex(entry) + 1);
   3574   }
   3575 
   3576   // Set the value for entry.
   3577   void ValueAtPut(int entry, Object* value) {
   3578     this->set(Derived::EntryToIndex(entry) + 1, value);
   3579   }
   3580 
   3581   // Returns the property details for the property at entry.
   3582   PropertyDetails DetailsAt(int entry) {
   3583     return Shape::DetailsAt(static_cast<Derived*>(this), entry);
   3584   }
   3585 
   3586   // Set the details for entry.
   3587   void DetailsAtPut(int entry, PropertyDetails value) {
   3588     Shape::DetailsAtPut(static_cast<Derived*>(this), entry, value);
   3589   }
   3590 
   3591   // Returns true if property at given entry is deleted.
   3592   bool IsDeleted(int entry) {
   3593     return Shape::IsDeleted(static_cast<Derived*>(this), entry);
   3594   }
   3595 
   3596   // Delete a property from the dictionary.
   3597   static Handle<Object> DeleteProperty(Handle<Derived> dictionary, int entry);
   3598 
   3599   // Attempt to shrink the dictionary after deletion of key.
   3600   MUST_USE_RESULT static inline Handle<Derived> Shrink(
   3601       Handle<Derived> dictionary,
   3602       Key key) {
   3603     return DerivedHashTable::Shrink(dictionary, key);
   3604   }
   3605 
   3606   // Sorting support
   3607   // TODO(dcarney): templatize or move to SeededNumberDictionary
   3608   void CopyValuesTo(FixedArray* elements);
   3609 
   3610   // Returns the number of elements in the dictionary filtering out properties
   3611   // with the specified attributes.
   3612   int NumberOfElementsFilterAttributes(PropertyFilter filter);
   3613 
   3614   // Returns the number of enumerable elements in the dictionary.
   3615   int NumberOfEnumElements() {
   3616     return NumberOfElementsFilterAttributes(ENUMERABLE_STRINGS);
   3617   }
   3618 
   3619   enum SortMode { UNSORTED, SORTED };
   3620 
   3621   // Return the key indices sorted by its enumeration index.
   3622   static Handle<FixedArray> IterationIndices(
   3623       Handle<Dictionary<Derived, Shape, Key>> dictionary);
   3624 
   3625   // Collect the keys into the given KeyAccumulator, in ascending chronological
   3626   // order of property creation.
   3627   static void CollectKeysTo(Handle<Dictionary<Derived, Shape, Key>> dictionary,
   3628                             KeyAccumulator* keys);
   3629 
   3630   // Copies enumerable keys to preallocated fixed array.
   3631   static void CopyEnumKeysTo(Handle<Dictionary<Derived, Shape, Key>> dictionary,
   3632                              Handle<FixedArray> storage, KeyCollectionMode mode,
   3633                              KeyAccumulator* accumulator);
   3634 
   3635   // Accessors for next enumeration index.
   3636   void SetNextEnumerationIndex(int index) {
   3637     DCHECK(index != 0);
   3638     this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
   3639   }
   3640 
   3641   int NextEnumerationIndex() {
   3642     return Smi::cast(this->get(kNextEnumerationIndexIndex))->value();
   3643   }
   3644 
   3645   // Creates a new dictionary.
   3646   MUST_USE_RESULT static Handle<Derived> New(
   3647       Isolate* isolate, int at_least_space_for,
   3648       PretenureFlag pretenure = NOT_TENURED,
   3649       MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY);
   3650 
   3651   // Creates an dictionary with minimal possible capacity.
   3652   MUST_USE_RESULT static Handle<Derived> NewEmpty(
   3653       Isolate* isolate, PretenureFlag pretenure = NOT_TENURED);
   3654 
   3655   // Ensures that a new dictionary is created when the capacity is checked.
   3656   void SetRequiresCopyOnCapacityChange();
   3657 
   3658   // Ensure enough space for n additional elements.
   3659   static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n, Key key);
   3660 
   3661 #ifdef OBJECT_PRINT
   3662   // For our gdb macros, we should perhaps change these in the future.
   3663   void Print();
   3664 
   3665   void Print(std::ostream& os);  // NOLINT
   3666 #endif
   3667   // Returns the key (slow).
   3668   Object* SlowReverseLookup(Object* value);
   3669 
   3670   // Sets the entry to (key, value) pair.
   3671   inline void SetEntry(int entry,
   3672                        Handle<Object> key,
   3673                        Handle<Object> value);
   3674   inline void SetEntry(int entry,
   3675                        Handle<Object> key,
   3676                        Handle<Object> value,
   3677                        PropertyDetails details);
   3678 
   3679   MUST_USE_RESULT static Handle<Derived> Add(Handle<Derived> dictionary,
   3680                                              Key key, Handle<Object> value,
   3681                                              PropertyDetails details,
   3682                                              int* entry_out = nullptr);
   3683 
   3684   static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex;
   3685   static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
   3686 
   3687   static const bool kIsEnumerable = Shape::kIsEnumerable;
   3688 
   3689  protected:
   3690   // Generic at put operation.
   3691   MUST_USE_RESULT static Handle<Derived> AtPut(
   3692       Handle<Derived> dictionary,
   3693       Key key,
   3694       Handle<Object> value);
   3695   // Add entry to dictionary. Returns entry value.
   3696   static int AddEntry(Handle<Derived> dictionary, Key key, Handle<Object> value,
   3697                       PropertyDetails details, uint32_t hash);
   3698   // Generate new enumeration indices to avoid enumeration index overflow.
   3699   // Returns iteration indices array for the |dictionary|.
   3700   static Handle<FixedArray> GenerateNewEnumerationIndices(
   3701       Handle<Derived> dictionary);
   3702 };
   3703 
   3704 
   3705 template <typename Derived, typename Shape>
   3706 class NameDictionaryBase : public Dictionary<Derived, Shape, Handle<Name> > {
   3707   typedef Dictionary<Derived, Shape, Handle<Name> > DerivedDictionary;
   3708 
   3709  public:
   3710   // Find entry for key, otherwise return kNotFound. Optimized version of
   3711   // HashTable::FindEntry.
   3712   int FindEntry(Handle<Name> key);
   3713 };
   3714 
   3715 
   3716 template <typename Key>
   3717 class BaseDictionaryShape : public BaseShape<Key> {
   3718  public:
   3719   template <typename Dictionary>
   3720   static inline PropertyDetails DetailsAt(Dictionary* dict, int entry) {
   3721     STATIC_ASSERT(Dictionary::kEntrySize == 3);
   3722     DCHECK(entry >= 0);  // Not found is -1, which is not caught by get().
   3723     return PropertyDetails(Smi::cast(dict->get(
   3724         Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex)));
   3725   }
   3726 
   3727   template <typename Dictionary>
   3728   static inline void DetailsAtPut(Dictionary* dict, int entry,
   3729                                   PropertyDetails value) {
   3730     STATIC_ASSERT(Dictionary::kEntrySize == 3);
   3731     dict->set(Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex,
   3732               value.AsSmi());
   3733   }
   3734 
   3735   template <typename Dictionary>
   3736   static bool IsDeleted(Dictionary* dict, int entry) {
   3737     return false;
   3738   }
   3739 
   3740   template <typename Dictionary>
   3741   static inline void SetEntry(Dictionary* dict, int entry, Handle<Object> key,
   3742                               Handle<Object> value, PropertyDetails details);
   3743 };
   3744 
   3745 
   3746 class NameDictionaryShape : public BaseDictionaryShape<Handle<Name> > {
   3747  public:
   3748   static inline bool IsMatch(Handle<Name> key, Object* other);
   3749   static inline uint32_t Hash(Handle<Name> key);
   3750   static inline uint32_t HashForObject(Handle<Name> key, Object* object);
   3751   static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
   3752   static const int kPrefixSize = 2;
   3753   static const int kEntrySize = 3;
   3754   static const int kEntryValueIndex = 1;
   3755   static const int kEntryDetailsIndex = 2;
   3756   static const bool kIsEnumerable = true;
   3757 };
   3758 
   3759 
   3760 class NameDictionary
   3761     : public NameDictionaryBase<NameDictionary, NameDictionaryShape> {
   3762   typedef NameDictionaryBase<NameDictionary, NameDictionaryShape>
   3763       DerivedDictionary;
   3764 
   3765  public:
   3766   DECLARE_CAST(NameDictionary)
   3767 
   3768   inline static Handle<FixedArray> DoGenerateNewEnumerationIndices(
   3769       Handle<NameDictionary> dictionary);
   3770 
   3771   static const int kEntryValueIndex = 1;
   3772   static const int kEntryDetailsIndex = 2;
   3773   static const int kInitialCapacity = 2;
   3774 };
   3775 
   3776 
   3777 class GlobalDictionaryShape : public NameDictionaryShape {
   3778  public:
   3779   static const int kEntrySize = 2;  // Overrides NameDictionaryShape::kEntrySize
   3780 
   3781   template <typename Dictionary>
   3782   static inline PropertyDetails DetailsAt(Dictionary* dict, int entry);
   3783 
   3784   template <typename Dictionary>
   3785   static inline void DetailsAtPut(Dictionary* dict, int entry,
   3786                                   PropertyDetails value);
   3787 
   3788   template <typename Dictionary>
   3789   static bool IsDeleted(Dictionary* dict, int entry);
   3790 
   3791   template <typename Dictionary>
   3792   static inline void SetEntry(Dictionary* dict, int entry, Handle<Object> key,
   3793                               Handle<Object> value, PropertyDetails details);
   3794 };
   3795 
   3796 
   3797 class GlobalDictionary
   3798     : public NameDictionaryBase<GlobalDictionary, GlobalDictionaryShape> {
   3799  public:
   3800   DECLARE_CAST(GlobalDictionary)
   3801 
   3802   static const int kEntryValueIndex = 1;
   3803 };
   3804 
   3805 
   3806 class NumberDictionaryShape : public BaseDictionaryShape<uint32_t> {
   3807  public:
   3808   static inline bool IsMatch(uint32_t key, Object* other);
   3809   static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
   3810   static const bool kIsEnumerable = false;
   3811 };
   3812 
   3813 
   3814 class SeededNumberDictionaryShape : public NumberDictionaryShape {
   3815  public:
   3816   static const bool UsesSeed = true;
   3817   static const int kPrefixSize = 2;
   3818   static const int kEntrySize = 3;
   3819 
   3820   static inline uint32_t SeededHash(uint32_t key, uint32_t seed);
   3821   static inline uint32_t SeededHashForObject(uint32_t key,
   3822                                              uint32_t seed,
   3823                                              Object* object);
   3824 };
   3825 
   3826 
   3827 class UnseededNumberDictionaryShape : public NumberDictionaryShape {
   3828  public:
   3829   static const int kPrefixSize = 0;
   3830   static const int kEntrySize = 2;
   3831 
   3832   static inline uint32_t Hash(uint32_t key);
   3833   static inline uint32_t HashForObject(uint32_t key, Object* object);
   3834 
   3835   template <typename Dictionary>
   3836   static inline PropertyDetails DetailsAt(Dictionary* dict, int entry) {
   3837     UNREACHABLE();
   3838     return PropertyDetails::Empty();
   3839   }
   3840 
   3841   template <typename Dictionary>
   3842   static inline void DetailsAtPut(Dictionary* dict, int entry,
   3843                                   PropertyDetails value) {
   3844     UNREACHABLE();
   3845   }
   3846 
   3847   static inline Map* GetMap(Isolate* isolate);
   3848 };
   3849 
   3850 
   3851 class SeededNumberDictionary
   3852     : public Dictionary<SeededNumberDictionary,
   3853                         SeededNumberDictionaryShape,
   3854                         uint32_t> {
   3855  public:
   3856   DECLARE_CAST(SeededNumberDictionary)
   3857 
   3858   // Type specific at put (default NONE attributes is used when adding).
   3859   MUST_USE_RESULT static Handle<SeededNumberDictionary> AtNumberPut(
   3860       Handle<SeededNumberDictionary> dictionary, uint32_t key,
   3861       Handle<Object> value, Handle<JSObject> dictionary_holder);
   3862   MUST_USE_RESULT static Handle<SeededNumberDictionary> AddNumberEntry(
   3863       Handle<SeededNumberDictionary> dictionary, uint32_t key,
   3864       Handle<Object> value, PropertyDetails details,
   3865       Handle<JSObject> dictionary_holder);
   3866 
   3867   // Set an existing entry or add a new one if needed.
   3868   // Return the updated dictionary.
   3869   MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
   3870       Handle<SeededNumberDictionary> dictionary, uint32_t key,
   3871       Handle<Object> value, PropertyDetails details,
   3872       Handle<JSObject> dictionary_holder);
   3873 
   3874   void UpdateMaxNumberKey(uint32_t key, Handle<JSObject> dictionary_holder);
   3875 
   3876   // Returns true if the dictionary contains any elements that are non-writable,
   3877   // non-configurable, non-enumerable, or have getters/setters.
   3878   bool HasComplexElements();
   3879 
   3880   // If slow elements are required we will never go back to fast-case
   3881   // for the elements kept in this dictionary.  We require slow
   3882   // elements if an element has been added at an index larger than
   3883   // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called
   3884   // when defining a getter or setter with a number key.
   3885   inline bool requires_slow_elements();
   3886   inline void set_requires_slow_elements();
   3887 
   3888   // Get the value of the max number key that has been added to this
   3889   // dictionary.  max_number_key can only be called if
   3890   // requires_slow_elements returns false.
   3891   inline uint32_t max_number_key();
   3892 
   3893   static const int kEntryValueIndex = 1;
   3894   static const int kEntryDetailsIndex = 2;
   3895 
   3896   // Bit masks.
   3897   static const int kRequiresSlowElementsMask = 1;
   3898   static const int kRequiresSlowElementsTagSize = 1;
   3899   static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1;
   3900 };
   3901 
   3902 
   3903 class UnseededNumberDictionary
   3904     : public Dictionary<UnseededNumberDictionary,
   3905                         UnseededNumberDictionaryShape,
   3906                         uint32_t> {
   3907  public:
   3908   DECLARE_CAST(UnseededNumberDictionary)
   3909 
   3910   // Type specific at put (default NONE attributes is used when adding).
   3911   MUST_USE_RESULT static Handle<UnseededNumberDictionary> AtNumberPut(
   3912       Handle<UnseededNumberDictionary> dictionary,
   3913       uint32_t key,
   3914       Handle<Object> value);
   3915   MUST_USE_RESULT static Handle<UnseededNumberDictionary> AddNumberEntry(
   3916       Handle<UnseededNumberDictionary> dictionary,
   3917       uint32_t key,
   3918       Handle<Object> value);
   3919   static Handle<UnseededNumberDictionary> DeleteKey(
   3920       Handle<UnseededNumberDictionary> dictionary, uint32_t key);
   3921 
   3922   // Set an existing entry or add a new one if needed.
   3923   // Return the updated dictionary.
   3924   MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
   3925       Handle<UnseededNumberDictionary> dictionary,
   3926       uint32_t key,
   3927       Handle<Object> value);
   3928 
   3929   static const int kEntryValueIndex = 1;
   3930   static const int kEntryDetailsIndex = 2;
   3931 };
   3932 
   3933 
   3934 class ObjectHashTableShape : public BaseShape<Handle<Object> > {
   3935  public:
   3936   static inline bool IsMatch(Handle<Object> key, Object* other);
   3937   static inline uint32_t Hash(Handle<Object> key);
   3938   static inline uint32_t HashForObject(Handle<Object> key, Object* object);
   3939   static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
   3940   static const int kPrefixSize = 0;
   3941   static const int kEntrySize = 2;
   3942 };
   3943 
   3944 
   3945 // ObjectHashTable maps keys that are arbitrary objects to object values by
   3946 // using the identity hash of the key for hashing purposes.
   3947 class ObjectHashTable: public HashTable<ObjectHashTable,
   3948                                         ObjectHashTableShape,
   3949                                         Handle<Object> > {
   3950   typedef HashTable<
   3951       ObjectHashTable, ObjectHashTableShape, Handle<Object> > DerivedHashTable;
   3952  public:
   3953   DECLARE_CAST(ObjectHashTable)
   3954 
   3955   // Attempt to shrink hash table after removal of key.
   3956   MUST_USE_RESULT static inline Handle<ObjectHashTable> Shrink(
   3957       Handle<ObjectHashTable> table,
   3958       Handle<Object> key);
   3959 
   3960   // Looks up the value associated with the given key. The hole value is
   3961   // returned in case the key is not present.
   3962   Object* Lookup(Handle<Object> key);
   3963   Object* Lookup(Handle<Object> key, int32_t hash);
   3964   Object* Lookup(Isolate* isolate, Handle<Object> key, int32_t hash);
   3965 
   3966   // Returns the value at entry.
   3967   Object* ValueAt(int entry);
   3968 
   3969   // Adds (or overwrites) the value associated with the given key.
   3970   static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
   3971                                      Handle<Object> key,
   3972                                      Handle<Object> value);
   3973   static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
   3974                                      Handle<Object> key, Handle<Object> value,
   3975                                      int32_t hash);
   3976 
   3977   // Returns an ObjectHashTable (possibly |table|) where |key| has been removed.
   3978   static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
   3979                                         Handle<Object> key,
   3980                                         bool* was_present);
   3981   static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
   3982                                         Handle<Object> key, bool* was_present,
   3983                                         int32_t hash);
   3984 
   3985  protected:
   3986   friend class MarkCompactCollector;
   3987 
   3988   void AddEntry(int entry, Object* key, Object* value);
   3989   void RemoveEntry(int entry);
   3990 
   3991   // Returns the index to the value of an entry.
   3992   static inline int EntryToValueIndex(int entry) {
   3993     return EntryToIndex(entry) + 1;
   3994   }
   3995 };
   3996 
   3997 class ObjectHashSetShape : public ObjectHashTableShape {
   3998  public:
   3999   static const int kPrefixSize = 0;
   4000   static const int kEntrySize = 1;
   4001 };
   4002 
   4003 class ObjectHashSet
   4004     : public HashTable<ObjectHashSet, ObjectHashSetShape, Handle<Object>> {
   4005  public:
   4006   static Handle<ObjectHashSet> Add(Handle<ObjectHashSet> set,
   4007                                    Handle<Object> key);
   4008 
   4009   inline bool Has(Isolate* isolate, Handle<Object> key, int32_t hash);
   4010   inline bool Has(Isolate* isolate, Handle<Object> key);
   4011 
   4012   DECLARE_CAST(ObjectHashSet)
   4013 };
   4014 
   4015 // OrderedHashTable is a HashTable with Object keys that preserves
   4016 // insertion order. There are Map and Set interfaces (OrderedHashMap
   4017 // and OrderedHashTable, below). It is meant to be used by JSMap/JSSet.
   4018 //
   4019 // Only Object* keys are supported, with Object::SameValueZero() used as the
   4020 // equality operator and Object::GetHash() for the hash function.
   4021 //
   4022 // Based on the "Deterministic Hash Table" as described by Jason Orendorff at
   4023 // https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables
   4024 // Originally attributed to Tyler Close.
   4025 //
   4026 // Memory layout:
   4027 //   [0]: bucket count
   4028 //   [1]: element count
   4029 //   [2]: deleted element count
   4030 //   [3..(3 + NumberOfBuckets() - 1)]: "hash table", where each item is an
   4031 //                            offset into the data table (see below) where the
   4032 //                            first item in this bucket is stored.
   4033 //   [3 + NumberOfBuckets()..length]: "data table", an array of length
   4034 //                            Capacity() * kEntrySize, where the first entrysize
   4035 //                            items are handled by the derived class and the
   4036 //                            item at kChainOffset is another entry into the
   4037 //                            data table indicating the next entry in this hash
   4038 //                            bucket.
   4039 //
   4040 // When we transition the table to a new version we obsolete it and reuse parts
   4041 // of the memory to store information how to transition an iterator to the new
   4042 // table:
   4043 //
   4044 // Memory layout for obsolete table:
   4045 //   [0]: bucket count
   4046 //   [1]: Next newer table
   4047 //   [2]: Number of removed holes or -1 when the table was cleared.
   4048 //   [3..(3 + NumberOfRemovedHoles() - 1)]: The indexes of the removed holes.
   4049 //   [3 + NumberOfRemovedHoles()..length]: Not used
   4050 //
   4051 template<class Derived, class Iterator, int entrysize>
   4052 class OrderedHashTable: public FixedArray {
   4053  public:
   4054   // Returns an OrderedHashTable with a capacity of at least |capacity|.
   4055   static Handle<Derived> Allocate(
   4056       Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED);
   4057 
   4058   // Returns an OrderedHashTable (possibly |table|) with enough space
   4059   // to add at least one new element.
   4060   static Handle<Derived> EnsureGrowable(Handle<Derived> table);
   4061 
   4062   // Returns an OrderedHashTable (possibly |table|) that's shrunken
   4063   // if possible.
   4064   static Handle<Derived> Shrink(Handle<Derived> table);
   4065 
   4066   // Returns a new empty OrderedHashTable and records the clearing so that
   4067   // existing iterators can be updated.
   4068   static Handle<Derived> Clear(Handle<Derived> table);
   4069 
   4070   // Returns a true if the OrderedHashTable contains the key
   4071   static bool HasKey(Handle<Derived> table, Handle<Object> key);
   4072 
   4073   int NumberOfElements() {
   4074     return Smi::cast(get(kNumberOfElementsIndex))->value();
   4075   }
   4076 
   4077   int NumberOfDeletedElements() {
   4078     return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
   4079   }
   4080 
   4081   // Returns the number of contiguous entries in the data table, starting at 0,
   4082   // that either are real entries or have been deleted.
   4083   int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); }
   4084 
   4085   int NumberOfBuckets() {
   4086     return Smi::cast(get(kNumberOfBucketsIndex))->value();
   4087   }
   4088 
   4089   // Returns an index into |this| for the given entry.
   4090   int EntryToIndex(int entry) {
   4091     return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize);
   4092   }
   4093 
   4094   int HashToBucket(int hash) { return hash & (NumberOfBuckets() - 1); }
   4095 
   4096   int HashToEntry(int hash) {
   4097     int bucket = HashToBucket(hash);
   4098     Object* entry = this->get(kHashTableStartIndex + bucket);
   4099     return Smi::cast(entry)->value();
   4100   }
   4101 
   4102   int KeyToFirstEntry(Isolate* isolate, Object* key) {
   4103     Object* hash = key->GetHash();
   4104     // If the object does not have an identity hash, it was never used as a key
   4105     if (hash->IsUndefined(isolate)) return kNotFound;
   4106     return HashToEntry(Smi::cast(hash)->value());
   4107   }
   4108 
   4109   int NextChainEntry(int entry) {
   4110     Object* next_entry = get(EntryToIndex(entry) + kChainOffset);
   4111     return Smi::cast(next_entry)->value();
   4112   }
   4113 
   4114   // use KeyAt(i)->IsTheHole(isolate) to determine if this is a deleted entry.
   4115   Object* KeyAt(int entry) {
   4116     DCHECK_LT(entry, this->UsedCapacity());
   4117     return get(EntryToIndex(entry));
   4118   }
   4119 
   4120   bool IsObsolete() {
   4121     return !get(kNextTableIndex)->IsSmi();
   4122   }
   4123 
   4124   // The next newer table. This is only valid if the table is obsolete.
   4125   Derived* NextTable() {
   4126     return Derived::cast(get(kNextTableIndex));
   4127   }
   4128 
   4129   // When the table is obsolete we store the indexes of the removed holes.
   4130   int RemovedIndexAt(int index) {
   4131     return Smi::cast(get(kRemovedHolesIndex + index))->value();
   4132   }
   4133 
   4134   static const int kNotFound = -1;
   4135   static const int kMinCapacity = 4;
   4136 
   4137   static const int kNumberOfElementsIndex = 0;
   4138   // The next table is stored at the same index as the nof elements.
   4139   static const int kNextTableIndex = kNumberOfElementsIndex;
   4140   static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
   4141   static const int kNumberOfBucketsIndex = kNumberOfDeletedElementsIndex + 1;
   4142   static const int kHashTableStartIndex = kNumberOfBucketsIndex + 1;
   4143 
   4144   static constexpr const int kNumberOfElementsOffset =
   4145       FixedArray::OffsetOfElementAt(kNumberOfElementsIndex);
   4146   static constexpr const int kNextTableOffset =
   4147       FixedArray::OffsetOfElementAt(kNextTableIndex);
   4148   static constexpr const int kNumberOfDeletedElementsOffset =
   4149       FixedArray::OffsetOfElementAt(kNumberOfDeletedElementsIndex);
   4150   static constexpr const int kNumberOfBucketsOffset =
   4151       FixedArray::OffsetOfElementAt(kNumberOfBucketsIndex);
   4152   static constexpr const int kHashTableStartOffset =
   4153       FixedArray::OffsetOfElementAt(kHashTableStartIndex);
   4154 
   4155   static const int kEntrySize = entrysize + 1;
   4156   static const int kChainOffset = entrysize;
   4157 
   4158   static const int kLoadFactor = 2;
   4159 
   4160   // NumberOfDeletedElements is set to kClearedTableSentinel when
   4161   // the table is cleared, which allows iterator transitions to
   4162   // optimize that case.
   4163   static const int kClearedTableSentinel = -1;
   4164 
   4165  protected:
   4166   static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
   4167 
   4168   void SetNumberOfBuckets(int num) {
   4169     set(kNumberOfBucketsIndex, Smi::FromInt(num));
   4170   }
   4171 
   4172   void SetNumberOfElements(int num) {
   4173     set(kNumberOfElementsIndex, Smi::FromInt(num));
   4174   }
   4175 
   4176   void SetNumberOfDeletedElements(int num) {
   4177     set(kNumberOfDeletedElementsIndex, Smi::FromInt(num));
   4178   }
   4179 
   4180   // Returns the number elements that can fit into the allocated buffer.
   4181   int Capacity() {
   4182     return NumberOfBuckets() * kLoadFactor;
   4183   }
   4184 
   4185   void SetNextTable(Derived* next_table) {
   4186     set(kNextTableIndex, next_table);
   4187   }
   4188 
   4189   void SetRemovedIndexAt(int index, int removed_index) {
   4190     return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
   4191   }
   4192 
   4193   static const int kRemovedHolesIndex = kHashTableStartIndex;
   4194 
   4195   static const int kMaxCapacity =
   4196       (FixedArray::kMaxLength - kHashTableStartIndex)
   4197       / (1 + (kEntrySize * kLoadFactor));
   4198 };
   4199 
   4200 
   4201 class JSSetIterator;
   4202 
   4203 
   4204 class OrderedHashSet: public OrderedHashTable<
   4205     OrderedHashSet, JSSetIterator, 1> {
   4206  public:
   4207   DECLARE_CAST(OrderedHashSet)
   4208 
   4209   static Handle<OrderedHashSet> Add(Handle<OrderedHashSet> table,
   4210                                     Handle<Object> value);
   4211   static Handle<FixedArray> ConvertToKeysArray(Handle<OrderedHashSet> table,
   4212                                                GetKeysConversion convert);
   4213 };
   4214 
   4215 
   4216 class JSMapIterator;
   4217 
   4218 
   4219 class OrderedHashMap
   4220     : public OrderedHashTable<OrderedHashMap, JSMapIterator, 2> {
   4221  public:
   4222   DECLARE_CAST(OrderedHashMap)
   4223 
   4224   inline Object* ValueAt(int entry);
   4225 
   4226   static const int kValueOffset = 1;
   4227 };
   4228 
   4229 
   4230 template <int entrysize>
   4231 class WeakHashTableShape : public BaseShape<Handle<Object> > {
   4232  public:
   4233   static inline bool IsMatch(Handle<Object> key, Object* other);
   4234   static inline uint32_t Hash(Handle<Object> key);
   4235   static inline uint32_t HashForObject(Handle<Object> key, Object* object);
   4236   static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
   4237   static const int kPrefixSize = 0;
   4238   static const int kEntrySize = entrysize;
   4239 };
   4240 
   4241 
   4242 // WeakHashTable maps keys that are arbitrary heap objects to heap object
   4243 // values. The table wraps the keys in weak cells and store values directly.
   4244 // Thus it references keys weakly and values strongly.
   4245 class WeakHashTable: public HashTable<WeakHashTable,
   4246                                       WeakHashTableShape<2>,
   4247                                       Handle<Object> > {
   4248   typedef HashTable<
   4249       WeakHashTable, WeakHashTableShape<2>, Handle<Object> > DerivedHashTable;
   4250  public:
   4251   DECLARE_CAST(WeakHashTable)
   4252 
   4253   // Looks up the value associated with the given key. The hole value is
   4254   // returned in case the key is not present.
   4255   Object* Lookup(Handle<HeapObject> key);
   4256 
   4257   // Adds (or overwrites) the value associated with the given key. Mapping a
   4258   // key to the hole value causes removal of the whole entry.
   4259   MUST_USE_RESULT static Handle<WeakHashTable> Put(Handle<WeakHashTable> table,
   4260                                                    Handle<HeapObject> key,
   4261                                                    Handle<HeapObject> value);
   4262 
   4263   static Handle<FixedArray> GetValues(Handle<WeakHashTable> table);
   4264 
   4265  private:
   4266   friend class MarkCompactCollector;
   4267 
   4268   void AddEntry(int entry, Handle<WeakCell> key, Handle<HeapObject> value);
   4269 
   4270   // Returns the index to the value of an entry.
   4271   static inline int EntryToValueIndex(int entry) {
   4272     return EntryToIndex(entry) + 1;
   4273   }
   4274 };
   4275 
   4276 
   4277 // The cache for maps used by normalized (dictionary mode) objects.
   4278 // Such maps do not have property descriptors, so a typical program
   4279 // needs very limited number of distinct normalized maps.
   4280 class NormalizedMapCache: public FixedArray {
   4281  public:
   4282   static Handle<NormalizedMapCache> New(Isolate* isolate);
   4283 
   4284   MUST_USE_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
   4285                                        PropertyNormalizationMode mode);
   4286   void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
   4287 
   4288   void Clear();
   4289 
   4290   DECLARE_CAST(NormalizedMapCache)
   4291 
   4292   static inline bool IsNormalizedMapCache(const HeapObject* obj);
   4293 
   4294   DECLARE_VERIFIER(NormalizedMapCache)
   4295  private:
   4296   static const int kEntries = 64;
   4297 
   4298   static inline int GetIndex(Handle<Map> map);
   4299 
   4300   // The following declarations hide base class methods.
   4301   Object* get(int index);
   4302   void set(int index, Object* value);
   4303 };
   4304 
   4305 // HandlerTable is a fixed array containing entries for exception handlers in
   4306 // the code object it is associated with. The tables comes in two flavors:
   4307 // 1) Based on ranges: Used for unoptimized code. Contains one entry per
   4308 //    exception handler and a range representing the try-block covered by that
   4309 //    handler. Layout looks as follows:
   4310 //      [ range-start , range-end , handler-offset , handler-data ]
   4311 // 2) Based on return addresses: Used for turbofanned code. Contains one entry
   4312 //    per call-site that could throw an exception. Layout looks as follows:
   4313 //      [ return-address-offset , handler-offset ]
   4314 class HandlerTable : public FixedArray {
   4315  public:
   4316   // Conservative prediction whether a given handler will locally catch an
   4317   // exception or cause a re-throw to outside the code boundary. Since this is
   4318   // undecidable it is merely an approximation (e.g. useful for debugger).
   4319   enum CatchPrediction {
   4320     UNCAUGHT,    // The handler will (likely) rethrow the exception.
   4321     CAUGHT,      // The exception will be caught by the handler.
   4322     PROMISE,     // The exception will be caught and cause a promise rejection.
   4323     DESUGARING,  // The exception will be caught, but both the exception and the
   4324                  // catching are part of a desugaring and should therefore not
   4325                  // be visible to the user (we won't notify the debugger of such
   4326                  // exceptions).
   4327     ASYNC_AWAIT,  // The exception will be caught and cause a promise rejection
   4328                   // in the desugaring of an async function, so special
   4329                   // async/await handling in the debugger can take place.
   4330   };
   4331 
   4332   // Getters for handler table based on ranges.
   4333   inline int GetRangeStart(int index) const;
   4334   inline int GetRangeEnd(int index) const;
   4335   inline int GetRangeHandler(int index) const;
   4336   inline int GetRangeData(int index) const;
   4337 
   4338   // Setters for handler table based on ranges.
   4339   inline void SetRangeStart(int index, int value);
   4340   inline void SetRangeEnd(int index, int value);
   4341   inline void SetRangeHandler(int index, int offset, CatchPrediction pred);
   4342   inline void SetRangeData(int index, int value);
   4343 
   4344   // Setters for handler table based on return addresses.
   4345   inline void SetReturnOffset(int index, int value);
   4346   inline void SetReturnHandler(int index, int offset);
   4347 
   4348   // Lookup handler in a table based on ranges. The {pc_offset} is an offset to
   4349   // the start of the potentially throwing instruction (using return addresses
   4350   // for this value would be invalid).
   4351   int LookupRange(int pc_offset, int* data, CatchPrediction* prediction);
   4352 
   4353   // Lookup handler in a table based on return addresses.
   4354   int LookupReturn(int pc_offset);
   4355 
   4356   // Returns the number of entries in the table.
   4357   inline int NumberOfRangeEntries() const;
   4358 
   4359   // Returns the required length of the underlying fixed array.
   4360   static int LengthForRange(int entries) { return entries * kRangeEntrySize; }
   4361   static int LengthForReturn(int entries) { return entries * kReturnEntrySize; }
   4362 
   4363   DECLARE_CAST(HandlerTable)
   4364 
   4365 #ifdef ENABLE_DISASSEMBLER
   4366   void HandlerTableRangePrint(std::ostream& os);   // NOLINT
   4367   void HandlerTableReturnPrint(std::ostream& os);  // NOLINT
   4368 #endif
   4369 
   4370  private:
   4371   // Layout description for handler table based on ranges.
   4372   static const int kRangeStartIndex = 0;
   4373   static const int kRangeEndIndex = 1;
   4374   static const int kRangeHandlerIndex = 2;
   4375   static const int kRangeDataIndex = 3;
   4376   static const int kRangeEntrySize = 4;
   4377 
   4378   // Layout description for handler table based on return addresses.
   4379   static const int kReturnOffsetIndex = 0;
   4380   static const int kReturnHandlerIndex = 1;
   4381   static const int kReturnEntrySize = 2;
   4382 
   4383   // Encoding of the {handler} field.
   4384   class HandlerPredictionField : public BitField<CatchPrediction, 0, 3> {};
   4385   class HandlerOffsetField : public BitField<int, 3, 29> {};
   4386 };
   4387 
   4388 // ByteArray represents fixed sized byte arrays.  Used for the relocation info
   4389 // that is attached to code objects.
   4390 class ByteArray: public FixedArrayBase {
   4391  public:
   4392   inline int Size();
   4393 
   4394   // Setter and getter.
   4395   inline byte get(int index);
   4396   inline void set(int index, byte value);
   4397 
   4398   // Copy in / copy out whole byte slices.
   4399   inline void copy_out(int index, byte* buffer, int length);
   4400   inline void copy_in(int index, const byte* buffer, int length);
   4401 
   4402   // Treat contents as an int array.
   4403   inline int get_int(int index);
   4404   inline void set_int(int index, int value);
   4405 
   4406   static int SizeFor(int length) {
   4407     return OBJECT_POINTER_ALIGN(kHeaderSize + length);
   4408   }
   4409   // We use byte arrays for free blocks in the heap.  Given a desired size in
   4410   // bytes that is a multiple of the word size and big enough to hold a byte
   4411   // array, this function returns the number of elements a byte array should
   4412   // have.
   4413   static int LengthFor(int size_in_bytes) {
   4414     DCHECK(IsAligned(size_in_bytes, kPointerSize));
   4415     DCHECK(size_in_bytes >= kHeaderSize);
   4416     return size_in_bytes - kHeaderSize;
   4417   }
   4418 
   4419   // Returns data start address.
   4420   inline Address GetDataStartAddress();
   4421 
   4422   // Returns a pointer to the ByteArray object for a given data start address.
   4423   static inline ByteArray* FromDataStartAddress(Address address);
   4424 
   4425   DECLARE_CAST(ByteArray)
   4426 
   4427   // Dispatched behavior.
   4428   inline int ByteArraySize();
   4429   DECLARE_PRINTER(ByteArray)
   4430   DECLARE_VERIFIER(ByteArray)
   4431 
   4432   // Layout description.
   4433   static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
   4434 
   4435   // Maximal memory consumption for a single ByteArray.
   4436   static const int kMaxSize = 512 * MB;
   4437   // Maximal length of a single ByteArray.
   4438   static const int kMaxLength = kMaxSize - kHeaderSize;
   4439 
   4440  private:
   4441   DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
   4442 };
   4443 
   4444 // Wrapper class for ByteArray which can store arbitrary C++ classes, as long
   4445 // as they can be copied with memcpy.
   4446 template <class T>
   4447 class PodArray : public ByteArray {
   4448  public:
   4449   static Handle<PodArray<T>> New(Isolate* isolate, int length,
   4450                                  PretenureFlag pretenure = NOT_TENURED);
   4451   void copy_out(int index, T* result) {
   4452     ByteArray::copy_out(index * sizeof(T), reinterpret_cast<byte*>(result),
   4453                         sizeof(T));
   4454   }
   4455   T get(int index) {
   4456     T result;
   4457     copy_out(index, &result);
   4458     return result;
   4459   }
   4460   void set(int index, const T& value) {
   4461     copy_in(index * sizeof(T), reinterpret_cast<const byte*>(&value),
   4462             sizeof(T));
   4463   }
   4464   int length() { return ByteArray::length() / sizeof(T); }
   4465   DECLARE_CAST(PodArray<T>)
   4466 
   4467  private:
   4468   DISALLOW_IMPLICIT_CONSTRUCTORS(PodArray<T>);
   4469 };
   4470 
   4471 // BytecodeArray represents a sequence of interpreter bytecodes.
   4472 class BytecodeArray : public FixedArrayBase {
   4473  public:
   4474 #define DECLARE_BYTECODE_AGE_ENUM(X) k##X##BytecodeAge,
   4475   enum Age {
   4476     kNoAgeBytecodeAge = 0,
   4477     CODE_AGE_LIST(DECLARE_BYTECODE_AGE_ENUM) kAfterLastBytecodeAge,
   4478     kFirstBytecodeAge = kNoAgeBytecodeAge,
   4479     kLastBytecodeAge = kAfterLastBytecodeAge - 1,
   4480     kBytecodeAgeCount = kAfterLastBytecodeAge - kFirstBytecodeAge - 1,
   4481     kIsOldBytecodeAge = kSexagenarianBytecodeAge
   4482   };
   4483 #undef DECLARE_BYTECODE_AGE_ENUM
   4484 
   4485   static int SizeFor(int length) {
   4486     return OBJECT_POINTER_ALIGN(kHeaderSize + length);
   4487   }
   4488 
   4489   // Setter and getter
   4490   inline byte get(int index);
   4491   inline void set(int index, byte value);
   4492 
   4493   // Returns data start address.
   4494   inline Address GetFirstBytecodeAddress();
   4495 
   4496   // Accessors for frame size.
   4497   inline int frame_size() const;
   4498   inline void set_frame_size(int frame_size);
   4499 
   4500   // Accessor for register count (derived from frame_size).
   4501   inline int register_count() const;
   4502 
   4503   // Accessors for parameter count (including implicit 'this' receiver).
   4504   inline int parameter_count() const;
   4505   inline void set_parameter_count(int number_of_parameters);
   4506 
   4507   // Accessors for profiling count.
   4508   inline int interrupt_budget() const;
   4509   inline void set_interrupt_budget(int interrupt_budget);
   4510 
   4511   // Accessors for OSR loop nesting level.
   4512   inline int osr_loop_nesting_level() const;
   4513   inline void set_osr_loop_nesting_level(int depth);
   4514 
   4515   // Accessors for bytecode's code age.
   4516   inline Age bytecode_age() const;
   4517   inline void set_bytecode_age(Age age);
   4518 
   4519   // Accessors for the constant pool.
   4520   DECL_ACCESSORS(constant_pool, FixedArray)
   4521 
   4522   // Accessors for handler table containing offsets of exception handlers.
   4523   DECL_ACCESSORS(handler_table, FixedArray)
   4524 
   4525   // Accessors for source position table containing mappings between byte code
   4526   // offset and source position.
   4527   DECL_ACCESSORS(source_position_table, ByteArray)
   4528 
   4529   DECLARE_CAST(BytecodeArray)
   4530 
   4531   // Dispatched behavior.
   4532   inline int BytecodeArraySize();
   4533 
   4534   inline int instruction_size();
   4535 
   4536   // Returns the size of bytecode and its metadata. This includes the size of
   4537   // bytecode, constant pool, source position table, and handler table.
   4538   inline int SizeIncludingMetadata();
   4539 
   4540   int SourcePosition(int offset);
   4541   int SourceStatementPosition(int offset);
   4542 
   4543   DECLARE_PRINTER(BytecodeArray)
   4544   DECLARE_VERIFIER(BytecodeArray)
   4545 
   4546   void Disassemble(std::ostream& os);
   4547 
   4548   void CopyBytecodesTo(BytecodeArray* to);
   4549 
   4550   // Bytecode aging
   4551   bool IsOld() const;
   4552   void MakeOlder();
   4553 
   4554   // Layout description.
   4555   static const int kConstantPoolOffset = FixedArrayBase::kHeaderSize;
   4556   static const int kHandlerTableOffset = kConstantPoolOffset + kPointerSize;
   4557   static const int kSourcePositionTableOffset =
   4558       kHandlerTableOffset + kPointerSize;
   4559   static const int kFrameSizeOffset = kSourcePositionTableOffset + kPointerSize;
   4560   static const int kParameterSizeOffset = kFrameSizeOffset + kIntSize;
   4561   static const int kInterruptBudgetOffset = kParameterSizeOffset + kIntSize;
   4562   static const int kOSRNestingLevelOffset = kInterruptBudgetOffset + kIntSize;
   4563   static const int kBytecodeAgeOffset = kOSRNestingLevelOffset + kCharSize;
   4564   static const int kHeaderSize = kBytecodeAgeOffset + kCharSize;
   4565 
   4566   // Maximal memory consumption for a single BytecodeArray.
   4567   static const int kMaxSize = 512 * MB;
   4568   // Maximal length of a single BytecodeArray.
   4569   static const int kMaxLength = kMaxSize - kHeaderSize;
   4570 
   4571   static const int kPointerFieldsBeginOffset = kConstantPoolOffset;
   4572   static const int kPointerFieldsEndOffset = kFrameSizeOffset;
   4573 
   4574   typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
   4575                               kPointerFieldsEndOffset, kHeaderSize>
   4576       MarkingBodyDescriptor;
   4577 
   4578   class BodyDescriptor;
   4579 
   4580  private:
   4581   DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeArray);
   4582 };
   4583 
   4584 
   4585 // FreeSpace are fixed-size free memory blocks used by the heap and GC.
   4586 // They look like heap objects (are heap object tagged and have a map) so that
   4587 // the heap remains iterable.  They have a size and a next pointer.
   4588 // The next pointer is the raw address of the next FreeSpace object (or NULL)
   4589 // in the free list.
   4590 class FreeSpace: public HeapObject {
   4591  public:
   4592   // [size]: size of the free space including the header.
   4593   inline int size() const;
   4594   inline void set_size(int value);
   4595 
   4596   inline int nobarrier_size() const;
   4597   inline void nobarrier_set_size(int value);
   4598 
   4599   inline int Size();
   4600 
   4601   // Accessors for the next field.
   4602   inline FreeSpace* next();
   4603   inline void set_next(FreeSpace* next);
   4604 
   4605   inline static FreeSpace* cast(HeapObject* obj);
   4606 
   4607   // Dispatched behavior.
   4608   DECLARE_PRINTER(FreeSpace)
   4609   DECLARE_VERIFIER(FreeSpace)
   4610 
   4611   // Layout description.
   4612   // Size is smi tagged when it is stored.
   4613   static const int kSizeOffset = HeapObject::kHeaderSize;
   4614   static const int kNextOffset = POINTER_SIZE_ALIGN(kSizeOffset + kPointerSize);
   4615   static const int kSize = kNextOffset + kPointerSize;
   4616 
   4617  private:
   4618   DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace);
   4619 };
   4620 
   4621 
   4622 // V has parameters (Type, type, TYPE, C type, element_size)
   4623 #define TYPED_ARRAYS(V) \
   4624   V(Uint8, uint8, UINT8, uint8_t, 1)                                           \
   4625   V(Int8, int8, INT8, int8_t, 1)                                               \
   4626   V(Uint16, uint16, UINT16, uint16_t, 2)                                       \
   4627   V(Int16, int16, INT16, int16_t, 2)                                           \
   4628   V(Uint32, uint32, UINT32, uint32_t, 4)                                       \
   4629   V(Int32, int32, INT32, int32_t, 4)                                           \
   4630   V(Float32, float32, FLOAT32, float, 4)                                       \
   4631   V(Float64, float64, FLOAT64, double, 8)                                      \
   4632   V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1)
   4633 
   4634 
   4635 class FixedTypedArrayBase: public FixedArrayBase {
   4636  public:
   4637   // [base_pointer]: Either points to the FixedTypedArrayBase itself or nullptr.
   4638   DECL_ACCESSORS(base_pointer, Object)
   4639 
   4640   // [external_pointer]: Contains the offset between base_pointer and the start
   4641   // of the data. If the base_pointer is a nullptr, the external_pointer
   4642   // therefore points to the actual backing store.
   4643   DECL_ACCESSORS(external_pointer, void)
   4644 
   4645   // Dispatched behavior.
   4646   DECLARE_CAST(FixedTypedArrayBase)
   4647 
   4648   static const int kBasePointerOffset = FixedArrayBase::kHeaderSize;
   4649   static const int kExternalPointerOffset = kBasePointerOffset + kPointerSize;
   4650   static const int kHeaderSize =
   4651       DOUBLE_POINTER_ALIGN(kExternalPointerOffset + kPointerSize);
   4652 
   4653   static const int kDataOffset = kHeaderSize;
   4654 
   4655   class BodyDescriptor;
   4656 
   4657   inline int size();
   4658 
   4659   static inline int TypedArraySize(InstanceType type, int length);
   4660   inline int TypedArraySize(InstanceType type);
   4661 
   4662   // Use with care: returns raw pointer into heap.
   4663   inline void* DataPtr();
   4664 
   4665   inline int DataSize();
   4666 
   4667  private:
   4668   static inline int ElementSize(InstanceType type);
   4669 
   4670   inline int DataSize(InstanceType type);
   4671 
   4672   DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArrayBase);
   4673 };
   4674 
   4675 
   4676 template <class Traits>
   4677 class FixedTypedArray: public FixedTypedArrayBase {
   4678  public:
   4679   typedef typename Traits::ElementType ElementType;
   4680   static const InstanceType kInstanceType = Traits::kInstanceType;
   4681 
   4682   DECLARE_CAST(FixedTypedArray<Traits>)
   4683 
   4684   inline ElementType get_scalar(int index);
   4685   static inline Handle<Object> get(FixedTypedArray* array, int index);
   4686   inline void set(int index, ElementType value);
   4687 
   4688   static inline ElementType from_int(int value);
   4689   static inline ElementType from_double(double value);
   4690 
   4691   // This accessor applies the correct conversion from Smi, HeapNumber
   4692   // and undefined.
   4693   inline void SetValue(uint32_t index, Object* value);
   4694 
   4695   DECLARE_PRINTER(FixedTypedArray)
   4696   DECLARE_VERIFIER(FixedTypedArray)
   4697 
   4698  private:
   4699   DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArray);
   4700 };
   4701 
   4702 #define FIXED_TYPED_ARRAY_TRAITS(Type, type, TYPE, elementType, size)         \
   4703   class Type##ArrayTraits {                                                   \
   4704    public:   /* NOLINT */                                                     \
   4705     typedef elementType ElementType;                                          \
   4706     static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE;      \
   4707     static const char* Designator() { return #type " array"; }                \
   4708     static inline Handle<Object> ToHandle(Isolate* isolate,                   \
   4709                                           elementType scalar);                \
   4710     static inline elementType defaultValue();                                 \
   4711   };                                                                          \
   4712                                                                               \
   4713   typedef FixedTypedArray<Type##ArrayTraits> Fixed##Type##Array;
   4714 
   4715 TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
   4716 
   4717 #undef FIXED_TYPED_ARRAY_TRAITS
   4718 
   4719 // DeoptimizationInputData is a fixed array used to hold the deoptimization
   4720 // data for code generated by the Hydrogen/Lithium compiler.  It also
   4721 // contains information about functions that were inlined.  If N different
   4722 // functions were inlined then first N elements of the literal array will
   4723 // contain these functions.
   4724 //
   4725 // It can be empty.
   4726 class DeoptimizationInputData: public FixedArray {
   4727  public:
   4728   // Layout description.  Indices in the array.
   4729   static const int kTranslationByteArrayIndex = 0;
   4730   static const int kInlinedFunctionCountIndex = 1;
   4731   static const int kLiteralArrayIndex = 2;
   4732   static const int kOsrAstIdIndex = 3;
   4733   static const int kOsrPcOffsetIndex = 4;
   4734   static const int kOptimizationIdIndex = 5;
   4735   static const int kSharedFunctionInfoIndex = 6;
   4736   static const int kWeakCellCacheIndex = 7;
   4737   static const int kInliningPositionsIndex = 8;
   4738   static const int kFirstDeoptEntryIndex = 9;
   4739 
   4740   // Offsets of deopt entry elements relative to the start of the entry.
   4741   static const int kAstIdRawOffset = 0;
   4742   static const int kTranslationIndexOffset = 1;
   4743   static const int kArgumentsStackHeightOffset = 2;
   4744   static const int kPcOffset = 3;
   4745   static const int kDeoptEntrySize = 4;
   4746 
   4747   // Simple element accessors.
   4748 #define DECLARE_ELEMENT_ACCESSORS(name, type) \
   4749   inline type* name();                        \
   4750   inline void Set##name(type* value);
   4751 
   4752   DECLARE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
   4753   DECLARE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
   4754   DECLARE_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
   4755   DECLARE_ELEMENT_ACCESSORS(OsrAstId, Smi)
   4756   DECLARE_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
   4757   DECLARE_ELEMENT_ACCESSORS(OptimizationId, Smi)
   4758   DECLARE_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
   4759   DECLARE_ELEMENT_ACCESSORS(WeakCellCache, Object)
   4760   DECLARE_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>)
   4761 
   4762 #undef DECLARE_ELEMENT_ACCESSORS
   4763 
   4764   // Accessors for elements of the ith deoptimization entry.
   4765 #define DECLARE_ENTRY_ACCESSORS(name, type) \
   4766   inline type* name(int i);                 \
   4767   inline void Set##name(int i, type* value);
   4768 
   4769   DECLARE_ENTRY_ACCESSORS(AstIdRaw, Smi)
   4770   DECLARE_ENTRY_ACCESSORS(TranslationIndex, Smi)
   4771   DECLARE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
   4772   DECLARE_ENTRY_ACCESSORS(Pc, Smi)
   4773 
   4774 #undef DECLARE_ENTRY_ACCESSORS
   4775 
   4776   inline BailoutId AstId(int i);
   4777 
   4778   inline void SetAstId(int i, BailoutId value);
   4779 
   4780   inline int DeoptCount();
   4781 
   4782   static const int kNotInlinedIndex = -1;
   4783 
   4784   // Returns the inlined function at the given position in LiteralArray, or the
   4785   // outer function if index == kNotInlinedIndex.
   4786   class SharedFunctionInfo* GetInlinedFunction(int index);
   4787 
   4788   // Allocates a DeoptimizationInputData.
   4789   static Handle<DeoptimizationInputData> New(Isolate* isolate,
   4790                                              int deopt_entry_count,
   4791                                              PretenureFlag pretenure);
   4792 
   4793   DECLARE_CAST(DeoptimizationInputData)
   4794 
   4795 #ifdef ENABLE_DISASSEMBLER
   4796   void DeoptimizationInputDataPrint(std::ostream& os);  // NOLINT
   4797 #endif
   4798 
   4799  private:
   4800   static int IndexForEntry(int i) {
   4801     return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
   4802   }
   4803 
   4804 
   4805   static int LengthFor(int entry_count) { return IndexForEntry(entry_count); }
   4806 };
   4807 
   4808 // DeoptimizationOutputData is a fixed array used to hold the deoptimization
   4809 // data for code generated by the full compiler.
   4810 // The format of the these objects is
   4811 //   [i * 2]: Ast ID for ith deoptimization.
   4812 //   [i * 2 + 1]: PC and state of ith deoptimization
   4813 class DeoptimizationOutputData: public FixedArray {
   4814  public:
   4815   inline int DeoptPoints();
   4816 
   4817   inline BailoutId AstId(int index);
   4818 
   4819   inline void SetAstId(int index, BailoutId id);
   4820 
   4821   inline Smi* PcAndState(int index);
   4822   inline void SetPcAndState(int index, Smi* offset);
   4823 
   4824   static int LengthOfFixedArray(int deopt_points) {
   4825     return deopt_points * 2;
   4826   }
   4827 
   4828   // Allocates a DeoptimizationOutputData.
   4829   static Handle<DeoptimizationOutputData> New(Isolate* isolate,
   4830                                               int number_of_deopt_points,
   4831                                               PretenureFlag pretenure);
   4832 
   4833   DECLARE_CAST(DeoptimizationOutputData)
   4834 
   4835 #ifdef ENABLE_DISASSEMBLER
   4836   void DeoptimizationOutputDataPrint(std::ostream& os);  // NOLINT
   4837 #endif
   4838 };
   4839 
   4840 class TemplateList : public FixedArray {
   4841  public:
   4842   static Handle<TemplateList> New(Isolate* isolate, int size);
   4843   inline int length() const;
   4844   inline Object* get(int index) const;
   4845   inline void set(int index, Object* value);
   4846   static Handle<TemplateList> Add(Isolate* isolate, Handle<TemplateList> list,
   4847                                   Handle<Object> value);
   4848   DECLARE_CAST(TemplateList)
   4849  private:
   4850   static const int kLengthIndex = 0;
   4851   static const int kFirstElementIndex = kLengthIndex + 1;
   4852   DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateList);
   4853 };
   4854 
   4855 // Code describes objects with on-the-fly generated machine code.
   4856 class Code: public HeapObject {
   4857  public:
   4858   // Opaque data type for encapsulating code flags like kind, inline
   4859   // cache state, and arguments count.
   4860   typedef uint32_t Flags;
   4861 
   4862 #define NON_IC_KIND_LIST(V) \
   4863   V(FUNCTION)               \
   4864   V(OPTIMIZED_FUNCTION)     \
   4865   V(BYTECODE_HANDLER)       \
   4866   V(STUB)                   \
   4867   V(HANDLER)                \
   4868   V(BUILTIN)                \
   4869   V(REGEXP)                 \
   4870   V(WASM_FUNCTION)          \
   4871   V(WASM_TO_JS_FUNCTION)    \
   4872   V(JS_TO_WASM_FUNCTION)    \
   4873   V(WASM_INTERPRETER_ENTRY)
   4874 
   4875 #define IC_KIND_LIST(V) \
   4876   V(LOAD_IC)            \
   4877   V(LOAD_GLOBAL_IC)     \
   4878   V(KEYED_LOAD_IC)      \
   4879   V(STORE_IC)           \
   4880   V(KEYED_STORE_IC)     \
   4881   V(BINARY_OP_IC)       \
   4882   V(COMPARE_IC)         \
   4883   V(TO_BOOLEAN_IC)
   4884 
   4885 #define CODE_KIND_LIST(V) \
   4886   NON_IC_KIND_LIST(V)     \
   4887   IC_KIND_LIST(V)
   4888 
   4889   enum Kind {
   4890 #define DEFINE_CODE_KIND_ENUM(name) name,
   4891     CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
   4892 #undef DEFINE_CODE_KIND_ENUM
   4893     NUMBER_OF_KINDS
   4894   };
   4895 
   4896   static const char* Kind2String(Kind kind);
   4897 
   4898   static const int kPrologueOffsetNotSet = -1;
   4899 
   4900 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
   4901   // Printing
   4902   static const char* ICState2String(InlineCacheState state);
   4903   static void PrintExtraICState(std::ostream& os,  // NOLINT
   4904                                 Kind kind, ExtraICState extra);
   4905 #endif  // defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
   4906 
   4907 #ifdef ENABLE_DISASSEMBLER
   4908   void Disassemble(const char* name, std::ostream& os);  // NOLINT
   4909 #endif  // ENABLE_DISASSEMBLER
   4910 
   4911   // [instruction_size]: Size of the native instructions
   4912   inline int instruction_size() const;
   4913   inline void set_instruction_size(int value);
   4914 
   4915   // [relocation_info]: Code relocation information
   4916   DECL_ACCESSORS(relocation_info, ByteArray)
   4917   void InvalidateRelocation();
   4918   void InvalidateEmbeddedObjects();
   4919 
   4920   // [handler_table]: Fixed array containing offsets of exception handlers.
   4921   DECL_ACCESSORS(handler_table, FixedArray)
   4922 
   4923   // [deoptimization_data]: Array containing data for deopt.
   4924   DECL_ACCESSORS(deoptimization_data, FixedArray)
   4925 
   4926   // [source_position_table]: ByteArray for the source positions table.
   4927   DECL_ACCESSORS(source_position_table, ByteArray)
   4928 
   4929   // [raw_type_feedback_info]: This field stores various things, depending on
   4930   // the kind of the code object.
   4931   //   FUNCTION           => type feedback information.
   4932   //   STUB and ICs       => major/minor key as Smi.
   4933   DECL_ACCESSORS(raw_type_feedback_info, Object)
   4934   inline Object* type_feedback_info();
   4935   inline void set_type_feedback_info(
   4936       Object* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
   4937   inline uint32_t stub_key();
   4938   inline void set_stub_key(uint32_t key);
   4939 
   4940   // [next_code_link]: Link for lists of optimized or deoptimized code.
   4941   // Note that storage for this field is overlapped with typefeedback_info.
   4942   DECL_ACCESSORS(next_code_link, Object)
   4943 
   4944   // [gc_metadata]: Field used to hold GC related metadata. The contents of this
   4945   // field does not have to be traced during garbage collection since
   4946   // it is only used by the garbage collector itself.
   4947   DECL_ACCESSORS(gc_metadata, Object)
   4948 
   4949   // [ic_age]: Inline caching age: the value of the Heap::global_ic_age
   4950   // at the moment when this object was created.
   4951   inline void set_ic_age(int count);
   4952   inline int ic_age() const;
   4953 
   4954   // [prologue_offset]: Offset of the function prologue, used for aging
   4955   // FUNCTIONs and OPTIMIZED_FUNCTIONs.
   4956   inline int prologue_offset() const;
   4957   inline void set_prologue_offset(int offset);
   4958 
   4959   // [constant_pool offset]: Offset of the constant pool.
   4960   // Valid for FLAG_enable_embedded_constant_pool only
   4961   inline int constant_pool_offset() const;
   4962   inline void set_constant_pool_offset(int offset);
   4963 
   4964   // Unchecked accessors to be used during GC.
   4965   inline ByteArray* unchecked_relocation_info();
   4966 
   4967   inline int relocation_size();
   4968 
   4969   // [flags]: Various code flags.
   4970   inline Flags flags();
   4971   inline void set_flags(Flags flags);
   4972 
   4973   // [flags]: Access to specific code flags.
   4974   inline Kind kind();
   4975   inline ExtraICState extra_ic_state();  // Only valid for IC stubs.
   4976 
   4977   // Testers for IC stub kinds.
   4978   inline bool is_inline_cache_stub();
   4979   inline bool is_debug_stub();
   4980   inline bool is_handler();
   4981   inline bool is_stub();
   4982   inline bool is_binary_op_stub();
   4983   inline bool is_compare_ic_stub();
   4984   inline bool is_to_boolean_ic_stub();
   4985   inline bool is_optimized_code();
   4986   inline bool is_wasm_code();
   4987 
   4988   inline bool IsCodeStubOrIC();
   4989 
   4990   inline void set_raw_kind_specific_flags1(int value);
   4991   inline void set_raw_kind_specific_flags2(int value);
   4992 
   4993   // Testers for interpreter builtins.
   4994   inline bool is_interpreter_trampoline_builtin();
   4995 
   4996   // [is_crankshafted]: For kind STUB or ICs, tells whether or not a code
   4997   // object was generated by either the hydrogen or the TurboFan optimizing
   4998   // compiler (but it may not be an optimized function).
   4999   inline bool is_crankshafted();
   5000   inline bool is_hydrogen_stub();  // Crankshafted, but not a function.
   5001   inline void set_is_crankshafted(bool value);
   5002 
   5003   // [is_turbofanned]: For kind STUB or OPTIMIZED_FUNCTION, tells whether the
   5004   // code object was generated by the TurboFan optimizing compiler.
   5005   inline bool is_turbofanned();
   5006   inline void set_is_turbofanned(bool value);
   5007 
   5008   // [can_have_weak_objects]: For kind OPTIMIZED_FUNCTION, tells whether the
   5009   // embedded objects in code should be treated weakly.
   5010   inline bool can_have_weak_objects();
   5011   inline void set_can_have_weak_objects(bool value);
   5012 
   5013   // [is_construct_stub]: For kind BUILTIN, tells whether the code object
   5014   // represents a hand-written construct stub
   5015   // (e.g., NumberConstructor_ConstructStub).
   5016   inline bool is_construct_stub();
   5017   inline void set_is_construct_stub(bool value);
   5018 
   5019   // [has_deoptimization_support]: For FUNCTION kind, tells if it has
   5020   // deoptimization support.
   5021   inline bool has_deoptimization_support();
   5022   inline void set_has_deoptimization_support(bool value);
   5023 
   5024   // [has_debug_break_slots]: For FUNCTION kind, tells if it has
   5025   // been compiled with debug break slots.
   5026   inline bool has_debug_break_slots();
   5027   inline void set_has_debug_break_slots(bool value);
   5028 
   5029   // [has_reloc_info_for_serialization]: For FUNCTION kind, tells if its
   5030   // reloc info includes runtime and external references to support
   5031   // serialization/deserialization.
   5032   inline bool has_reloc_info_for_serialization();
   5033   inline void set_has_reloc_info_for_serialization(bool value);
   5034 
   5035   // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
   5036   // how long the function has been marked for OSR and therefore which
   5037   // level of loop nesting we are willing to do on-stack replacement
   5038   // for.
   5039   inline void set_allow_osr_at_loop_nesting_level(int level);
   5040   inline int allow_osr_at_loop_nesting_level();
   5041 
   5042   // [profiler_ticks]: For FUNCTION kind, tells for how many profiler ticks
   5043   // the code object was seen on the stack with no IC patching going on.
   5044   inline int profiler_ticks();
   5045   inline void set_profiler_ticks(int ticks);
   5046 
   5047   // [builtin_index]: For builtins, tells which builtin index the code object
   5048   // has. Note that builtins can have a code kind other than BUILTIN. The
   5049   // builtin index is a non-negative integer for builtins, and -1 otherwise.
   5050   inline int builtin_index();
   5051   inline void set_builtin_index(int id);
   5052 
   5053   // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
   5054   // reserved in the code prologue.
   5055   inline unsigned stack_slots();
   5056   inline void set_stack_slots(unsigned slots);
   5057 
   5058   // [safepoint_table_start]: For kind OPTIMIZED_FUNCTION, the offset in
   5059   // the instruction stream where the safepoint table starts.
   5060   inline unsigned safepoint_table_offset();
   5061   inline void set_safepoint_table_offset(unsigned offset);
   5062 
   5063   // [back_edge_table_start]: For kind FUNCTION, the offset in the
   5064   // instruction stream where the back edge table starts.
   5065   inline unsigned back_edge_table_offset();
   5066   inline void set_back_edge_table_offset(unsigned offset);
   5067 
   5068   inline bool back_edges_patched_for_osr();
   5069 
   5070   // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
   5071   inline uint16_t to_boolean_state();
   5072 
   5073   // [marked_for_deoptimization]: For kind OPTIMIZED_FUNCTION tells whether
   5074   // the code is going to be deoptimized because of dead embedded maps.
   5075   inline bool marked_for_deoptimization();
   5076   inline void set_marked_for_deoptimization(bool flag);
   5077 
   5078   // [is_promise_rejection]: For kind BUILTIN tells whether the exception
   5079   // thrown by the code will lead to promise rejection.
   5080   inline bool is_promise_rejection();
   5081   inline void set_is_promise_rejection(bool flag);
   5082 
   5083   // [is_exception_caught]: For kind BUILTIN tells whether the exception
   5084   // thrown by the code will be caught internally.
   5085   inline bool is_exception_caught();
   5086   inline void set_is_exception_caught(bool flag);
   5087 
   5088   // [constant_pool]: The constant pool for this function.
   5089   inline Address constant_pool();
   5090 
   5091   // Get the safepoint entry for the given pc.
   5092   SafepointEntry GetSafepointEntry(Address pc);
   5093 
   5094   // Find an object in a stub with a specified map
   5095   Object* FindNthObject(int n, Map* match_map);
   5096 
   5097   // Find the first allocation site in an IC stub.
   5098   AllocationSite* FindFirstAllocationSite();
   5099 
   5100   // Find the first map in an IC stub.
   5101   Map* FindFirstMap();
   5102 
   5103   // For each (map-to-find, object-to-replace) pair in the pattern, this
   5104   // function replaces the corresponding placeholder in the code with the
   5105   // object-to-replace. The function assumes that pairs in the pattern come in
   5106   // the same order as the placeholders in the code.
   5107   // If the placeholder is a weak cell, then the value of weak cell is matched
   5108   // against the map-to-find.
   5109   void FindAndReplace(const FindAndReplacePattern& pattern);
   5110 
   5111   // The entire code object including its header is copied verbatim to the
   5112   // snapshot so that it can be written in one, fast, memcpy during
   5113   // deserialization. The deserializer will overwrite some pointers, rather
   5114   // like a runtime linker, but the random allocation addresses used in the
   5115   // mksnapshot process would still be present in the unlinked snapshot data,
   5116   // which would make snapshot production non-reproducible. This method wipes
   5117   // out the to-be-overwritten header data for reproducible snapshots.
   5118   inline void WipeOutHeader();
   5119 
   5120   // Flags operations.
   5121   static inline Flags ComputeFlags(
   5122       Kind kind, ExtraICState extra_ic_state = kNoExtraICState,
   5123       CacheHolderFlag holder = kCacheOnReceiver);
   5124 
   5125   static inline Flags ComputeHandlerFlags(
   5126       Kind handler_kind, CacheHolderFlag holder = kCacheOnReceiver);
   5127 
   5128   static inline CacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
   5129   static inline Kind ExtractKindFromFlags(Flags flags);
   5130   static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
   5131 
   5132   static inline Flags RemoveHolderFromFlags(Flags flags);
   5133 
   5134   // Convert a target address into a code object.
   5135   static inline Code* GetCodeFromTargetAddress(Address address);
   5136 
   5137   // Convert an entry address into an object.
   5138   static inline Object* GetObjectFromEntryAddress(Address location_of_address);
   5139 
   5140   // Returns the address of the first instruction.
   5141   inline byte* instruction_start();
   5142 
   5143   // Returns the address right after the last instruction.
   5144   inline byte* instruction_end();
   5145 
   5146   // Returns the size of the instructions, padding, relocation and unwinding
   5147   // information.
   5148   inline int body_size();
   5149 
   5150   // Returns the size of code and its metadata. This includes the size of code
   5151   // relocation information, deoptimization data and handler table.
   5152   inline int SizeIncludingMetadata();
   5153 
   5154   // Returns the address of the first relocation info (read backwards!).
   5155   inline byte* relocation_start();
   5156 
   5157   // [has_unwinding_info]: Whether this code object has unwinding information.
   5158   // If it doesn't, unwinding_information_start() will point to invalid data.
   5159   //
   5160   // The body of all code objects has the following layout.
   5161   //
   5162   //  +--------------------------+  <-- instruction_start()
   5163   //  |       instructions       |
   5164   //  |           ...            |
   5165   //  +--------------------------+
   5166   //  |      relocation info     |
   5167   //  |           ...            |
   5168   //  +--------------------------+  <-- instruction_end()
   5169   //
   5170   // If has_unwinding_info() is false, instruction_end() points to the first
   5171   // memory location after the end of the code object. Otherwise, the body
   5172   // continues as follows:
   5173   //
   5174   //  +--------------------------+
   5175   //  |    padding to the next   |
   5176   //  |  8-byte aligned address  |
   5177   //  +--------------------------+  <-- instruction_end()
   5178   //  |   [unwinding_info_size]  |
   5179   //  |        as uint64_t       |
   5180   //  +--------------------------+  <-- unwinding_info_start()
   5181   //  |       unwinding info     |
   5182   //  |            ...           |
   5183   //  +--------------------------+  <-- unwinding_info_end()
   5184   //
   5185   // and unwinding_info_end() points to the first memory location after the end
   5186   // of the code object.
   5187   //
   5188   DECL_BOOLEAN_ACCESSORS(has_unwinding_info)
   5189 
   5190   // [unwinding_info_size]: Size of the unwinding information.
   5191   inline int unwinding_info_size() const;
   5192   inline void set_unwinding_info_size(int value);
   5193 
   5194   // Returns the address of the unwinding information, if any.
   5195   inline byte* unwinding_info_start();
   5196 
   5197   // Returns the address right after the end of the unwinding information.
   5198   inline byte* unwinding_info_end();
   5199 
   5200   // Code entry point.
   5201   inline byte* entry();
   5202 
   5203   // Returns true if pc is inside this object's instructions.
   5204   inline bool contains(byte* pc);
   5205 
   5206   // Relocate the code by delta bytes. Called to signal that this code
   5207   // object has been moved by delta bytes.
   5208   void Relocate(intptr_t delta);
   5209 
   5210   // Migrate code described by desc.
   5211   void CopyFrom(const CodeDesc& desc);
   5212 
   5213   // Returns the object size for a given body (used for allocation).
   5214   static int SizeFor(int body_size) {
   5215     DCHECK_SIZE_TAG_ALIGNED(body_size);
   5216     return RoundUp(kHeaderSize + body_size, kCodeAlignment);
   5217   }
   5218 
   5219   // Calculate the size of the code object to report for log events. This takes
   5220   // the layout of the code object into account.
   5221   inline int ExecutableSize();
   5222 
   5223   DECLARE_CAST(Code)
   5224 
   5225   // Dispatched behavior.
   5226   inline int CodeSize();
   5227 
   5228   DECLARE_PRINTER(Code)
   5229   DECLARE_VERIFIER(Code)
   5230 
   5231   void ClearInlineCaches();
   5232 
   5233   BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
   5234   uint32_t TranslateAstIdToPcOffset(BailoutId ast_id);
   5235 
   5236 #define DECLARE_CODE_AGE_ENUM(X) k##X##CodeAge,
   5237   enum Age {
   5238     kToBeExecutedOnceCodeAge = -3,
   5239     kNotExecutedCodeAge = -2,
   5240     kExecutedOnceCodeAge = -1,
   5241     kNoAgeCodeAge = 0,
   5242     CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
   5243     kAfterLastCodeAge,
   5244     kFirstCodeAge = kToBeExecutedOnceCodeAge,
   5245     kLastCodeAge = kAfterLastCodeAge - 1,
   5246     kCodeAgeCount = kAfterLastCodeAge - kFirstCodeAge - 1,
   5247     kIsOldCodeAge = kSexagenarianCodeAge,
   5248     kPreAgedCodeAge = kIsOldCodeAge - 1
   5249   };
   5250 #undef DECLARE_CODE_AGE_ENUM
   5251 
   5252   // Code aging.  Indicates how many full GCs this code has survived without
   5253   // being entered through the prologue.  Used to determine when it is
   5254   // relatively safe to flush this code object and replace it with the lazy
   5255   // compilation stub.
   5256   static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
   5257   static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
   5258   void MakeYoung(Isolate* isolate);
   5259   void PreAge(Isolate* isolate);
   5260   void MarkToBeExecutedOnce(Isolate* isolate);
   5261   void MakeOlder();
   5262   static bool IsYoungSequence(Isolate* isolate, byte* sequence);
   5263   bool IsOld();
   5264   Age GetAge();
   5265   static inline Code* GetPreAgedCodeAgeStub(Isolate* isolate) {
   5266     return GetCodeAgeStub(isolate, kNotExecutedCodeAge);
   5267   }
   5268 
   5269   void PrintDeoptLocation(FILE* out, Address pc);
   5270   bool CanDeoptAt(Address pc);
   5271 
   5272 #ifdef VERIFY_HEAP
   5273   void VerifyEmbeddedObjectsDependency();
   5274 #endif
   5275 
   5276 #ifdef DEBUG
   5277   enum VerifyMode { kNoContextSpecificPointers, kNoContextRetainingPointers };
   5278   void VerifyEmbeddedObjects(VerifyMode mode = kNoContextRetainingPointers);
   5279   static void VerifyRecompiledCode(Code* old_code, Code* new_code);
   5280 #endif  // DEBUG
   5281 
   5282   inline bool CanContainWeakObjects();
   5283 
   5284   inline bool IsWeakObject(Object* object);
   5285 
   5286   static inline bool IsWeakObjectInOptimizedCode(Object* object);
   5287 
   5288   static Handle<WeakCell> WeakCellFor(Handle<Code> code);
   5289   WeakCell* CachedWeakCell();
   5290 
   5291   static const int kConstantPoolSize =
   5292       FLAG_enable_embedded_constant_pool ? kIntSize : 0;
   5293 
   5294   // Layout description.
   5295   static const int kRelocationInfoOffset = HeapObject::kHeaderSize;
   5296   static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
   5297   static const int kDeoptimizationDataOffset =
   5298       kHandlerTableOffset + kPointerSize;
   5299   static const int kSourcePositionTableOffset =
   5300       kDeoptimizationDataOffset + kPointerSize;
   5301   // For FUNCTION kind, we store the type feedback info here.
   5302   static const int kTypeFeedbackInfoOffset =
   5303       kSourcePositionTableOffset + kPointerSize;
   5304   static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset + kPointerSize;
   5305   static const int kGCMetadataOffset = kNextCodeLinkOffset + kPointerSize;
   5306   static const int kInstructionSizeOffset = kGCMetadataOffset + kPointerSize;
   5307   static const int kICAgeOffset = kInstructionSizeOffset + kIntSize;
   5308   static const int kFlagsOffset = kICAgeOffset + kIntSize;
   5309   static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
   5310   static const int kKindSpecificFlags2Offset =
   5311       kKindSpecificFlags1Offset + kIntSize;
   5312   // Note: We might be able to squeeze this into the flags above.
   5313   static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
   5314   static const int kConstantPoolOffset = kPrologueOffset + kIntSize;
   5315   static const int kBuiltinIndexOffset =
   5316       kConstantPoolOffset + kConstantPoolSize;
   5317   static const int kHeaderPaddingStart = kBuiltinIndexOffset + kIntSize;
   5318 
   5319   enum TrapFields { kTrapCodeOffset, kTrapLandingOffset, kTrapDataSize };
   5320 
   5321 
   5322   // Add padding to align the instruction start following right after
   5323   // the Code object header.
   5324   static const int kHeaderSize =
   5325       (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
   5326 
   5327   inline int GetUnwindingInfoSizeOffset() const;
   5328 
   5329   class BodyDescriptor;
   5330 
   5331   // Byte offsets within kKindSpecificFlags1Offset.
   5332   static const int kFullCodeFlags = kKindSpecificFlags1Offset;
   5333   class FullCodeFlagsHasDeoptimizationSupportField:
   5334       public BitField<bool, 0, 1> {};  // NOLINT
   5335   class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {};
   5336   class FullCodeFlagsHasRelocInfoForSerialization
   5337       : public BitField<bool, 2, 1> {};
   5338   // Bit 3 in this bitfield is unused.
   5339   class ProfilerTicksField : public BitField<int, 4, 28> {};
   5340 
   5341   // Flags layout.  BitField<type, shift, size>.
   5342   class HasUnwindingInfoField : public BitField<bool, 0, 1> {};
   5343   class CacheHolderField
   5344       : public BitField<CacheHolderFlag, HasUnwindingInfoField::kNext, 2> {};
   5345   class KindField : public BitField<Kind, CacheHolderField::kNext, 5> {};
   5346   STATIC_ASSERT(NUMBER_OF_KINDS <= KindField::kMax);
   5347   class ExtraICStateField
   5348       : public BitField<ExtraICState, KindField::kNext,
   5349                         PlatformSmiTagging::kSmiValueSize - KindField::kNext> {
   5350   };
   5351 
   5352   // KindSpecificFlags1 layout (STUB, BUILTIN and OPTIMIZED_FUNCTION)
   5353   static const int kStackSlotsFirstBit = 0;
   5354   static const int kStackSlotsBitCount = 24;
   5355   static const int kMarkedForDeoptimizationBit =
   5356       kStackSlotsFirstBit + kStackSlotsBitCount;
   5357   static const int kIsTurbofannedBit = kMarkedForDeoptimizationBit + 1;
   5358   static const int kCanHaveWeakObjects = kIsTurbofannedBit + 1;
   5359   // Could be moved to overlap previous bits when we need more space.
   5360   static const int kIsConstructStub = kCanHaveWeakObjects + 1;
   5361   static const int kIsPromiseRejection = kIsConstructStub + 1;
   5362   static const int kIsExceptionCaught = kIsPromiseRejection + 1;
   5363 
   5364   STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
   5365   STATIC_ASSERT(kIsExceptionCaught + 1 <= 32);
   5366 
   5367   class StackSlotsField: public BitField<int,
   5368       kStackSlotsFirstBit, kStackSlotsBitCount> {};  // NOLINT
   5369   class MarkedForDeoptimizationField
   5370       : public BitField<bool, kMarkedForDeoptimizationBit, 1> {};  // NOLINT
   5371   class IsTurbofannedField : public BitField<bool, kIsTurbofannedBit, 1> {
   5372   };  // NOLINT
   5373   class CanHaveWeakObjectsField
   5374       : public BitField<bool, kCanHaveWeakObjects, 1> {};  // NOLINT
   5375   class IsConstructStubField : public BitField<bool, kIsConstructStub, 1> {
   5376   };  // NOLINT
   5377   class IsPromiseRejectionField
   5378       : public BitField<bool, kIsPromiseRejection, 1> {};  // NOLINT
   5379   class IsExceptionCaughtField : public BitField<bool, kIsExceptionCaught, 1> {
   5380   };  // NOLINT
   5381 
   5382   // KindSpecificFlags2 layout (ALL)
   5383   static const int kIsCrankshaftedBit = 0;
   5384   class IsCrankshaftedField: public BitField<bool,
   5385       kIsCrankshaftedBit, 1> {};  // NOLINT
   5386 
   5387   // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
   5388   static const int kSafepointTableOffsetFirstBit = kIsCrankshaftedBit + 1;
   5389   static const int kSafepointTableOffsetBitCount = 30;
   5390 
   5391   STATIC_ASSERT(kSafepointTableOffsetFirstBit +
   5392                 kSafepointTableOffsetBitCount <= 32);
   5393   STATIC_ASSERT(1 + kSafepointTableOffsetBitCount <= 32);
   5394 
   5395   class SafepointTableOffsetField: public BitField<int,
   5396       kSafepointTableOffsetFirstBit,
   5397       kSafepointTableOffsetBitCount> {};  // NOLINT
   5398 
   5399   // KindSpecificFlags2 layout (FUNCTION)
   5400   class BackEdgeTableOffsetField: public BitField<int,
   5401       kIsCrankshaftedBit + 1, 27> {};  // NOLINT
   5402   class AllowOSRAtLoopNestingLevelField: public BitField<int,
   5403       kIsCrankshaftedBit + 1 + 27, 4> {};  // NOLINT
   5404 
   5405   static const int kArgumentsBits = 16;
   5406   static const int kMaxArguments = (1 << kArgumentsBits) - 1;
   5407 
   5408   // This constant should be encodable in an ARM instruction.
   5409   static const int kFlagsNotUsedInLookup = CacheHolderField::kMask;
   5410 
   5411  private:
   5412   friend class RelocIterator;
   5413   friend class Deoptimizer;  // For FindCodeAgeSequence.
   5414 
   5415   // Code aging
   5416   byte* FindCodeAgeSequence();
   5417   static Age GetCodeAge(Isolate* isolate, byte* sequence);
   5418   static Age GetAgeOfCodeAgeStub(Code* code);
   5419   static Code* GetCodeAgeStub(Isolate* isolate, Age age);
   5420 
   5421   // Code aging -- platform-specific
   5422   static void PatchPlatformCodeAge(Isolate* isolate, byte* sequence, Age age);
   5423 
   5424   DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
   5425 };
   5426 
   5427 class AbstractCode : public HeapObject {
   5428  public:
   5429   // All code kinds and INTERPRETED_FUNCTION.
   5430   enum Kind {
   5431 #define DEFINE_CODE_KIND_ENUM(name) name,
   5432     CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
   5433 #undef DEFINE_CODE_KIND_ENUM
   5434         INTERPRETED_FUNCTION,
   5435     NUMBER_OF_KINDS
   5436   };
   5437 
   5438   static const char* Kind2String(Kind kind);
   5439 
   5440   int SourcePosition(int offset);
   5441   int SourceStatementPosition(int offset);
   5442 
   5443   // Returns the address of the first instruction.
   5444   inline Address instruction_start();
   5445 
   5446   // Returns the address right after the last instruction.
   5447   inline Address instruction_end();
   5448 
   5449   // Returns the size of the code instructions.
   5450   inline int instruction_size();
   5451 
   5452   // Return the source position table.
   5453   inline ByteArray* source_position_table();
   5454 
   5455   // Set the source position table.
   5456   inline void set_source_position_table(ByteArray* source_position_table);
   5457 
   5458   // Returns the size of instructions and the metadata.
   5459   inline int SizeIncludingMetadata();
   5460 
   5461   // Returns true if pc is inside this object's instructions.
   5462   inline bool contains(byte* pc);
   5463 
   5464   // Returns the AbstractCode::Kind of the code.
   5465   inline Kind kind();
   5466 
   5467   // Calculate the size of the code object to report for log events. This takes
   5468   // the layout of the code object into account.
   5469   inline int ExecutableSize();
   5470 
   5471   DECLARE_CAST(AbstractCode)
   5472   inline Code* GetCode();
   5473   inline BytecodeArray* GetBytecodeArray();
   5474 
   5475   // Max loop nesting marker used to postpose OSR. We don't take loop
   5476   // nesting that is deeper than 5 levels into account.
   5477   static const int kMaxLoopNestingMarker = 6;
   5478   STATIC_ASSERT(Code::AllowOSRAtLoopNestingLevelField::kMax >=
   5479                 kMaxLoopNestingMarker);
   5480 };
   5481 
   5482 // Dependent code is a singly linked list of fixed arrays. Each array contains
   5483 // code objects in weak cells for one dependent group. The suffix of the array
   5484 // can be filled with the undefined value if the number of codes is less than
   5485 // the length of the array.
   5486 //
   5487 // +------+-----------------+--------+--------+-----+--------+-----------+-----+
   5488 // | next | count & group 1 | code 1 | code 2 | ... | code n | undefined | ... |
   5489 // +------+-----------------+--------+--------+-----+--------+-----------+-----+
   5490 //    |
   5491 //    V
   5492 // +------+-----------------+--------+--------+-----+--------+-----------+-----+
   5493 // | next | count & group 2 | code 1 | code 2 | ... | code m | undefined | ... |
   5494 // +------+-----------------+--------+--------+-----+--------+-----------+-----+
   5495 //    |
   5496 //    V
   5497 // empty_fixed_array()
   5498 //
   5499 // The list of fixed arrays is ordered by dependency groups.
   5500 
   5501 class DependentCode: public FixedArray {
   5502  public:
   5503   enum DependencyGroup {
   5504     // Group of code that weakly embed this map and depend on being
   5505     // deoptimized when the map is garbage collected.
   5506     kWeakCodeGroup,
   5507     // Group of code that embed a transition to this map, and depend on being
   5508     // deoptimized when the transition is replaced by a new version.
   5509     kTransitionGroup,
   5510     // Group of code that omit run-time prototype checks for prototypes
   5511     // described by this map. The group is deoptimized whenever an object
   5512     // described by this map changes shape (and transitions to a new map),
   5513     // possibly invalidating the assumptions embedded in the code.
   5514     kPrototypeCheckGroup,
   5515     // Group of code that depends on global property values in property cells
   5516     // not being changed.
   5517     kPropertyCellChangedGroup,
   5518     // Group of code that omit run-time checks for field(s) introduced by
   5519     // this map, i.e. for the field type.
   5520     kFieldOwnerGroup,
   5521     // Group of code that omit run-time type checks for initial maps of
   5522     // constructors.
   5523     kInitialMapChangedGroup,
   5524     // Group of code that depends on tenuring information in AllocationSites
   5525     // not being changed.
   5526     kAllocationSiteTenuringChangedGroup,
   5527     // Group of code that depends on element transition information in
   5528     // AllocationSites not being changed.
   5529     kAllocationSiteTransitionChangedGroup
   5530   };
   5531 
   5532   static const int kGroupCount = kAllocationSiteTransitionChangedGroup + 1;
   5533   static const int kNextLinkIndex = 0;
   5534   static const int kFlagsIndex = 1;
   5535   static const int kCodesStartIndex = 2;
   5536 
   5537   bool Contains(DependencyGroup group, WeakCell* code_cell);
   5538   bool IsEmpty(DependencyGroup group);
   5539 
   5540   static Handle<DependentCode> InsertCompilationDependencies(
   5541       Handle<DependentCode> entries, DependencyGroup group,
   5542       Handle<Foreign> info);
   5543 
   5544   static Handle<DependentCode> InsertWeakCode(Handle<DependentCode> entries,
   5545                                               DependencyGroup group,
   5546                                               Handle<WeakCell> code_cell);
   5547 
   5548   void UpdateToFinishedCode(DependencyGroup group, Foreign* info,
   5549                             WeakCell* code_cell);
   5550 
   5551   void RemoveCompilationDependencies(DependentCode::DependencyGroup group,
   5552                                      Foreign* info);
   5553 
   5554   void DeoptimizeDependentCodeGroup(Isolate* isolate,
   5555                                     DependentCode::DependencyGroup group);
   5556 
   5557   bool MarkCodeForDeoptimization(Isolate* isolate,
   5558                                  DependentCode::DependencyGroup group);
   5559 
   5560   // The following low-level accessors should only be used by this class
   5561   // and the mark compact collector.
   5562   inline DependentCode* next_link();
   5563   inline void set_next_link(DependentCode* next);
   5564   inline int count();
   5565   inline void set_count(int value);
   5566   inline DependencyGroup group();
   5567   inline void set_group(DependencyGroup group);
   5568   inline Object* object_at(int i);
   5569   inline void set_object_at(int i, Object* object);
   5570   inline void clear_at(int i);
   5571   inline void copy(int from, int to);
   5572   DECLARE_CAST(DependentCode)
   5573 
   5574   static const char* DependencyGroupName(DependencyGroup group);
   5575   static void SetMarkedForDeoptimization(Code* code, DependencyGroup group);
   5576 
   5577  private:
   5578   static Handle<DependentCode> Insert(Handle<DependentCode> entries,
   5579                                       DependencyGroup group,
   5580                                       Handle<Object> object);
   5581   static Handle<DependentCode> New(DependencyGroup group, Handle<Object> object,
   5582                                    Handle<DependentCode> next);
   5583   static Handle<DependentCode> EnsureSpace(Handle<DependentCode> entries);
   5584   // Compact by removing cleared weak cells and return true if there was
   5585   // any cleared weak cell.
   5586   bool Compact();
   5587   static int Grow(int number_of_entries) {
   5588     if (number_of_entries < 5) return number_of_entries + 1;
   5589     return number_of_entries * 5 / 4;
   5590   }
   5591   inline int flags();
   5592   inline void set_flags(int flags);
   5593   class GroupField : public BitField<int, 0, 3> {};
   5594   class CountField : public BitField<int, 3, 27> {};
   5595   STATIC_ASSERT(kGroupCount <= GroupField::kMax + 1);
   5596 };
   5597 
   5598 
   5599 class PrototypeInfo;
   5600 
   5601 
   5602 // All heap objects have a Map that describes their structure.
   5603 //  A Map contains information about:
   5604 //  - Size information about the object
   5605 //  - How to iterate over an object (for garbage collection)
   5606 class Map: public HeapObject {
   5607  public:
   5608   // Instance size.
   5609   // Size in bytes or kVariableSizeSentinel if instances do not have
   5610   // a fixed size.
   5611   inline int instance_size();
   5612   inline void set_instance_size(int value);
   5613 
   5614   // Only to clear an unused byte, remove once byte is used.
   5615   inline void clear_unused();
   5616 
   5617   // [inobject_properties_or_constructor_function_index]: Provides access
   5618   // to the inobject properties in case of JSObject maps, or the constructor
   5619   // function index in case of primitive maps.
   5620   inline int inobject_properties_or_constructor_function_index();
   5621   inline void set_inobject_properties_or_constructor_function_index(int value);
   5622   // Count of properties allocated in the object (JSObject only).
   5623   inline int GetInObjectProperties();
   5624   inline void SetInObjectProperties(int value);
   5625   // Index of the constructor function in the native context (primitives only),
   5626   // or the special sentinel value to indicate that there is no object wrapper
   5627   // for the primitive (i.e. in case of null or undefined).
   5628   static const int kNoConstructorFunctionIndex = 0;
   5629   inline int GetConstructorFunctionIndex();
   5630   inline void SetConstructorFunctionIndex(int value);
   5631   static MaybeHandle<JSFunction> GetConstructorFunction(
   5632       Handle<Map> map, Handle<Context> native_context);
   5633 
   5634   // Retrieve interceptors.
   5635   inline InterceptorInfo* GetNamedInterceptor();
   5636   inline InterceptorInfo* GetIndexedInterceptor();
   5637 
   5638   // Instance type.
   5639   inline InstanceType instance_type();
   5640   inline void set_instance_type(InstanceType value);
   5641 
   5642   // Tells how many unused property fields are available in the
   5643   // instance (only used for JSObject in fast mode).
   5644   inline int unused_property_fields();
   5645   inline void set_unused_property_fields(int value);
   5646 
   5647   // Bit field.
   5648   inline byte bit_field() const;
   5649   inline void set_bit_field(byte value);
   5650 
   5651   // Bit field 2.
   5652   inline byte bit_field2() const;
   5653   inline void set_bit_field2(byte value);
   5654 
   5655   // Bit field 3.
   5656   inline uint32_t bit_field3() const;
   5657   inline void set_bit_field3(uint32_t bits);
   5658 
   5659   class EnumLengthBits:             public BitField<int,
   5660       0, kDescriptorIndexBitCount> {};  // NOLINT
   5661   class NumberOfOwnDescriptorsBits: public BitField<int,
   5662       kDescriptorIndexBitCount, kDescriptorIndexBitCount> {};  // NOLINT
   5663   STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20);
   5664   class DictionaryMap : public BitField<bool, 20, 1> {};
   5665   class OwnsDescriptors : public BitField<bool, 21, 1> {};
   5666   class HasHiddenPrototype : public BitField<bool, 22, 1> {};
   5667   class Deprecated : public BitField<bool, 23, 1> {};
   5668   class IsUnstable : public BitField<bool, 24, 1> {};
   5669   class IsMigrationTarget : public BitField<bool, 25, 1> {};
   5670   class ImmutablePrototype : public BitField<bool, 26, 1> {};
   5671   class NewTargetIsBase : public BitField<bool, 27, 1> {};
   5672   // Bit 28 is free.
   5673 
   5674   // Keep this bit field at the very end for better code in
   5675   // Builtins::kJSConstructStubGeneric stub.
   5676   // This counter is used for in-object slack tracking.
   5677   // The in-object slack tracking is considered enabled when the counter is
   5678   // non zero. The counter only has a valid count for initial maps. For
   5679   // transitioned maps only kNoSlackTracking has a meaning, namely that inobject
   5680   // slack tracking already finished for the transition tree. Any other value
   5681   // indicates that either inobject slack tracking is still in progress, or that
   5682   // the map isn't part of the transition tree anymore.
   5683   class ConstructionCounter : public BitField<int, 29, 3> {};
   5684   static const int kSlackTrackingCounterStart = 7;
   5685   static const int kSlackTrackingCounterEnd = 1;
   5686   static const int kNoSlackTracking = 0;
   5687   STATIC_ASSERT(kSlackTrackingCounterStart <= ConstructionCounter::kMax);
   5688 
   5689 
   5690   // Inobject slack tracking is the way to reclaim unused inobject space.
   5691   //
   5692   // The instance size is initially determined by adding some slack to
   5693   // expected_nof_properties (to allow for a few extra properties added
   5694   // after the constructor). There is no guarantee that the extra space
   5695   // will not be wasted.
   5696   //
   5697   // Here is the algorithm to reclaim the unused inobject space:
   5698   // - Detect the first constructor call for this JSFunction.
   5699   //   When it happens enter the "in progress" state: initialize construction
   5700   //   counter in the initial_map.
   5701   // - While the tracking is in progress initialize unused properties of a new
   5702   //   object with one_pointer_filler_map instead of undefined_value (the "used"
   5703   //   part is initialized with undefined_value as usual). This way they can
   5704   //   be resized quickly and safely.
   5705   // - Once enough objects have been created  compute the 'slack'
   5706   //   (traverse the map transition tree starting from the
   5707   //   initial_map and find the lowest value of unused_property_fields).
   5708   // - Traverse the transition tree again and decrease the instance size
   5709   //   of every map. Existing objects will resize automatically (they are
   5710   //   filled with one_pointer_filler_map). All further allocations will
   5711   //   use the adjusted instance size.
   5712   // - SharedFunctionInfo's expected_nof_properties left unmodified since
   5713   //   allocations made using different closures could actually create different
   5714   //   kind of objects (see prototype inheritance pattern).
   5715   //
   5716   //  Important: inobject slack tracking is not attempted during the snapshot
   5717   //  creation.
   5718 
   5719   static const int kGenerousAllocationCount =
   5720       kSlackTrackingCounterStart - kSlackTrackingCounterEnd + 1;
   5721 
   5722   // Starts the tracking by initializing object constructions countdown counter.
   5723   void StartInobjectSlackTracking();
   5724 
   5725   // True if the object constructions countdown counter is a range
   5726   // [kSlackTrackingCounterEnd, kSlackTrackingCounterStart].
   5727   inline bool IsInobjectSlackTrackingInProgress();
   5728 
   5729   // Does the tracking step.
   5730   inline void InobjectSlackTrackingStep();
   5731 
   5732   // Completes inobject slack tracking for the transition tree starting at this
   5733   // initial map.
   5734   void CompleteInobjectSlackTracking();
   5735 
   5736   // Tells whether the object in the prototype property will be used
   5737   // for instances created from this function.  If the prototype
   5738   // property is set to a value that is not a JSObject, the prototype
   5739   // property will not be used to create instances of the function.
   5740   // See ECMA-262, 13.2.2.
   5741   inline void set_non_instance_prototype(bool value);
   5742   inline bool has_non_instance_prototype();
   5743 
   5744   // Tells whether the instance has a [[Construct]] internal method.
   5745   // This property is implemented according to ES6, section 7.2.4.
   5746   inline void set_is_constructor(bool value);
   5747   inline bool is_constructor() const;
   5748 
   5749   // Tells whether the instance with this map has a hidden prototype.
   5750   inline void set_has_hidden_prototype(bool value);
   5751   inline bool has_hidden_prototype() const;
   5752 
   5753   // Records and queries whether the instance has a named interceptor.
   5754   inline void set_has_named_interceptor();
   5755   inline bool has_named_interceptor();
   5756 
   5757   // Records and queries whether the instance has an indexed interceptor.
   5758   inline void set_has_indexed_interceptor();
   5759   inline bool has_indexed_interceptor();
   5760 
   5761   // Tells whether the instance is undetectable.
   5762   // An undetectable object is a special class of JSObject: 'typeof' operator
   5763   // returns undefined, ToBoolean returns false. Otherwise it behaves like
   5764   // a normal JS object.  It is useful for implementing undetectable
   5765   // document.all in Firefox & Safari.
   5766   // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
   5767   inline void set_is_undetectable();
   5768   inline bool is_undetectable();
   5769 
   5770   // Tells whether the instance has a [[Call]] internal method.
   5771   // This property is implemented according to ES6, section 7.2.3.
   5772   inline void set_is_callable();
   5773   inline bool is_callable() const;
   5774 
   5775   inline void set_new_target_is_base(bool value);
   5776   inline bool new_target_is_base();
   5777   inline void set_is_extensible(bool value);
   5778   inline bool is_extensible();
   5779   inline void set_is_prototype_map(bool value);
   5780   inline bool is_prototype_map() const;
   5781 
   5782   inline void set_elements_kind(ElementsKind elements_kind);
   5783   inline ElementsKind elements_kind();
   5784 
   5785   // Tells whether the instance has fast elements that are only Smis.
   5786   inline bool has_fast_smi_elements();
   5787 
   5788   // Tells whether the instance has fast elements.
   5789   inline bool has_fast_object_elements();
   5790   inline bool has_fast_smi_or_object_elements();
   5791   inline bool has_fast_double_elements();
   5792   inline bool has_fast_elements();
   5793   inline bool has_sloppy_arguments_elements();
   5794   inline bool has_fast_sloppy_arguments_elements();
   5795   inline bool has_fast_string_wrapper_elements();
   5796   inline bool has_fixed_typed_array_elements();
   5797   inline bool has_dictionary_elements();
   5798 
   5799   static bool IsValidElementsTransition(ElementsKind from_kind,
   5800                                         ElementsKind to_kind);
   5801 
   5802   // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a
   5803   // map with DICTIONARY_ELEMENTS was found in the prototype chain.
   5804   bool DictionaryElementsInPrototypeChainOnly();
   5805 
   5806   inline Map* ElementsTransitionMap();
   5807 
   5808   inline FixedArrayBase* GetInitialElements();
   5809 
   5810   // [raw_transitions]: Provides access to the transitions storage field.
   5811   // Don't call set_raw_transitions() directly to overwrite transitions, use
   5812   // the TransitionArray::ReplaceTransitions() wrapper instead!
   5813   DECL_ACCESSORS(raw_transitions, Object)
   5814   // [prototype_info]: Per-prototype metadata. Aliased with transitions
   5815   // (which prototype maps don't have).
   5816   DECL_ACCESSORS(prototype_info, Object)
   5817   // PrototypeInfo is created lazily using this helper (which installs it on
   5818   // the given prototype's map).
   5819   static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
   5820       Handle<JSObject> prototype, Isolate* isolate);
   5821   static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
   5822       Handle<Map> prototype_map, Isolate* isolate);
   5823   inline bool should_be_fast_prototype_map() const;
   5824   static void SetShouldBeFastPrototypeMap(Handle<Map> map, bool value,
   5825                                           Isolate* isolate);